[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:
struct WrapBase {
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 void free() noexcept = 0;
};
@@ -32,7 +32,7 @@ class AnyPtrT {
T *data{};
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");
if (std::is_constant_evaluated()) {
return new Wrap(data);
@@ -49,8 +49,10 @@ class AnyPtrT {
}
};
WrapBase *m_wrapPtr{};
ox::Array<char, sizeof(Wrap<void*>)> m_wrapData;
union {
WrapBase *m_wrapPtr{};
AllocAlias<Wrap<void*>> m_wrapData;
} m_data;
public:
constexpr AnyPtrT() noexcept = default;
@@ -58,25 +60,25 @@ class AnyPtrT {
template<typename T>
constexpr AnyPtrT(T *ptr) noexcept {
if (std::is_constant_evaluated()) {
m_wrapPtr = new Wrap<T>(ptr);
setWrapPtr(new Wrap<T>(ptr));
} 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) {
m_wrapPtr = other.m_wrapPtr->copyTo(m_wrapData);
setWrapPtr(other.getWrapPtr()->copyTo(m_data.m_wrapData.buff));
}
}
constexpr AnyPtrT(AnyPtrT &&other) noexcept {
if (other) {
m_wrapPtr = other.m_wrapPtr->copyTo(m_wrapData);
setWrapPtr(other.getWrapPtr()->copyTo(m_data.m_wrapData.buff));
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();
}
if (std::is_constant_evaluated()) {
ox::safeDelete(m_wrapPtr);
ox::safeDelete(m_data.m_wrapPtr);
}
}
@@ -94,25 +96,31 @@ class AnyPtrT {
if constexpr(unique) {
free();
} else if (std::is_constant_evaluated()) {
ox::safeDelete(m_wrapPtr);
ox::safeDelete(m_data.m_wrapPtr);
}
if (std::is_constant_evaluated()) {
m_wrapPtr = new Wrap(ptr);
setWrapPtr(new Wrap(ptr));
} else {
m_wrapPtr = new(m_wrapData.data()) Wrap(ptr);
new(m_data.m_wrapData.data()) Wrap(ptr);
}
return *this;
}
constexpr AnyPtrT &operator=(AnyPtrT const&ptr) noexcept requires(!unique) {
constexpr AnyPtrT &operator=(AnyPtrT const &ptr) noexcept requires(!unique) {
if (this != &ptr) {
if (std::is_constant_evaluated()) {
ox::safeDelete(m_wrapPtr);
ox::safeDelete(m_data.m_wrapPtr);
}
if (ptr) {
m_wrapPtr = ptr.m_wrapPtr->copyTo(m_wrapData);
if (std::is_constant_evaluated()) {
if (ptr) {
ptr.getWrapPtr()->copyTo(m_data.m_wrapData.buff);
}
} else {
m_wrapPtr = nullptr;
if (ptr) {
setWrapPtr(ptr.getWrapPtr()->copyTo(m_data.m_wrapData.buff));
} else {
setWrapPtr(nullptr);
}
}
}
return *this;
@@ -123,43 +131,65 @@ class AnyPtrT {
if constexpr(unique) {
free();
} else if (std::is_constant_evaluated()) {
ox::safeDelete(m_wrapPtr);
ox::safeDelete(m_data.m_wrapPtr);
}
if (ptr) {
m_wrapPtr = ptr.m_wrapPtr->copyTo(m_wrapData);
setWrapPtr(ptr.getWrapPtr()->copyTo(m_data.m_wrapData.buff));
if (std::is_constant_evaluated()) {
ox::safeDelete(ptr.m_wrapPtr);
ptr.m_wrapPtr = nullptr;
ox::safeDelete(ptr.m_data.m_wrapPtr);
setWrapPtr(nullptr);
}
} else {
m_wrapPtr = nullptr;
m_data = {};
}
}
return *this;
}
constexpr operator bool() const noexcept {
return m_wrapPtr && *m_wrapPtr;
return getWrapPtr() && *getWrapPtr();
}
constexpr void free() noexcept {
if (m_wrapPtr) {
m_wrapPtr->free();
if (auto p = getWrapPtr()) {
p->free();
}
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>
[[nodiscard]]
constexpr T *get() const noexcept {
#ifdef OX_BARE_METAL
return static_cast<Wrap<T>*>(m_wrapPtr)->data;
#else
return dynamic_cast<Wrap<T>*>(m_wrapPtr)->data;
#endif
if constexpr(defines::HasRTTI) {
return dynamic_cast<Wrap<T> const*>(getWrapPtr())->data;
}
return static_cast<Wrap<T> const*>(getWrapPtr())->data;
}
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;
#endif
#if defined(OX_BARE_METAL)
constexpr auto HasRTTI = false;
#else
constexpr auto HasRTTI = true;
#endif
#if defined(__BIG_ENDIAN__)
constexpr auto BigEndian = true;
constexpr auto LittleEndian = false;