Skip to content

Commit 45f1b13

Browse files
committed
is()/as(): refactor is() and as() for std::optional
1 parent dc39a71 commit 45f1b13

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

21262126
// is Type
21272127
//
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+
}
21382138

21392139
// is Value
21402140
//
21412141
template<typename T>
21422142
constexpr auto is( std::optional<T> const& x, auto&& value ) -> bool
21432143
{
21442144
// Predicate case
2145-
if constexpr (requires{ bool{ value(x) }; }) {
2145+
if constexpr (valid_predicate<decltype(value), decltype(x)>) {
21462146
return value(x);
21472147
}
2148-
else if constexpr (std::is_function_v<decltype(value)> || requires{ &value.operator(); }) {
2149-
return false;
2150-
}
21512148

21522149
// Value case
21532150
else if constexpr (requires{ bool{ x.value() == value }; }) {
@@ -2159,10 +2156,15 @@ constexpr auto is( std::optional<T> const& x, auto&& value ) -> bool
21592156

21602157
// as
21612158
//
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+
}
21662168

21672169

21682170
} // impl

0 commit comments

Comments
 (0)