From 98b6f14c8c27898da75a8c556b9c240c388ba6dc Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Mon, 6 May 2024 19:25:46 +0200 Subject: fix up borrowed-ptr include layout --- compat/borrowed-ptr-cast.hpp | 42 ++++++++++++++++++++++ compat/borrowed-ptr-fwd.hpp | 68 ++--------------------------------- compat/borrowed-ptr.hpp | 85 ++++++++++++++++++++++++++++++-------------- test/bptr.cpp | 1 + 4 files changed, 103 insertions(+), 93 deletions(-) create mode 100644 compat/borrowed-ptr-cast.hpp diff --git a/compat/borrowed-ptr-cast.hpp b/compat/borrowed-ptr-cast.hpp new file mode 100644 index 00000000..b9db2e5b --- /dev/null +++ b/compat/borrowed-ptr-cast.hpp @@ -0,0 +1,42 @@ +#pragma once +#include "borrowed-ptr-fwd.hpp" +#include "compat/assert.hpp" + +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 +bptr static_pointer_cast(const bptr& p) noexcept +{ + // hack to generate better error message + if constexpr (detail_borrowed_ptr::StaticCastable) + { + if (p.blk && p.blk->_ptr) [[likely]] + { + fm_assert(p.casted_ptr); + auto* ret = static_cast(p.casted_ptr); + return bptr{DirectInit, ret, p.blk}; + } + } + else + { + using detail_borrowed_ptr::StaticCastable; + // concepts can't be forward-declared so use static_assert + static_assert(StaticCastable, + "cannot static_cast, classes must be related by inheritance"); + } + + return bptr{nullptr}; +} + +} // namespace floormat diff --git a/compat/borrowed-ptr-fwd.hpp b/compat/borrowed-ptr-fwd.hpp index 8f4fafbe..3bb509d9 100644 --- a/compat/borrowed-ptr-fwd.hpp +++ b/compat/borrowed-ptr-fwd.hpp @@ -1,74 +1,10 @@ #pragma once - -namespace floormat::detail_borrowed_ptr { - -struct control_block; -template -concept DerivedFrom = requires(From* x) { - requires !std::is_same_v; - requires std::is_nothrow_convertible_v; -}; - -} // namespace floormat::detail_borrowed_ptr - namespace floormat { template class bptr; -template bool operator==(const bptr& a, const bptr& b) noexcept; - -template -class bptr final // NOLINT(*-special-member-functions) -{ - mutable T* casted_ptr; - detail_borrowed_ptr::control_block* blk; - - explicit bptr(DirectInitT, T* casted_ptr, detail_borrowed_ptr::control_block* blk) noexcept; - - struct private_tag_t final {}; - static constexpr private_tag_t private_tag{}; - - template bptr(const bptr& other, private_tag_t) noexcept; - template bptr& _copy_assign(const bptr& other) noexcept; - template bptr(bptr&& other, private_tag_t) noexcept; - template bptr& _move_assign(bptr&& other) noexcept; -public: - template - requires std::is_constructible_v - explicit bptr(InPlaceInitT, Ts&&... args) noexcept; - - explicit bptr(T* ptr) noexcept; - bptr() noexcept; - ~bptr() noexcept; - - bptr(std::nullptr_t) noexcept; // NOLINT(*-explicit-conversions) - bptr& operator=(std::nullptr_t) noexcept; - - bptr(const bptr&) noexcept; - bptr& operator=(const bptr&) noexcept; - template Y> bptr(const bptr&) noexcept; - template Y> bptr& operator=(const bptr&) noexcept; - - bptr(bptr&&) noexcept; - bptr& operator=(bptr&&) noexcept; - template Y> bptr(bptr&&) noexcept; - template Y> bptr& operator=(bptr&&) noexcept; - - void reset() noexcept; - template void destroy() noexcept; - void swap(bptr& other) noexcept; - uint32_t use_count() const noexcept; - - T* get() const noexcept; - T* operator->() const noexcept; - T& operator*() const noexcept; - - explicit operator bool() const noexcept; - friend bool operator==(const bptr& a, const bptr& b) noexcept; - - template friend class bptr; - template friend bptr static_pointer_cast(const bptr& p) noexcept; -}; +template bool operator==(const bptr& a, const bptr& b) noexcept; +template bptr static_pointer_cast(const bptr& p) noexcept; template bptr(T* ptr) -> bptr; diff --git a/compat/borrowed-ptr.hpp b/compat/borrowed-ptr.hpp index b9db2e5b..e622f6d8 100644 --- a/compat/borrowed-ptr.hpp +++ b/compat/borrowed-ptr.hpp @@ -1,42 +1,73 @@ #pragma once #include "borrowed-ptr-fwd.hpp" -#include "compat/assert.hpp" 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 - +struct control_block; template -concept StaticCastable = requires(From* from) { - static_cast(from); +concept DerivedFrom = requires(From* x) { + requires !std::is_same_v; + requires std::is_nothrow_convertible_v; }; } // namespace floormat::detail_borrowed_ptr namespace floormat { -template -bptr static_pointer_cast(const bptr& p) noexcept +template class bptr; + +template +class bptr final // NOLINT(*-special-member-functions) { - // hack to generate better error message - if constexpr (detail_borrowed_ptr::StaticCastable) - { - if (p.blk && p.blk->_ptr) [[likely]] - { - fm_assert(p.casted_ptr); - auto* ret = static_cast(p.casted_ptr); - return bptr{DirectInit, ret, p.blk}; - } - } - else - { - using detail_borrowed_ptr::StaticCastable; - // concepts can't be forward-declared so use static_assert - static_assert(StaticCastable, - "cannot static_cast, classes must be related by inheritance"); - } - - return bptr{nullptr}; -} + mutable T* casted_ptr; + detail_borrowed_ptr::control_block* blk; + + explicit bptr(DirectInitT, T* casted_ptr, detail_borrowed_ptr::control_block* blk) noexcept; + + struct private_tag_t final {}; + static constexpr private_tag_t private_tag{}; + + template bptr(const bptr& other, private_tag_t) noexcept; + template bptr& _copy_assign(const bptr& other) noexcept; + template bptr(bptr&& other, private_tag_t) noexcept; + template bptr& _move_assign(bptr&& other) noexcept; + +public: + template + requires std::is_constructible_v + explicit bptr(InPlaceInitT, Ts&&... args) noexcept; + + explicit bptr(T* ptr) noexcept; + bptr() noexcept; + ~bptr() noexcept; + + bptr(std::nullptr_t) noexcept; // NOLINT(*-explicit-conversions) + bptr& operator=(std::nullptr_t) noexcept; + + bptr(const bptr&) noexcept; + bptr& operator=(const bptr&) noexcept; + template Y> bptr(const bptr&) noexcept; + template Y> bptr& operator=(const bptr&) noexcept; + + bptr(bptr&&) noexcept; + bptr& operator=(bptr&&) noexcept; + template Y> bptr(bptr&&) noexcept; + template Y> bptr& operator=(bptr&&) noexcept; + + void reset() noexcept; + template void destroy() noexcept; + void swap(bptr& other) noexcept; + uint32_t use_count() const noexcept; + + T* get() const noexcept; + T* operator->() const noexcept; + T& operator*() const noexcept; + + explicit operator bool() const noexcept; + friend bool operator==(const bptr& a, const bptr& b) noexcept; + + template friend class bptr; + template friend bptr static_pointer_cast(const bptr& p) noexcept; +}; } // namespace floormat diff --git a/test/bptr.cpp b/test/bptr.cpp index e4672d66..b254f295 100644 --- a/test/bptr.cpp +++ b/test/bptr.cpp @@ -1,5 +1,6 @@ #include "app.hpp" #include "compat/borrowed-ptr.inl" +#include "compat/borrowed-ptr-cast.hpp" #include "compat/assert.hpp" #include "compat/defs.hpp" #include -- cgit v1.2.3