#include <iostream>
#include <type_traits>
template <int I> using int_ = std::integral_constant<int, I>;
template<typename T> using eval = typename T::type;
template<typename... List>
struct seq
{
using type = seq;
};
template<typename> struct car;
template<typename Car, typename... Cdr>
struct car< seq<Car, Cdr...>>
{
typedef Car type;
};
template<typename> struct cdr;
template<typename Car, typename... Cdr>
struct cdr< seq<Car, Cdr...>>
{
typedef seq<Cdr...> type;
};
template <typename, typename> struct cons;
template <typename T, typename... L>
struct cons<T, seq<L...>>
{
typedef seq<T, L...> type;
};
template<typename, typename> struct concat;
template <typename... As, typename... Bs>
struct concat<seq<As...>, seq<Bs...>>
{
typedef seq<As..., Bs...> type;
};
template<typename> struct length;
template<typename... As>
struct length<seq<As...>>
{
typedef std::integral_constant<unsigned, sizeof...(As)> type;
};
template<typename>
struct is_empty
{
typedef std::integral_constant<bool, true> type;
};
template<>
struct is_empty<seq<>>
{
typedef std::integral_constant<bool, true> type;
};
template<template<typename... Args> class Fun, typename... Args>
struct apply
{
typedef eval<Fun<Args...>> type;
};
typedef seq<int_<1>, int_<2>, int_<3> > s1;
typedef seq<int_<7>, int_<5>, int_<9> > s2;
typedef seq<int_<1>, s2, int_<17>, s1 > s3;
typedef seq<> empty;
template<typename Seq> using concat_fix = apply<concat, s2, Seq>;
int main()
{
std::cerr << eval < length < eval < apply < concat, s1, s3 >> >> ::value << '\n';
std::cerr << eval < length <eval< concat_fix<s3>>>>::value << '\n';
std::cerr << eval < apply < length, empty> >::value << '\n';
std::cerr << eval<length < eval < concat<s1, s3 >>>>::value << '\n';
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+Cgp0ZW1wbGF0ZSA8aW50IEk+IHVzaW5nIGludF8gPSBzdGQ6OmludGVncmFsX2NvbnN0YW50PGludCwgST47Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBUPiB1c2luZyBldmFsID0gdHlwZW5hbWUgVDo6dHlwZTsKCnRlbXBsYXRlPHR5cGVuYW1lLi4uIExpc3Q+CnN0cnVjdCBzZXEKewogICAgdXNpbmcgdHlwZSA9IHNlcTsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lPiBzdHJ1Y3QgY2FyOwp0ZW1wbGF0ZTx0eXBlbmFtZSBDYXIsIHR5cGVuYW1lLi4uIENkcj4Kc3RydWN0IGNhcjwgc2VxPENhciwgQ2RyLi4uPj4KewogICAgdHlwZWRlZiBDYXIgdHlwZTsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lPiBzdHJ1Y3QgY2RyOwp0ZW1wbGF0ZTx0eXBlbmFtZSBDYXIsIHR5cGVuYW1lLi4uIENkcj4Kc3RydWN0IGNkcjwgc2VxPENhciwgQ2RyLi4uPj4KewogICAgdHlwZWRlZiBzZXE8Q2RyLi4uPiB0eXBlOwp9OwoKCnRlbXBsYXRlIDx0eXBlbmFtZSwgdHlwZW5hbWU+IHN0cnVjdCBjb25zOwp0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUuLi4gTD4Kc3RydWN0IGNvbnM8VCwgc2VxPEwuLi4+Pgp7CiAgICB0eXBlZGVmIHNlcTxULCBMLi4uPiB0eXBlOwp9OwoKdGVtcGxhdGU8dHlwZW5hbWUsIHR5cGVuYW1lPiBzdHJ1Y3QgY29uY2F0Owp0ZW1wbGF0ZSA8dHlwZW5hbWUuLi4gQXMsIHR5cGVuYW1lLi4uIEJzPgpzdHJ1Y3QgY29uY2F0PHNlcTxBcy4uLj4sIHNlcTxCcy4uLj4+CnsKICAgIHR5cGVkZWYgc2VxPEFzLi4uLCBCcy4uLj4gdHlwZTsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lPiBzdHJ1Y3QgbGVuZ3RoOwp0ZW1wbGF0ZTx0eXBlbmFtZS4uLiBBcz4Kc3RydWN0IGxlbmd0aDxzZXE8QXMuLi4+Pgp7CiAgICB0eXBlZGVmIHN0ZDo6aW50ZWdyYWxfY29uc3RhbnQ8dW5zaWduZWQsIHNpemVvZi4uLihBcyk+IHR5cGU7Cn07Cgp0ZW1wbGF0ZTx0eXBlbmFtZT4Kc3RydWN0IGlzX2VtcHR5CnsKICAgIHR5cGVkZWYgc3RkOjppbnRlZ3JhbF9jb25zdGFudDxib29sLCB0cnVlPiB0eXBlOwp9OwoKdGVtcGxhdGU8PgpzdHJ1Y3QgaXNfZW1wdHk8c2VxPD4+CnsKICAgIHR5cGVkZWYgc3RkOjppbnRlZ3JhbF9jb25zdGFudDxib29sLCB0cnVlPiB0eXBlOwp9OwoKdGVtcGxhdGU8dGVtcGxhdGU8dHlwZW5hbWUuLi4gQXJncz4gY2xhc3MgRnVuLCB0eXBlbmFtZS4uLiBBcmdzPgpzdHJ1Y3QgYXBwbHkKewogICAgdHlwZWRlZiBldmFsPEZ1bjxBcmdzLi4uPj4gdHlwZTsKfTsKCnR5cGVkZWYgc2VxPGludF88MT4sIGludF88Mj4sIGludF88Mz4gPiBzMTsKdHlwZWRlZiBzZXE8aW50Xzw3PiwgaW50Xzw1PiwgaW50Xzw5PiA+IHMyOwp0eXBlZGVmIHNlcTxpbnRfPDE+LCBzMiwgaW50XzwxNz4sIHMxID4gczM7CnR5cGVkZWYgc2VxPD4gZW1wdHk7CnRlbXBsYXRlPHR5cGVuYW1lIFNlcT4gdXNpbmcgY29uY2F0X2ZpeCA9IGFwcGx5PGNvbmNhdCwgczIsIFNlcT47CgppbnQgbWFpbigpCnsKCiAgICBzdGQ6OmNlcnIgPDwgZXZhbCA8IGxlbmd0aCA8IGV2YWwgPCBhcHBseSA8IGNvbmNhdCwgczEsIHMzID4+ID4+IDo6dmFsdWUgPDwgJ1xuJzsKICAgIHN0ZDo6Y2VyciA8PCBldmFsIDwgbGVuZ3RoIDxldmFsPCBjb25jYXRfZml4PHMzPj4+Pjo6dmFsdWUgPDwgJ1xuJzsKICAgIHN0ZDo6Y2VyciA8PCBldmFsIDwgYXBwbHkgPCBsZW5ndGgsIGVtcHR5PiA+Ojp2YWx1ZSA8PCAnXG4nOwogICAgc3RkOjpjZXJyIDw8IGV2YWw8bGVuZ3RoIDwgZXZhbCA8IGNvbmNhdDxzMSwgczMgPj4+Pjo6dmFsdWUgPDwgJ1xuJzsKICAgIHJldHVybiAwOwp9