Skip to content

Instantly share code, notes, and snippets.

@kuhar
Last active August 29, 2015 14:08
Show Gist options
  • Save kuhar/82fdcc69dec0b4d97342 to your computer and use it in GitHub Desktop.
Save kuhar/82fdcc69dec0b4d97342 to your computer and use it in GitHub Desktop.
Curry
#include <iostream>
#include <type_traits>
#include <tuple>
using namespace std;
namespace impl
{
template <typename Functor, typename Tuple, size_t... Index>
decltype(auto) apply_helper(Functor&& functor, Tuple&& tupleOfArgs,
integer_sequence<size_t, Index...>)
{
return std::forward<Functor>(functor)(std::get<Index>(
std::forward<Tuple>(tupleOfArgs))...);
}
}
template <typename Functor, typename Tuple>
decltype(auto) apply(Functor&& functor, Tuple&& tupleOfArgs)
{
return impl::apply_helper(std::forward<Functor>(functor),
std::forward<Tuple>(tupleOfArgs),
make_index_sequence<std::tuple_size<std::decay_t<Tuple>>::value>());
}
template<typename F, typename... Ts>
struct curry
{
template<typename Tuple>
curry(F&& f, Tuple&& a) : f(forward<F>(f)), args(forward<Tuple>(a)) {}
decltype(auto) operator()()
{
return apply(f, args);
}
template<typename... Rs>
auto operator()(Rs&&... rs)
{
return curry<F, Ts..., Rs...>(f, tuple_cat(args, forward_as_tuple(forward<Rs>(rs)...)));
}
F f;
tuple<Ts...> args;
};
template<typename F>
auto make_curry(F&& f)
{
return curry<F>(forward<F>(f), make_tuple());
}
void test2(int a, char b, float c)
{
cout << a << " " << b << " " << c << "\n";
}
int main()
{
auto test = [](auto... xs) { cout << "test " << sizeof...(xs) << "\n"; };
make_curry(test)(1)("2")('3')();
make_curry(test)(1, "2", '3', 4.0f)(5.0)();
make_curry(test2)(42)('x')(3.5f)();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment