Skip to content

Commit

Permalink
is()/as(): refactor is() and as() for std::optional
Browse files Browse the repository at this point in the history
  • Loading branch information
filipsajdak committed Aug 20, 2024
1 parent 572e52f commit 4fb2f40
Showing 1 changed file with 20 additions and 18 deletions.
38 changes: 20 additions & 18 deletions include/cpp2util.h
Original file line number Diff line number Diff line change
Expand Up @@ -2088,29 +2088,26 @@ constexpr auto as( X && x ) -> decltype(auto) {

// is Type
//
template<typename T, typename X>
requires std::is_same_v<X,std::optional<T>>
constexpr auto is( X const& x ) -> bool
{ return x.has_value(); }

template<typename T, typename U>
requires std::is_same_v<T,empty>
constexpr auto is( std::optional<U> const& x ) -> bool
{ return !x.has_value(); }

template<typename T, specialization_of_template<std::optional> X>
constexpr auto is( X const& x ) -> bool {
if (!x.has_value()) {
return std::same_as<T, empty>;
}
if constexpr (requires { static_cast<const T&>(*x);}) {
return true;
}
return false;
}

// is Value
//
template<typename T>
constexpr auto is( std::optional<T> const& x, auto&& value ) -> bool
{
// Predicate case
if constexpr (requires{ bool{ value(x) }; }) {
if constexpr (valid_predicate<decltype(value), decltype(x)>) {
return value(x);
}
else if constexpr (std::is_function_v<decltype(value)> || requires{ &value.operator(); }) {
return false;
}

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

// as
//
template<typename T, typename X>
requires std::is_same_v<X,std::optional<T>>
constexpr auto as( X const& x ) -> decltype(auto)
{ return x.value(); }
template<typename T, specialization_of_template<std::optional> X>
constexpr auto as( X&& x ) -> decltype(auto) {
constness_like_t<T, X>* ptr = nullptr;
if constexpr (requires { static_cast<const T&>(*x); }) {
ptr = &static_cast<const T&>(*x);
}
if (!ptr) { Throw( std::bad_optional_access(), "'as' cast failed for 'std::optional'"); }
return cpp2::forward_like<X>(*ptr);
}


} // impl
Expand Down

0 comments on commit 4fb2f40

Please sign in to comment.