#include <tuple>
#include <iostream>
#include <functional>
#include <type_traits>
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;
};
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>(std::forward<Tp>(t)) ...);
}
};
template <typename R, typename Tp, typename ...FArgs>
R t_app(std::function<R (FArgs...)> f, Tp&& t)
{
static_assert(std::tuple_size<typename std::remove_reference<Tp>::type>::value == sizeof...(FArgs),
"type error: t_app wrong arity");
return t_app_aux<R, Tp, FArgs...>::callFunc(f, std::forward<Tp>(t), typename gens<sizeof...(FArgs)>::type());
}
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+CiNpbmNsdWRlIDxmdW5jdGlvbmFsPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CgoKc3RydWN0IGZvbwp7CiAgZm9vKCkgOiBfdmFsdWUoMCkgeyBzdGQ6OmNvdXQgPDwgImRlZmF1bHQgZm9vIiA8PCBzdGQ6OmVuZGw7IH0KICBmb28oaW50IHZhbHVlKSA6IF92YWx1ZSh2YWx1ZSkgeyBzdGQ6OmNvdXQgPDwgImludCBmb28iIDw8IHN0ZDo6ZW5kbDsgfQogIGZvbyhjb25zdCBmb28mIG90aGVyKSA6IF92YWx1ZShvdGhlci5fdmFsdWUpIHsgc3RkOjpjb3V0IDw8ICJjb3B5IGZvbyIgPDwgc3RkOjplbmRsOyB9CiAgZm9vKGZvbyYmIG90aGVyKSA6IF92YWx1ZShvdGhlci5fdmFsdWUpIHsgc3RkOjpjb3V0IDw8ICJtb3ZlIGZvbyIgPDwgc3RkOjplbmRsOyB9CgogIGludCBfdmFsdWU7Cn07Cgp0ZW1wbGF0ZTxpbnQgLi4uPiBzdHJ1Y3Qgc2VxIHt9OwoKdGVtcGxhdGU8aW50IE4sIGludCAuLi5TPiBzdHJ1Y3QgZ2VucyA6IGdlbnM8Ti0xLCBOLTEsIFMuLi4+IHt9OwoKdGVtcGxhdGU8aW50IC4uLlM+IHN0cnVjdCBnZW5zPDAsIFMuLi4+eyB0eXBlZGVmIHNlcTxTLi4uPiB0eXBlOyB9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFIsIHR5cGVuYW1lIFRwLCB0eXBlbmFtZSAuLi5GQXJncz4gCnN0cnVjdCB0X2FwcF9hdXggewogIHRlbXBsYXRlPGludCAuLi5TPgogIFIgc3RhdGljIGNhbGxGdW5jKHN0ZDo6ZnVuY3Rpb248UiAoRkFyZ3MuLi4pPiBmLCBUcCYmIHQsIHNlcTxTLi4uPikgewogICAgcmV0dXJuIGYoc3RkOjpnZXQ8Uz4oc3RkOjpmb3J3YXJkPFRwPih0KSkgLi4uKTsKICB9Cn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgUiwgdHlwZW5hbWUgVHAsIHR5cGVuYW1lIC4uLkZBcmdzPgpSIHRfYXBwKHN0ZDo6ZnVuY3Rpb248UiAoRkFyZ3MuLi4pPiBmLCBUcCYmIHQpIAp7CiBzdGF0aWNfYXNzZXJ0KHN0ZDo6dHVwbGVfc2l6ZTx0eXBlbmFtZSBzdGQ6OnJlbW92ZV9yZWZlcmVuY2U8VHA+Ojp0eXBlPjo6dmFsdWUgPT0gc2l6ZW9mLi4uKEZBcmdzKSwgCiAgICAgICAgICAgICAgICAidHlwZSBlcnJvcjogdF9hcHAgd3JvbmcgYXJpdHkiKTsKCiAgcmV0dXJuIHRfYXBwX2F1eDxSLCBUcCwgRkFyZ3MuLi4+OjpjYWxsRnVuYyhmLCBzdGQ6OmZvcndhcmQ8VHA+KHQpLCB0eXBlbmFtZSBnZW5zPHNpemVvZi4uLihGQXJncyk+Ojp0eXBlKCkpOwp9CgoKCmludCBtYWluKHZvaWQpCnsKICBzdGQ6OmNvdXQgPDwgIlR1cGxlIGNyZWF0aW9uIiA8PCBzdGQ6OmVuZGw7CiAgc3RkOjp0dXBsZTxpbnQsIGZsb2F0LCBmb28+IHQgPSBzdGQ6Om1ha2VfdHVwbGUoMSwgMS4yLCBmb28oNSkpOwogIHN0ZDo6Y291dCA8PCAiVHVwbGUgY3JlYXRlZCIgPDwgc3RkOjplbmRsOwogIHN0ZDo6ZnVuY3Rpb248ZG91YmxlIChpbnQsZmxvYXQsZm9vJik+IGZvbzEgPSBbXShpbnQgeCwgZmxvYXQgeSwgZm9vJiB6KSB7CiAgICByZXR1cm4geCArIHkgKyB6Ll92YWx1ZTsgICAgCiAgfTsKCiAgc3RkOjpjb3V0IDw8ICJGdW5jdGlvbiBjcmVhdGVkIiA8PCBzdGQ6OmVuZGw7CiAgc3RkOjpjb3V0IDw8ICB0X2FwcChmb28xLHQpIDw8IHN0ZDo6ZW5kbDsKICBzdGQ6OmNvdXQgPDwgIkZ1bmN0aW9uIGFwcGxpZWQiIDw8IHN0ZDo6ZW5kbDsKfQ==