#include<iostream>
#include<type_traits>
int constexpr powOf10(size_t power)
{
return power == 0 ? 1 : 10 * powOf10(power - 1);
}
template<int... digits>
struct buildNumber;
template<int first, int... digits>
struct buildNumber<first, digits...> : std::integral_constant<int, first * powOf10(sizeof...(digits)) + buildNumber<digits...>::value>
{
};
template<>
struct buildNumber<> : std::integral_constant<int, 0>
{
};
template<int... digits>
struct areAllDigits;
template<int first, int... digits>
struct areAllDigits<first, digits...>
{
static bool constexpr value = first > 0 && first < 10 && areAllDigits<digits...>::value;
};
template<int first>
struct areAllDigits<first>
{
static bool constexpr value = first>0 && first < 10;
};
template<class T>
struct buildNumberT;
template<int... digits>
struct digitContainer
{
};
template<int... digits>
struct buildNumberT<digitContainer<digits...>> : buildNumber<digits...> {};
template<class T1, class T2>
struct concatCtr;
template<int... digits1, int... digits2>
struct concatCtr<digitContainer<digits1...>, digitContainer<digits2...>>
{
typedef digitContainer<digits1..., digits2...> type;
};
template<int number, size_t digit>
struct breakIntoDigits
{
typedef typename concatCtr<digitContainer<number / powOf10(digit)>, typename breakIntoDigits<number % powOf10(digit), digit - 1>::ctr>::type ctr;
};
template<int number>
struct breakIntoDigits<number, 0>
{
typedef digitContainer<number> ctr;
};
template<int needle, int... haystack>
struct contains;
template<int needle, int first, int... haystack>
struct contains<needle, first, haystack...>
{
static bool constexpr value = needle == first || contains<needle, haystack...>::value;
};
template<int needle>
struct contains<needle>
{
static constexpr bool value = false;
};
template<int... values>
struct max;
template<int first, int... rest>
struct max<first, rest...>
{
static constexpr int value = first > max<rest...>::value ? first : max<rest...>::value;
};
template<>
struct max<>
{
static int constexpr value = 0;
};
template<class container, int... digits>
struct ruleChecker;
template<int current, int... allPrevious, int... rest>
struct ruleChecker<digitContainer<allPrevious...>, current, rest...>
{
static bool constexpr value = (current == 0 || sizeof...(allPrevious) == 0 || contains<current, allPrevious...>::value || current > max<allPrevious...>::value) && ruleChecker<digitContainer<allPrevious..., current>, rest...>::value;
};
template<class container>
struct ruleChecker<container>
{
static bool constexpr value = true;
};
template<class ctr1, class ctr2>
struct ruleCheckerT;
template<class ctr1, int... set2>
struct ruleCheckerT<ctr1, digitContainer<set2...>> : ruleChecker<ctr1, set2...>{};
template<int number, int length>
struct isValidNumber : ruleCheckerT<digitContainer<>, typename breakIntoDigits<number, length>::ctr>
{
};
template<int number, int length>
struct generateList
{
typedef typename std::conditional<number % powOf10(length) == 0,
digitContainer<>,
typename concatCtr<
typename generateList<number + 1, length>::container,
typename std::conditional<isValidNumber<number, length>::value,
digitContainer<number>,
digitContainer<>
>::type
>::type
>::type container;
};
template<int number>
struct generateList<number, 1>
{
typedef typename concatCtr<
typename generateList<number + 1, 1>::container,
typename std::conditional<isValidNumber<number, 1>::value,
digitContainer<number>,
digitContainer<>
>::type
>::type container;
};
#define DEFINE_ENDPOINT_FOR_LENGTH(length) template<> struct generateList<powOf10(length), (length)>{typedef digitContainer<> container;}
template<int length>
struct insanity
{
static_assert(length > 0, "Length must be greater than 0.");
typedef typename concatCtr<typename generateList<1, length>::container, digitContainer<0>>::type numberList;
};
template<int first, int... rest>
void outputContainer(digitContainer<first, rest...> values)
{
std::cout<<first<<'\n';
outputContainer(digitContainer<rest...>{});
}
void outputContainer(digitContainer<> empty)
{
std::flush(std::cout);
}
DEFINE_ENDPOINT_FOR_LENGTH(1);
DEFINE_ENDPOINT_FOR_LENGTH(2);
int main()
{
outputContainer(insanity<2>::numberList{});
}
I2luY2x1ZGU8aW9zdHJlYW0+CiNpbmNsdWRlPHR5cGVfdHJhaXRzPgoKaW50IGNvbnN0ZXhwciBwb3dPZjEwKHNpemVfdCBwb3dlcikKewogICAgcmV0dXJuIHBvd2VyID09IDAgPyAxIDogMTAgKiBwb3dPZjEwKHBvd2VyIC0gMSk7Cn0KCnRlbXBsYXRlPGludC4uLiBkaWdpdHM+CnN0cnVjdCBidWlsZE51bWJlcjsKCnRlbXBsYXRlPGludCBmaXJzdCwgaW50Li4uIGRpZ2l0cz4Kc3RydWN0IGJ1aWxkTnVtYmVyPGZpcnN0LCBkaWdpdHMuLi4+IDogc3RkOjppbnRlZ3JhbF9jb25zdGFudDxpbnQsIGZpcnN0ICogcG93T2YxMChzaXplb2YuLi4oZGlnaXRzKSkgKyBidWlsZE51bWJlcjxkaWdpdHMuLi4+Ojp2YWx1ZT4Kewp9OwoKdGVtcGxhdGU8PgpzdHJ1Y3QgYnVpbGROdW1iZXI8PiA6IHN0ZDo6aW50ZWdyYWxfY29uc3RhbnQ8aW50LCAwPgp7Cn07Cgp0ZW1wbGF0ZTxpbnQuLi4gZGlnaXRzPgpzdHJ1Y3QgYXJlQWxsRGlnaXRzOwoKdGVtcGxhdGU8aW50IGZpcnN0LCBpbnQuLi4gZGlnaXRzPgpzdHJ1Y3QgYXJlQWxsRGlnaXRzPGZpcnN0LCBkaWdpdHMuLi4+CnsKICAgIHN0YXRpYyBib29sIGNvbnN0ZXhwciB2YWx1ZSA9IGZpcnN0ID4gMCAmJiBmaXJzdCA8IDEwICYmIGFyZUFsbERpZ2l0czxkaWdpdHMuLi4+Ojp2YWx1ZTsKfTsKCnRlbXBsYXRlPGludCBmaXJzdD4Kc3RydWN0IGFyZUFsbERpZ2l0czxmaXJzdD4KewogICAgc3RhdGljIGJvb2wgY29uc3RleHByIHZhbHVlID0gZmlyc3Q+MCAmJiBmaXJzdCA8IDEwOwp9OwoKdGVtcGxhdGU8Y2xhc3MgVD4Kc3RydWN0IGJ1aWxkTnVtYmVyVDsKCgp0ZW1wbGF0ZTxpbnQuLi4gZGlnaXRzPgpzdHJ1Y3QgZGlnaXRDb250YWluZXIKewoKfTsKCgp0ZW1wbGF0ZTxpbnQuLi4gZGlnaXRzPgpzdHJ1Y3QgYnVpbGROdW1iZXJUPGRpZ2l0Q29udGFpbmVyPGRpZ2l0cy4uLj4+IDogYnVpbGROdW1iZXI8ZGlnaXRzLi4uPiB7fTsKCnRlbXBsYXRlPGNsYXNzIFQxLCBjbGFzcyBUMj4Kc3RydWN0IGNvbmNhdEN0cjsKCnRlbXBsYXRlPGludC4uLiBkaWdpdHMxLCBpbnQuLi4gZGlnaXRzMj4Kc3RydWN0IGNvbmNhdEN0cjxkaWdpdENvbnRhaW5lcjxkaWdpdHMxLi4uPiwgZGlnaXRDb250YWluZXI8ZGlnaXRzMi4uLj4+CnsKICAgIHR5cGVkZWYgIGRpZ2l0Q29udGFpbmVyPGRpZ2l0czEuLi4sIGRpZ2l0czIuLi4+IHR5cGU7Cn07Cgp0ZW1wbGF0ZTxpbnQgbnVtYmVyLCBzaXplX3QgZGlnaXQ+CnN0cnVjdCBicmVha0ludG9EaWdpdHMKewogICAgdHlwZWRlZiB0eXBlbmFtZSBjb25jYXRDdHI8ZGlnaXRDb250YWluZXI8bnVtYmVyIC8gcG93T2YxMChkaWdpdCk+LCB0eXBlbmFtZSBicmVha0ludG9EaWdpdHM8bnVtYmVyICUgcG93T2YxMChkaWdpdCksIGRpZ2l0IC0gMT46OmN0cj46OnR5cGUgY3RyOwp9OwoKdGVtcGxhdGU8aW50IG51bWJlcj4Kc3RydWN0IGJyZWFrSW50b0RpZ2l0czxudW1iZXIsIDA+CnsKICAgIHR5cGVkZWYgZGlnaXRDb250YWluZXI8bnVtYmVyPiBjdHI7Cn07Cgp0ZW1wbGF0ZTxpbnQgbmVlZGxlLCBpbnQuLi4gaGF5c3RhY2s+CnN0cnVjdCBjb250YWluczsKCnRlbXBsYXRlPGludCBuZWVkbGUsIGludCBmaXJzdCwgaW50Li4uIGhheXN0YWNrPgpzdHJ1Y3QgY29udGFpbnM8bmVlZGxlLCBmaXJzdCwgaGF5c3RhY2suLi4+CnsKICAgIHN0YXRpYyBib29sIGNvbnN0ZXhwciB2YWx1ZSA9IG5lZWRsZSA9PSBmaXJzdCB8fCBjb250YWluczxuZWVkbGUsIGhheXN0YWNrLi4uPjo6dmFsdWU7Cn07Cgp0ZW1wbGF0ZTxpbnQgbmVlZGxlPgpzdHJ1Y3QgY29udGFpbnM8bmVlZGxlPgp7CiAgICBzdGF0aWMgY29uc3RleHByIGJvb2wgdmFsdWUgPSBmYWxzZTsKfTsKCnRlbXBsYXRlPGludC4uLiB2YWx1ZXM+CnN0cnVjdCBtYXg7Cgp0ZW1wbGF0ZTxpbnQgZmlyc3QsIGludC4uLiByZXN0PgpzdHJ1Y3QgbWF4PGZpcnN0LCByZXN0Li4uPgp7CiAgICBzdGF0aWMgY29uc3RleHByIGludCB2YWx1ZSA9IGZpcnN0ID4gbWF4PHJlc3QuLi4+Ojp2YWx1ZSA/IGZpcnN0IDogbWF4PHJlc3QuLi4+Ojp2YWx1ZTsKfTsKCnRlbXBsYXRlPD4Kc3RydWN0IG1heDw+CnsKICAgIHN0YXRpYyBpbnQgY29uc3RleHByIHZhbHVlID0gMDsKfTsKCnRlbXBsYXRlPGNsYXNzIGNvbnRhaW5lciwgaW50Li4uIGRpZ2l0cz4Kc3RydWN0IHJ1bGVDaGVja2VyOwoKdGVtcGxhdGU8aW50IGN1cnJlbnQsIGludC4uLiBhbGxQcmV2aW91cywgaW50Li4uIHJlc3Q+CnN0cnVjdCBydWxlQ2hlY2tlcjxkaWdpdENvbnRhaW5lcjxhbGxQcmV2aW91cy4uLj4sIGN1cnJlbnQsIHJlc3QuLi4+CnsKICAgIHN0YXRpYyBib29sIGNvbnN0ZXhwciB2YWx1ZSA9IChjdXJyZW50ID09IDAgfHwgc2l6ZW9mLi4uKGFsbFByZXZpb3VzKSA9PSAwIHx8IGNvbnRhaW5zPGN1cnJlbnQsIGFsbFByZXZpb3VzLi4uPjo6dmFsdWUgfHwgY3VycmVudCA+IG1heDxhbGxQcmV2aW91cy4uLj46OnZhbHVlKSAmJiBydWxlQ2hlY2tlcjxkaWdpdENvbnRhaW5lcjxhbGxQcmV2aW91cy4uLiwgY3VycmVudD4sIHJlc3QuLi4+Ojp2YWx1ZTsKfTsKCnRlbXBsYXRlPGNsYXNzIGNvbnRhaW5lcj4Kc3RydWN0IHJ1bGVDaGVja2VyPGNvbnRhaW5lcj4KewogICAgc3RhdGljIGJvb2wgY29uc3RleHByIHZhbHVlID0gdHJ1ZTsKfTsKCnRlbXBsYXRlPGNsYXNzIGN0cjEsIGNsYXNzIGN0cjI+CnN0cnVjdCBydWxlQ2hlY2tlclQ7Cgp0ZW1wbGF0ZTxjbGFzcyBjdHIxLCBpbnQuLi4gc2V0Mj4Kc3RydWN0IHJ1bGVDaGVja2VyVDxjdHIxLCBkaWdpdENvbnRhaW5lcjxzZXQyLi4uPj4gOiBydWxlQ2hlY2tlcjxjdHIxLCBzZXQyLi4uPnt9OwoKCnRlbXBsYXRlPGludCBudW1iZXIsIGludCBsZW5ndGg+CnN0cnVjdCBpc1ZhbGlkTnVtYmVyIDogcnVsZUNoZWNrZXJUPGRpZ2l0Q29udGFpbmVyPD4sIHR5cGVuYW1lIGJyZWFrSW50b0RpZ2l0czxudW1iZXIsIGxlbmd0aD46OmN0cj4Kewp9OwoKCnRlbXBsYXRlPGludCBudW1iZXIsIGludCBsZW5ndGg+CnN0cnVjdCBnZW5lcmF0ZUxpc3QKewogICAgdHlwZWRlZiB0eXBlbmFtZSBzdGQ6OmNvbmRpdGlvbmFsPG51bWJlciAlIHBvd09mMTAobGVuZ3RoKSA9PSAwLCAKCQlkaWdpdENvbnRhaW5lcjw+LAoJCXR5cGVuYW1lIGNvbmNhdEN0cjwKCQkJdHlwZW5hbWUgZ2VuZXJhdGVMaXN0PG51bWJlciArIDEsIGxlbmd0aD46OmNvbnRhaW5lciwKCQkJdHlwZW5hbWUgc3RkOjpjb25kaXRpb25hbDxpc1ZhbGlkTnVtYmVyPG51bWJlciwgbGVuZ3RoPjo6dmFsdWUsCgkJCQkJZGlnaXRDb250YWluZXI8bnVtYmVyPiwKCQkJCQlkaWdpdENvbnRhaW5lcjw+CgkJCQk+Ojp0eXBlCgkJCT46OnR5cGUKCQk+Ojp0eXBlIGNvbnRhaW5lcjsKfTsKCnRlbXBsYXRlPGludCBudW1iZXI+CnN0cnVjdCBnZW5lcmF0ZUxpc3Q8bnVtYmVyLCAxPgp7CiAgICB0eXBlZGVmIHR5cGVuYW1lIGNvbmNhdEN0cjwKICAgIAl0eXBlbmFtZSBnZW5lcmF0ZUxpc3Q8bnVtYmVyICsgMSwgMT46OmNvbnRhaW5lciwKICAgIAl0eXBlbmFtZSBzdGQ6OmNvbmRpdGlvbmFsPGlzVmFsaWROdW1iZXI8bnVtYmVyLCAxPjo6dmFsdWUsCiAgICAJCQlkaWdpdENvbnRhaW5lcjxudW1iZXI+LAogICAgCQkJZGlnaXRDb250YWluZXI8PgogICAgCQk+Ojp0eXBlCiAgICAJPjo6dHlwZSBjb250YWluZXI7Cn07CgojZGVmaW5lIERFRklORV9FTkRQT0lOVF9GT1JfTEVOR1RIKGxlbmd0aCkgdGVtcGxhdGU8PiBzdHJ1Y3QgZ2VuZXJhdGVMaXN0PHBvd09mMTAobGVuZ3RoKSwgKGxlbmd0aCk+e3R5cGVkZWYgZGlnaXRDb250YWluZXI8PiBjb250YWluZXI7fQoKdGVtcGxhdGU8aW50IGxlbmd0aD4Kc3RydWN0IGluc2FuaXR5CnsKICAgIHN0YXRpY19hc3NlcnQobGVuZ3RoID4gMCwgIkxlbmd0aCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwLiIpOwogICAgdHlwZWRlZiB0eXBlbmFtZSBjb25jYXRDdHI8dHlwZW5hbWUgZ2VuZXJhdGVMaXN0PDEsIGxlbmd0aD46OmNvbnRhaW5lciwgZGlnaXRDb250YWluZXI8MD4+Ojp0eXBlIG51bWJlckxpc3Q7Cn07Cgp0ZW1wbGF0ZTxpbnQgZmlyc3QsIGludC4uLiByZXN0Pgp2b2lkIG91dHB1dENvbnRhaW5lcihkaWdpdENvbnRhaW5lcjxmaXJzdCwgcmVzdC4uLj4gdmFsdWVzKQp7CglzdGQ6OmNvdXQ8PGZpcnN0PDwnXG4nOwogICAgb3V0cHV0Q29udGFpbmVyKGRpZ2l0Q29udGFpbmVyPHJlc3QuLi4+e30pOwp9Cgp2b2lkIG91dHB1dENvbnRhaW5lcihkaWdpdENvbnRhaW5lcjw+IGVtcHR5KQp7CiAgICBzdGQ6OmZsdXNoKHN0ZDo6Y291dCk7Cn0KREVGSU5FX0VORFBPSU5UX0ZPUl9MRU5HVEgoMSk7CkRFRklORV9FTkRQT0lOVF9GT1JfTEVOR1RIKDIpOwppbnQgbWFpbigpCnsKICAgIG91dHB1dENvbnRhaW5lcihpbnNhbml0eTwyPjo6bnVtYmVyTGlzdHt9KTsKfQ==