diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2024-05-04 15:50:13 +0200 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2024-05-05 03:31:19 +0200 |
commit | 5e00350a9373056ca32f9cfb03c2f0e0e4acf385 (patch) | |
tree | 4fa885028edf58cbb6bf269c63ae26889c7819e4 | |
parent | c1ad7d0ead5132520956c8d6ee6a9c6887d38556 (diff) |
a w
-rw-r--r-- | compat/borrowed-ptr-fwd.hpp | 25 | ||||
-rw-r--r-- | compat/borrowed-ptr.cpp | 6 | ||||
-rw-r--r-- | compat/borrowed-ptr.hpp | 24 | ||||
-rw-r--r-- | compat/borrowed-ptr.inl | 28 |
4 files changed, 59 insertions, 24 deletions
diff --git a/compat/borrowed-ptr-fwd.hpp b/compat/borrowed-ptr-fwd.hpp index e773a089..df985fd7 100644 --- a/compat/borrowed-ptr-fwd.hpp +++ b/compat/borrowed-ptr-fwd.hpp @@ -1,22 +1,13 @@ #pragma once -namespace floormat::detail_borrowed_ptr { - -struct control_block_; - -template<typename From, typename To> -concept StaticCastable = requires(From* ptr) { - static_cast<To*>(ptr); -}; - -} // namespace floormat::detail_borrowed_ptr +namespace floormat::detail_borrowed_ptr { struct control_block_; } namespace floormat { template<typename T> class bptr final // NOLINT(*-special-member-functions) { - T* ptr; // todo add simple_bptr that doesn't allow casting. should only have the control block member variable. + mutable T* ptr; detail_borrowed_ptr::control_block_* blk; explicit constexpr bptr(NoInitT) noexcept; @@ -37,17 +28,15 @@ public: template<typename Y> requires std::is_convertible_v<Y*, T*> bptr& operator=(const bptr<Y>&) noexcept; template<typename Y> requires std::is_convertible_v<Y*, T*> bptr& operator=(bptr<Y>&&) noexcept; - void swap() noexcept; - T* get() noexcept; - const T* get() const noexcept; - T& operator*() const noexcept; - T* operator->() const noexcept; + void swap(bptr& other) noexcept; + constexpr T* get() const noexcept; + constexpr T& operator*() const noexcept; + constexpr T* operator->() const noexcept; uint32_t use_count() const noexcept; explicit operator bool() const noexcept; template<typename U> friend class bptr; - template<typename Tʹ, typename U> - friend bptr<U> static_pointer_cast(const bptr<Tʹ>& p) noexcept; + template<typename Tʹ, typename U> friend bptr<U> static_pointer_cast(const bptr<Tʹ>& p) noexcept; }; } // namespace floormat diff --git a/compat/borrowed-ptr.cpp b/compat/borrowed-ptr.cpp index 67a55ed7..cc4bf54e 100644 --- a/compat/borrowed-ptr.cpp +++ b/compat/borrowed-ptr.cpp @@ -5,20 +5,20 @@ namespace floormat::detail_borrowed_ptr { control_block_::control_block_(void* ptr) noexcept: _ptr{ptr}, _count{1} { - fm_debug_assert(ptr); + fm_bptr_assert(ptr); } void control_block_::incr() noexcept { auto val = ++_count; (void)val; - fm_debug_assert(val > 1); + fm_bptr_assert(val > 1); } void control_block_::decr() noexcept { auto val = --_count; - fm_debug_assert(val != (uint32_t)-1); + fm_bptr_assert(val != (uint32_t)-1); if (val == 0) { free(); diff --git a/compat/borrowed-ptr.hpp b/compat/borrowed-ptr.hpp index 872902a2..d3feee2f 100644 --- a/compat/borrowed-ptr.hpp +++ b/compat/borrowed-ptr.hpp @@ -1,11 +1,35 @@ #pragma once #include "borrowed-ptr-fwd.hpp" +#include "borrowed-ptr.inl" + +#define FM_BPTR_DEBUG +#ifdef FM_BPTR_DEBUG +#include "compat/assert.hpp" +#define fm_bptr_assert(...) fm_debug_assert(__VA_ARGS__) +#else +#define fm_bptr_assert(...) void() +#endif + +namespace floormat::detail_borrowed_ptr { + +//static_assert(std::is_same_v<T, U> || std::has_virtual_destructor_v<T> && std::has_virtual_destructor_v<T>); // todo! for simple_bptr + +template<typename From, typename To> +concept StaticCastable = requires(From* from) { + static_cast<To*>(from); +}; + +} // namespace floormat::detail_borrowed_ptr namespace floormat { template<typename T> constexpr bptr<T>::bptr(std::nullptr_t) noexcept: ptr{nullptr}, blk{nullptr} {} template<typename T> constexpr bptr<T>::bptr() noexcept: bptr{nullptr} {} +template<typename T> constexpr T* bptr<T>::get() const noexcept { return ptr; } +template<typename T> constexpr T& bptr<T>::operator*() const noexcept { fm_debug_assert(ptr); return *ptr; } +template<typename T> constexpr T* bptr<T>::operator->() const noexcept { fm_debug_assert(ptr); return ptr; } + template<typename T, typename U> bptr<U> static_pointer_cast(const bptr<T>& p) noexcept { diff --git a/compat/borrowed-ptr.inl b/compat/borrowed-ptr.inl index 2faca999..d468b231 100644 --- a/compat/borrowed-ptr.inl +++ b/compat/borrowed-ptr.inl @@ -1,5 +1,4 @@ #pragma once -#include "compat/assert.hpp" #include "borrowed-ptr.hpp" namespace floormat::detail_borrowed_ptr { @@ -42,7 +41,7 @@ template <typename T> control_block<T>::control_block(T* ptr) noexcept: control_block_{ptr} { - fm_debug_assert(ptr); + fm_bptr_assert(ptr); } template <typename T> @@ -103,7 +102,7 @@ bptr<T>::bptr(const bptr<Y>& other) noexcept: if (blk) blk->incr(); else - fm_debug_assert(!ptr); + fm_bptr_assert(!ptr); } template<typename T> @@ -147,4 +146,27 @@ bptr<T>& bptr<T>::operator=(bptr<Y>&& other) noexcept return *this; } +template<typename T> +void bptr<T>::swap(bptr& other) noexcept +{ + using floormat::swap; + swap(ptr, other.ptr); + swap(blk, other.blk); +} + +template<typename T> uint32_t bptr<T>::use_count() const noexcept +{ + if (blk) [[likely]] + { + auto count = blk->_count; + fm_bptr_assert(count > 0); + return count; + } + else + { + fm_bptr_assert(ptr); + return 0; + } +} + } // namespace floormat |