Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

is()/as(): refactor of is() and as() for std::any and std::optional to new design (part 3 of n) #1251

Merged
merged 3 commits into from
Sep 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 36 additions & 36 deletions include/cpp2util.h
Original file line number Diff line number Diff line change
Expand Up @@ -2083,28 +2083,22 @@ auto as(X&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS) -> decltype(auto)

// is Type
//
template<typename T, typename X>
requires (std::is_same_v<X,std::any> && !std::is_same_v<T,std::any> && !std::is_same_v<T,empty>)
constexpr auto is( X const& x ) -> bool
{ return x.type() == Typeid<T>(); }

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

template<typename T, std::same_as<std::any> X>
constexpr auto is( X const& x ) -> bool{
if (!x.has_value()) {
return std::is_same_v<T,empty>;
}
return x.type() == Typeid<T>();
}

// is Value
//
inline constexpr auto is( std::any 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{ *std::any_cast<CPP2_TYPEOF(value)>(&x) == value }; }) {
Expand All @@ -2118,10 +2112,12 @@ inline constexpr auto is( std::any const& x, auto&& value ) -> bool

// as
//
template<typename T, typename X>
requires (!std::is_reference_v<T> && std::is_same_v<X,std::any> && !std::is_same_v<T,std::any>)
constexpr auto as( X const& x ) -> T
{ return std::any_cast<T>( x ); }
template<typename T, same_type_as<std::any> X>
constexpr auto as( X && x ) -> decltype(auto) {
constness_like_t<T, X>* ptr = std::any_cast<T>( &x );
if (!ptr) { Throw( std::bad_any_cast(), "'as' cast failed for 'std::any'"); }
return cpp2::forward_like<X>(*ptr);
}


//-------------------------------------------------------------------------------------------------------------
Expand All @@ -2130,29 +2126,26 @@ constexpr auto as( X const& x ) -> T

// 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 @@ -2164,10 +2157,17 @@ 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<constness_like_t<T, X>&>(*x); }) {
if (x.has_value()) {
ptr = &static_cast<constness_like_t<T, X>&>(*x);
}
}
if (!ptr) { Throw( std::bad_optional_access(), "'as' cast failed for 'std::optional'"); }
return cpp2::forward_like<X>(*ptr);
}


} // impl
Expand Down
Original file line number Diff line number Diff line change
@@ -1,66 +1,66 @@
In file included from pure2-default-arguments.cpp:7:
../../../include/cpp2util.h:2086:28: error: local variable ‘obj’ may not appear in this context
2086 | template<typename T, typename X>
2086 | template<typename T, std::same_as<std::any> X>
| ^~~
../../../include/cpp2util.h:2047:34: note: in definition of macro ‘CPP2_UFCS_IDENTITY’
2047 | return false;
| ^
../../../include/cpp2util.h:2086:15: note: in expansion of macro ‘CPP2_FORWARD’
2086 | template<typename T, typename X>
2086 | template<typename T, std::same_as<std::any> X>
| ^~~~~~~~~~~~
../../../include/cpp2util.h:2107:22: note: in expansion of macro ‘CPP2_UFCS_CONSTRAINT_ARG’
2107 | }
| ^
../../../include/cpp2util.h:2137:59: note: in expansion of macro ‘CPP2_UFCS_’
2137 |
2137 | return false;
| ^
pure2-default-arguments.cpp2:6:22: note: in expansion of macro ‘CPP2_UFCS_NONLOCAL’
../../../include/cpp2util.h:2086:92: error: local variable ‘params’ may not appear in this context
2086 | template<typename T, typename X>
2086 | template<typename T, std::same_as<std::any> X>
| ^
../../../include/cpp2util.h:2047:34: note: in definition of macro ‘CPP2_UFCS_IDENTITY’
2047 | return false;
| ^
../../../include/cpp2util.h:2086:79: note: in expansion of macro ‘CPP2_FORWARD’
2086 | template<typename T, typename X>
2086 | template<typename T, std::same_as<std::any> X>
| ^
../../../include/cpp2util.h:2107:22: note: in expansion of macro ‘CPP2_UFCS_CONSTRAINT_ARG’
2107 | }
| ^
../../../include/cpp2util.h:2137:59: note: in expansion of macro ‘CPP2_UFCS_’
2137 |
2137 | return false;
| ^
pure2-default-arguments.cpp2:6:22: note: in expansion of macro ‘CPP2_UFCS_NONLOCAL’
../../../include/cpp2util.h:2087:74: error: local variable ‘obj’ may not appear in this context
2087 | requires (std::is_same_v<X,std::any> && !std::is_same_v<T,std::any> && !std::is_same_v<T,empty>)
| ^~~
2087 | constexpr auto is( X const& x ) -> bool{
| ^
../../../include/cpp2util.h:2047:34: note: in definition of macro ‘CPP2_UFCS_IDENTITY’
2047 | return false;
| ^
../../../include/cpp2util.h:2087:61: note: in expansion of macro ‘CPP2_FORWARD’
2087 | requires (std::is_same_v<X,std::any> && !std::is_same_v<T,std::any> && !std::is_same_v<T,empty>)
| ^~~~~~~~~~~~
2087 | constexpr auto is( X const& x ) -> bool{
| ^
../../../include/cpp2util.h:2107:22: note: in expansion of macro ‘CPP2_UFCS_CONSTRAINT_ARG’
2107 | }
| ^
../../../include/cpp2util.h:2137:59: note: in expansion of macro ‘CPP2_UFCS_’
2137 |
2137 | return false;
| ^
pure2-default-arguments.cpp2:6:22: note: in expansion of macro ‘CPP2_UFCS_NONLOCAL’
../../../include/cpp2util.h:2087:93: error: local variable ‘params’ may not appear in this context
2087 | requires (std::is_same_v<X,std::any> && !std::is_same_v<T,std::any> && !std::is_same_v<T,empty>)
| ^~~~~~
2087 | constexpr auto is( X const& x ) -> bool{
| ^
../../../include/cpp2util.h:2047:34: note: in definition of macro ‘CPP2_UFCS_IDENTITY’
2047 | return false;
| ^
../../../include/cpp2util.h:2087:80: note: in expansion of macro ‘CPP2_FORWARD’
2087 | requires (std::is_same_v<X,std::any> && !std::is_same_v<T,std::any> && !std::is_same_v<T,empty>)
| ^~~~~~~~~~~~
2087 | constexpr auto is( X const& x ) -> bool{
| ^
../../../include/cpp2util.h:2107:22: note: in expansion of macro ‘CPP2_UFCS_CONSTRAINT_ARG’
2107 | }
| ^
../../../include/cpp2util.h:2137:59: note: in expansion of macro ‘CPP2_UFCS_’
2137 |
2137 | return false;
| ^
pure2-default-arguments.cpp2:6:22: note: in expansion of macro ‘CPP2_UFCS_NONLOCAL’
pure2-default-arguments.cpp2:6:61: error: ‘std::source_location’ has not been declared
Original file line number Diff line number Diff line change
@@ -1,41 +1,41 @@
In file included from mixed-bugfix-for-ufcs-non-local.cpp:6:
../../../include/cpp2util.h:2100:1: error: lambda-expression in template parameter type
2100 | {
2100 | return value(x);
| ^
../../../include/cpp2util.h:2137:59: note: in expansion of macro ‘CPP2_UFCS_’
2137 |
2137 | return false;
| ^
mixed-bugfix-for-ufcs-non-local.cpp2:13:12: note: in expansion of macro ‘CPP2_UFCS_NONLOCAL’
mixed-bugfix-for-ufcs-non-local.cpp2:13:36: error: template argument 1 is invalid
../../../include/cpp2util.h:2100:1: error: lambda-expression in template parameter type
2100 | {
2100 | return value(x);
| ^
../../../include/cpp2util.h:2137:59: note: in expansion of macro ‘CPP2_UFCS_’
2137 |
2137 | return false;
| ^
mixed-bugfix-for-ufcs-non-local.cpp2:21:12: note: in expansion of macro ‘CPP2_UFCS_NONLOCAL’
mixed-bugfix-for-ufcs-non-local.cpp2:21:36: error: template argument 1 is invalid
../../../include/cpp2util.h:2100:1: error: lambda-expression in template parameter type
2100 | {
2100 | return value(x);
| ^
../../../include/cpp2util.h:2137:59: note: in expansion of macro ‘CPP2_UFCS_’
2137 |
2137 | return false;
| ^
mixed-bugfix-for-ufcs-non-local.cpp2:31:12: note: in expansion of macro ‘CPP2_UFCS_NONLOCAL’
mixed-bugfix-for-ufcs-non-local.cpp2:31:36: error: template argument 1 is invalid
../../../include/cpp2util.h:2100:1: error: lambda-expression in template parameter type
2100 | {
2100 | return value(x);
| ^
../../../include/cpp2util.h:2137:59: note: in expansion of macro ‘CPP2_UFCS_’
2137 |
2137 | return false;
| ^
mixed-bugfix-for-ufcs-non-local.cpp2:33:12: note: in expansion of macro ‘CPP2_UFCS_NONLOCAL’
mixed-bugfix-for-ufcs-non-local.cpp2:33:36: error: template argument 1 is invalid
../../../include/cpp2util.h:2100:1: error: lambda-expression in template parameter type
2100 | {
2100 | return value(x);
| ^
../../../include/cpp2util.h:2137:59: note: in expansion of macro ‘CPP2_UFCS_’
2137 |
2137 | return false;
| ^
mixed-bugfix-for-ufcs-non-local.cpp2:21:12: note: in expansion of macro ‘CPP2_UFCS_NONLOCAL’
mixed-bugfix-for-ufcs-non-local.cpp2:21:36: error: template argument 1 is invalid
Original file line number Diff line number Diff line change
@@ -1,41 +1,41 @@
In file included from mixed-bugfix-for-ufcs-non-local.cpp:6:
../../../include/cpp2util.h:2100:1: error: lambda-expression in template parameter type
2100 | {
2100 | return value(x);
| ^
../../../include/cpp2util.h:2137:59: note: in expansion of macro ‘CPP2_UFCS_’
2137 |
2137 | return false;
| ^
mixed-bugfix-for-ufcs-non-local.cpp2:13:12: note: in expansion of macro ‘CPP2_UFCS_NONLOCAL’
mixed-bugfix-for-ufcs-non-local.cpp2:13:36: error: template argument 1 is invalid
../../../include/cpp2util.h:2100:1: error: lambda-expression in template parameter type
2100 | {
2100 | return value(x);
| ^
../../../include/cpp2util.h:2137:59: note: in expansion of macro ‘CPP2_UFCS_’
2137 |
2137 | return false;
| ^
mixed-bugfix-for-ufcs-non-local.cpp2:21:12: note: in expansion of macro ‘CPP2_UFCS_NONLOCAL’
mixed-bugfix-for-ufcs-non-local.cpp2:21:36: error: template argument 1 is invalid
../../../include/cpp2util.h:2100:1: error: lambda-expression in template parameter type
2100 | {
2100 | return value(x);
| ^
../../../include/cpp2util.h:2137:59: note: in expansion of macro ‘CPP2_UFCS_’
2137 |
2137 | return false;
| ^
mixed-bugfix-for-ufcs-non-local.cpp2:31:12: note: in expansion of macro ‘CPP2_UFCS_NONLOCAL’
mixed-bugfix-for-ufcs-non-local.cpp2:31:36: error: template argument 1 is invalid
../../../include/cpp2util.h:2100:1: error: lambda-expression in template parameter type
2100 | {
2100 | return value(x);
| ^
../../../include/cpp2util.h:2137:59: note: in expansion of macro ‘CPP2_UFCS_’
2137 |
2137 | return false;
| ^
mixed-bugfix-for-ufcs-non-local.cpp2:33:12: note: in expansion of macro ‘CPP2_UFCS_NONLOCAL’
mixed-bugfix-for-ufcs-non-local.cpp2:33:36: error: template argument 1 is invalid
../../../include/cpp2util.h:2100:1: error: lambda-expression in template parameter type
2100 | {
2100 | return value(x);
| ^
../../../include/cpp2util.h:2137:59: note: in expansion of macro ‘CPP2_UFCS_’
2137 |
2137 | return false;
| ^
mixed-bugfix-for-ufcs-non-local.cpp2:21:12: note: in expansion of macro ‘CPP2_UFCS_NONLOCAL’
mixed-bugfix-for-ufcs-non-local.cpp2:21:36: error: template argument 1 is invalid
Loading