@@ -2088,29 +2088,26 @@ constexpr auto as( X && x ) -> decltype(auto) {
2088
2088
2089
2089
// is Type
2090
2090
//
2091
- template <typename T, typename X>
2092
- requires std::is_same_v<X,std::optional<T>>
2093
- constexpr auto is ( X const & x ) -> bool
2094
- { return x. has_value (); }
2095
-
2096
- template < typename T, typename U>
2097
- requires std::is_same_v<T,empty>
2098
- constexpr auto is ( std::optional<U> const & x ) -> bool
2099
- { return !x. has_value (); }
2100
-
2091
+ template <typename T, specialization_of_template<std::optional> X>
2092
+ constexpr auto is ( X const & x ) -> bool {
2093
+ if (!x. has_value ()) {
2094
+ return std::same_as<T, empty>;
2095
+ }
2096
+ if constexpr (requires { static_cast < const T&>(*x);}) {
2097
+ return true ;
2098
+ }
2099
+ return false ;
2100
+ }
2101
2101
2102
2102
// is Value
2103
2103
//
2104
2104
template <typename T>
2105
2105
constexpr auto is ( std::optional<T> const & x, auto && value ) -> bool
2106
2106
{
2107
2107
// Predicate case
2108
- if constexpr (requires{ bool { value (x) }; } ) {
2108
+ if constexpr (valid_predicate< decltype ( value), decltype (x)> ) {
2109
2109
return value (x);
2110
2110
}
2111
- else if constexpr (std::is_function_v<decltype (value)> || requires{ &value.operator (); }) {
2112
- return false ;
2113
- }
2114
2111
2115
2112
// Value case
2116
2113
else if constexpr (requires{ bool { x.value () == value }; }) {
@@ -2122,10 +2119,15 @@ constexpr auto is( std::optional<T> const& x, auto&& value ) -> bool
2122
2119
2123
2120
// as
2124
2121
//
2125
- template <typename T, typename X>
2126
- requires std::is_same_v<X,std::optional<T>>
2127
- constexpr auto as ( X const & x ) -> decltype(auto )
2128
- { return x.value (); }
2122
+ template <typename T, specialization_of_template<std::optional> X>
2123
+ constexpr auto as ( X&& x ) -> decltype(auto ) {
2124
+ constness_like_t <T, X>* ptr = nullptr ;
2125
+ if constexpr (requires { static_cast <const T&>(*x); }) {
2126
+ ptr = &static_cast <const T&>(*x);
2127
+ }
2128
+ if (!ptr) { Throw ( std::bad_optional_access (), " 'as' cast failed for 'std::optional'" ); }
2129
+ return cpp2::forward_like<X>(*ptr);
2130
+ }
2129
2131
2130
2132
2131
2133
} // impl
0 commit comments