diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2024-07-14 17:01:46 +0200 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2024-07-14 17:17:45 +0200 |
commit | 25057f99ac871684695175738f9ac31890bb4bba (patch) | |
tree | fc482b9077032ae8ae2c973a0085dc2824c9a3c3 /compat/borrowed-ptr.hpp | |
parent | b47f6164b82c166afb6d560caa3ffb79db15c7b7 (diff) |
w
Diffstat (limited to 'compat/borrowed-ptr.hpp')
-rw-r--r-- | compat/borrowed-ptr.hpp | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/compat/borrowed-ptr.hpp b/compat/borrowed-ptr.hpp index 146fc334..2f7f00d2 100644 --- a/compat/borrowed-ptr.hpp +++ b/compat/borrowed-ptr.hpp @@ -4,18 +4,22 @@ namespace floormat::detail_borrowed_ptr { struct control_block; + +template<typename From, typename To> +concept StaticCastable = requires(From* from) { + static_cast<To*>(from); +}; + template<typename From, typename To> concept DerivedFrom = requires(From* x) { - requires !std::is_same_v<From, To>; - requires std::is_nothrow_convertible_v<From*, To*>; + !std::is_same_v<From, To>; + std::is_convertible_v<From*, To*>; }; } // namespace floormat::detail_borrowed_ptr namespace floormat { -template<typename T> class bptr; - struct bptr_base { virtual ~bptr_base() noexcept; @@ -27,6 +31,7 @@ struct bptr_base }; template<typename T> +requires std::is_convertible_v<T*, const bptr_base*> class bptr final // NOLINT(*-special-member-functions) { detail_borrowed_ptr::control_block* blk; @@ -58,8 +63,6 @@ public: template<detail_borrowed_ptr::DerivedFrom<T> Y> CORRADE_ALWAYS_INLINE bptr(bptr<Y>&&) noexcept; template<detail_borrowed_ptr::DerivedFrom<T> Y> CORRADE_ALWAYS_INLINE bptr& operator=(bptr<Y>&&) noexcept; - operator bptr<const T>() const noexcept requires (!std::is_const_v<T>); - void reset() noexcept; void destroy() noexcept; void swap(bptr& other) noexcept; @@ -73,8 +76,20 @@ public: 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; + template<typename U> requires std::is_convertible_v<U*, const bptr_base*> friend class bptr; + + template<typename To, typename From> + requires (std::is_convertible_v<To*, const bptr_base*> && detail_borrowed_ptr::StaticCastable<From, To>) + friend bptr<To> static_pointer_cast(const bptr<From>& p) noexcept; }; +template<typename To, typename From> +requires (std::is_convertible_v<To*, const bptr_base*> && detail_borrowed_ptr::StaticCastable<From, To>) +bptr<To> static_pointer_cast(const bptr<From>& p) noexcept +{ + if (p.blk && p.blk->_ptr) [[likely]] + return bptr<To>{p, nullptr}; + return bptr<To>{nullptr}; +} + } // namespace floormat |