Skip to content

Commit 1e518de

Browse files
committed
is()/as(): refactor is() and as() for std::optional
1 parent d9ee8da commit 1e518de

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

21272127
// is Type
21282128
//
2129-
template<typename T, typename X>
2130-
requires std::is_same_v<X,std::optional<T>>
2131-
constexpr auto is( X const& x ) -> bool
2132-
{ return x.has_value(); }
2133-
2134-
template<typename T, typename U>
2135-
requires std::is_same_v<T,empty>
2136-
constexpr auto is( std::optional<U> const& x ) -> bool
2137-
{ return !x.has_value(); }
2138-
2129+
template<typename T, specialization_of_template<std::optional> X>
2130+
constexpr auto is( X const& x ) -> bool {
2131+
if (!x.has_value()) {
2132+
return std::same_as<T, empty>;
2133+
}
2134+
if constexpr (requires { static_cast<const T&>(*x);}) {
2135+
return true;
2136+
}
2137+
return false;
2138+
}
21392139

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

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

21612158
// as
21622159
//
2163-
template<typename T, typename X>
2164-
requires std::is_same_v<X,std::optional<T>>
2165-
constexpr auto as( X const& x ) -> decltype(auto)
2166-
{ return x.value(); }
2160+
template<typename T, specialization_of_template<std::optional> X>
2161+
constexpr auto as( X&& x ) -> decltype(auto) {
2162+
constness_like_t<T, X>* ptr = nullptr;
2163+
if constexpr (requires { static_cast<const T&>(*x); }) {
2164+
ptr = &static_cast<const T&>(*x);
2165+
}
2166+
if (!ptr) { Throw( std::bad_optional_access(), "'as' cast failed for 'std::optional'"); }
2167+
return cpp2::forward_like<X>(*ptr);
2168+
}
21672169

21682170

21692171
} // impl

0 commit comments

Comments
 (0)