@@ -2103,29 +2103,26 @@ constexpr auto as( X && x ) -> decltype(auto) {
2103
2103
2104
2104
// is Type
2105
2105
//
2106
- template <typename T, typename X>
2107
- requires std::is_same_v<X,std::optional<T>>
2108
- constexpr auto is ( X const & x ) -> bool
2109
- { return x. has_value (); }
2110
-
2111
- template < typename T, typename U>
2112
- requires std::is_same_v<T,empty>
2113
- constexpr auto is ( std::optional<U> const & x ) -> bool
2114
- { return !x. has_value (); }
2115
-
2106
+ template <typename T, specialization_of_template<std::optional> X>
2107
+ constexpr auto is ( X const & x ) -> bool {
2108
+ if (!x. has_value ()) {
2109
+ return std::same_as<T, empty>;
2110
+ }
2111
+ if constexpr (requires { static_cast < const T&>(*x);}) {
2112
+ return true ;
2113
+ }
2114
+ return false ;
2115
+ }
2116
2116
2117
2117
// is Value
2118
2118
//
2119
2119
template <typename T>
2120
2120
constexpr auto is ( std::optional<T> const & x, auto && value ) -> bool
2121
2121
{
2122
2122
// Predicate case
2123
- if constexpr (requires{ bool { value (x) }; } ) {
2123
+ if constexpr (valid_predicate< decltype ( value), decltype (x)> ) {
2124
2124
return value (x);
2125
2125
}
2126
- else if constexpr (std::is_function_v<decltype (value)> || requires{ &value.operator (); }) {
2127
- return false ;
2128
- }
2129
2126
2130
2127
// Value case
2131
2128
else if constexpr (requires{ bool { x.value () == value }; }) {
@@ -2137,10 +2134,15 @@ constexpr auto is( std::optional<T> const& x, auto&& value ) -> bool
2137
2134
2138
2135
// as
2139
2136
//
2140
- template <typename T, typename X>
2141
- requires std::is_same_v<X,std::optional<T>>
2142
- constexpr auto as ( X const & x ) -> decltype(auto )
2143
- { return x.value (); }
2137
+ template <typename T, specialization_of_template<std::optional> X>
2138
+ constexpr auto as ( X&& x ) -> decltype(auto ) {
2139
+ constness_like_t <T, X>* ptr = nullptr ;
2140
+ if constexpr (requires { static_cast <const T&>(*x); }) {
2141
+ ptr = &static_cast <const T&>(*x);
2142
+ }
2143
+ if (!ptr) { Throw ( std::bad_optional_access (), " 'as' cast failed for 'std::optional'" ); }
2144
+ return cpp2::forward_like<X>(*ptr);
2145
+ }
2144
2146
2145
2147
2146
2148
} // impl
0 commit comments