#include <iostream>
#include <tuple>
#include <functional>
#include <string>
using namespace std;
template <size_t N>
struct apply_tuple_func
{
template<typename F, typename T, typename... A>
static inline auto apply(F&& f, T&& t, A&&... a) ->
decltype(
apply_tuple_func<N-1>::apply(
std::forward<F>(f),
std::forward<T>(t),
std::get<N-1>(std::forward<T>(t)),
std::forward<A>(a)...))
{
return apply_tuple_func<N-1>::apply(
std::forward<F>(f),
std::forward<T>(t),
std::get<N-1>(std::forward<T>(t)),
std::forward<A>(a)...);
}
};
template <>
struct apply_tuple_func<0>
{
template<typename F, typename T, typename... A>
static inline auto apply(F&& f, T&&, A&&... a) ->
decltype(
std::forward<F>(f)(std::forward<A>(a)...))
{
return std::forward<F>(f)(std::forward<A>(a)...);
}
};
template <typename F, typename T>
inline auto apply_tuple(F&& f, T&& t) ->
decltype(
apply_tuple_func<
std::tuple_size<typename std::decay<T>::type>::value>
::apply(
std::forward<F>(f),
std::forward<T>(t)))
{
return apply_tuple_func<
std::tuple_size<typename std::decay<T>::type>::value>
::apply(std::forward<F>(f), std::forward<T>(t));
}
/*
FUN STUFF BELOW:
This will only run one specific function type,
but you could do stuff through other fun means to make it run other things
*/
template<typename R, typename... A>
R test(const std::function<R(A...)>& func)
{
std::tuple<int, float, string> a(5, 2.3, "Some text");
return apply_tuple(func, a);
}
void test2(int i, float f, string s)
{
cout << i << " " << f << " " << s << endl;
}
int main() {
test(std::function<void(int, float, string)>([](int i, float f, string s)
{
cout << i << " " << f << " " << s << endl;
}));
test(std::function<void(int, float, string)>(&test2));
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHVwbGU+CiNpbmNsdWRlIDxmdW5jdGlvbmFsPgojaW5jbHVkZSA8c3RyaW5nPgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKdGVtcGxhdGUgPHNpemVfdCBOPgpzdHJ1Y3QgYXBwbHlfdHVwbGVfZnVuYwp7CiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBGLCB0eXBlbmFtZSBULCB0eXBlbmFtZS4uLiBBPgogICAgc3RhdGljIGlubGluZSBhdXRvIGFwcGx5KEYmJiBmLCBUJiYgdCwgQSYmLi4uIGEpIC0+IAogICAgCWRlY2x0eXBlKAogICAgCQlhcHBseV90dXBsZV9mdW5jPE4tMT46OmFwcGx5KAogICAgCQkJc3RkOjpmb3J3YXJkPEY+KGYpLCAKICAgIAkJCXN0ZDo6Zm9yd2FyZDxUPih0KSwgCiAgICAJCQlzdGQ6OmdldDxOLTE+KHN0ZDo6Zm9yd2FyZDxUPih0KSksIAogICAgCQkJc3RkOjpmb3J3YXJkPEE+KGEpLi4uKSkKICAgIHsKICAgICAgICByZXR1cm4gYXBwbHlfdHVwbGVfZnVuYzxOLTE+OjphcHBseSgKICAgICAgICAJc3RkOjpmb3J3YXJkPEY+KGYpLCAKICAgICAgICAJc3RkOjpmb3J3YXJkPFQ+KHQpLCAKICAgICAgICAJc3RkOjpnZXQ8Ti0xPihzdGQ6OmZvcndhcmQ8VD4odCkpLCAKICAgICAgICAJc3RkOjpmb3J3YXJkPEE+KGEpLi4uKTsKICAgIH0KfTsKCnRlbXBsYXRlIDw+CnN0cnVjdCBhcHBseV90dXBsZV9mdW5jPDA+CnsKICAgIHRlbXBsYXRlPHR5cGVuYW1lIEYsIHR5cGVuYW1lIFQsIHR5cGVuYW1lLi4uIEE+CiAgICBzdGF0aWMgaW5saW5lIGF1dG8gYXBwbHkoRiYmIGYsIFQmJiwgQSYmLi4uIGEpIC0+IAogICAgCWRlY2x0eXBlKAogICAgCQlzdGQ6OmZvcndhcmQ8Rj4oZikoc3RkOjpmb3J3YXJkPEE+KGEpLi4uKSkKICAgIHsKICAgICAgICByZXR1cm4gc3RkOjpmb3J3YXJkPEY+KGYpKHN0ZDo6Zm9yd2FyZDxBPihhKS4uLik7CiAgICB9Cn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgRiwgdHlwZW5hbWUgVD4KaW5saW5lIGF1dG8gYXBwbHlfdHVwbGUoRiYmIGYsIFQmJiB0KSAtPiAKCWRlY2x0eXBlKAoJCWFwcGx5X3R1cGxlX2Z1bmM8CgkJCQlzdGQ6OnR1cGxlX3NpemU8dHlwZW5hbWUgc3RkOjpkZWNheTxUPjo6dHlwZT46OnZhbHVlPgoJCTo6YXBwbHkoCgkJCXN0ZDo6Zm9yd2FyZDxGPihmKSwKCQkJc3RkOjpmb3J3YXJkPFQ+KHQpKSkKewogICAgcmV0dXJuIGFwcGx5X3R1cGxlX2Z1bmM8CiAgICAJCXN0ZDo6dHVwbGVfc2l6ZTx0eXBlbmFtZSBzdGQ6OmRlY2F5PFQ+Ojp0eXBlPjo6dmFsdWU+CiAgICAJOjphcHBseShzdGQ6OmZvcndhcmQ8Rj4oZiksIHN0ZDo6Zm9yd2FyZDxUPih0KSk7Cn0KCi8qCgoJRlVOIFNUVUZGIEJFTE9XOgoJCglUaGlzIHdpbGwgb25seSBydW4gb25lIHNwZWNpZmljIGZ1bmN0aW9uIHR5cGUsCglidXQgeW91IGNvdWxkIGRvIHN0dWZmIHRocm91Z2ggb3RoZXIgZnVuIG1lYW5zIHRvIG1ha2UgaXQgcnVuIG90aGVyIHRoaW5ncwoKKi8KCnRlbXBsYXRlPHR5cGVuYW1lIFIsIHR5cGVuYW1lLi4uIEE+ClIgdGVzdChjb25zdCBzdGQ6OmZ1bmN0aW9uPFIoQS4uLik+JiBmdW5jKQp7CglzdGQ6OnR1cGxlPGludCwgZmxvYXQsIHN0cmluZz4gYSg1LCAyLjMsICJTb21lIHRleHQiKTsKCXJldHVybiBhcHBseV90dXBsZShmdW5jLCBhKTsKfQoKdm9pZCB0ZXN0MihpbnQgaSwgZmxvYXQgZiwgc3RyaW5nIHMpCnsKCWNvdXQgPDwgaSA8PCAiICIgPDwgZiA8PCAiICIgPDwgcyA8PCBlbmRsOwp9CgppbnQgbWFpbigpIHsKCXRlc3Qoc3RkOjpmdW5jdGlvbjx2b2lkKGludCwgZmxvYXQsIHN0cmluZyk+KFtdKGludCBpLCBmbG9hdCBmLCBzdHJpbmcgcykKCQl7CgkJCWNvdXQgPDwgaSA8PCAiICIgPDwgZiA8PCAiICIgPDwgcyA8PCBlbmRsOwoJCX0pKTsKCXRlc3Qoc3RkOjpmdW5jdGlvbjx2b2lkKGludCwgZmxvYXQsIHN0cmluZyk+KCZ0ZXN0MikpOwoJcmV0dXJuIDA7Cn0=