diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2024-05-04 20:13:15 +0200 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2024-05-05 03:31:20 +0200 |
commit | 5c54707ed13c2996f36b99dddb76f017765cec72 (patch) | |
tree | ed74b0f349822a58c731823e03aee3661a8d74e7 | |
parent | 210ee6eab1dcd7b1b2710dc927943d62330ffde3 (diff) |
a w
-rw-r--r-- | compat/borrowed-ptr-fwd.hpp | 2 | ||||
-rw-r--r-- | compat/borrowed-ptr.hpp | 13 | ||||
-rw-r--r-- | test/bptr.cpp | 31 |
3 files changed, 38 insertions, 8 deletions
diff --git a/compat/borrowed-ptr-fwd.hpp b/compat/borrowed-ptr-fwd.hpp index da91502d..465e9bf4 100644 --- a/compat/borrowed-ptr-fwd.hpp +++ b/compat/borrowed-ptr-fwd.hpp @@ -44,7 +44,7 @@ public: T& operator*() 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 U, typename Tʹ> friend bptr<U> static_pointer_cast(const bptr<Tʹ>& p) noexcept; }; } // namespace floormat diff --git a/compat/borrowed-ptr.hpp b/compat/borrowed-ptr.hpp index 5caa2261..d13d8ee2 100644 --- a/compat/borrowed-ptr.hpp +++ b/compat/borrowed-ptr.hpp @@ -28,20 +28,23 @@ concept StaticCastable = requires(From* from) { namespace floormat { -template<typename T, typename U> +template<typename U, typename T> bptr<U> static_pointer_cast(const bptr<T>& p) noexcept { - static_assert(detail_borrowed_ptr::StaticCastable<T, U>); - - if (p.blk) [[likely]] + // hack to generate better error message + if constexpr (detail_borrowed_ptr::StaticCastable<T, U>) { - if (auto* ptr = p.blk->_ptr) + if (p.blk && p.blk->_ptr) [[likely]] { fm_bptr_assert(p.casted_ptr); auto* ret = static_cast<U*>(p.casted_ptr); return bptr<U>{DirectInit, ret, p.blk}; } } + else + // concepts can't be forward-declared so use static_assert + static_assert(detail_borrowed_ptr::StaticCastable<T, U>); + return bptr<U>{nullptr}; } diff --git a/test/bptr.cpp b/test/bptr.cpp index b8e4bef1..99d6cd2c 100644 --- a/test/bptr.cpp +++ b/test/bptr.cpp @@ -4,10 +4,38 @@ namespace floormat { -namespace { struct Foo {}; struct Bar : Foo {}; struct Baz {}; } +namespace { +struct Foo {}; +struct Bar : Foo {}; +struct Baz {}; +} // namespace + +// NOLINTBEGIN(*-use-anonymous-namespace) + template struct detail_borrowed_ptr::control_block_impl<Foo>; +template struct detail_borrowed_ptr::control_block_impl<Bar>; +template struct detail_borrowed_ptr::control_block_impl<Baz>; + +template bool operator==(const bptr<Foo>&, const bptr<Foo>&) noexcept; +template bool operator==(const bptr<Bar>&, const bptr<Bar>&) noexcept; +template bool operator==(const bptr<Baz>&, const bptr<Baz>&) noexcept; + template class bptr<Foo>; +template class bptr<Bar>; +template class bptr<Baz>; + +template bptr<Foo> static_pointer_cast(const bptr<Foo>&) noexcept; +template bptr<Bar> static_pointer_cast(const bptr<Bar>&) noexcept; +template bptr<Baz> static_pointer_cast(const bptr<Baz>&) noexcept; + template bptr<Bar> static_pointer_cast(const bptr<Foo>&) noexcept; +template bptr<Foo> static_pointer_cast(const bptr<Bar>&) noexcept; + +//template bptr<Baz> static_pointer_cast(const bptr<Bar>&) noexcept; // must fail +//template bptr<Foo> static_pointer_cast(const bptr<Baz>&) noexcept; // must fail +//template bptr<Bar> static_pointer_cast(const bptr<Baz>&) noexcept; // must fail + +// NOLINTEND(*-use-anonymous-namespace) namespace { @@ -22,5 +50,4 @@ void test_app::test_bptr() test1(); } - } // namespace floormat |