This commit is contained in:
		
							
								
								
									
										11
									
								
								.clang-tidy
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								.clang-tidy
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | |||||||
|  | Checks: 'readability-*,clang-diagnostic-*,clang-analyzer-*,-clang-analyzer-alpha*,performance-*,cppcoreguidelines-*, | ||||||
|  | bugprone-*,modernize-*,-modernize-use-trailing-return-type' | ||||||
|  | HeaderFilterRegex: '' | ||||||
|  | AnalyzeTemporaryDtors: false | ||||||
|  | CheckOptions: | ||||||
|  |   - key: readability-identifier-naming.ClassCase | ||||||
|  |     value: CamelCase | ||||||
|  |   - key: readability-identifier-naming.PrivateMemberCase | ||||||
|  |     value: camelBack | ||||||
|  |   - key: readability-identifier-naming.PrivateMemberPrefix | ||||||
|  |     value: '_' | ||||||
| @@ -4,7 +4,8 @@ | |||||||
| #include "../Assert.hpp" | #include "../Assert.hpp" | ||||||
|  |  | ||||||
| namespace ArbUt { | namespace ArbUt { | ||||||
|     /// @brief A borrowed pointer is used to indicate a pointer that is not owned by its holder. |     /// @brief A borrowed pointer is used to indicate a pointer that is not owned by its holder. As with all Arbutils | ||||||
|  |     /// pointers, this cannot be assigned null. Use an OptionalBorrowedPtr for pointers that can be null. | ||||||
|     /// @details A borrowed pointer is used to indicate a pointer that is not owned by an object, but instead borrowed |     /// @details A borrowed pointer is used to indicate a pointer that is not owned by an object, but instead borrowed | ||||||
|     /// from another owning object that is assumed to always be kept alive during the entire lifetime of the borrowing |     /// from another owning object that is assumed to always be kept alive during the entire lifetime of the borrowing | ||||||
|     //  object. |     //  object. | ||||||
| @@ -13,42 +14,46 @@ namespace ArbUt { | |||||||
|         T* _raw; |         T* _raw; | ||||||
|  |  | ||||||
|     public: |     public: | ||||||
|         /// @brief Initialise a BorrowedPtr with a null pointer. |  | ||||||
|         inline BorrowedPtr<T>() noexcept : _raw(nullptr){}; |  | ||||||
|         /// @brief Initialise a BorrowedPtr with a specific raw pointer. |         /// @brief Initialise a BorrowedPtr with a specific raw pointer. | ||||||
|         inline BorrowedPtr<T>(T* ptr) noexcept : _raw(ptr){}; |         inline BorrowedPtr<T>(__attribute__((nonnull)) T* ptr) : _raw(ptr) { AssertNotNull(ptr); }; | ||||||
|         /// @brief Initialise a BorrowedPtr from a copy. |         /// @brief Initialise a BorrowedPtr from a copy. | ||||||
|         inline BorrowedPtr<T>(const BorrowedPtr<T>& other) noexcept : _raw(other._raw){}; |         inline BorrowedPtr<T>(const BorrowedPtr<T>& other) : _raw(other._raw){}; | ||||||
|         /// @brief Initialise a BorrowedPtr with a std unique_ptr. |         /// @brief Initialise a BorrowedPtr with a std unique_ptr. | ||||||
|         inline BorrowedPtr<T>(const std::unique_ptr<T>& other) noexcept : _raw(other.get()){}; |         inline BorrowedPtr<T>(const std::unique_ptr<T>& other) : _raw(other.get()){}; | ||||||
|  |  | ||||||
|         ~BorrowedPtr() noexcept = default; |         ~BorrowedPtr() noexcept = default; | ||||||
|  |  | ||||||
|         /// @brief Copy operator. |         /// @brief Copy operator. | ||||||
|         inline BorrowedPtr<T>& operator=(const BorrowedPtr<T>& rhs) noexcept { |         inline BorrowedPtr<T>& operator=(const BorrowedPtr<T>& rhs) { | ||||||
|             if (this == &rhs) |             if (this == &rhs) | ||||||
|                 return *this; |                 return *this; | ||||||
|             _raw = rhs._raw; |             _raw = rhs._raw; | ||||||
|             return *this; |             return *this; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         inline BorrowedPtr<T>& operator=(__attribute__((nonnull)) T* rhs) { | ||||||
|  |             if (_raw == &rhs) | ||||||
|  |                 return *this; | ||||||
|  |             AssertNotNull(rhs); | ||||||
|  |             _raw = rhs; | ||||||
|  |             return *this; | ||||||
|  |         } | ||||||
|  |  | ||||||
|         /// @brief Operator for access into underlying pointer. |         /// @brief Operator for access into underlying pointer. | ||||||
|         /// @warning Note that this asserts that the underlying pointer is not null first, to prevent segfaults. |         /// @warning Note that this asserts that the underlying pointer is not null first, to prevent segfaults. | ||||||
|         inline T* operator->() const { |         inline T* operator->() const noexcept { return _raw; } | ||||||
|             AssertNotNull(_raw); |  | ||||||
|             return _raw; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         /// @brief Get the raw underlying pointer. |         /// @brief Get the raw underlying pointer. | ||||||
|         inline T* GetRaw() const noexcept { return _raw; } |         inline T* GetRaw() const noexcept { return _raw; } | ||||||
|  |  | ||||||
|         /// @brief Check equality of two BorrowedPtr objects |         /// @brief Check equality of two BorrowedPtr objects | ||||||
|         inline bool operator==(const BorrowedPtr& rhs) const noexcept { return _raw == rhs._raw; } |         inline bool operator==(const BorrowedPtr<T>& rhs) const noexcept { return _raw == rhs._raw; } | ||||||
|  |         /// @brief Check equality of pointers | ||||||
|  |         inline bool operator==(T* rhs) const noexcept { return _raw == rhs; } | ||||||
|         /// @brief Check equality of two BorrowedPtr objects |         /// @brief Check equality of two BorrowedPtr objects | ||||||
|         inline bool operator!=(const BorrowedPtr& rhs) const noexcept { return _raw != rhs._raw; } |         inline bool operator!=(const BorrowedPtr<T>& rhs) const noexcept { return _raw != rhs._raw; } | ||||||
|  |         /// @brief Check equality of pointers | ||||||
|         /// @brief Returns whether the underlying pointer is a nullptr or not. |         inline bool operator!=(T* rhs) const noexcept { return _raw == rhs; } | ||||||
|         [[nodiscard]] inline constexpr bool IsNull() const noexcept { return _raw == nullptr; } |  | ||||||
|  |  | ||||||
|         /// @brief Returns a const version of the underlying pointer. |         /// @brief Returns a const version of the underlying pointer. | ||||||
|         inline BorrowedPtr<const T> Const() const noexcept { return BorrowedPtr<const T>(_raw); } |         inline BorrowedPtr<const T> Const() const noexcept { return BorrowedPtr<const T>(_raw); } | ||||||
| @@ -73,6 +78,9 @@ namespace ArbUt { | |||||||
|             auto cast = reinterpret_cast<TCast*>(_raw); |             auto cast = reinterpret_cast<TCast*>(_raw); | ||||||
|             return BorrowedPtr<TCast>(cast); |             return BorrowedPtr<TCast>(cast); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         /// @brief Implicit cast to retrieve raw pointer. | ||||||
|  |         inline operator T*() const noexcept { return _raw; } | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								src/Memory/Memory.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/Memory/Memory.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | #ifndef ARBUTILS_MEMORY_HPP | ||||||
|  | #define ARBUTILS_MEMORY_HPP | ||||||
|  |  | ||||||
|  | #include "BorrowedPtr.hpp" | ||||||
|  | #include "OptionalBorrowedPtr.hpp" | ||||||
|  | #include "UniquePtr.hpp" | ||||||
|  | #include "OptionalUniquePtr.hpp" | ||||||
|  | #include "UniquePtrList.hpp" | ||||||
|  |  | ||||||
|  | namespace ArbUt { | ||||||
|  |     template <class T> | ||||||
|  |     using OwnedPtr<T> = T*; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif // ARBUTILS_MEMORY_HPP | ||||||
							
								
								
									
										87
									
								
								src/Memory/OptionalBorrowedPtr.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								src/Memory/OptionalBorrowedPtr.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,87 @@ | |||||||
|  | #ifndef ARBUTILS_OPTIONALBORROWEDPTR_HPP | ||||||
|  | #define ARBUTILS_OPTIONALBORROWEDPTR_HPP | ||||||
|  |  | ||||||
|  | #include "../Assert.hpp" | ||||||
|  |  | ||||||
|  | namespace ArbUt { | ||||||
|  |     /// @brief An optional borrowed pointer is used to indicate a pointer that is not owned by its holder. This pointer | ||||||
|  |     /// can be null. | ||||||
|  |     /// @details A borrowed pointer is used to indicate a pointer that is not owned by an object, but instead borrowed | ||||||
|  |     /// from another owning object that is assumed to always be kept alive during the entire lifetime of the borrowing | ||||||
|  |     //  object. | ||||||
|  |     template <class T> class OptionalBorrowedPtr { | ||||||
|  |     private: | ||||||
|  |         T* _raw; | ||||||
|  |  | ||||||
|  |     public: | ||||||
|  |         /// @brief Initialise a BorrowedPtr with a specific raw pointer. | ||||||
|  |         inline OptionalBorrowedPtr<T>(T* ptr) : _raw(ptr){}; | ||||||
|  |         /// @brief Initialise a BorrowedPtr from a copy. | ||||||
|  |         inline OptionalBorrowedPtr<T>(const BorrowedPtr<T>& other) : _raw(other._raw){}; | ||||||
|  |         /// @brief Initialise a BorrowedPtr with a std unique_ptr. | ||||||
|  |         inline OptionalBorrowedPtr<T>(const std::unique_ptr<T>& other) : _raw(other.get()){}; | ||||||
|  |  | ||||||
|  |         ~OptionalBorrowedPtr() noexcept = default; | ||||||
|  |  | ||||||
|  |         /// @brief Copy operator. | ||||||
|  |         inline OptionalBorrowedPtr<T>& operator=(const BorrowedPtr<T>& rhs) { | ||||||
|  |             if (this == &rhs) | ||||||
|  |                 return *this; | ||||||
|  |             _raw = rhs._raw; | ||||||
|  |             return *this; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// @brief Return whether the pointer is null or not. | ||||||
|  |         [[nodiscard]] inline bool HasValue() const noexcept { return _raw == nullptr; } | ||||||
|  |  | ||||||
|  |         /// @brief Get the raw underlying pointer. | ||||||
|  |         inline T* GetValue() const noexcept { return _raw; } | ||||||
|  |  | ||||||
|  |         /// @brief Check equality of two BorrowedPtr objects | ||||||
|  |         inline bool operator==(const OptionalBorrowedPtr<T>& rhs) const noexcept { return _raw == rhs._raw; } | ||||||
|  |         /// @brief Check equality of pointers | ||||||
|  |         inline bool operator==(T* rhs) const noexcept { return _raw == rhs; } | ||||||
|  |         /// @brief Check equality of two BorrowedPtr objects | ||||||
|  |         inline bool operator!=(const OptionalBorrowedPtr<T>& rhs) const noexcept { return _raw != rhs._raw; } | ||||||
|  |         /// @brief Check equality of pointers | ||||||
|  |         inline bool operator!=(T* rhs) const noexcept { return _raw == rhs; } | ||||||
|  |  | ||||||
|  |         /// @brief Returns a const version of the underlying pointer. | ||||||
|  |         inline OptionalBorrowedPtr<const T> Const() const noexcept { return BorrowedPtr<const T>(_raw); } | ||||||
|  |  | ||||||
|  |         /// @brief Casts the underlying pointer to another type using dynamic_cast. | ||||||
|  |         template <class TCast> inline OptionalBorrowedPtr<TCast> As() const { | ||||||
|  |             auto cast = dynamic_cast<TCast*>(_raw); | ||||||
|  |             return BorrowedPtr<TCast>(cast); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// @brief Try to cast the underlying pointer to another type using dynamic_cast. | ||||||
|  |         template <class TCast> inline bool TryAs(OptionalBorrowedPtr<TCast>& out) const noexcept { | ||||||
|  |             auto cast = dynamic_cast<TCast*>(_raw); | ||||||
|  |             if (cast == nullptr) | ||||||
|  |                 return false; | ||||||
|  |             out = OptionalBorrowedPtr<TCast>(cast); | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// @brief Force cast the underlying pointer to another type using reinterpret_cast. | ||||||
|  |         template <class TCast> inline OptionalBorrowedPtr<TCast> ForceAs() const noexcept { | ||||||
|  |             auto cast = reinterpret_cast<TCast*>(_raw); | ||||||
|  |             return BorrowedPtr<TCast>(cast); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         inline operator T*() const noexcept { return _raw; } | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | namespace std { | ||||||
|  |     /// @brief Helper class for allowing hashing of BorrowedPtr. | ||||||
|  |     template <class T> struct hash<ArbUt::OptionalBorrowedPtr<T>> { | ||||||
|  |         /// @brief Returns a hash of for a borrowed Pointer. Effectively just the raw memory address. | ||||||
|  |         /// @param k A borrowed pointer. | ||||||
|  |         /// @return The hash of the borrowed pointer. | ||||||
|  |         std::size_t operator()(const ArbUt::OptionalBorrowedPtr<T>& k) const { return (size_t)k.GetValue(); } | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif // ARBUTILS_OPTIONALBORROWEDPTR_HPP | ||||||
							
								
								
									
										75
									
								
								src/Memory/OptionalUniquePtr.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								src/Memory/OptionalUniquePtr.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | |||||||
|  | #ifndef ARBUTILS_OPTIONALOptionalUniquePtr_HPP | ||||||
|  | #define ARBUTILS_OPTIONALOptionalUniquePtr_HPP | ||||||
|  |  | ||||||
|  | #include "../Assert.hpp" | ||||||
|  |  | ||||||
|  | namespace ArbUt { | ||||||
|  |     /// @brief An optional unique pointer is used to indicate a pointer that is owned by its holder, and will be deleted | ||||||
|  |     /// when its owner is deleted. | ||||||
|  |     /// @details A unique pointer is used to indicate a pointer that is owned by an object, and that needs to be deleted | ||||||
|  |     /// when its owner is deleted. | ||||||
|  |     template <class T> class OptionalUniquePtr { | ||||||
|  |     private: | ||||||
|  |         T* _raw; | ||||||
|  |  | ||||||
|  |     public: | ||||||
|  |         /// @brief Initialise a OptionalUniquePtr with a specific raw pointer. | ||||||
|  |         inline OptionalUniquePtr<T>(__attribute__((nonnull)) T* ptr) : _raw(ptr){}; | ||||||
|  |         /// @brief Initialise a OptionalUniquePtr from a copy. | ||||||
|  |         inline OptionalUniquePtr<T>(const OptionalUniquePtr<T>& other) : _raw(other._raw){}; | ||||||
|  |         /// @brief Initialise a OptionalUniquePtr with a std unique_ptr. | ||||||
|  |         inline OptionalUniquePtr<T>(const std::unique_ptr<T>& other) : _raw(other.get()){}; | ||||||
|  |  | ||||||
|  |         ~OptionalUniquePtr() noexcept { delete _raw; } | ||||||
|  |  | ||||||
|  |         /// @brief Copy operator. | ||||||
|  |         inline OptionalUniquePtr<T>& operator=(const OptionalUniquePtr<T>& rhs) { | ||||||
|  |             if (this == &rhs) | ||||||
|  |                 return *this; | ||||||
|  |             _raw = rhs._raw; | ||||||
|  |             return *this; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         inline OptionalUniquePtr<T>& operator=(__attribute__((nonnull)) T* rhs) { | ||||||
|  |             if (_raw == &rhs) | ||||||
|  |                 return *this; | ||||||
|  |             AssertNotNull(rhs); | ||||||
|  |             _raw = rhs; | ||||||
|  |             return *this; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// @brief Operator for access into underlying pointer. | ||||||
|  |         /// @warning Note that this asserts that the underlying pointer is not null first, to prevent segfaults. | ||||||
|  |         inline T* operator->() const noexcept { return _raw; } | ||||||
|  |  | ||||||
|  |         /// @brief Get the raw underlying pointer. | ||||||
|  |         inline T* GetRaw() const noexcept { return _raw; } | ||||||
|  |  | ||||||
|  |         /// @brief Check equality of two OptionalUniquePtr objects | ||||||
|  |         inline bool operator==(const OptionalUniquePtr& rhs) const noexcept { return _raw == rhs._raw; } | ||||||
|  |         /// @brief Check equality of pointers | ||||||
|  |         inline bool operator==(T* rhs) const noexcept { return _raw == rhs; } | ||||||
|  |         /// @brief Check equality of two OptionalUniquePtr objects | ||||||
|  |         inline bool operator!=(const OptionalUniquePtr& rhs) const noexcept { return _raw != rhs._raw; } | ||||||
|  |         /// @brief Check equality of pointers | ||||||
|  |         inline bool operator!=(T* rhs) const noexcept { return _raw == rhs; } | ||||||
|  |  | ||||||
|  |         /// @brief Implicit cast to retrieve raw pointer. | ||||||
|  |         inline operator T*() const noexcept { | ||||||
|  |             AssertNotNull(_raw); | ||||||
|  |             return _raw; | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | namespace std { | ||||||
|  |     /// @brief Helper class for allowing hashing of OptionalUniquePtr. | ||||||
|  |     template <class T> struct hash<ArbUt::OptionalUniquePtr<T>> { | ||||||
|  |         /// @brief Returns a hash of for a borrowed Pointer. Effectively just the raw memory address. | ||||||
|  |         /// @param k A borrowed pointer. | ||||||
|  |         /// @return The hash of the borrowed pointer. | ||||||
|  |         std::size_t operator()(const ArbUt::OptionalUniquePtr<T>& k) const { return (size_t)k.GetRaw(); } | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif // ARBUTILS_OPTIONALOptionalUniquePtr_HPP | ||||||
							
								
								
									
										73
									
								
								src/Memory/ScopedPtr.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								src/Memory/ScopedPtr.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | |||||||
|  | #ifndef ARBUTILS_SCOPEDPTR_HPP | ||||||
|  | #define ARBUTILS_SCOPEDPTR_HPP | ||||||
|  |  | ||||||
|  | #include "../Assert.hpp" | ||||||
|  |  | ||||||
|  | namespace ArbUt { | ||||||
|  |     /// @brief An optional unique pointer is used to indicate a pointer that is owned by its holder, and will be deleted | ||||||
|  |     /// when its owner is deleted. | ||||||
|  |     /// @details A unique pointer is used to indicate a pointer that is owned by an object, and that needs to be deleted | ||||||
|  |     /// when its owner is deleted. | ||||||
|  |     template <class T> class ScopedPtr { | ||||||
|  |     private: | ||||||
|  |         T* _raw; | ||||||
|  |  | ||||||
|  |     public: | ||||||
|  |         /// @brief Initialise a ScopedPtr with a specific raw pointer. | ||||||
|  |         inline ScopedPtr<T>(__attribute__((nonnull)) T* ptr) : _raw(ptr){}; | ||||||
|  |         /// @brief Initialise a ScopedPtr from a copy. | ||||||
|  |         inline ScopedPtr<T>(const ScopedPtr<T>& other) : _raw(other._raw){}; | ||||||
|  |         /// @brief Initialise a ScopedPtr with a std unique_ptr. | ||||||
|  |         inline ScopedPtr<T>(const std::unique_ptr<T>& other) : _raw(other.get()){}; | ||||||
|  |  | ||||||
|  |         ~ScopedPtr() noexcept { delete _raw; } | ||||||
|  |  | ||||||
|  |         /// @brief Copy operator. | ||||||
|  |         inline ScopedPtr<T>& operator=(const ScopedPtr<T>& rhs) { | ||||||
|  |             if (this == &rhs) | ||||||
|  |                 return *this; | ||||||
|  |             _raw = rhs._raw; | ||||||
|  |             return *this; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         inline ScopedPtr<T>& operator=(__attribute__((nonnull)) T* rhs) { | ||||||
|  |             if (_raw == &rhs) | ||||||
|  |                 return *this; | ||||||
|  |             AssertNotNull(rhs); | ||||||
|  |             _raw = rhs; | ||||||
|  |             return *this; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// @brief Operator for access into underlying pointer. | ||||||
|  |         /// @warning Note that this asserts that the underlying pointer is not null first, to prevent segfaults. | ||||||
|  |         inline T* operator->() const noexcept { return _raw; } | ||||||
|  |  | ||||||
|  |         /// @brief Get the raw underlying pointer. | ||||||
|  |         inline T* TakeOwnership() const noexcept { | ||||||
|  |             auto raw = _raw; | ||||||
|  |             _raw = nullptr; | ||||||
|  |             return raw; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// @brief Check equality of two ScopedPtr objects | ||||||
|  |         inline bool operator==(const ScopedPtr& rhs) const noexcept { return _raw == rhs._raw; } | ||||||
|  |         /// @brief Check equality of pointers | ||||||
|  |         inline bool operator==(T* rhs) const noexcept { return _raw == rhs; } | ||||||
|  |         /// @brief Check equality of two ScopedPtr objects | ||||||
|  |         inline bool operator!=(const ScopedPtr& rhs) const noexcept { return _raw != rhs._raw; } | ||||||
|  |         /// @brief Check equality of pointers | ||||||
|  |         inline bool operator!=(T* rhs) const noexcept { return _raw == rhs; } | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | namespace std { | ||||||
|  |     /// @brief Helper class for allowing hashing of ScopedPtr. | ||||||
|  |     template <class T> struct hash<ArbUt::ScopedPtr<T>> { | ||||||
|  |         /// @brief Returns a hash of for a borrowed Pointer. Effectively just the raw memory address. | ||||||
|  |         /// @param k A borrowed pointer. | ||||||
|  |         /// @return The hash of the borrowed pointer. | ||||||
|  |         std::size_t operator()(const ArbUt::ScopedPtr<T>& k) const { return (size_t)k.GetRaw(); } | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif // ARBUTILS_SCOPEDPTR_HPP | ||||||
							
								
								
									
										71
									
								
								src/Memory/UniquePtr.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								src/Memory/UniquePtr.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,71 @@ | |||||||
|  | #ifndef ARBUTILS_UNIQUEPTR_HPP | ||||||
|  | #define ARBUTILS_UNIQUEPTR_HPP | ||||||
|  |  | ||||||
|  | #include "../Assert.hpp" | ||||||
|  |  | ||||||
|  | namespace ArbUt { | ||||||
|  |     /// @brief A unique pointer is used to indicate a pointer that is owned by its holder, and will be deleted when its | ||||||
|  |     /// owner is deleted. As with all Arbutils pointers, this cannot be assigned null. Use an OptionalUniquePtr for pointers that can be null. | ||||||
|  |     /// @details A unique pointer is used to indicate a pointer that is owned by an object, and that needs to be deleted | ||||||
|  |     /// when its owner is deleted. | ||||||
|  |     template <class T> class UniquePtr { | ||||||
|  |     private: | ||||||
|  |         T* _raw; | ||||||
|  |  | ||||||
|  |     public: | ||||||
|  |         /// @brief Initialise a UniquePtr with a specific raw pointer. | ||||||
|  |         inline UniquePtr<T>(__attribute__((nonnull)) T* ptr) : _raw(ptr) { AssertNotNull(ptr); }; | ||||||
|  |         /// @brief Initialise a UniquePtr from a copy. | ||||||
|  |         inline UniquePtr<T>(const UniquePtr<T>& other) : _raw(other._raw){}; | ||||||
|  |         /// @brief Initialise a UniquePtr with a std unique_ptr. | ||||||
|  |         inline UniquePtr<T>(const std::unique_ptr<T>& other) : _raw(other.get()){}; | ||||||
|  |  | ||||||
|  |         ~UniquePtr() noexcept{ | ||||||
|  |             delete _raw; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// @brief Copy operator. | ||||||
|  |         inline UniquePtr<T>& operator=(const UniquePtr<T>& rhs) { | ||||||
|  |             if (this == &rhs) | ||||||
|  |                 return *this; | ||||||
|  |             _raw = rhs._raw; | ||||||
|  |             return *this; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         inline UniquePtr<T>& operator=(__attribute__((nonnull)) T* rhs) { | ||||||
|  |             if (_raw == &rhs) | ||||||
|  |                 return *this; | ||||||
|  |             AssertNotNull(rhs); | ||||||
|  |             _raw = rhs; | ||||||
|  |             return *this; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// @brief Operator for access into underlying pointer. | ||||||
|  |         /// @warning Note that this asserts that the underlying pointer is not null first, to prevent segfaults. | ||||||
|  |         inline T* operator->() const noexcept { return _raw; } | ||||||
|  |  | ||||||
|  |         /// @brief Get the raw underlying pointer. | ||||||
|  |         inline T* GetRaw() const noexcept { return _raw; } | ||||||
|  |  | ||||||
|  |         /// @brief Check equality of two UniquePtr objects | ||||||
|  |         inline bool operator==(const UniquePtr& rhs) const noexcept { return _raw == rhs._raw; } | ||||||
|  |         /// @brief Check equality of pointers | ||||||
|  |         inline bool operator==(T* rhs) const noexcept { return _raw == rhs; } | ||||||
|  |         /// @brief Check equality of two UniquePtr objects | ||||||
|  |         inline bool operator!=(const UniquePtr& rhs) const noexcept { return _raw != rhs._raw; } | ||||||
|  |         /// @brief Check equality of pointers | ||||||
|  |         inline bool operator!=(T* rhs) const noexcept { return _raw == rhs; } | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | namespace std { | ||||||
|  |     /// @brief Helper class for allowing hashing of UniquePtr. | ||||||
|  |     template <class T> struct hash<ArbUt::UniquePtr<T>> { | ||||||
|  |         /// @brief Returns a hash of for a borrowed Pointer. Effectively just the raw memory address. | ||||||
|  |         /// @param k A borrowed pointer. | ||||||
|  |         /// @return The hash of the borrowed pointer. | ||||||
|  |         std::size_t operator()(const ArbUt::UniquePtr<T>& k) const { return (size_t)k.GetRaw(); } | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif // ARBUTILS_UNIQUEPTR_HPP | ||||||
		Reference in New Issue
	
	Block a user