diff --git a/src/Memory/borrowed_ptr.hpp b/src/Memory/borrowed_ptr.hpp index eefdd70..fb7e597 100644 --- a/src/Memory/borrowed_ptr.hpp +++ b/src/Memory/borrowed_ptr.hpp @@ -3,32 +3,53 @@ #include -/// 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 borrowed_ptr { -private: - T* _raw; +namespace ArbUt::Memory { + /// 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 borrowed_ptr { + private: + T* _raw; -public: - inline borrowed_ptr() : _raw(nullptr){}; - inline borrowed_ptr(T* ptr) : _raw(ptr){}; - inline borrowed_ptr(const borrowed_ptr& other) : _raw(other._raw){}; - inline borrowed_ptr(const std::unique_ptr& other) : _raw(other.get()){}; + public: + inline borrowed_ptr() : _raw(nullptr){}; + inline borrowed_ptr(T* ptr) : _raw(ptr){}; + inline borrowed_ptr(const borrowed_ptr& other) : _raw(other._raw){}; + inline borrowed_ptr(const std::unique_ptr& other) : _raw(other.get()){}; - ~borrowed_ptr() = default; + ~borrowed_ptr() = default; - inline borrowed_ptr& operator=(const borrowed_ptr& rhs) { - _raw = rhs._raw; - return *this; - } + inline borrowed_ptr& operator=(const borrowed_ptr& rhs) { + _raw = rhs._raw; + return *this; + } - inline T* operator->() const noexcept { return _raw; } - inline T* GetRaw() const noexcept { return _raw; } + inline T* operator->() const noexcept { return _raw; } + inline T* GetRaw() const noexcept { return _raw; } - inline bool operator==(const borrowed_ptr& rhs) const { return _raw == rhs._raw; } - inline bool operator!=(const borrowed_ptr& rhs) const { return _raw != rhs._raw; } + inline bool operator==(const borrowed_ptr& rhs) const { return _raw == rhs._raw; } + inline bool operator!=(const borrowed_ptr& rhs) const { return _raw != rhs._raw; } - [[nodiscard]] inline constexpr bool IsNull() const noexcept { return _raw == nullptr; } -}; + [[nodiscard]] inline constexpr bool IsNull() const noexcept { return _raw == nullptr; } + + template inline borrowed_ptr As() const { + auto cast = dynamic_cast(_raw); + return borrowed_ptr(cast); + } + + template inline bool TryAs(borrowed_ptr& out) const { + auto cast = dynamic_cast(_raw); + if (cast == nullptr) + return false; + out = borrowed_ptr(cast); + return true; + } + + template inline borrowed_ptr ForceAs() const { + auto cast = reinterpret_cast(_raw); + return borrowed_ptr(cast); + } + }; +} #endif // ARBUTILS_BORROWED_PTR_HPP