summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2024-07-14 13:03:39 +0200
committerStanislaw Halik <sthalik@misaki.pl>2024-07-14 13:04:43 +0200
commitec67a7720a236918188b384c95631c4a5f1abb3c (patch)
treefd124da2adff5c68c27ea473d51ddefd6e469634
parent5fe8eec392fa0568a03ad566a5b41c3b1df7a465 (diff)
w
-rw-r--r--compat/borrowed-ptr-cast.hpp2
-rw-r--r--compat/borrowed-ptr-fwd.hpp4
-rw-r--r--compat/borrowed-ptr.hpp24
-rw-r--r--compat/borrowed-ptr.inl48
-rw-r--r--test/bptr.cpp12
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