[ox/std] Make AnyPtr constexpr
All checks were successful
Build / build (push) Successful in 2m38s

This commit is contained in:
Gary Talent 2024-03-23 17:01:49 -05:00
parent 1616ca7018
commit 50f3479d10

View File

@ -9,9 +9,9 @@ namespace ox {
class AnyPtr {
private:
struct WrapBase {
virtual ~WrapBase() = default;
virtual WrapBase *copyTo(ox::Span<char> s) noexcept = 0;
virtual operator bool() const noexcept = 0;
virtual constexpr ~WrapBase() = default;
virtual constexpr WrapBase *copyTo(ox::Span<char> s) noexcept = 0;
virtual constexpr operator bool() const noexcept = 0;
};
template<typename T>
@ -19,8 +19,12 @@ class AnyPtr {
T *data{};
constexpr Wrap(T *pData) noexcept: data(pData) {
}
inline WrapBase *copyTo(ox::Span<char> s) noexcept override {
return new(s.data()) Wrap{data};
constexpr WrapBase *copyTo(ox::Span<char> 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<char, sizeof(Wrap<void*>)> m_wrapData;
public:
constexpr AnyPtr() noexcept = default;
template<typename T>
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<typename T>
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<typename T>
[[nodiscard]]
constexpr T *get() const noexcept {
#ifdef OX_BARE_METAL
auto const out = static_cast<Wrap<T>*>(m_wrapPtr);
return static_cast<Wrap<T>*>(m_wrapPtr)->data;
#else
auto const out = dynamic_cast<Wrap<T>*>(m_wrapPtr);
return dynamic_cast<Wrap<T>*>(m_wrapPtr)->data;
#endif
return out->data;
}
};