Skip to content

Commit

Permalink
Replace nth_argument_of with argument_of
Browse files Browse the repository at this point in the history
gcc-10.x, clang-12.x, is not handling variable arguments correctly.
As we need only one argument the helper was reduced to only one arg.
  • Loading branch information
filipsajdak committed Oct 3, 2023
1 parent 367e9d4 commit 348ecd1
Showing 1 changed file with 15 additions and 15 deletions.
30 changes: 15 additions & 15 deletions include/cpp2util.h
Original file line number Diff line number Diff line change
Expand Up @@ -1175,20 +1175,20 @@ constexpr auto is( std::monostate const& ) -> std::true_type {
return {};
}

template<std::size_t I, typename Ret, typename... Args>
auto nth_argument_of_helper(Ret(*) (Args...)) -> std::tuple_element_t<I, std::tuple<Args...>>;
template<typename Ret, typename Arg>
auto argument_of_helper(Ret(*) (Arg)) -> Arg;

template<std::size_t I, typename Ret, typename F, typename... Args>
auto nth_argument_of_helper(Ret(F::*) (Args...)) -> std::tuple_element_t<I, std::tuple<Args...>>;
template<typename Ret, typename F, typename Arg>
auto argument_of_helper(Ret(F::*) (Arg)) -> Arg;

template<std::size_t I, typename Ret, typename F, typename... Args>
auto nth_argument_of_helper(Ret(F::*) (Args...) const) -> std::tuple_element_t<I, std::tuple<Args...>>;
template<typename Ret, typename F, typename Arg>
auto argument_of_helper(Ret(F::*) (Arg) const) -> Arg;

template <std::size_t I, typename F>
auto nth_argument_of_helper(F) -> CPP2_TYPEOF(nth_argument_of_helper<I>(&F::operator()));
template <typename F>
auto argument_of_helper(F) -> CPP2_TYPEOF(argument_of_helper(&F::operator()));

template <std::size_t I, typename T>
using nth_argument_of = CPP2_TYPEOF(nth_argument_of_helper<I>(std::declval<T>()));
template <typename T>
using argument_of = CPP2_TYPEOF(argument_of_helper(std::declval<T>()));

// Values
//
Expand All @@ -1206,9 +1206,9 @@ inline constexpr auto is( auto const& x, auto const& value ) -> bool
// Predicate case
else if constexpr ( requires{ {value(x)} -> boolean_testable; } ) {
// defined argument type
if constexpr (requires { std::declval<nth_argument_of<0, CPP2_TYPEOF(value)>>(); }){
if constexpr (requires { std::declval<argument_of<CPP2_TYPEOF(value)>>(); }){
// valid coversion of x to argument type
if constexpr ( requires { nth_argument_of<0, CPP2_TYPEOF(value)>{x}; }) {
if constexpr ( requires { argument_of<CPP2_TYPEOF(value)>{x}; }) {
return value(x); // function-like with valid coversion of argument
}
return false; // function-like with invalid coversion of argument
Expand Down Expand Up @@ -1513,10 +1513,10 @@ constexpr auto is( std::optional<T> const& x, auto const& value ) -> bool
// Predicate case
if constexpr ( requires{ {value(x)} -> boolean_testable; } ) {
// defined argument type
if constexpr (requires { std::declval<nth_argument_of<0, CPP2_TYPEOF(value)>>(); }){
if constexpr (requires { std::declval<argument_of<CPP2_TYPEOF(value)>>(); }){
// argument type is optional
if constexpr (requires{is<std::optional>(std::declval<nth_argument_of<0, CPP2_TYPEOF(value)>>());}) {
using value_type = typename nth_argument_of<0, CPP2_TYPEOF(value)>::value_type; // workaround for gcc-10
if constexpr (requires{is<std::optional>(std::declval<argument_of<CPP2_TYPEOF(value)>>());}) {
using value_type = typename argument_of<CPP2_TYPEOF(value)>::value_type; // workaround for gcc-10
// valid conversion of x::value_type to argument value_type
if constexpr ( requires { value_type{std::declval<T>()}; }) {
return value(x); // function-like with valid conversion of argument
Expand Down

0 comments on commit 348ecd1

Please sign in to comment.