From 4fb2f40f43c0fa38946cd877829af29983ec49e8 Mon Sep 17 00:00:00 2001 From: Filip Sajdak Date: Wed, 21 Aug 2024 00:56:51 +0200 Subject: [PATCH] is()/as(): refactor is() and as() for std::optional --- include/cpp2util.h | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/include/cpp2util.h b/include/cpp2util.h index 375a539e7..14bc64fca 100644 --- a/include/cpp2util.h +++ b/include/cpp2util.h @@ -2088,16 +2088,16 @@ constexpr auto as( X && x ) -> decltype(auto) { // is Type // -template - requires std::is_same_v> -constexpr auto is( X const& x ) -> bool - { return x.has_value(); } - -template - requires std::is_same_v -constexpr auto is( std::optional const& x ) -> bool - { return !x.has_value(); } - +template X> +constexpr auto is( X const& x ) -> bool { + if (!x.has_value()) { + return std::same_as; + } + if constexpr (requires { static_cast(*x);}) { + return true; + } + return false; +} // is Value // @@ -2105,12 +2105,9 @@ template constexpr auto is( std::optional const& x, auto&& value ) -> bool { // Predicate case - if constexpr (requires{ bool{ value(x) }; }) { + if constexpr (valid_predicate) { return value(x); } - else if constexpr (std::is_function_v || requires{ &value.operator(); }) { - return false; - } // Value case else if constexpr (requires{ bool{ x.value() == value }; }) { @@ -2122,10 +2119,15 @@ constexpr auto is( std::optional const& x, auto&& value ) -> bool // as // -template - requires std::is_same_v> -constexpr auto as( X const& x ) -> decltype(auto) - { return x.value(); } +template X> +constexpr auto as( X&& x ) -> decltype(auto) { + constness_like_t* ptr = nullptr; + if constexpr (requires { static_cast(*x); }) { + ptr = &static_cast(*x); + } + if (!ptr) { Throw( std::bad_optional_access(), "'as' cast failed for 'std::optional'"); } + return cpp2::forward_like(*ptr); +} } // impl