#include <typeinfo>
#include <iostream>
using namespace std;
template <typename typed, int i> struct enumerate
{
static auto get(typed x) -> decltype(x.template get<i>()) { return x.template get<i>(); };
const static auto next = 0;
const static bool has_next = !is_same<decltype(typed().template get<i+1>()), void>::value;
};
struct smth
{
template <int i> struct key_t {};
template <int i> void get(key_t<i>) {}
int x; int get(key_t<1>) { return this->x; }
double y; double get(key_t<2>) { return this->y; }
template <int i> auto get() -> decltype(this->get(key_t<i>())) { return this->get(key_t<i>()); }
};
int main()
{
smth s = {1, 2.5};
cout.setf(ios::boolalpha);
cout << s.x << ' ' << s.y << endl;
cout << s.get<1>() << ' ' << s.get<2>() << endl;
cout << endl;
cout << enumerate<smth, 1>::get(s) << ' ' << enumerate<smth, 1>::has_next << endl;
cout << enumerate<smth, 2>::get(s) << ' ' << enumerate<smth, 2>::has_next << endl;
return 0;
}
I2luY2x1ZGUgPHR5cGVpbmZvPgojaW5jbHVkZSA8aW9zdHJlYW0+Cgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKdGVtcGxhdGUgPHR5cGVuYW1lIHR5cGVkLCBpbnQgaT4gc3RydWN0IGVudW1lcmF0ZQp7CglzdGF0aWMgYXV0byBnZXQodHlwZWQgeCkgLT4gZGVjbHR5cGUoeC50ZW1wbGF0ZSBnZXQ8aT4oKSkgeyByZXR1cm4geC50ZW1wbGF0ZSBnZXQ8aT4oKTsgfTsKCWNvbnN0IHN0YXRpYyBhdXRvIG5leHQgPSAwOwoJY29uc3Qgc3RhdGljIGJvb2wgaGFzX25leHQgPSAhaXNfc2FtZTxkZWNsdHlwZSh0eXBlZCgpLnRlbXBsYXRlIGdldDxpKzE+KCkpLCB2b2lkPjo6dmFsdWU7Cn07CgpzdHJ1Y3Qgc210aAp7Cgl0ZW1wbGF0ZSA8aW50IGk+IHN0cnVjdCBrZXlfdCB7fTsKCQoJdGVtcGxhdGUgPGludCBpPiB2b2lkIGdldChrZXlfdDxpPikge30KCQoJaW50IHg7IGludCBnZXQoa2V5X3Q8MT4pIHsgcmV0dXJuIHRoaXMtPng7IH0KCWRvdWJsZSB5OyBkb3VibGUgZ2V0KGtleV90PDI+KSB7IHJldHVybiB0aGlzLT55OyB9CgkKCXRlbXBsYXRlIDxpbnQgaT4gYXV0byBnZXQoKSAtPiBkZWNsdHlwZSh0aGlzLT5nZXQoa2V5X3Q8aT4oKSkpIHsgcmV0dXJuIHRoaXMtPmdldChrZXlfdDxpPigpKTsgfQp9OwoKaW50IG1haW4oKQp7CglzbXRoIHMgPSB7MSwgMi41fTsKCQoJY291dC5zZXRmKGlvczo6Ym9vbGFscGhhKTsKCQoJY291dCA8PCBzLnggPDwgJyAnIDw8IHMueSA8PCBlbmRsOwoJY291dCA8PCBzLmdldDwxPigpIDw8ICcgJyA8PCBzLmdldDwyPigpIDw8IGVuZGw7Cgljb3V0IDw8IGVuZGw7Cgljb3V0IDw8IGVudW1lcmF0ZTxzbXRoLCAxPjo6Z2V0KHMpIDw8ICcgJyA8PCBlbnVtZXJhdGU8c210aCwgMT46Omhhc19uZXh0IDw8IGVuZGw7Cgljb3V0IDw8IGVudW1lcmF0ZTxzbXRoLCAyPjo6Z2V0KHMpIDw8ICcgJyA8PCBlbnVtZXJhdGU8c210aCwgMj46Omhhc19uZXh0IDw8IGVuZGw7CgkKCXJldHVybiAwOwp9