Skip to content

Commit 0cf570b

Browse files
committed
is()/as(): refactor is() and as() for std::optional
1 parent 4189f08 commit 0cf570b

File tree

1 file changed

+20
-18
lines changed

1 file changed

+20
-18
lines changed

include/cpp2util.h

+20-18
Original file line numberDiff line numberDiff line change
@@ -2103,29 +2103,26 @@ constexpr auto as( X && x ) -> decltype(auto) {
21032103

21042104
// is Type
21052105
//
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+
}
21162116

21172117
// is Value
21182118
//
21192119
template<typename T>
21202120
constexpr auto is( std::optional<T> const& x, auto&& value ) -> bool
21212121
{
21222122
// Predicate case
2123-
if constexpr (requires{ bool{ value(x) }; }) {
2123+
if constexpr (valid_predicate<decltype(value), decltype(x)>) {
21242124
return value(x);
21252125
}
2126-
else if constexpr (std::is_function_v<decltype(value)> || requires{ &value.operator(); }) {
2127-
return false;
2128-
}
21292126

21302127
// Value case
21312128
else if constexpr (requires{ bool{ x.value() == value }; }) {
@@ -2137,10 +2134,15 @@ constexpr auto is( std::optional<T> const& x, auto&& value ) -> bool
21372134

21382135
// as
21392136
//
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+
}
21442146

21452147

21462148
} // impl

0 commit comments

Comments
 (0)