#include <functional>
#include <tuple>
// apply a functor to every element of a tuple
namespace Detail {
template <std::size_t i, typename Tuple, typename F>
typename std::enable_if<i == std::tuple_size<Tuple>::value>::type
ForEachTupleImpl(Tuple& t, F& f)
{
}
template <std::size_t i, typename Tuple, typename F>
typename std::enable_if<i != std::tuple_size<Tuple>::value>::type
ForEachTupleImpl(Tuple& t, F& f)
{
f(std::get<i>(t));
ForEachTupleImpl<i+1>(t, f);
}
}
template <typename Tuple, typename F>
void ForEachTuple(Tuple& t, F& f)
{
Detail::ForEachTupleImpl<0>(t, f);
}
struct A
{
A() : a(0) {}
A(A& a) = delete;
A(const A& a) = delete;
int a;
};
int main()
{
// create a tuple of types and initialise them with zeros
using T = std::tuple<A, A, A>;
T t;
// creator a simple function object that increments the objects member
struct F
{
void operator()(A& a) const { a.a++; }
} f;
// if this works I should end up with a tuple of A's with members equal to 1
ForEachTuple(t, f);
return 0;
}
I2luY2x1ZGUgPGZ1bmN0aW9uYWw+CiNpbmNsdWRlIDx0dXBsZT4KCi8vIGFwcGx5IGEgZnVuY3RvciB0byBldmVyeSBlbGVtZW50IG9mIGEgdHVwbGUKbmFtZXNwYWNlIERldGFpbCB7CnRlbXBsYXRlIDxzdGQ6OnNpemVfdCBpLCB0eXBlbmFtZSBUdXBsZSwgdHlwZW5hbWUgRj4KdHlwZW5hbWUgc3RkOjplbmFibGVfaWY8aSA9PSBzdGQ6OnR1cGxlX3NpemU8VHVwbGU+Ojp2YWx1ZT46OnR5cGUKRm9yRWFjaFR1cGxlSW1wbChUdXBsZSYgdCwgRiYgZikKewp9Cgp0ZW1wbGF0ZSA8c3RkOjpzaXplX3QgaSwgdHlwZW5hbWUgVHVwbGUsIHR5cGVuYW1lIEY+CnR5cGVuYW1lIHN0ZDo6ZW5hYmxlX2lmPGkgIT0gc3RkOjp0dXBsZV9zaXplPFR1cGxlPjo6dmFsdWU+Ojp0eXBlCkZvckVhY2hUdXBsZUltcGwoVHVwbGUmIHQsIEYmIGYpCnsKICAgIGYoc3RkOjpnZXQ8aT4odCkpOwogICAgRm9yRWFjaFR1cGxlSW1wbDxpKzE+KHQsIGYpOwp9Cgp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVHVwbGUsIHR5cGVuYW1lIEY+CnZvaWQgRm9yRWFjaFR1cGxlKFR1cGxlJiB0LCBGJiBmKQp7CiAgICBEZXRhaWw6OkZvckVhY2hUdXBsZUltcGw8MD4odCwgZik7Cn0KCnN0cnVjdCBBCnsKICAgIEEoKSA6IGEoMCkge30KICAgIEEoQSYgYSkgPSBkZWxldGU7CiAgICBBKGNvbnN0IEEmIGEpID0gZGVsZXRlOwoKICAgIGludCBhOwp9OwoKaW50IG1haW4oKQp7CiAgICAvLyBjcmVhdGUgYSB0dXBsZSBvZiB0eXBlcyBhbmQgaW5pdGlhbGlzZSB0aGVtIHdpdGggemVyb3MKICAgIHVzaW5nIFQgPSBzdGQ6OnR1cGxlPEEsIEEsIEE+OwogICAgVCB0OwoKICAgIC8vIGNyZWF0b3IgYSBzaW1wbGUgZnVuY3Rpb24gb2JqZWN0IHRoYXQgaW5jcmVtZW50cyB0aGUgb2JqZWN0cyBtZW1iZXIKICAgIHN0cnVjdCBGCiAgICB7CiAgICAgICAgdm9pZCBvcGVyYXRvcigpKEEmIGEpIGNvbnN0IHsgYS5hKys7IH0KICAgIH0gZjsKCiAgICAvLyBpZiB0aGlzIHdvcmtzIEkgc2hvdWxkIGVuZCB1cCB3aXRoIGEgdHVwbGUgb2YgQSdzIHdpdGggbWVtYmVycyBlcXVhbCB0byAxCiAgICBGb3JFYWNoVHVwbGUodCwgZik7CiAgICByZXR1cm4gMDsKfQ==