From 5e00350a9373056ca32f9cfb03c2f0e0e4acf385 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sat, 4 May 2024 15:50:13 +0200 Subject: a w --- compat/borrowed-ptr-fwd.hpp | 25 +++++++------------------ compat/borrowed-ptr.cpp | 6 +++--- compat/borrowed-ptr.hpp | 24 ++++++++++++++++++++++++ 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 -concept StaticCastable = requires(From* ptr) { - static_cast(ptr); -}; - -} // namespace floormat::detail_borrowed_ptr +namespace floormat::detail_borrowed_ptr { struct control_block_; } namespace floormat { template 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 requires std::is_convertible_v bptr& operator=(const bptr&) noexcept; template requires std::is_convertible_v bptr& operator=(bptr&&) 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 friend class bptr; - template - friend bptr static_pointer_cast(const bptr& p) noexcept; + template friend bptr static_pointer_cast(const bptr& 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 || std::has_virtual_destructor_v && std::has_virtual_destructor_v); // todo! for simple_bptr + +template +concept StaticCastable = requires(From* from) { + static_cast(from); +}; + +} // namespace floormat::detail_borrowed_ptr namespace floormat { template constexpr bptr::bptr(std::nullptr_t) noexcept: ptr{nullptr}, blk{nullptr} {} template constexpr bptr::bptr() noexcept: bptr{nullptr} {} +template constexpr T* bptr::get() const noexcept { return ptr; } +template constexpr T& bptr::operator*() const noexcept { fm_debug_assert(ptr); return *ptr; } +template constexpr T* bptr::operator->() const noexcept { fm_debug_assert(ptr); return ptr; } + template bptr static_pointer_cast(const bptr& 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 control_block::control_block(T* ptr) noexcept: control_block_{ptr} { - fm_debug_assert(ptr); + fm_bptr_assert(ptr); } template @@ -103,7 +102,7 @@ bptr::bptr(const bptr& other) noexcept: if (blk) blk->incr(); else - fm_debug_assert(!ptr); + fm_bptr_assert(!ptr); } template @@ -147,4 +146,27 @@ bptr& bptr::operator=(bptr&& other) noexcept return *this; } +template +void bptr::swap(bptr& other) noexcept +{ + using floormat::swap; + swap(ptr, other.ptr); + swap(blk, other.blk); +} + +template uint32_t bptr::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 -- cgit v1.2.3