From 50f3479d10688592d2d9fecbe169608e38b65767 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sat, 23 Mar 2024 17:01:49 -0500 Subject: [PATCH] [ox/std] Make AnyPtr constexpr --- deps/ox/src/ox/std/anyptr.hpp | 54 ++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 14 deletions(-) diff --git a/deps/ox/src/ox/std/anyptr.hpp b/deps/ox/src/ox/std/anyptr.hpp index 3a8729f1..c6611318 100644 --- a/deps/ox/src/ox/std/anyptr.hpp +++ b/deps/ox/src/ox/std/anyptr.hpp @@ -9,9 +9,9 @@ namespace ox { class AnyPtr { private: struct WrapBase { - virtual ~WrapBase() = default; - virtual WrapBase *copyTo(ox::Span s) noexcept = 0; - virtual operator bool() const noexcept = 0; + virtual constexpr ~WrapBase() = default; + virtual constexpr WrapBase *copyTo(ox::Span s) noexcept = 0; + virtual constexpr operator bool() const noexcept = 0; }; template @@ -19,8 +19,12 @@ class AnyPtr { T *data{}; constexpr Wrap(T *pData) noexcept: data(pData) { } - inline WrapBase *copyTo(ox::Span s) noexcept override { - return new(s.data()) Wrap{data}; + constexpr WrapBase *copyTo(ox::Span s) noexcept override { + if (std::is_constant_evaluated()) { + return new Wrap(data); + } else { + return new(s.data()) Wrap(data); + } } constexpr operator bool() const noexcept override { return data != nullptr; @@ -29,25 +33,46 @@ class AnyPtr { WrapBase *m_wrapPtr{}; ox::Array)> m_wrapData; + public: constexpr AnyPtr() noexcept = default; + template - inline AnyPtr(T *ptr) noexcept { - m_wrapPtr = new(m_wrapData.data()) Wrap(ptr); + constexpr AnyPtr(T *ptr) noexcept { + if (std::is_constant_evaluated()) { + m_wrapPtr = new Wrap(ptr); + } else { + m_wrapPtr = new(m_wrapData.data()) Wrap(ptr); + } } - inline AnyPtr(AnyPtr const&other) noexcept { + + constexpr AnyPtr(AnyPtr const&other) noexcept { if (other) { m_wrapPtr = other.m_wrapPtr->copyTo(m_wrapData); } } + + constexpr ~AnyPtr() noexcept { + if (std::is_constant_evaluated()) { + ox::safeDelete(m_wrapPtr); + } + } + template - inline AnyPtr &operator=(T *ptr) noexcept { - m_wrapPtr = new(m_wrapData.data()) Wrap(ptr); + constexpr AnyPtr &operator=(T *ptr) noexcept { + if (std::is_constant_evaluated()) { + ox::safeDelete(m_wrapPtr); + m_wrapPtr = new Wrap(ptr); + } else { + m_wrapPtr = new(m_wrapData.data()) Wrap(ptr); + } return *this; } - inline AnyPtr &operator=(AnyPtr const&ptr) noexcept { + + constexpr AnyPtr &operator=(AnyPtr const&ptr) noexcept { if (this != &ptr) { if (ptr) { + ox::safeDelete(m_wrapPtr); m_wrapPtr = ptr.m_wrapPtr->copyTo(m_wrapData); } else { m_wrapPtr = nullptr; @@ -55,18 +80,19 @@ class AnyPtr { } return *this; } + constexpr operator bool() const noexcept { return m_wrapPtr && *m_wrapPtr; } + template [[nodiscard]] constexpr T *get() const noexcept { #ifdef OX_BARE_METAL - auto const out = static_cast*>(m_wrapPtr); + return static_cast*>(m_wrapPtr)->data; #else - auto const out = dynamic_cast*>(m_wrapPtr); + return dynamic_cast*>(m_wrapPtr)->data; #endif - return out->data; } };