@@ -2125,29 +2125,26 @@ constexpr auto as( X && x ) -> decltype(auto) {
2125
2125
2126
2126
// is Type
2127
2127
//
2128
- template <typename T, typename X>
2129
- requires std::is_same_v<X,std::optional<T>>
2130
- constexpr auto is ( X const & x ) -> bool
2131
- { return x. has_value (); }
2132
-
2133
- template < typename T, typename U>
2134
- requires std::is_same_v<T,empty>
2135
- constexpr auto is ( std::optional<U> const & x ) -> bool
2136
- { return !x. has_value (); }
2137
-
2128
+ template <typename T, specialization_of_template<std::optional> X>
2129
+ constexpr auto is ( X const & x ) -> bool {
2130
+ if (!x. has_value ()) {
2131
+ return std::same_as<T, empty>;
2132
+ }
2133
+ if constexpr (requires { static_cast < const T&>(*x);}) {
2134
+ return true ;
2135
+ }
2136
+ return false ;
2137
+ }
2138
2138
2139
2139
// is Value
2140
2140
//
2141
2141
template <typename T>
2142
2142
constexpr auto is ( std::optional<T> const & x, auto && value ) -> bool
2143
2143
{
2144
2144
// Predicate case
2145
- if constexpr (requires{ bool { value (x) }; } ) {
2145
+ if constexpr (valid_predicate< decltype ( value), decltype (x)> ) {
2146
2146
return value (x);
2147
2147
}
2148
- else if constexpr (std::is_function_v<decltype (value)> || requires{ &value.operator (); }) {
2149
- return false ;
2150
- }
2151
2148
2152
2149
// Value case
2153
2150
else if constexpr (requires{ bool { x.value () == value }; }) {
@@ -2159,10 +2156,15 @@ constexpr auto is( std::optional<T> const& x, auto&& value ) -> bool
2159
2156
2160
2157
// as
2161
2158
//
2162
- template <typename T, typename X>
2163
- requires std::is_same_v<X,std::optional<T>>
2164
- constexpr auto as ( X const & x ) -> decltype(auto )
2165
- { return x.value (); }
2159
+ template <typename T, specialization_of_template<std::optional> X>
2160
+ constexpr auto as ( X&& x ) -> decltype(auto ) {
2161
+ constness_like_t <T, X>* ptr = nullptr ;
2162
+ if constexpr (requires { static_cast <const T&>(*x); }) {
2163
+ ptr = &static_cast <const T&>(*x);
2164
+ }
2165
+ if (!ptr) { Throw ( std::bad_optional_access (), " 'as' cast failed for 'std::optional'" ); }
2166
+ return cpp2::forward_like<X>(*ptr);
2167
+ }
2166
2168
2167
2169
2168
2170
} // impl
0 commit comments