diff --git a/src/Memory/Memory.hpp b/src/Memory/Memory.hpp index b3d6f0b..255db0e 100644 --- a/src/Memory/Memory.hpp +++ b/src/Memory/Memory.hpp @@ -3,8 +3,10 @@ #include "__BorrowedPtr.hpp" #include "__OptionalBorrowedPtr.hpp" +#include "__OptionalScopedPtr.hpp" #include "__OptionalUniquePtr.hpp" #include "__OptionalUniquePtrList.hpp" +#include "__ScopedPtr.hpp" #include "__UniquePtr.hpp" #include "__UniquePtrList.hpp" diff --git a/src/Memory/__OptionalScopedPtr.hpp b/src/Memory/__OptionalScopedPtr.hpp new file mode 100644 index 0000000..7b96658 --- /dev/null +++ b/src/Memory/__OptionalScopedPtr.hpp @@ -0,0 +1,77 @@ +#ifndef ARBUTILS___OPTIONALSCOPEDPTR_HPP +#define ARBUTILS___OPTIONALSCOPEDPTR_HPP + +#include "../Ensure.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 OptionalScopedPtr { + private: + T* _raw; + + public: + /// @brief Initialise a ScopedPtr with a specific raw pointer. + inline ScopedPtr(T* ptr) : _raw(ptr){}; + /// @brief Initialise a ScopedPtr from a copy. + inline ScopedPtr(const ScopedPtr& other) : _raw(other._raw){}; + /// @brief Initialise a ScopedPtr with a std unique_ptr. + inline ScopedPtr(const std::unique_ptr& other) : _raw(other.get()){}; + + ~ScopedPtr() noexcept { delete _raw; } + + /// @brief Copy operator. + inline ScopedPtr& operator=(const ScopedPtr& rhs) { + if (this == &rhs) { + return *this; + } + _raw = rhs._raw; + return *this; + } + + /// @brief Assign operator with raw pointer. + inline ScopedPtr& operator=(T* rhs) { + if (_raw == rhs) { + return *this; + } + _raw = rhs; + 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 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 OptionalScopedPtr. + template struct hash> { + /// @brief Returns a hash of for an optional scoped Pointer. Effectively just the raw memory address. + /// @param k An optional scoped pointer. + /// @return The hash of the optional scoped pointer. + std::size_t operator()(const ArbUt::OptionalScopedPtr& k) const { return (size_t)k.GetRaw(); } + }; +} + +#endif // ARBUTILS___OPTIONALSCOPEDPTR_HPP diff --git a/src/Memory/__OptionalUniquePtr.hpp b/src/Memory/__OptionalUniquePtr.hpp index c4db339..c3593f3 100644 --- a/src/Memory/__OptionalUniquePtr.hpp +++ b/src/Memory/__OptionalUniquePtr.hpp @@ -48,13 +48,6 @@ namespace ArbUt { 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 diff --git a/src/Memory/__ScopedPtr.hpp b/src/Memory/__ScopedPtr.hpp index 9b43614..d251fb4 100644 --- a/src/Memory/__ScopedPtr.hpp +++ b/src/Memory/__ScopedPtr.hpp @@ -14,12 +14,14 @@ namespace ArbUt { public: /// @brief Initialise a ScopedPtr with a specific raw pointer. - inline ScopedPtr(T* ptr) : _raw(ptr){}; + inline ScopedPtr(T* ptr) : _raw(ptr) { EnsureNotNull(_raw); }; /// @brief Initialise a ScopedPtr from a copy. inline ScopedPtr(const ScopedPtr& other) : _raw(other._raw){}; /// @brief Initialise a ScopedPtr with a std unique_ptr. inline ScopedPtr(const std::unique_ptr& other) : _raw(other.get()){}; + ScopedPtr(std::nullptr_t) = delete; + ~ScopedPtr() noexcept { delete _raw; } /// @brief Copy operator. @@ -36,16 +38,13 @@ namespace ArbUt { if (_raw == rhs) { return *this; } + EnsureNotNull(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 { - EnsureNotNull(_raw); - return _raw; - } + inline T* operator->() const noexcept { return _raw; } /// @brief Get the raw underlying pointer. inline T* TakeOwnership() const noexcept { @@ -54,6 +53,8 @@ namespace ArbUt { return raw; } + /// @brief Delete comparison with nullptr, ScopedPtr can't be null + inline bool operator==(std::nullptr_t) const = delete; /// @brief Check equality of two ScopedPtr objects inline bool operator==(const ScopedPtr& rhs) const noexcept { return _raw == rhs._raw; } /// @brief Check equality of pointers @@ -68,9 +69,9 @@ namespace ArbUt { namespace std { /// @brief Helper class for allowing hashing of ScopedPtr. template struct hash> { - /// @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. + /// @brief Returns a hash of for a scoped Pointer. Effectively just the raw memory address. + /// @param k A scoped pointer. + /// @return The hash of the scoped pointer. std::size_t operator()(const ArbUt::ScopedPtr& k) const { return (size_t)k.GetRaw(); } }; }