@@ -2126,29 +2126,26 @@ constexpr auto as( X && x ) -> decltype(auto) {
21262126
21272127// is Type
21282128//
2129- template <typename T, typename X>
2130- requires std::is_same_v<X,std::optional<T>>
2131- constexpr auto is ( X const & x ) -> bool
2132- { return x. has_value (); }
2133-
2134- template < typename T, typename U>
2135- requires std::is_same_v<T,empty>
2136- constexpr auto is ( std::optional<U> const & x ) -> bool
2137- { return !x. has_value (); }
2138-
2129+ template <typename T, specialization_of_template<std::optional> X>
2130+ constexpr auto is ( X const & x ) -> bool {
2131+ if (!x. has_value ()) {
2132+ return std::same_as<T, empty>;
2133+ }
2134+ if constexpr ( requires { static_cast < const T&>(*x);}) {
2135+ return true ;
2136+ }
2137+ return false ;
2138+ }
21392139
21402140// is Value
21412141//
21422142template <typename T>
21432143constexpr auto is ( std::optional<T> const & x, auto && value ) -> bool
21442144{
21452145 // Predicate case
2146- if constexpr (requires { bool { value (x) }; } ) {
2146+ if constexpr (valid_predicate< decltype ( value), decltype (x)> ) {
21472147 return value (x);
21482148 }
2149- else if constexpr (std::is_function_v<decltype (value)> || requires { &value.operator (); }) {
2150- return false ;
2151- }
21522149
21532150 // Value case
21542151 else if constexpr (requires { bool { x.value () == value }; }) {
@@ -2160,10 +2157,15 @@ constexpr auto is( std::optional<T> const& x, auto&& value ) -> bool
21602157
21612158// as
21622159//
2163- template <typename T, typename X>
2164- requires std::is_same_v<X,std::optional<T>>
2165- constexpr auto as ( X const & x ) -> decltype(auto )
2166- { return x.value (); }
2160+ template <typename T, specialization_of_template<std::optional> X>
2161+ constexpr auto as ( X&& x ) -> decltype(auto ) {
2162+ constness_like_t <T, X>* ptr = nullptr ;
2163+ if constexpr (requires { static_cast <const T&>(*x); }) {
2164+ ptr = &static_cast <constness_like_t <T, X>&>(*x);
2165+ }
2166+ if (!ptr) { Throw ( std::bad_optional_access (), " 'as' cast failed for 'std::optional'" ); }
2167+ return cpp2::forward_like<X>(*ptr);
2168+ }
21672169
21682170
21692171} // impl
0 commit comments