summaryrefslogtreecommitdiffhomepage
path: root/compat/borrowed-ptr.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'compat/borrowed-ptr.hpp')
-rw-r--r--compat/borrowed-ptr.hpp66
1 files changed, 54 insertions, 12 deletions
diff --git a/compat/borrowed-ptr.hpp b/compat/borrowed-ptr.hpp
index 92c1f761..62394087 100644
--- a/compat/borrowed-ptr.hpp
+++ b/compat/borrowed-ptr.hpp
@@ -2,6 +2,16 @@
#include "borrowed-ptr-fwd.hpp"
#include <compare>
+#define FM_BPTR_DEBUG
+
+#ifdef __CLION_IDE__
+#define fm_bptr_assert(...) (void(__VA_ARGS__))
+#elif defined FM_BPTR_DEBUG && !defined FM_NO_DEBUG
+#define fm_bptr_assert(...) fm_assert(__VA_ARGS__)
+#else
+#define fm_bptr_assert(...) void()
+#endif
+
namespace floormat { struct bptr_base; }
namespace floormat::detail_bptr {
@@ -9,19 +19,29 @@ namespace floormat::detail_bptr {
struct control_block final
{
bptr_base* _ptr;
- uint32_t _count;
+ uint32_t _soft_count, _hard_count;
static void decrement(control_block*& blk) noexcept;
+ static void weak_decrement(control_block*& blk) noexcept;
};
template<typename From, typename To>
concept StaticCastable = requires(From* from) {
static_cast<To*>(from);
+ requires std::is_base_of_v<std::remove_cvref_t<From>, std::remove_cvref_t<To>>;
};
template<typename From, typename To>
concept DerivedFrom = requires(From* x) {
- std::is_convertible_v<From*, To*>;
- std::is_convertible_v<From*, const bptr_base*>;
+#if 0
+ requires std::is_convertible_v<From*, To*>;
+ requires std::is_convertible_v<From*, const bptr_base*>;
+ requires std::is_convertible_v<To*, const bptr_base*>;
+ requires std::is_base_of_v<bptr_base, From>;
+ requires std::is_base_of_v<bptr_base, To>;
+ requires std::is_base_of_v<std::remove_cvref_t<To>, std::remove_cvref_t<From>>;
+#else
+ static_cast<To*>(std::declval<From*>());
+#endif
};
} // namespace floormat::detail_bptr
@@ -50,7 +70,7 @@ class bptr final // NOLINT(*-special-member-functions)
public:
template<typename... Ts>
- requires std::is_constructible_v<std::remove_const_t<T>, Ts&&...>
+ //requires std::is_constructible_v<std::remove_const_t<T>, Ts&&...>
explicit bptr(InPlaceInitT, Ts&&... args) noexcept;
template<detail_bptr::DerivedFrom<T> Y> explicit bptr(Y* ptr) noexcept;
@@ -82,27 +102,49 @@ public:
explicit operator bool() const 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;
- bool operator==(const std::nullptr_t& other) const noexcept;
-
- std::strong_ordering operator<=>(const bptr<const std::remove_const_t<T>>& other) const noexcept;
- std::strong_ordering operator<=>(const bptr<std::remove_const_t<T>>& other) const noexcept;
- std::strong_ordering operator<=>(const std::nullptr_t& other) const noexcept;
+ bool operator==(const bptr<const T>& other) const noexcept;
+ std::strong_ordering operator<=>(const bptr<const T>& other) const noexcept;
template<typename U> friend class bptr;
+ template<typename U> friend class weak_bptr;
+
+ template<typename To, typename From>
+ requires detail_bptr::StaticCastable<From, To>
+ friend bptr<To> static_pointer_cast(bptr<From>&& p) noexcept;
template<typename To, typename From>
requires detail_bptr::StaticCastable<From, To>
friend bptr<To> static_pointer_cast(const bptr<From>& p) noexcept;
};
+template<typename T> bptr<T>::bptr(std::nullptr_t) noexcept: blk{nullptr} {}
+
+template<typename To, typename From>
+requires detail_bptr::StaticCastable<From, To>
+bptr<To> static_pointer_cast(bptr<From>&& p) noexcept
+{
+ if (p.blk && p.blk->_ptr) [[likely]]
+ {
+ bptr<To> ret{nullptr};
+ ret.blk = p.blk;
+ p.blk = nullptr;
+ return ret;
+ }
+ return bptr<To>{nullptr};
+}
+
template<typename To, typename From>
requires detail_bptr::StaticCastable<From, To>
bptr<To> static_pointer_cast(const bptr<From>& p) noexcept
{
if (p.blk && p.blk->_ptr) [[likely]]
- return bptr<To>{p};
+ {
+ bptr<To> ret{nullptr};
+ ++p.blk->_soft_count;
+ ++p.blk->_hard_count;
+ ret.blk = p.blk;
+ return ret;
+ }
return bptr<To>{nullptr};
}