diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2024-07-14 13:03:39 +0200 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2024-07-14 13:04:43 +0200 |
commit | ec67a7720a236918188b384c95631c4a5f1abb3c (patch) | |
tree | fd124da2adff5c68c27ea473d51ddefd6e469634 | |
parent | 5fe8eec392fa0568a03ad566a5b41c3b1df7a465 (diff) |
w
-rw-r--r-- | compat/borrowed-ptr-cast.hpp | 2 | ||||
-rw-r--r-- | compat/borrowed-ptr-fwd.hpp | 4 | ||||
-rw-r--r-- | compat/borrowed-ptr.hpp | 24 | ||||
-rw-r--r-- | compat/borrowed-ptr.inl | 48 | ||||
-rw-r--r-- | test/bptr.cpp | 12 |
5 files changed, 51 insertions, 39 deletions
diff --git a/compat/borrowed-ptr-cast.hpp b/compat/borrowed-ptr-cast.hpp index f202af30..18f0a50e 100644 --- a/compat/borrowed-ptr-cast.hpp +++ b/compat/borrowed-ptr-cast.hpp @@ -22,7 +22,7 @@ bptr<To> static_pointer_cast(const bptr<From>& p) noexcept if constexpr (detail_borrowed_ptr::StaticCastable<From, To>) { if (p.blk && p.blk->_ptr) [[likely]] - return bptr<To>{p, bptr<To>::private_tag}; + return bptr<To>{p, nullptr}; } else { diff --git a/compat/borrowed-ptr-fwd.hpp b/compat/borrowed-ptr-fwd.hpp index 3bb509d9..8386decc 100644 --- a/compat/borrowed-ptr-fwd.hpp +++ b/compat/borrowed-ptr-fwd.hpp @@ -2,10 +2,8 @@ namespace floormat { template<typename T> class bptr; - -template<typename T> bool operator==(const bptr<T>& a, const bptr<T>& b) noexcept; template<typename To, typename From> bptr<To> static_pointer_cast(const bptr<From>& p) noexcept; - template<typename T> bptr(T* ptr) -> bptr<T>; +template<typename T> bptr(const T* ptr) -> bptr<const T>; } // namespace floormat diff --git a/compat/borrowed-ptr.hpp b/compat/borrowed-ptr.hpp index 31f83c16..affad912 100644 --- a/compat/borrowed-ptr.hpp +++ b/compat/borrowed-ptr.hpp @@ -29,21 +29,18 @@ struct bptr_base template<typename T> class bptr final // NOLINT(*-special-member-functions) { - static_assert(std::is_convertible_v<T*, bptr_base*>); - detail_borrowed_ptr::control_block* blk; - struct private_tag_t final {}; - static constexpr private_tag_t private_tag{}; + bptr(detail_borrowed_ptr::control_block* blk) noexcept; - template<typename Y> bptr(const bptr<Y>& other, private_tag_t) noexcept; + template<typename Y> bptr(const bptr<Y>& other, std::nullptr_t) noexcept; template<typename Y> bptr& _copy_assign(const bptr<Y>& other) noexcept; - template<typename Y> bptr(bptr<Y>&& other, private_tag_t) noexcept; + template<typename Y> bptr(bptr<Y>&& other, std::nullptr_t) noexcept; template<typename Y> bptr& _move_assign(bptr<Y>&& other) noexcept; public: template<typename... Ts> - requires std::is_constructible_v<T, Ts&&...> + requires std::is_constructible_v<std::remove_const_t<T>, Ts&&...> explicit bptr(InPlaceInitT, Ts&&... args) noexcept; explicit bptr(T* ptr) noexcept; @@ -55,13 +52,15 @@ public: bptr(const bptr&) noexcept; bptr& operator=(const bptr&) noexcept; - template<detail_borrowed_ptr::DerivedFrom<T> Y> bptr(const bptr<Y>&) noexcept; - template<detail_borrowed_ptr::DerivedFrom<T> Y> bptr& operator=(const bptr<Y>&) noexcept; + template<detail_borrowed_ptr::DerivedFrom<std::remove_const_t<T>> Y> bptr(const bptr<Y>&) noexcept; + template<detail_borrowed_ptr::DerivedFrom<std::remove_const_t<T>> Y> bptr& operator=(const bptr<Y>&) noexcept; bptr(bptr&&) noexcept; bptr& operator=(bptr&&) noexcept; - template<detail_borrowed_ptr::DerivedFrom<T> Y> bptr(bptr<Y>&&) noexcept; - template<detail_borrowed_ptr::DerivedFrom<T> Y> bptr& operator=(bptr<Y>&&) noexcept; + template<detail_borrowed_ptr::DerivedFrom<std::remove_const_t<T>> Y> bptr(bptr<Y>&&) noexcept; + template<detail_borrowed_ptr::DerivedFrom<std::remove_const_t<T>> Y> bptr& operator=(bptr<Y>&&) noexcept; + + operator bptr<const T>() const noexcept requires (!std::is_const_v<T>); void reset() noexcept; void destroy() noexcept; @@ -73,7 +72,8 @@ public: T& operator*() const noexcept; explicit operator bool() const noexcept; - friend bool operator==<T>(const bptr<T>& a, const bptr<T>& b) noexcept; + bool operator==(const bptr<const std::remove_const_t<T>>& other) const noexcept; + bool operator==(const bptr<std::remove_const_t<T>>& other) const noexcept; template<typename U> friend class bptr; template<typename U, typename Tʹ> friend bptr<U> static_pointer_cast(const bptr<Tʹ>& p) noexcept; diff --git a/compat/borrowed-ptr.inl b/compat/borrowed-ptr.inl index 390593bf..acdcb0df 100644 --- a/compat/borrowed-ptr.inl +++ b/compat/borrowed-ptr.inl @@ -41,7 +41,7 @@ namespace floormat { template<typename T> template<typename... Ts> -requires std::is_constructible_v<T, Ts&&...> +requires std::is_constructible_v<std::remove_const_t<T>, Ts&&...> bptr<T>::bptr(InPlaceInitT, Ts&&... args) noexcept: bptr{ new T{ forward<Ts...>(args...) } } { @@ -50,12 +50,7 @@ bptr{ new T{ forward<Ts...>(args...) } } template<typename T> bptr<T>::bptr(std::nullptr_t) noexcept: blk{nullptr} {} template<typename T> bptr<T>::bptr() noexcept: bptr{nullptr} {} -template<typename T> -bptr<T>::bptr(T* ptr) noexcept: - blk{ptr ? new detail_borrowed_ptr::control_block{ptr, 1} : nullptr} -{ - fm_bptr_assert(!blk || blk->_count == 1 && blk->_ptr); -} +template<typename T> bptr<T>::bptr(T* ptr) noexcept: blk{ptr ? new detail_borrowed_ptr::control_block{ptr, 1} : nullptr} {} template<typename T> bptr<T>::~bptr() noexcept @@ -64,31 +59,41 @@ bptr<T>::~bptr() noexcept blk->decrement(blk); } -template<typename T> bptr<T>::bptr(const bptr& other) noexcept: bptr{other, private_tag} {} +template<typename T> bptr<T>::bptr(const bptr& other) noexcept: bptr{other, nullptr} {} template<typename T> bptr<T>& bptr<T>::operator=(const bptr& other) noexcept { return _copy_assign(other); } template<typename T> -template<detail_borrowed_ptr::DerivedFrom<T> Y> -bptr<T>::bptr(const bptr<Y>& other) noexcept: bptr{other, private_tag} {} +template<detail_borrowed_ptr::DerivedFrom<std::remove_const_t<T>> Y> +bptr<T>::bptr(const bptr<Y>& other) noexcept: bptr{other, nullptr} {} template<typename T> -template<detail_borrowed_ptr::DerivedFrom<T> Y> +template<detail_borrowed_ptr::DerivedFrom<std::remove_const_t<T>> Y> bptr<T>& bptr<T>::operator=(const bptr<Y>& other) noexcept { return _copy_assign(other); } template<typename T> bptr<T>& bptr<T>::operator=(bptr&& other) noexcept { return _move_assign(move(other)); } -template<typename T> bptr<T>::bptr(bptr&& other) noexcept: bptr{move(other), private_tag} {} +template<typename T> bptr<T>::bptr(bptr&& other) noexcept: bptr{move(other), nullptr} {} template<typename T> -template<detail_borrowed_ptr::DerivedFrom<T> Y> -bptr<T>::bptr(bptr<Y>&& other) noexcept: bptr{move(other), private_tag} {} +template<detail_borrowed_ptr::DerivedFrom<std::remove_const_t<T>> Y> +bptr<T>::bptr(bptr<Y>&& other) noexcept: bptr{move(other), nullptr} {} template<typename T> -template<detail_borrowed_ptr::DerivedFrom<T> Y> +template<detail_borrowed_ptr::DerivedFrom<std::remove_const_t<T>> Y> bptr<T>& bptr<T>::operator=(bptr<Y>&& other) noexcept { return _move_assign(move(other)); } template<typename T> +bptr<T>::operator bptr<const T>() const noexcept requires (!std::is_const_v<T>) { + if (blk && blk->_ptr) + { + ++blk->_count; + return bptr<const T>{}; + } + return bptr<const T>{nullptr}; +} + +template<typename T> void bptr<T>::reset() noexcept { if (blk) @@ -110,8 +115,11 @@ void bptr<T>::destroy() noexcept template<typename T> bptr<T>& bptr<T>::operator=(std::nullptr_t) noexcept { reset(); return *this; } template<typename T> +bptr<T>::bptr(detail_borrowed_ptr::control_block* blk) noexcept: blk{blk} { } + +template<typename T> template<typename Y> -bptr<T>::bptr(const bptr<Y>& other, private_tag_t) noexcept: +bptr<T>::bptr(const bptr<Y>& other, std::nullptr_t) noexcept: blk{other.blk} { if (blk) @@ -127,7 +135,7 @@ bptr<T>& bptr<T>::_copy_assign(const bptr<Y>& other) noexcept { if (blk != other.blk) { - CORRADE_ASSUME(this != &other); // todo! see if helps + CORRADE_ASSUME(this != &other); // todo see if helps if (blk) blk->decrement(blk); blk = other.blk; @@ -139,7 +147,7 @@ bptr<T>& bptr<T>::_copy_assign(const bptr<Y>& other) noexcept template<typename T> template<typename Y> -bptr<T>::bptr(bptr<Y>&& other, private_tag_t) noexcept: +bptr<T>::bptr(bptr<Y>&& other, std::nullptr_t) noexcept: blk{other.blk} { other.blk = nullptr; @@ -172,8 +180,10 @@ template<typename T> T* bptr<T>::operator->() const noexcept } template<typename T> T& bptr<T>::operator*() const noexcept { return *operator->(); } -template<typename T> bool operator==(const bptr<T>& a, const bptr<T>& b) noexcept { return a.get() == b.get(); } + template<typename T> bptr<T>::operator bool() const noexcept { return get(); } +template<typename T> bool bptr<T>::operator==(const bptr<const std::remove_const_t<T>>& other) const noexcept { return get() == other.get(); } +template<typename T> bool bptr<T>::operator==(const bptr<std::remove_const_t<T>>& other) const noexcept { return get() == other.get(); } template<typename T> void bptr<T>::swap(bptr& other) noexcept diff --git a/test/bptr.cpp b/test/bptr.cpp index ee254b68..3a62de53 100644 --- a/test/bptr.cpp +++ b/test/bptr.cpp @@ -15,10 +15,6 @@ struct Baz : bptr_base {}; // NOLINTBEGIN(*-use-anonymous-namespace) -template bool operator==(const bptr<Foo>&, const bptr<Foo>&) noexcept; -template bool operator==(const bptr<Bar>&, const bptr<Bar>&) noexcept; -template bool operator==(const bptr<Baz>&, const bptr<Baz>&) noexcept; - template class bptr<Foo>; template class bptr<Bar>; template class bptr<Baz>; @@ -333,6 +329,13 @@ void test9() fm_assert(A_total == 1 && A_alive == 0); }; +void test10() +{ + fm_assert(bptr<Foo>{} == bptr<Foo>{}); + fm_assert(bptr<const Foo>{} == bptr<const Foo>{}); + fm_assert(bptr<Foo>{} == bptr<const Foo>{}); +} + } // namespace void Test::test_bptr() @@ -346,6 +349,7 @@ void Test::test_bptr() test7(); test8(); test9(); + test10(); } } // namespace floormat |