Skip to content

Commit 4fb2f40

Browse files
committed
is()/as(): refactor is() and as() for std::optional
1 parent 572e52f commit 4fb2f40

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
@@ -2088,29 +2088,26 @@ constexpr auto as( X && x ) -> decltype(auto) {
20882088

20892089
// is Type
20902090
//
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+
}
21012101

21022102
// is Value
21032103
//
21042104
template<typename T>
21052105
constexpr auto is( std::optional<T> const& x, auto&& value ) -> bool
21062106
{
21072107
// Predicate case
2108-
if constexpr (requires{ bool{ value(x) }; }) {
2108+
if constexpr (valid_predicate<decltype(value), decltype(x)>) {
21092109
return value(x);
21102110
}
2111-
else if constexpr (std::is_function_v<decltype(value)> || requires{ &value.operator(); }) {
2112-
return false;
2113-
}
21142111

21152112
// Value case
21162113
else if constexpr (requires{ bool{ x.value() == value }; }) {
@@ -2122,10 +2119,15 @@ constexpr auto is( std::optional<T> const& x, auto&& value ) -> bool
21222119

21232120
// as
21242121
//
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+
}
21292131

21302132

21312133
} // impl

0 commit comments

Comments
 (0)