diff --git a/develop/singles/headers/meta.hpp/meta_all.hpp b/develop/singles/headers/meta.hpp/meta_all.hpp index a8b5a67..2e42669 100644 --- a/develop/singles/headers/meta.hpp/meta_all.hpp +++ b/develop/singles/headers/meta.hpp/meta_all.hpp @@ -2904,15 +2904,14 @@ namespace meta_hpp uvalue& operator=(const uvalue& other); template < typename T, typename Tp = std::decay_t > - requires(!detail::any_uvalue_kind) // + requires(!std::is_same_v) // && (!detail::is_in_place_type_v) // && (std::is_copy_constructible_v) // // NOLINTNEXTLINE(*-forwarding-reference-overload) uvalue(T&& val); template < typename T, typename Tp = std::decay_t > - requires(!detail::any_uvalue_kind) // - && (!detail::is_in_place_type_v) // + requires(!std::is_same_v) // && (std::is_copy_constructible_v) // uvalue& operator=(T&& val); @@ -2968,6 +2967,10 @@ namespace meta_hpp [[nodiscard]] auto get_as() const& // -> std::conditional_t, T, const T&>; + template < typename T > + [[nodiscard]] auto get_as() const&& // + -> std::conditional_t, T, const T&&>; + template < typename T > [[nodiscard]] auto try_get_as() noexcept // -> std::conditional_t, T, T*>; @@ -8600,7 +8603,7 @@ namespace meta_hpp } template < typename T, typename Tp > - requires(!detail::any_uvalue_kind) // + requires(!std::is_same_v) // && (!detail::is_in_place_type_v) // && (std::is_copy_constructible_v) // // NOLINTNEXTLINE(*-forwarding-reference-overload) @@ -8609,8 +8612,7 @@ namespace meta_hpp } template < typename T, typename Tp > - requires(!detail::any_uvalue_kind) // - && (!detail::is_in_place_type_v) // + requires(!std::is_same_v) // && (std::is_copy_constructible_v) // uvalue& uvalue::operator=(T&& val) { vtable_t::do_reset(*this); @@ -8807,6 +8809,23 @@ namespace meta_hpp throw_generic_exception(generic_error::bad_uvalue_cast); } + template < typename T > + auto uvalue::get_as() const&& -> std::conditional_t, T, const T&&> { + static_assert(std::is_same_v>); + + if constexpr ( detail::pointer_kind ) { + if ( T ptr = try_get_as(); ptr || get_type().is_nullptr() ) { + return ptr; + } + } else { + if ( const T* ptr = try_get_as() ) { + return std::move(*ptr); + } + } + + throw_generic_exception(generic_error::bad_uvalue_cast); + } + template < typename T > // NOLINTNEXTLINE(*-cognitive-complexity) auto uvalue::try_get_as() noexcept -> std::conditional_t, T, T*> { diff --git a/develop/untests/meta_utilities/value3_tests.cpp b/develop/untests/meta_utilities/value3_tests.cpp index 23ff0ba..f4f1514 100644 --- a/develop/untests/meta_utilities/value3_tests.cpp +++ b/develop/untests/meta_utilities/value3_tests.cpp @@ -94,7 +94,7 @@ TEST_CASE("meta/meta_utilities/value3/get_as") { static_assert(std::is_same_v().get_as()), derived&>); static_assert(std::is_same_v().get_as()), derived>); static_assert(std::is_same_v().get_as()), const derived&>); - static_assert(std::is_same_v().get_as()), const derived&>); + static_assert(std::is_same_v().get_as()), const derived&&>); static_assert(std::is_same_v().get_as()), derived*>); static_assert(std::is_same_v().get_as()), derived*>); diff --git a/develop/untests/meta_utilities/value_tests.cpp b/develop/untests/meta_utilities/value_tests.cpp index c174148..2383433 100644 --- a/develop/untests/meta_utilities/value_tests.cpp +++ b/develop/untests/meta_utilities/value_tests.cpp @@ -151,7 +151,7 @@ TEST_CASE("meta/meta_utilities/value") { const ivec2&>); static_assert(std::is_same_v< decltype(std::declval().get_as()), - const ivec2&>); + const ivec2&&>); } SUBCASE("ivec2{}") { diff --git a/headers/meta.hpp/meta_uvalue.hpp b/headers/meta.hpp/meta_uvalue.hpp index e1924c6..9848ed2 100644 --- a/headers/meta.hpp/meta_uvalue.hpp +++ b/headers/meta.hpp/meta_uvalue.hpp @@ -38,15 +38,14 @@ namespace meta_hpp uvalue& operator=(const uvalue& other); template < typename T, typename Tp = std::decay_t > - requires(!detail::any_uvalue_kind) // + requires(!std::is_same_v) // && (!detail::is_in_place_type_v) // && (std::is_copy_constructible_v) // // NOLINTNEXTLINE(*-forwarding-reference-overload) uvalue(T&& val); template < typename T, typename Tp = std::decay_t > - requires(!detail::any_uvalue_kind) // - && (!detail::is_in_place_type_v) // + requires(!std::is_same_v) // && (std::is_copy_constructible_v) // uvalue& operator=(T&& val); @@ -102,6 +101,10 @@ namespace meta_hpp [[nodiscard]] auto get_as() const& // -> std::conditional_t, T, const T&>; + template < typename T > + [[nodiscard]] auto get_as() const&& // + -> std::conditional_t, T, const T&&>; + template < typename T > [[nodiscard]] auto try_get_as() noexcept // -> std::conditional_t, T, T*>; diff --git a/headers/meta.hpp/meta_uvalue/uvalue.hpp b/headers/meta.hpp/meta_uvalue/uvalue.hpp index 8760b8d..ddb2925 100644 --- a/headers/meta.hpp/meta_uvalue/uvalue.hpp +++ b/headers/meta.hpp/meta_uvalue/uvalue.hpp @@ -283,7 +283,7 @@ namespace meta_hpp } template < typename T, typename Tp > - requires(!detail::any_uvalue_kind) // + requires(!std::is_same_v) // && (!detail::is_in_place_type_v) // && (std::is_copy_constructible_v) // // NOLINTNEXTLINE(*-forwarding-reference-overload) @@ -292,8 +292,7 @@ namespace meta_hpp } template < typename T, typename Tp > - requires(!detail::any_uvalue_kind) // - && (!detail::is_in_place_type_v) // + requires(!std::is_same_v) // && (std::is_copy_constructible_v) // uvalue& uvalue::operator=(T&& val) { vtable_t::do_reset(*this); @@ -490,6 +489,23 @@ namespace meta_hpp throw_generic_exception(generic_error::bad_uvalue_cast); } + template < typename T > + auto uvalue::get_as() const&& -> std::conditional_t, T, const T&&> { + static_assert(std::is_same_v>); + + if constexpr ( detail::pointer_kind ) { + if ( T ptr = try_get_as(); ptr || get_type().is_nullptr() ) { + return ptr; + } + } else { + if ( const T* ptr = try_get_as() ) { + return std::move(*ptr); + } + } + + throw_generic_exception(generic_error::bad_uvalue_cast); + } + template < typename T > // NOLINTNEXTLINE(*-cognitive-complexity) auto uvalue::try_get_as() noexcept -> std::conditional_t, T, T*> {