#include <iostream>
#include <utility>
#include <type_traits>
enum class values {
zero = 7,
one = 3,
two = 1,
three = -7,
four = 2,
five = 4,
};
template<class T, T... ts> struct list {typedef list type;};
template<unsigned max, unsigned... ts> struct make_indexes:make_indexes<max-1, max-1, ts...>{};
template<unsigned... ts> struct make_indexes<0, ts...>:list<unsigned, ts...> {};
template<unsigned max> using make_indexes_t=typename make_indexes<max>::type;
template<class list> struct length_of;
template<class T, T... ts> struct length_of<list<T, ts...>>:std::integral_constant<unsigned, sizeof...(ts)> {};
template<class T, T t, class list> struct index_of;
template<class T, T t, T t0, T...ts> struct index_of<T, t, list<T, t0, ts...>>:
std::integral_constant< unsigned, index_of<T, t, list<T, ts...>>::value+1 >
{};
template<class T, T t, T...ts> struct index_of<T, t, list<T, t, ts...>>:
std::integral_constant< unsigned, 1 >
{};
template<class T, unsigned N, class list> struct value_at;
template<class T, unsigned N, T t0, T... ts> struct value_at<T, N, list<T, t0, ts...>>:value_at<T, N-1, list<T, ts...>> {};
template<class T, T t0, T... ts> struct value_at<T, 0, list<T, t0, ts...>>:std::integral_constant<T, t0> {};
template<class T> struct summable {};
template<> struct summable<values> {
typedef values T;
typedef list<T, T::zero, T::one, T::two, T::three, T::four, T::five> list_type;
template<T t>
using index = index_of< T, t, list_type >;
template<unsigned N>
using value = value_at< T, N, list_type >;
};
template<class T, template<T>class indexer>
unsigned index( T t, list<T> ) {
return -1;
}
template<class T, template<T>class indexer, T t0, T... ts>
unsigned index( T t, list<T, t0, ts...> ) {
if (t==t0)
return indexer<t0>::value;
else
return index<T, indexer>( t, list<T, ts...>{} );
}
template<class T, template<unsigned>class valuer>
T value( unsigned N, list<unsigned> ) {
return static_cast<T>(-1);
}
template<class T, template<unsigned>class valuer, unsigned M0, unsigned... Ms>
T value( unsigned N, list<unsigned, M0, Ms...> ) {
if (N-1==M0)
return valuer<M0>::value;
else
return value<T, valuer>( N, list<unsigned, Ms...>{} );
}
template<typename T>
T sum( T lhs, T rhs ) {
typedef typename summable<T>::list_type list_type;
return value<T, summable<T>::template value>( index<T, summable<T>::template index>(lhs, list_type{})+index<values, summable<T>::template index>(rhs, list_type{}), make_indexes_t<length_of<list_type>::value>{} );
}
template<typename T, typename=typename summable<T>::list_type >
T operator+( T lhs, T rhs ) {
return sum( lhs, rhs );
}
int main() {
auto two = values::two;
auto five = values::five;
std::cout << (two+two==five) << "\n";
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dXRpbGl0eT4KI2luY2x1ZGUgPHR5cGVfdHJhaXRzPgoKZW51bSBjbGFzcyB2YWx1ZXMgewoJemVybyA9IDcsCglvbmUgPSAzLAoJdHdvID0gMSwKCXRocmVlID0gLTcsCglmb3VyID0gMiwKCWZpdmUgPSA0LAp9OwoKdGVtcGxhdGU8Y2xhc3MgVCwgVC4uLiB0cz4gc3RydWN0IGxpc3Qge3R5cGVkZWYgbGlzdCB0eXBlO307CnRlbXBsYXRlPHVuc2lnbmVkIG1heCwgdW5zaWduZWQuLi4gdHM+IHN0cnVjdCBtYWtlX2luZGV4ZXM6bWFrZV9pbmRleGVzPG1heC0xLCBtYXgtMSwgdHMuLi4+e307CnRlbXBsYXRlPHVuc2lnbmVkLi4uIHRzPiBzdHJ1Y3QgbWFrZV9pbmRleGVzPDAsIHRzLi4uPjpsaXN0PHVuc2lnbmVkLCB0cy4uLj4ge307CnRlbXBsYXRlPHVuc2lnbmVkIG1heD4gdXNpbmcgbWFrZV9pbmRleGVzX3Q9dHlwZW5hbWUgbWFrZV9pbmRleGVzPG1heD46OnR5cGU7Cgp0ZW1wbGF0ZTxjbGFzcyBsaXN0PiBzdHJ1Y3QgbGVuZ3RoX29mOwp0ZW1wbGF0ZTxjbGFzcyBULCBULi4uIHRzPiBzdHJ1Y3QgbGVuZ3RoX29mPGxpc3Q8VCwgdHMuLi4+PjpzdGQ6OmludGVncmFsX2NvbnN0YW50PHVuc2lnbmVkLCBzaXplb2YuLi4odHMpPiB7fTsKCnRlbXBsYXRlPGNsYXNzIFQsIFQgdCwgY2xhc3MgbGlzdD4gc3RydWN0IGluZGV4X29mOwp0ZW1wbGF0ZTxjbGFzcyBULCBUIHQsIFQgdDAsIFQuLi50cz4gc3RydWN0IGluZGV4X29mPFQsIHQsIGxpc3Q8VCwgdDAsIHRzLi4uPj46CglzdGQ6OmludGVncmFsX2NvbnN0YW50PCB1bnNpZ25lZCwgaW5kZXhfb2Y8VCwgdCwgbGlzdDxULCB0cy4uLj4+Ojp2YWx1ZSsxID4Ke307CnRlbXBsYXRlPGNsYXNzIFQsIFQgdCwgVC4uLnRzPiBzdHJ1Y3QgaW5kZXhfb2Y8VCwgdCwgbGlzdDxULCB0LCB0cy4uLj4+OgoJc3RkOjppbnRlZ3JhbF9jb25zdGFudDwgdW5zaWduZWQsIDEgPgp7fTsKdGVtcGxhdGU8Y2xhc3MgVCwgdW5zaWduZWQgTiwgY2xhc3MgbGlzdD4gc3RydWN0IHZhbHVlX2F0Owp0ZW1wbGF0ZTxjbGFzcyBULCB1bnNpZ25lZCBOLCBUIHQwLCBULi4uIHRzPiBzdHJ1Y3QgdmFsdWVfYXQ8VCwgTiwgbGlzdDxULCB0MCwgdHMuLi4+Pjp2YWx1ZV9hdDxULCBOLTEsIGxpc3Q8VCwgdHMuLi4+PiB7fTsKdGVtcGxhdGU8Y2xhc3MgVCwgVCB0MCwgVC4uLiB0cz4gc3RydWN0IHZhbHVlX2F0PFQsIDAsIGxpc3Q8VCwgdDAsIHRzLi4uPj46c3RkOjppbnRlZ3JhbF9jb25zdGFudDxULCB0MD4ge307Cgp0ZW1wbGF0ZTxjbGFzcyBUPiBzdHJ1Y3Qgc3VtbWFibGUge307CnRlbXBsYXRlPD4gc3RydWN0IHN1bW1hYmxlPHZhbHVlcz4gewogIHR5cGVkZWYgdmFsdWVzIFQ7CiAgdHlwZWRlZiBsaXN0PFQsIFQ6Onplcm8sIFQ6Om9uZSwgVDo6dHdvLCBUOjp0aHJlZSwgVDo6Zm91ciwgVDo6Zml2ZT4gbGlzdF90eXBlOwogIHRlbXBsYXRlPFQgdD4KICB1c2luZyBpbmRleCA9IGluZGV4X29mPCBULCB0LCBsaXN0X3R5cGUgPjsKICB0ZW1wbGF0ZTx1bnNpZ25lZCBOPgogIHVzaW5nIHZhbHVlID0gdmFsdWVfYXQ8IFQsIE4sIGxpc3RfdHlwZSA+Owp9OwoKdGVtcGxhdGU8Y2xhc3MgVCwgdGVtcGxhdGU8VD5jbGFzcyBpbmRleGVyPgp1bnNpZ25lZCBpbmRleCggVCB0LCBsaXN0PFQ+ICkgewoJcmV0dXJuIC0xOwp9Cgp0ZW1wbGF0ZTxjbGFzcyBULCB0ZW1wbGF0ZTxUPmNsYXNzIGluZGV4ZXIsIFQgdDAsIFQuLi4gdHM+CnVuc2lnbmVkIGluZGV4KCBUIHQsIGxpc3Q8VCwgdDAsIHRzLi4uPiApIHsKCWlmICh0PT10MCkKCQlyZXR1cm4gaW5kZXhlcjx0MD46OnZhbHVlOwoJZWxzZQoJCXJldHVybiBpbmRleDxULCBpbmRleGVyPiggdCwgbGlzdDxULCB0cy4uLj57fSApOwp9Cgp0ZW1wbGF0ZTxjbGFzcyBULCB0ZW1wbGF0ZTx1bnNpZ25lZD5jbGFzcyB2YWx1ZXI+ClQgdmFsdWUoIHVuc2lnbmVkIE4sIGxpc3Q8dW5zaWduZWQ+ICkgewoJcmV0dXJuIHN0YXRpY19jYXN0PFQ+KC0xKTsKfQp0ZW1wbGF0ZTxjbGFzcyBULCB0ZW1wbGF0ZTx1bnNpZ25lZD5jbGFzcyB2YWx1ZXIsIHVuc2lnbmVkIE0wLCB1bnNpZ25lZC4uLiBNcz4KVCB2YWx1ZSggdW5zaWduZWQgTiwgbGlzdDx1bnNpZ25lZCwgTTAsIE1zLi4uPiApIHsKCWlmIChOLTE9PU0wKQoJCXJldHVybiB2YWx1ZXI8TTA+Ojp2YWx1ZTsKCWVsc2UKCQlyZXR1cm4gdmFsdWU8VCwgdmFsdWVyPiggTiwgbGlzdDx1bnNpZ25lZCwgTXMuLi4+e30gKTsKfQoKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+ClQgc3VtKCBUIGxocywgVCByaHMgKSB7Cgl0eXBlZGVmIHR5cGVuYW1lIHN1bW1hYmxlPFQ+OjpsaXN0X3R5cGUgbGlzdF90eXBlOwoJcmV0dXJuIHZhbHVlPFQsIHN1bW1hYmxlPFQ+Ojp0ZW1wbGF0ZSB2YWx1ZT4oIGluZGV4PFQsIHN1bW1hYmxlPFQ+Ojp0ZW1wbGF0ZSBpbmRleD4obGhzLCBsaXN0X3R5cGV7fSkraW5kZXg8dmFsdWVzLCBzdW1tYWJsZTxUPjo6dGVtcGxhdGUgaW5kZXg+KHJocywgbGlzdF90eXBle30pLCBtYWtlX2luZGV4ZXNfdDxsZW5ndGhfb2Y8bGlzdF90eXBlPjo6dmFsdWU+e30gKTsKfQoKdGVtcGxhdGU8dHlwZW5hbWUgVCwgdHlwZW5hbWU9dHlwZW5hbWUgc3VtbWFibGU8VD46Omxpc3RfdHlwZSA+ClQgb3BlcmF0b3IrKCBUIGxocywgVCByaHMgKSB7CglyZXR1cm4gc3VtKCBsaHMsIHJocyApOwp9CgppbnQgbWFpbigpIHsKCWF1dG8gdHdvID0gdmFsdWVzOjp0d287CglhdXRvIGZpdmUgPSB2YWx1ZXM6OmZpdmU7CglzdGQ6OmNvdXQgPDwgKHR3byt0d289PWZpdmUpIDw8ICJcbiI7CglyZXR1cm4gMDsKfQ==