#include <tuple>
#include <iostream>
#include <functional>
template<int ...> struct seq {};
template<int N, int ...S> struct gens : gens<N-1, N-1, S...> {};
template<int ...S> struct gens<0, S...>{ typedef seq<S...> type; };
template <typename R, typename Tp, typename ...FArgs>
struct t_app_aux {
template<int ...S>
R static callFunc(std::function<R (FArgs...)> f,Tp t,seq<S...>) {
return f(std::get<S>(t) ...);
}
};
template <typename R, typename Tp, typename ...FArgs>
R t_app(std::function<R (FArgs...)> f, Tp t) {
static_assert(std::tuple_size<Tp>::value == sizeof...(FArgs), "type error: t_app wrong arity");
return t_app_aux<R, Tp, FArgs...>::callFunc(f,t,typename gens<sizeof...(FArgs)>::type());
}
struct foo
{
foo() : _value(0) { std::cout << "default foo" << std::endl; }
foo(int value) : _value(value) { std::cout << "int foo" << std::endl; }
foo(const foo& other) : _value(other._value) { std::cout << "copy foo" << std::endl; }
foo(foo&& other) : _value(other._value) { std::cout << "move foo" << std::endl; }
int _value;
};
int main(void)
{
std::cout << "Tuple creation" << std::endl;
std::tuple<int, float, foo> t = std::make_tuple(1, 1.2, foo(5));
std::cout << "Tuple created" << std::endl;
std::function<double (int,float,foo&)> foo1 = [](int x, float y, foo& z) {
return x + y + z._value;
};
std::cout << "Function created" << std::endl;
std::cout << t_app(foo1,t) << std::endl;
std::cout << "Function applied" << std::endl;
}
I2luY2x1ZGUgPHR1cGxlPgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDxmdW5jdGlvbmFsPgoKdGVtcGxhdGU8aW50IC4uLj4gc3RydWN0IHNlcSB7fTsKCnRlbXBsYXRlPGludCBOLCBpbnQgLi4uUz4gc3RydWN0IGdlbnMgOiBnZW5zPE4tMSwgTi0xLCBTLi4uPiB7fTsKCnRlbXBsYXRlPGludCAuLi5TPiBzdHJ1Y3QgZ2VuczwwLCBTLi4uPnsgdHlwZWRlZiBzZXE8Uy4uLj4gdHlwZTsgfTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBSLCB0eXBlbmFtZSBUcCwgdHlwZW5hbWUgLi4uRkFyZ3M+IApzdHJ1Y3QgdF9hcHBfYXV4IHsKICB0ZW1wbGF0ZTxpbnQgLi4uUz4KICBSIHN0YXRpYyBjYWxsRnVuYyhzdGQ6OmZ1bmN0aW9uPFIgKEZBcmdzLi4uKT4gZixUcCB0LHNlcTxTLi4uPikgewogICAgcmV0dXJuIGYoc3RkOjpnZXQ8Uz4odCkgLi4uKTsKICB9Cn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgUiwgdHlwZW5hbWUgVHAsIHR5cGVuYW1lIC4uLkZBcmdzPgpSIHRfYXBwKHN0ZDo6ZnVuY3Rpb248UiAoRkFyZ3MuLi4pPiBmLCBUcCB0KSB7CiAgc3RhdGljX2Fzc2VydChzdGQ6OnR1cGxlX3NpemU8VHA+Ojp2YWx1ZSA9PSBzaXplb2YuLi4oRkFyZ3MpLCAidHlwZSBlcnJvcjogdF9hcHAgd3JvbmcgYXJpdHkiKTsKICByZXR1cm4gdF9hcHBfYXV4PFIsIFRwLCBGQXJncy4uLj46OmNhbGxGdW5jKGYsdCx0eXBlbmFtZSBnZW5zPHNpemVvZi4uLihGQXJncyk+Ojp0eXBlKCkpOwp9CgoKc3RydWN0IGZvbwp7CiAgZm9vKCkgOiBfdmFsdWUoMCkgeyBzdGQ6OmNvdXQgPDwgImRlZmF1bHQgZm9vIiA8PCBzdGQ6OmVuZGw7IH0KICBmb28oaW50IHZhbHVlKSA6IF92YWx1ZSh2YWx1ZSkgeyBzdGQ6OmNvdXQgPDwgImludCBmb28iIDw8IHN0ZDo6ZW5kbDsgfQogIGZvbyhjb25zdCBmb28mIG90aGVyKSA6IF92YWx1ZShvdGhlci5fdmFsdWUpIHsgc3RkOjpjb3V0IDw8ICJjb3B5IGZvbyIgPDwgc3RkOjplbmRsOyB9CiAgZm9vKGZvbyYmIG90aGVyKSA6IF92YWx1ZShvdGhlci5fdmFsdWUpIHsgc3RkOjpjb3V0IDw8ICJtb3ZlIGZvbyIgPDwgc3RkOjplbmRsOyB9CgogIGludCBfdmFsdWU7Cn07CgppbnQgbWFpbih2b2lkKQp7CiAgc3RkOjpjb3V0IDw8ICJUdXBsZSBjcmVhdGlvbiIgPDwgc3RkOjplbmRsOwogIHN0ZDo6dHVwbGU8aW50LCBmbG9hdCwgZm9vPiB0ID0gc3RkOjptYWtlX3R1cGxlKDEsIDEuMiwgZm9vKDUpKTsKICBzdGQ6OmNvdXQgPDwgIlR1cGxlIGNyZWF0ZWQiIDw8IHN0ZDo6ZW5kbDsKICBzdGQ6OmZ1bmN0aW9uPGRvdWJsZSAoaW50LGZsb2F0LGZvbyYpPiBmb28xID0gW10oaW50IHgsIGZsb2F0IHksIGZvbyYgeikgewogICAgcmV0dXJuIHggKyB5ICsgei5fdmFsdWU7ICAgIAogIH07CgogIHN0ZDo6Y291dCA8PCAiRnVuY3Rpb24gY3JlYXRlZCIgPDwgc3RkOjplbmRsOwogIHN0ZDo6Y291dCA8PCAgdF9hcHAoZm9vMSx0KSA8PCBzdGQ6OmVuZGw7CiAgc3RkOjpjb3V0IDw8ICJGdW5jdGlvbiBhcHBsaWVkIiA8PCBzdGQ6OmVuZGw7Cn0=