summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--compat/borrowed-ptr.hpp12
-rw-r--r--compat/borrowed-ptr.inl101
2 files changed, 72 insertions, 41 deletions
diff --git a/compat/borrowed-ptr.hpp b/compat/borrowed-ptr.hpp
index d8cff42b..65115f94 100644
--- a/compat/borrowed-ptr.hpp
+++ b/compat/borrowed-ptr.hpp
@@ -13,6 +13,7 @@ concept StaticCastable = requires(From* from) {
template<typename From, typename To>
concept DerivedFrom = requires(From* x) {
std::is_convertible_v<From*, To*>;
+ std::is_convertible_v<From*, const bptr_base*>;
};
} // namespace floormat::detail_bptr
@@ -34,21 +35,30 @@ class bptr final // NOLINT(*-special-member-functions)
{
detail_bptr::control_block* blk;
+ template<typename Y> bptr(const bptr<Y>& other, std::nullptr_t) noexcept;
+ template<typename Y> bptr(bptr<Y>&& other, std::nullptr_t) noexcept;
+ template<typename Y> bptr& _copy_assign(const bptr<Y>& other) noexcept;
+ template<typename Y> bptr& _move_assign(bptr<Y>&& other) noexcept;
+
public:
template<typename... Ts>
requires std::is_constructible_v<std::remove_const_t<T>, Ts&&...>
explicit bptr(InPlaceInitT, Ts&&... args) noexcept;
- explicit bptr(T* ptr) noexcept requires std::is_convertible_v<const T*, const bptr_base*>;
+ template<detail_bptr::DerivedFrom<T> Y> explicit bptr(Y* 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<detail_bptr::DerivedFrom<T> Y> bptr(const bptr<Y>&) noexcept;
template<detail_bptr::DerivedFrom<T> Y> bptr& operator=(const bptr<Y>&) noexcept;
+ bptr(bptr&&) noexcept;
+ bptr& operator=(bptr&&) noexcept;
template<detail_bptr::DerivedFrom<T> Y> bptr(bptr<Y>&&) noexcept;
template<detail_bptr::DerivedFrom<T> Y> bptr& operator=(bptr<Y>&&) noexcept;
diff --git a/compat/borrowed-ptr.inl b/compat/borrowed-ptr.inl
index fa83dace..ccc6ced4 100644
--- a/compat/borrowed-ptr.inl
+++ b/compat/borrowed-ptr.inl
@@ -12,27 +12,22 @@
#define fm_bptr_assert(...) void()
#endif
+#if 0
#ifdef __GNUG__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
+#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
+#endif
#endif
namespace floormat::detail_bptr {
-#ifdef __GNUG__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
-#endif
struct control_block
{
bptr_base* _ptr;
uint32_t _count;
static void decrement(control_block*& blk) noexcept;
};
-#ifdef __GNUG__
-#pragma GCC diagnostic pop
-
-#endif
} // namespace floormat::detail_bptr
@@ -48,15 +43,57 @@ bptr<T>::bptr(InPlaceInitT, Ts&&... args) noexcept:
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 requires std::is_convertible_v<const T*, const bptr_base*>:
- blk{ptr ? new detail_bptr::control_block{const_cast<std::remove_const_t<T>*>(ptr), 1} : nullptr}
+template<typename T>
+template<detail_bptr::DerivedFrom<T> Y>
+bptr<T>::bptr(Y* ptr) noexcept:
+ blk{ptr ? new detail_bptr::control_block{const_cast<std::remove_const_t<Y>*>(ptr), 1} : nullptr}
{}
template<typename T> bptr<T>::~bptr() noexcept { if (blk) blk->decrement(blk); }
+template<typename T> bptr<T>::bptr(const bptr& other) noexcept: bptr{other, nullptr} {}
+template<typename T> bptr<T>::bptr(bptr&& other) noexcept: bptr{move(other), nullptr} {}
+template<typename T> bptr<T>& bptr<T>::operator=(const bptr& 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>
template<detail_bptr::DerivedFrom<T> Y>
bptr<T>::bptr(const bptr<Y>& other) noexcept:
+ bptr{other, nullptr}
+{}
+
+template<typename T>
+template<detail_bptr::DerivedFrom<T> Y>
+bptr<T>& bptr<T>::operator=(const bptr<Y>& other) noexcept
+{ return _copy_assign(other); }
+
+template<typename T>
+template<detail_bptr::DerivedFrom<T> Y>
+bptr<T>::bptr(bptr<Y>&& other) noexcept:
+ bptr{move(other), nullptr}
+{}
+
+template<typename T>
+template<detail_bptr::DerivedFrom<T> Y>
+bptr<T>& bptr<T>::operator=(bptr<Y>&& other) noexcept
+{ return _move_assign(move(other)); }
+
+template<typename T> void bptr<T>::reset() noexcept { if (blk) blk->decrement(blk); }
+
+template<typename T>
+void bptr<T>::destroy() noexcept
+{
+ if (!blk)
+ return;
+ delete blk->_ptr;
+ blk->_ptr = nullptr;
+}
+
+template<typename T> bptr<T>& bptr<T>::operator=(std::nullptr_t) noexcept { reset(); return *this; }
+
+template<typename T>
+template<typename Y>
+bptr<T>::bptr(const bptr<Y>& other, std::nullptr_t) noexcept:
blk{other.blk}
{
if (blk)
@@ -64,8 +101,16 @@ bptr<T>::bptr(const bptr<Y>& other) noexcept:
}
template<typename T>
-template<detail_bptr::DerivedFrom<T> Y>
-bptr<T>& bptr<T>::operator=(const bptr<Y>& other) noexcept
+template<typename Y>
+bptr<T>::bptr(bptr<Y>&& other, std::nullptr_t) noexcept:
+ blk{other.blk}
+{
+ other.blk = nullptr;
+}
+
+template<typename T>
+template<typename Y>
+bptr<T>& bptr<T>::_copy_assign(const bptr<Y>& other) noexcept
{
if (blk != other.blk)
{
@@ -79,16 +124,8 @@ bptr<T>& bptr<T>::operator=(const bptr<Y>& other) noexcept
}
template<typename T>
-template<detail_bptr::DerivedFrom<T> Y>
-bptr<T>::bptr(bptr<Y>&& other) noexcept:
- blk{other.blk}
-{
- other.blk = nullptr;
-}
-
-template<typename T>
-template<detail_bptr::DerivedFrom<T> Y>
-bptr<T>& bptr<T>::operator=(bptr<Y>&& other) noexcept
+template<typename Y>
+bptr<T>& bptr<T>::_move_assign(bptr<Y>&& other) noexcept
{
if (blk)
blk->decrement(blk);
@@ -98,24 +135,6 @@ bptr<T>& bptr<T>::operator=(bptr<Y>&& other) noexcept
}
template<typename T>
-void bptr<T>::reset() noexcept
-{
- if (blk)
- blk->decrement(blk);
-}
-
-template<typename T>
-void bptr<T>::destroy() noexcept
-{
- if (!blk)
- return;
- delete blk->_ptr;
- blk->_ptr = nullptr;
-}
-
-template<typename T> bptr<T>& bptr<T>::operator=(std::nullptr_t) noexcept { reset(); return *this; }
-
-template<typename T>
T* bptr<T>::get() const noexcept
{
if (blk) [[likely]]
@@ -150,6 +169,8 @@ uint32_t bptr<T>::use_count() const noexcept
} // namespace floormat
+#if 0
#ifdef __GNUG__
#pragma GCC diagnostic pop
#endif
+#endif