[ox/std] Reduce AnyPtr to 2/3 the size
All checks were successful
Build / build (push) Successful in 1m13s

This commit is contained in:
2026-01-30 20:54:04 -06:00
parent c812051ec0
commit d19b848427
2 changed files with 71 additions and 35 deletions

View File

@@ -22,7 +22,7 @@ class AnyPtrT {
private: private:
struct WrapBase { struct WrapBase {
virtual constexpr ~WrapBase() = default; virtual constexpr ~WrapBase() = default;
virtual constexpr WrapBase *copyTo(ox::Span<char> s) noexcept = 0; virtual constexpr WrapBase *copyTo(Span<char> s) const noexcept = 0;
virtual constexpr operator bool() const noexcept = 0; virtual constexpr operator bool() const noexcept = 0;
virtual void free() noexcept = 0; virtual void free() noexcept = 0;
}; };
@@ -32,7 +32,7 @@ class AnyPtrT {
T *data{}; T *data{};
explicit constexpr Wrap(T *pData) noexcept: data(pData) { explicit constexpr Wrap(T *pData) noexcept: data(pData) {
} }
constexpr WrapBase *copyTo(ox::Span<char> s) noexcept override { constexpr WrapBase *copyTo(Span<char> s) const noexcept override {
oxAssert(s.size() >= sizeof(Wrap), "too small buffer"); oxAssert(s.size() >= sizeof(Wrap), "too small buffer");
if (std::is_constant_evaluated()) { if (std::is_constant_evaluated()) {
return new Wrap(data); return new Wrap(data);
@@ -49,8 +49,10 @@ class AnyPtrT {
} }
}; };
union {
WrapBase *m_wrapPtr{}; WrapBase *m_wrapPtr{};
ox::Array<char, sizeof(Wrap<void*>)> m_wrapData; AllocAlias<Wrap<void*>> m_wrapData;
} m_data;
public: public:
constexpr AnyPtrT() noexcept = default; constexpr AnyPtrT() noexcept = default;
@@ -58,25 +60,25 @@ class AnyPtrT {
template<typename T> template<typename T>
constexpr AnyPtrT(T *ptr) noexcept { constexpr AnyPtrT(T *ptr) noexcept {
if (std::is_constant_evaluated()) { if (std::is_constant_evaluated()) {
m_wrapPtr = new Wrap<T>(ptr); setWrapPtr(new Wrap<T>(ptr));
} else { } else {
m_wrapPtr = new(m_wrapData.data()) Wrap<T>(ptr); new(m_data.m_wrapData.data()) Wrap<T>(ptr);
} }
} }
constexpr AnyPtrT(AnyPtrT const&other) noexcept requires(!unique) { constexpr AnyPtrT(AnyPtrT const &other) noexcept requires(!unique) {
if (other) { if (other) {
m_wrapPtr = other.m_wrapPtr->copyTo(m_wrapData); setWrapPtr(other.getWrapPtr()->copyTo(m_data.m_wrapData.buff));
} }
} }
constexpr AnyPtrT(AnyPtrT &&other) noexcept { constexpr AnyPtrT(AnyPtrT &&other) noexcept {
if (other) { if (other) {
m_wrapPtr = other.m_wrapPtr->copyTo(m_wrapData); setWrapPtr(other.getWrapPtr()->copyTo(m_data.m_wrapData.buff));
if (std::is_constant_evaluated()) { if (std::is_constant_evaluated()) {
ox::safeDelete(m_wrapPtr); ox::safeDelete(m_data.m_wrapPtr);
} }
other.m_wrapPtr = {}; m_data.m_wrapData = {};
} }
} }
@@ -85,7 +87,7 @@ class AnyPtrT {
free(); free();
} }
if (std::is_constant_evaluated()) { if (std::is_constant_evaluated()) {
ox::safeDelete(m_wrapPtr); ox::safeDelete(m_data.m_wrapPtr);
} }
} }
@@ -94,25 +96,31 @@ class AnyPtrT {
if constexpr(unique) { if constexpr(unique) {
free(); free();
} else if (std::is_constant_evaluated()) { } else if (std::is_constant_evaluated()) {
ox::safeDelete(m_wrapPtr); ox::safeDelete(m_data.m_wrapPtr);
} }
if (std::is_constant_evaluated()) { if (std::is_constant_evaluated()) {
m_wrapPtr = new Wrap(ptr); setWrapPtr(new Wrap(ptr));
} else { } else {
m_wrapPtr = new(m_wrapData.data()) Wrap(ptr); new(m_data.m_wrapData.data()) Wrap(ptr);
} }
return *this; return *this;
} }
constexpr AnyPtrT &operator=(AnyPtrT const&ptr) noexcept requires(!unique) { constexpr AnyPtrT &operator=(AnyPtrT const &ptr) noexcept requires(!unique) {
if (this != &ptr) { if (this != &ptr) {
if (std::is_constant_evaluated()) { if (std::is_constant_evaluated()) {
ox::safeDelete(m_wrapPtr); ox::safeDelete(m_data.m_wrapPtr);
} }
if (std::is_constant_evaluated()) {
if (ptr) { if (ptr) {
m_wrapPtr = ptr.m_wrapPtr->copyTo(m_wrapData); ptr.getWrapPtr()->copyTo(m_data.m_wrapData.buff);
}
} else { } else {
m_wrapPtr = nullptr; if (ptr) {
setWrapPtr(ptr.getWrapPtr()->copyTo(m_data.m_wrapData.buff));
} else {
setWrapPtr(nullptr);
}
} }
} }
return *this; return *this;
@@ -123,43 +131,65 @@ class AnyPtrT {
if constexpr(unique) { if constexpr(unique) {
free(); free();
} else if (std::is_constant_evaluated()) { } else if (std::is_constant_evaluated()) {
ox::safeDelete(m_wrapPtr); ox::safeDelete(m_data.m_wrapPtr);
} }
if (ptr) { if (ptr) {
m_wrapPtr = ptr.m_wrapPtr->copyTo(m_wrapData); setWrapPtr(ptr.getWrapPtr()->copyTo(m_data.m_wrapData.buff));
if (std::is_constant_evaluated()) { if (std::is_constant_evaluated()) {
ox::safeDelete(ptr.m_wrapPtr); ox::safeDelete(ptr.m_data.m_wrapPtr);
ptr.m_wrapPtr = nullptr; setWrapPtr(nullptr);
} }
} else { } else {
m_wrapPtr = nullptr; m_data = {};
} }
} }
return *this; return *this;
} }
constexpr operator bool() const noexcept { constexpr operator bool() const noexcept {
return m_wrapPtr && *m_wrapPtr; return getWrapPtr() && *getWrapPtr();
} }
constexpr void free() noexcept { constexpr void free() noexcept {
if (m_wrapPtr) { if (auto p = getWrapPtr()) {
m_wrapPtr->free(); p->free();
} }
if (std::is_constant_evaluated()) { if (std::is_constant_evaluated()) {
ox::safeDelete(m_wrapPtr); ox::safeDelete(m_data.m_wrapPtr);
} }
m_wrapPtr = nullptr; m_data.m_wrapData = {};
} }
template<typename T> template<typename T>
[[nodiscard]] [[nodiscard]]
constexpr T *get() const noexcept { constexpr T *get() const noexcept {
#ifdef OX_BARE_METAL if constexpr(defines::HasRTTI) {
return static_cast<Wrap<T>*>(m_wrapPtr)->data; return dynamic_cast<Wrap<T> const*>(getWrapPtr())->data;
#else }
return dynamic_cast<Wrap<T>*>(m_wrapPtr)->data; return static_cast<Wrap<T> const*>(getWrapPtr())->data;
#endif }
private:
constexpr void setWrapPtr(WrapBase *ptr) noexcept {
if (std::is_constant_evaluated()) {
m_data.m_wrapPtr = ptr;
}
}
constexpr WrapBase *getWrapPtr() noexcept {
if (std::is_constant_evaluated()) {
return m_data.m_wrapPtr;
} else {
return std::launder(reinterpret_cast<WrapBase*>(m_data.m_wrapData.data()));
}
}
constexpr WrapBase const *getWrapPtr() const noexcept {
if (std::is_constant_evaluated()) {
return m_data.m_wrapPtr;
} else {
return std::launder(reinterpret_cast<WrapBase const*>(m_data.m_wrapData.data()));
}
} }
}; };

View File

@@ -53,6 +53,12 @@ constexpr auto NDebug = true;
constexpr auto NDebug = false; constexpr auto NDebug = false;
#endif #endif
#if defined(OX_BARE_METAL)
constexpr auto HasRTTI = false;
#else
constexpr auto HasRTTI = true;
#endif
#if defined(__BIG_ENDIAN__) #if defined(__BIG_ENDIAN__)
constexpr auto BigEndian = true; constexpr auto BigEndian = true;
constexpr auto LittleEndian = false; constexpr auto LittleEndian = false;