blob: 263e1b61e9f9076027afa44b19c51030ba5627f1 [file] [log] [blame]
// PR c++/69066
// { dg-do compile { target c++14 } }
template <typename T> T&& declval();
template<typename T, T v>
struct integral_constant
{
static constexpr T value = v;
typedef T value_type;
typedef integral_constant<T, v> type;
constexpr operator value_type() const { return value; }
};
typedef integral_constant<bool, true> true_type;
typedef integral_constant<bool, false> false_type;
template <typename...>
using void_t = void;
template <typename, typename = void>
class is_zero_callable : public false_type
{
};
template <typename T>
class is_zero_callable<T, void_t<decltype(declval<T>()())>>
: public true_type
{
};
template <typename TF, bool TLastStep>
struct curry_impl
{
static auto exec(TF f)
{
// Bind `x` to subsequent calls.
return [=](auto x)
{
auto bound_f = [=](auto... xs) -> decltype(f(x, xs...))
{
return f(x, xs...);
};
// Recursive step.
return curry_impl<decltype(bound_f),
is_zero_callable<decltype(bound_f)>{}>::exec(bound_f);
};
}
};
template <typename TF>
struct curry_impl<TF, true>
{
static auto exec(TF f)
{
return f();
}
};
template <typename TF>
auto curry(TF f)
{
return curry_impl<TF, is_zero_callable<decltype(f)>{}>::exec(f);
}
int main()
{
auto sum = [](int x, int y)
{
return x + y;
};
(void)curry(sum)(1)(1);
}