diff --git a/deps/ox/src/ox/std/memory.hpp b/deps/ox/src/ox/std/memory.hpp index 92abf965..4231f9fb 100644 --- a/deps/ox/src/ox/std/memory.hpp +++ b/deps/ox/src/ox/std/memory.hpp @@ -63,6 +63,117 @@ struct DefaultDelete { } }; + +template +class SharedPtr { + + private: + T *m_t = nullptr; + int *m_refCnt = nullptr; + + public: + explicit constexpr SharedPtr(T *t = nullptr) noexcept: m_t(t), m_refCnt(new int) { + } + + constexpr SharedPtr(SharedPtr &other) { + m_t = other.m_t; + m_refCnt = other.m_refCnt; + ++*m_refCnt; + } + + constexpr SharedPtr(const SharedPtr&) = delete; + + template + constexpr SharedPtr(SharedPtr &&other) noexcept { + m_t = other.m_t; + m_refCnt = other.m_refCnt; + other.m_refCnt = nullptr; + } + + ~SharedPtr() { + if (m_refCnt) { + --*m_refCnt; + if (!*m_refCnt) { + Deleter()(m_t); + safeDelete(m_refCnt); + } + } + } + + [[nodiscard]] + constexpr T *get() const noexcept { + return m_t; + } + + constexpr T *reset() noexcept { + if (m_refCnt) { + --*m_refCnt; + if (!*m_refCnt) { + safeDelete(m_refCnt); + Deleter()(m_t); + } + } + } + + template + constexpr void reset(U *other) { + reset(); + m_t = other; + m_refCnt = new int(1); + } + + template + constexpr SharedPtr &operator=(SharedPtr &&other) { + reset(std::move(other)); + return *this; + } + + constexpr T *operator->() const noexcept { + return m_t; + } + + constexpr T &operator*() const noexcept { + return *m_t; + } + + constexpr operator bool() const noexcept { + return m_t; + } + +}; + +template +constexpr bool operator==(const SharedPtr &p1, const SharedPtr &p2) noexcept { + return p1.get() == p2.get(); +} + +template +constexpr bool operator==(const SharedPtr &p1, std::nullptr_t) noexcept { + return p1.get(); +} + +template +constexpr bool operator==(std::nullptr_t, const SharedPtr &p2) noexcept { + return p2.get(); +} + + +template +constexpr bool operator!=(const SharedPtr &p1, const SharedPtr &p2) noexcept { + return p1.get() != p2.get(); +} + +template +constexpr bool operator!=(const SharedPtr &p1, std::nullptr_t) noexcept { + return !p1.get(); +} + +template +constexpr bool operator!=(std::nullptr_t, const SharedPtr &p2) noexcept { + return !p2.get(); +} + + template class UniquePtr { @@ -82,7 +193,7 @@ class UniquePtr { m_t = other.release(); } - ~UniquePtr() { + constexpr ~UniquePtr() { Deleter()(m_t); } @@ -104,6 +215,16 @@ class UniquePtr { Deleter()(t); } + constexpr UniquePtr &operator=(const UniquePtr &other) = delete; + + template + constexpr UniquePtr &operator=(const UniquePtr &other) = delete; + + constexpr UniquePtr &operator=(UniquePtr &&other) { + reset(std::move(other)); + return *this; + } + template constexpr UniquePtr &operator=(UniquePtr &&other) { reset(std::move(other));