summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2024-05-04 15:50:13 +0200
committerStanislaw Halik <sthalik@misaki.pl>2024-05-05 03:31:19 +0200
commit5e00350a9373056ca32f9cfb03c2f0e0e4acf385 (patch)
tree4fa885028edf58cbb6bf269c63ae26889c7819e4
parentc1ad7d0ead5132520956c8d6ee6a9c6887d38556 (diff)
a w
-rw-r--r--compat/borrowed-ptr-fwd.hpp25
-rw-r--r--compat/borrowed-ptr.cpp6
-rw-r--r--compat/borrowed-ptr.hpp24
-rw-r--r--compat/borrowed-ptr.inl28
4 files changed, 59 insertions, 24 deletions
diff --git a/compat/borrowed-ptr-fwd.hpp b/compat/borrowed-ptr-fwd.hpp
index e773a089..df985fd7 100644
--- a/compat/borrowed-ptr-fwd.hpp
+++ b/compat/borrowed-ptr-fwd.hpp
@@ -1,22 +1,13 @@
#pragma once
-namespace floormat::detail_borrowed_ptr {
-
-struct control_block_;
-
-template<typename From, typename To>
-concept StaticCastable = requires(From* ptr) {
- static_cast<To*>(ptr);
-};
-
-} // namespace floormat::detail_borrowed_ptr
+namespace floormat::detail_borrowed_ptr { struct control_block_; }
namespace floormat {
template<typename T>
class bptr final // NOLINT(*-special-member-functions)
{
- T* ptr; // todo add simple_bptr that doesn't allow casting. should only have the control block member variable.
+ mutable T* ptr;
detail_borrowed_ptr::control_block_* blk;
explicit constexpr bptr(NoInitT) noexcept;
@@ -37,17 +28,15 @@ public:
template<typename Y> requires std::is_convertible_v<Y*, T*> bptr& operator=(const bptr<Y>&) noexcept;
template<typename Y> requires std::is_convertible_v<Y*, T*> bptr& operator=(bptr<Y>&&) noexcept;
- void swap() noexcept;
- T* get() noexcept;
- const T* get() const noexcept;
- T& operator*() const noexcept;
- T* operator->() const noexcept;
+ void swap(bptr& other) noexcept;
+ constexpr T* get() const noexcept;
+ constexpr T& operator*() const noexcept;
+ constexpr T* operator->() const noexcept;
uint32_t use_count() const noexcept;
explicit operator bool() const noexcept;
template<typename U> friend class bptr;
- template<typename Tʹ, typename U>
- friend bptr<U> static_pointer_cast(const bptr<Tʹ>& p) noexcept;
+ template<typename Tʹ, typename U> friend bptr<U> static_pointer_cast(const bptr<Tʹ>& p) noexcept;
};
} // namespace floormat
diff --git a/compat/borrowed-ptr.cpp b/compat/borrowed-ptr.cpp
index 67a55ed7..cc4bf54e 100644
--- a/compat/borrowed-ptr.cpp
+++ b/compat/borrowed-ptr.cpp
@@ -5,20 +5,20 @@ namespace floormat::detail_borrowed_ptr {
control_block_::control_block_(void* ptr) noexcept: _ptr{ptr}, _count{1}
{
- fm_debug_assert(ptr);
+ fm_bptr_assert(ptr);
}
void control_block_::incr() noexcept
{
auto val = ++_count;
(void)val;
- fm_debug_assert(val > 1);
+ fm_bptr_assert(val > 1);
}
void control_block_::decr() noexcept
{
auto val = --_count;
- fm_debug_assert(val != (uint32_t)-1);
+ fm_bptr_assert(val != (uint32_t)-1);
if (val == 0)
{
free();
diff --git a/compat/borrowed-ptr.hpp b/compat/borrowed-ptr.hpp
index 872902a2..d3feee2f 100644
--- a/compat/borrowed-ptr.hpp
+++ b/compat/borrowed-ptr.hpp
@@ -1,11 +1,35 @@
#pragma once
#include "borrowed-ptr-fwd.hpp"
+#include "borrowed-ptr.inl"
+
+#define FM_BPTR_DEBUG
+#ifdef FM_BPTR_DEBUG
+#include "compat/assert.hpp"
+#define fm_bptr_assert(...) fm_debug_assert(__VA_ARGS__)
+#else
+#define fm_bptr_assert(...) void()
+#endif
+
+namespace floormat::detail_borrowed_ptr {
+
+//static_assert(std::is_same_v<T, U> || std::has_virtual_destructor_v<T> && std::has_virtual_destructor_v<T>); // todo! for simple_bptr
+
+template<typename From, typename To>
+concept StaticCastable = requires(From* from) {
+ static_cast<To*>(from);
+};
+
+} // namespace floormat::detail_borrowed_ptr
namespace floormat {
template<typename T> constexpr bptr<T>::bptr(std::nullptr_t) noexcept: ptr{nullptr}, blk{nullptr} {}
template<typename T> constexpr bptr<T>::bptr() noexcept: bptr{nullptr} {}
+template<typename T> constexpr T* bptr<T>::get() const noexcept { return ptr; }
+template<typename T> constexpr T& bptr<T>::operator*() const noexcept { fm_debug_assert(ptr); return *ptr; }
+template<typename T> constexpr T* bptr<T>::operator->() const noexcept { fm_debug_assert(ptr); return ptr; }
+
template<typename T, typename U>
bptr<U> static_pointer_cast(const bptr<T>& p) noexcept
{
diff --git a/compat/borrowed-ptr.inl b/compat/borrowed-ptr.inl
index 2faca999..d468b231 100644
--- a/compat/borrowed-ptr.inl
+++ b/compat/borrowed-ptr.inl
@@ -1,5 +1,4 @@
#pragma once
-#include "compat/assert.hpp"
#include "borrowed-ptr.hpp"
namespace floormat::detail_borrowed_ptr {
@@ -42,7 +41,7 @@ template <typename T>
control_block<T>::control_block(T* ptr) noexcept:
control_block_{ptr}
{
- fm_debug_assert(ptr);
+ fm_bptr_assert(ptr);
}
template <typename T>
@@ -103,7 +102,7 @@ bptr<T>::bptr(const bptr<Y>& other) noexcept:
if (blk)
blk->incr();
else
- fm_debug_assert(!ptr);
+ fm_bptr_assert(!ptr);
}
template<typename T>
@@ -147,4 +146,27 @@ bptr<T>& bptr<T>::operator=(bptr<Y>&& other) noexcept
return *this;
}
+template<typename T>
+void bptr<T>::swap(bptr& other) noexcept
+{
+ using floormat::swap;
+ swap(ptr, other.ptr);
+ swap(blk, other.blk);
+}
+
+template<typename T> uint32_t bptr<T>::use_count() const noexcept
+{
+ if (blk) [[likely]]
+ {
+ auto count = blk->_count;
+ fm_bptr_assert(count > 0);
+ return count;
+ }
+ else
+ {
+ fm_bptr_assert(ptr);
+ return 0;
+ }
+}
+
} // namespace floormat