From b29b9a9b3ad6062f498c62ba0e163e3aeb023422 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sat, 18 Jan 2025 20:11:42 -0600 Subject: [PATCH] [ox/std] Add UAnyPtr --- deps/ox/src/ox/std/anyptr.hpp | 85 ++++++++++++++++++++++++++++++----- 1 file changed, 75 insertions(+), 10 deletions(-) diff --git a/deps/ox/src/ox/std/anyptr.hpp b/deps/ox/src/ox/std/anyptr.hpp index 2e3ad1c8..bc0c460a 100644 --- a/deps/ox/src/ox/std/anyptr.hpp +++ b/deps/ox/src/ox/std/anyptr.hpp @@ -15,16 +15,20 @@ namespace ox { -class AnyPtr { +namespace detail { + +template +class AnyPtrT { private: struct WrapBase { virtual constexpr ~WrapBase() = default; virtual constexpr WrapBase *copyTo(ox::Span s) noexcept = 0; virtual constexpr operator bool() const noexcept = 0; + virtual void free() noexcept = 0; }; template - struct Wrap: public WrapBase { + struct Wrap final: WrapBase { T *data{}; constexpr Wrap(T *pData) noexcept: data(pData) { } @@ -39,16 +43,20 @@ class AnyPtr { constexpr operator bool() const noexcept override { return data != nullptr; } + constexpr void free() noexcept override { + ox::safeDelete(data); + data = {}; + } }; WrapBase *m_wrapPtr{}; ox::Array)> m_wrapData; public: - constexpr AnyPtr() noexcept = default; + constexpr AnyPtrT() noexcept = default; template - constexpr AnyPtr(T *ptr) noexcept { + constexpr AnyPtrT(T *ptr) noexcept { if (std::is_constant_evaluated()) { m_wrapPtr = new Wrap(ptr); } else { @@ -56,22 +64,39 @@ class AnyPtr { } } - constexpr AnyPtr(AnyPtr const&other) noexcept { + constexpr AnyPtrT(AnyPtrT const&other) noexcept { if (other) { m_wrapPtr = other.m_wrapPtr->copyTo(m_wrapData); } } - constexpr ~AnyPtr() noexcept { + constexpr AnyPtrT(AnyPtrT &&other) noexcept { + if (other) { + m_wrapPtr = other.m_wrapPtr->copyTo(m_wrapData); + if (std::is_constant_evaluated()) { + ox::safeDelete(m_wrapPtr); + } + other.m_wrapPtr = {}; + } + } + + constexpr ~AnyPtrT() noexcept { + if constexpr(unique) { + free(); + } if (std::is_constant_evaluated()) { ox::safeDelete(m_wrapPtr); } } template - constexpr AnyPtr &operator=(T *ptr) noexcept { - if (std::is_constant_evaluated()) { + constexpr AnyPtrT &operator=(T *ptr) noexcept { + if constexpr(unique) { + free(); + } else if (std::is_constant_evaluated()) { ox::safeDelete(m_wrapPtr); + } + if (std::is_constant_evaluated()) { m_wrapPtr = new Wrap(ptr); } else { m_wrapPtr = new(m_wrapData.data()) Wrap(ptr); @@ -79,10 +104,14 @@ class AnyPtr { return *this; } - constexpr AnyPtr &operator=(AnyPtr const&ptr) noexcept { + constexpr AnyPtrT &operator=(AnyPtrT const&ptr) noexcept { if (this != &ptr) { - if (ptr) { + if constexpr(unique) { + free(); + } else if (std::is_constant_evaluated()) { ox::safeDelete(m_wrapPtr); + } + if (ptr) { m_wrapPtr = ptr.m_wrapPtr->copyTo(m_wrapData); } else { m_wrapPtr = nullptr; @@ -91,10 +120,40 @@ class AnyPtr { return *this; } + constexpr AnyPtrT &operator=(AnyPtrT &&ptr) noexcept { + if (this != &ptr) { + if constexpr(unique) { + free(); + } else if (std::is_constant_evaluated()) { + ox::safeDelete(m_wrapPtr); + } + if (ptr) { + m_wrapPtr = ptr.m_wrapPtr->copyTo(m_wrapData); + if (std::is_constant_evaluated()) { + ox::safeDelete(ptr.m_wrapPtr); + ptr.m_wrapPtr = nullptr; + } + } else { + m_wrapPtr = nullptr; + } + } + return *this; + } + constexpr operator bool() const noexcept { return m_wrapPtr && *m_wrapPtr; } + constexpr void free() noexcept { + if (m_wrapPtr) { + m_wrapPtr->free(); + } + if (std::is_constant_evaluated()) { + ox::safeDelete(m_wrapPtr); + } + m_wrapPtr = nullptr; + } + template [[nodiscard]] constexpr T *get() const noexcept { @@ -104,6 +163,12 @@ class AnyPtr { return dynamic_cast*>(m_wrapPtr)->data; #endif } + }; +} + +using AnyPtr = detail::AnyPtrT; +using UAnyPtr = detail::AnyPtrT; + } \ No newline at end of file