diff options
Diffstat (limited to 'compat/borrowed-ptr.inl')
-rw-r--r-- | compat/borrowed-ptr.inl | 90 |
1 files changed, 62 insertions, 28 deletions
diff --git a/compat/borrowed-ptr.inl b/compat/borrowed-ptr.inl index e7b4bbbd..c4f19de5 100644 --- a/compat/borrowed-ptr.inl +++ b/compat/borrowed-ptr.inl @@ -39,6 +39,7 @@ struct control_block namespace floormat { template<typename T> +requires std::is_convertible_v<T*, const bptr_base*> template<typename... Ts> requires std::is_constructible_v<std::remove_const_t<T>, Ts&&...> bptr<T>::bptr(InPlaceInitT, Ts&&... args) noexcept: @@ -46,65 +47,75 @@ bptr{ new std::remove_const_t<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> +requires std::is_convertible_v<T*, const bptr_base*> +bptr<T>::bptr(std::nullptr_t) noexcept: blk{nullptr} {} + +template<typename T> +requires std::is_convertible_v<T*, const bptr_base*> +bptr<T>::bptr() noexcept: bptr{nullptr} {} -template<typename T> bptr<T>::bptr(T* ptr) noexcept: +template<typename T> +requires std::is_convertible_v<T*, const bptr_base*> +bptr<T>::bptr(T* ptr) noexcept: blk{ptr ? new detail_borrowed_ptr::control_block{const_cast<std::remove_const_t<T>*>(ptr), 1} : nullptr} {} template<typename T> +requires std::is_convertible_v<T*, const bptr_base*> 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<T>::operator=(const bptr& other) noexcept { return _copy_assign(other); } +template<typename T> +requires std::is_convertible_v<T*, const bptr_base*> +bptr<T>::bptr(const bptr& other) noexcept: bptr{other, nullptr} {} + +template<typename T> +requires std::is_convertible_v<T*, const bptr_base*> +bptr<T>& bptr<T>::operator=(const bptr& other) noexcept { return _copy_assign(other); } template<typename T> +requires std::is_convertible_v<T*, const bptr_base*> template<detail_borrowed_ptr::DerivedFrom<T> Y> bptr<T>::bptr(const bptr<Y>& other) noexcept: bptr{other, nullptr} {} template<typename T> +requires std::is_convertible_v<T*, const bptr_base*> template<detail_borrowed_ptr::DerivedFrom<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), nullptr} {} +template<typename T> +requires std::is_convertible_v<T*, const bptr_base*> +bptr<T>& bptr<T>::operator=(bptr&& other) noexcept { return _move_assign(move(other)); } +template<typename T> +requires std::is_convertible_v<T*, const bptr_base*> +bptr<T>::bptr(bptr&& other) noexcept: bptr{move(other), nullptr} {} template<typename T> +requires std::is_convertible_v<T*, const bptr_base*> template<detail_borrowed_ptr::DerivedFrom<T> Y> bptr<T>::bptr(bptr<Y>&& other) noexcept: bptr{move(other), nullptr} {} template<typename T> +requires std::is_convertible_v<T*, const bptr_base*> template<detail_borrowed_ptr::DerivedFrom<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> +requires std::is_convertible_v<T*, const bptr_base*> void bptr<T>::reset() noexcept { if (blk) - { blk->decrement(blk); - blk = nullptr; - } } template<typename T> +requires std::is_convertible_v<T*, const bptr_base*> void bptr<T>::destroy() noexcept { if (!blk) @@ -113,9 +124,12 @@ void bptr<T>::destroy() noexcept blk->_ptr = nullptr; } -template<typename T> bptr<T>& bptr<T>::operator=(std::nullptr_t) noexcept { reset(); return *this; } +template<typename T> +requires std::is_convertible_v<T*, const bptr_base*> +bptr<T>& bptr<T>::operator=(std::nullptr_t) noexcept { reset(); return *this; } template<typename T> +requires std::is_convertible_v<T*, const bptr_base*> template<typename Y> bptr<T>::bptr(const bptr<Y>& other, std::nullptr_t) noexcept: blk{other.blk} @@ -128,6 +142,7 @@ bptr<T>::bptr(const bptr<Y>& other, std::nullptr_t) noexcept: } template<typename T> +requires std::is_convertible_v<T*, const bptr_base*> template<typename Y> bptr<T>& bptr<T>::_copy_assign(const bptr<Y>& other) noexcept { @@ -143,6 +158,7 @@ bptr<T>& bptr<T>::_copy_assign(const bptr<Y>& other) noexcept } template<typename T> +requires std::is_convertible_v<T*, const bptr_base*> template<typename Y> bptr<T>::bptr(bptr<Y>&& other, std::nullptr_t) noexcept: blk{other.blk} @@ -151,6 +167,7 @@ bptr<T>::bptr(bptr<Y>&& other, std::nullptr_t) noexcept: } template<typename T> +requires std::is_convertible_v<T*, const bptr_base*> template<typename Y> bptr<T>& bptr<T>::_move_assign(bptr<Y>&& other) noexcept { @@ -161,7 +178,9 @@ bptr<T>& bptr<T>::_move_assign(bptr<Y>&& other) noexcept return *this; } -template<typename T> T* bptr<T>::get() const noexcept +template<typename T> +requires std::is_convertible_v<T*, const bptr_base*> +T* bptr<T>::get() const noexcept { if (blk) [[likely]] return static_cast<T*>(blk->_ptr); @@ -169,26 +188,41 @@ template<typename T> T* bptr<T>::get() const noexcept return nullptr; } -template<typename T> T* bptr<T>::operator->() const noexcept +template<typename T> +requires std::is_convertible_v<T*, const bptr_base*> +T* bptr<T>::operator->() const noexcept { auto* ret = get(); fm_bptr_assert(ret); return ret; } -template<typename T> T& bptr<T>::operator*() const noexcept { return *operator->(); } +template<typename T> +requires std::is_convertible_v<T*, const bptr_base*> +T& bptr<T>::operator*() const noexcept { return *operator->(); } -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> +requires std::is_convertible_v<T*, const bptr_base*> +bptr<T>::operator bool() const noexcept { return get(); } + +template<typename T> +requires std::is_convertible_v<T*, const bptr_base*> +bool bptr<T>::operator==(const bptr<const std::remove_const_t<T>>& other) const noexcept { return get() == other.get(); } template<typename T> +requires std::is_convertible_v<T*, const bptr_base*> +bool bptr<T>::operator==(const bptr<std::remove_const_t<T>>& other) const noexcept { return get() == other.get(); } + +template<typename T> +requires std::is_convertible_v<T*, const bptr_base*> void bptr<T>::swap(bptr& other) noexcept { floormat::swap(blk, other.blk); } -template<typename T> uint32_t bptr<T>::use_count() const noexcept +template<typename T> +requires std::is_convertible_v<T*, const bptr_base*> +uint32_t bptr<T>::use_count() const noexcept { if (blk && blk->_ptr) [[likely]] return blk->_count; |