#include <cstddef>
#include <iostream>
#include <tuple>
#include <cstdint>
#include <type_traits>
#include <tuple>
template <typename T, typename Tuple> struct get_index;
template <typename T, typename... Ts>
struct get_index<T, std::tuple<T, Ts...>> : std::integral_constant<std::size_t, 0> {};
template <typename T, typename Tail, typename... Ts>
struct get_index<T, std::tuple<Tail, Ts...>> :
std::integral_constant<std::size_t, 1 + get_index<T, std::tuple<Ts...>>::value> {};
struct A
{
std::size_t size() { return 3; }
};
struct B
{
std::size_t size() { return 2; }
};
struct C
{
std::size_t size() { return 4; }
};
template <typename Tuple> struct Foo
{
const Tuple& tuple_;
std::array<int, std::tuple_size<Tuple>::value> array_;
Foo(const Tuple& tuple)
: tuple_(tuple)
{
std::cout << init() << '\n';
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template <std::size_t INDEX = 0>
typename std::enable_if<std::tuple_size<Tuple>::value == INDEX, std::size_t>::type init()
{
return 0;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template <std::size_t INDEX = 0>
typename std::enable_if<std::tuple_size<Tuple>::value != INDEX, std::size_t>::type init()
{
auto offset = init<INDEX + 1>();
std::cout << "index: " << INDEX << "; offset: " << offset << '\n';
array_[INDEX] = offset;
return offset + std::get<INDEX>(tuple_).size();
}
template <typename T>
std::size_t
offset(const T&)
{
return array_[get_index<T&, Tuple>::value];
}
};
int main()
{
A a;
B b;
C c;
auto t = std::tie(a, b, c);
using T = decltype(t);
Foo<T> foo(t);
std::cout << foo.offset(a) << '\n';
std::cout << foo.offset(b) << '\n';
std::cout << foo.offset(c) << '\n';
}
I2luY2x1ZGUgPGNzdGRkZWY+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPHR1cGxlPgoKCiNpbmNsdWRlIDxjc3RkaW50PgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CiNpbmNsdWRlIDx0dXBsZT4KCnRlbXBsYXRlIDx0eXBlbmFtZSBULCB0eXBlbmFtZSBUdXBsZT4gc3RydWN0IGdldF9pbmRleDsKCnRlbXBsYXRlIDx0eXBlbmFtZSBULCB0eXBlbmFtZS4uLiBUcz4Kc3RydWN0IGdldF9pbmRleDxULCBzdGQ6OnR1cGxlPFQsIFRzLi4uPj4gOiBzdGQ6OmludGVncmFsX2NvbnN0YW50PHN0ZDo6c2l6ZV90LCAwPiB7fTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBULCB0eXBlbmFtZSBUYWlsLCB0eXBlbmFtZS4uLiBUcz4Kc3RydWN0IGdldF9pbmRleDxULCBzdGQ6OnR1cGxlPFRhaWwsIFRzLi4uPj4gOgogICAgc3RkOjppbnRlZ3JhbF9jb25zdGFudDxzdGQ6OnNpemVfdCwgMSArIGdldF9pbmRleDxULCBzdGQ6OnR1cGxlPFRzLi4uPj46OnZhbHVlPiB7fTsKCgpzdHJ1Y3QgQQp7CiAgICBzdGQ6OnNpemVfdCBzaXplKCkgeyByZXR1cm4gMzsgfQp9OwoKc3RydWN0IEIKewogICAgc3RkOjpzaXplX3Qgc2l6ZSgpIHsgcmV0dXJuIDI7IH0KfTsKCnN0cnVjdCBDCnsKICAgIHN0ZDo6c2l6ZV90IHNpemUoKSB7IHJldHVybiA0OyB9Cn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVHVwbGU+IHN0cnVjdCBGb28KewogICAgY29uc3QgVHVwbGUmIHR1cGxlXzsKICAgIHN0ZDo6YXJyYXk8aW50LCBzdGQ6OnR1cGxlX3NpemU8VHVwbGU+Ojp2YWx1ZT4gYXJyYXlfOwoKICAgIEZvbyhjb25zdCBUdXBsZSYgdHVwbGUpCiAgICAgICAgOiB0dXBsZV8odHVwbGUpCiAgICB7CiAgICAgICAgc3RkOjpjb3V0IDw8IGluaXQoKSA8PCAnXG4nOwogICAgfQoKICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KCiAgICB0ZW1wbGF0ZSA8c3RkOjpzaXplX3QgSU5ERVggPSAwPgogICAgdHlwZW5hbWUgc3RkOjplbmFibGVfaWY8c3RkOjp0dXBsZV9zaXplPFR1cGxlPjo6dmFsdWUgPT0gSU5ERVgsIHN0ZDo6c2l6ZV90Pjo6dHlwZSBpbml0KCkKICAgIHsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCgogICAgdGVtcGxhdGUgPHN0ZDo6c2l6ZV90IElOREVYID0gMD4KICAgIHR5cGVuYW1lIHN0ZDo6ZW5hYmxlX2lmPHN0ZDo6dHVwbGVfc2l6ZTxUdXBsZT46OnZhbHVlICE9IElOREVYLCBzdGQ6OnNpemVfdD46OnR5cGUgaW5pdCgpCiAgICB7CiAgICAgICAgYXV0byBvZmZzZXQgPSBpbml0PElOREVYICsgMT4oKTsKCiAgICAgICAgc3RkOjpjb3V0IDw8ICJpbmRleDogIiA8PCBJTkRFWCA8PCAiOyBvZmZzZXQ6ICIgPDwgb2Zmc2V0IDw8ICdcbic7CgogICAgICAgIGFycmF5X1tJTkRFWF0gPSBvZmZzZXQ7CgogICAgICAgIHJldHVybiBvZmZzZXQgKyBzdGQ6OmdldDxJTkRFWD4odHVwbGVfKS5zaXplKCk7CiAgICB9CgogICAgdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CiAgICBzdGQ6OnNpemVfdAogICAgb2Zmc2V0KGNvbnN0IFQmKQogICAgewogICAgICAgIHJldHVybiBhcnJheV9bZ2V0X2luZGV4PFQmLCBUdXBsZT46OnZhbHVlXTsKICAgIH0KfTsKCmludCBtYWluKCkKewogICAgQSBhOwogICAgQiBiOwogICAgQyBjOwogICAgYXV0byB0ID0gc3RkOjp0aWUoYSwgYiwgYyk7CiAgICB1c2luZyBUID0gZGVjbHR5cGUodCk7CiAgICBGb288VD4gZm9vKHQpOwoKICAgIHN0ZDo6Y291dCA8PCBmb28ub2Zmc2V0KGEpIDw8ICdcbic7CiAgICBzdGQ6OmNvdXQgPDwgZm9vLm9mZnNldChiKSA8PCAnXG4nOwogICAgc3RkOjpjb3V0IDw8IGZvby5vZmZzZXQoYykgPDwgJ1xuJzsKfQo=