@@ -2126,29 +2126,26 @@ constexpr auto as( X && x ) -> decltype(auto) {
2126
2126
2127
2127
// is Type
2128
2128
//
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
+ }
2139
2139
2140
2140
// is Value
2141
2141
//
2142
2142
template <typename T>
2143
2143
constexpr auto is ( std::optional<T> const & x, auto && value ) -> bool
2144
2144
{
2145
2145
// Predicate case
2146
- if constexpr (requires{ bool { value (x) }; } ) {
2146
+ if constexpr (valid_predicate< decltype ( value), decltype (x)> ) {
2147
2147
return value (x);
2148
2148
}
2149
- else if constexpr (std::is_function_v<decltype (value)> || requires{ &value.operator (); }) {
2150
- return false ;
2151
- }
2152
2149
2153
2150
// Value case
2154
2151
else if constexpr (requires{ bool { x.value () == value }; }) {
@@ -2160,10 +2157,15 @@ constexpr auto is( std::optional<T> const& x, auto&& value ) -> bool
2160
2157
2161
2158
// as
2162
2159
//
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 <const T&>(*x);
2165
+ }
2166
+ if (!ptr) { Throw ( std::bad_optional_access (), " 'as' cast failed for 'std::optional'" ); }
2167
+ return cpp2::forward_like<X>(*ptr);
2168
+ }
2167
2169
2168
2170
2169
2171
} // impl
0 commit comments