#include <tuple>
#include <type_traits>
#include <array>
#include <typeinfo>
#include <iostream>
template<typename T1, typename T2>
struct concat_tuples;
template<typename... T1, typename... T2>
struct concat_tuples<std::tuple<T1...>, std::tuple<T2...>>
{
using type = std::tuple<T1..., T2...>;
};
template<typename T, size_t n>
struct n_tuple;
template<typename T>
struct n_tuple<T, 0>
{
using type = std::tuple<>;
};
template<typename T, size_t n>
struct n_tuple
{
using type = typename concat_tuples<
typename n_tuple<T, n-1>::type,
std::tuple<T>
>::type;
};
template <class Scalar, class Array, class Tuple>
struct Test;
template <class Scalar, typename T, size_t n, typename... Ts>
struct Test<Scalar, std::array<T, n>, std::tuple<Ts...>>
{
using type = typename concat_tuples<
typename concat_tuples<
std::tuple<Scalar>,
typename n_tuple<T, n>::type
>::type,
std::tuple<Ts...>
>::type;
};
int main() {
static_assert(std::is_same<n_tuple<int, 3>::type, std::tuple<int, int, int>>::value, "NOT EQUAL");
static_assert(std::is_same<Test<float, std::array<int, 3>, std::tuple<char, bool>>::type, std::tuple<float, int, int, int, char, bool>>::value, "NOT EQUAL");
}
I2luY2x1ZGUgPHR1cGxlPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CiNpbmNsdWRlIDxhcnJheT4KI2luY2x1ZGUgPHR5cGVpbmZvPgojaW5jbHVkZSA8aW9zdHJlYW0+Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBUMSwgdHlwZW5hbWUgVDI+CnN0cnVjdCBjb25jYXRfdHVwbGVzOwoKdGVtcGxhdGU8dHlwZW5hbWUuLi4gVDEsIHR5cGVuYW1lLi4uIFQyPgpzdHJ1Y3QgY29uY2F0X3R1cGxlczxzdGQ6OnR1cGxlPFQxLi4uPiwgc3RkOjp0dXBsZTxUMi4uLj4+CnsKICAgIHVzaW5nIHR5cGUgPSBzdGQ6OnR1cGxlPFQxLi4uLCBUMi4uLj47Cn07IAoKdGVtcGxhdGU8dHlwZW5hbWUgVCwgc2l6ZV90IG4+CnN0cnVjdCBuX3R1cGxlOwoKdGVtcGxhdGU8dHlwZW5hbWUgVD4Kc3RydWN0IG5fdHVwbGU8VCwgMD4gCnsKICAgIHVzaW5nIHR5cGUgPSBzdGQ6OnR1cGxlPD47Cn07Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBULCBzaXplX3Qgbj4Kc3RydWN0IG5fdHVwbGUKewogICAgdXNpbmcgdHlwZSA9IHR5cGVuYW1lIGNvbmNhdF90dXBsZXM8CiAgICAgICAgICAgICAgICAgICAgdHlwZW5hbWUgbl90dXBsZTxULCBuLTE+Ojp0eXBlLCAKICAgICAgICAgICAgICAgICAgICBzdGQ6OnR1cGxlPFQ+CiAgICAgICAgICAgICAgICA+Ojp0eXBlOwp9OwoKdGVtcGxhdGUgPGNsYXNzIFNjYWxhciwgY2xhc3MgQXJyYXksIGNsYXNzIFR1cGxlPgpzdHJ1Y3QgVGVzdDsKCnRlbXBsYXRlIDxjbGFzcyBTY2FsYXIsICB0eXBlbmFtZSBULCBzaXplX3QgbiwgdHlwZW5hbWUuLi4gVHM+CnN0cnVjdCBUZXN0PFNjYWxhciwgc3RkOjphcnJheTxULCBuPiwgc3RkOjp0dXBsZTxUcy4uLj4+CnsKICAgIHVzaW5nIHR5cGUgPSB0eXBlbmFtZSBjb25jYXRfdHVwbGVzPAogICAgICAgICAgICAgICAgICAgIHR5cGVuYW1lIGNvbmNhdF90dXBsZXM8CiAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6dHVwbGU8U2NhbGFyPiwgCiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVuYW1lIG5fdHVwbGU8VCwgbj46OnR5cGUKICAgICAgICAgICAgICAgICAgICA+Ojp0eXBlLCAKICAgICAgICAgICAgICAgICAgICBzdGQ6OnR1cGxlPFRzLi4uPgogICAgICAgICAgICAgICAgPjo6dHlwZTsKfTsKCmludCBtYWluKCkgewogICAgc3RhdGljX2Fzc2VydChzdGQ6OmlzX3NhbWU8bl90dXBsZTxpbnQsIDM+Ojp0eXBlLCBzdGQ6OnR1cGxlPGludCwgaW50LCBpbnQ+Pjo6dmFsdWUsICJOT1QgRVFVQUwiKTsKICAgIHN0YXRpY19hc3NlcnQoc3RkOjppc19zYW1lPFRlc3Q8ZmxvYXQsIHN0ZDo6YXJyYXk8aW50LCAzPiwgc3RkOjp0dXBsZTxjaGFyLCBib29sPj46OnR5cGUsIHN0ZDo6dHVwbGU8ZmxvYXQsIGludCwgaW50LCBpbnQsIGNoYXIsIGJvb2w+Pjo6dmFsdWUsICJOT1QgRVFVQUwiKTsKfQo=