#include <cstddef>
#include <iostream>
#include <type_traits>
namespace mpl {
template<typename... Ts>
struct TypeList
{
static constexpr std::size_t size{ sizeof... (Ts) };
};
// -----
template<typename, typename>
struct IndexOf {};
// IndexOf base case: found the type we're looking for.
template <typename T, typename... Ts>
struct IndexOf<T, TypeList<T, Ts...>>
: std::integral_constant<std::size_t, 0>
{
};
// IndexOf recursive case: 1 + IndexOf the rest of the types.
template <typename T, typename TOther, typename... Ts>
struct IndexOf<T, TypeList<TOther, Ts...>>
: std::integral_constant<std::size_t,
1 + IndexOf<T, TypeList<Ts...>>::value>
{
};
} // namespace mpl
struct T1
{
};
struct T2
{
};
struct T3
{
};
using Types = mpl::TypeList<T1, T2, T3>;
int main() {
using namespace mpl;
std::cout << "Given TypeList<T1, T2, T3>..."
<< "\nT1 is type #" << IndexOf<T1, Types>::value
<< "\nT2 is type #" << IndexOf<T2, Types>::value
<< "\nT3 is type #" << IndexOf<T3, Types>::value
// Breaks if uncommented.
// << "\nint is type #" << IndexOf<int, Types>::value
<< std::endl;
}
I2luY2x1ZGUgPGNzdGRkZWY+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPHR5cGVfdHJhaXRzPgoKbmFtZXNwYWNlIG1wbCB7Cgl0ZW1wbGF0ZTx0eXBlbmFtZS4uLiBUcz4KCXN0cnVjdCBUeXBlTGlzdAoJewoJICAgIHN0YXRpYyBjb25zdGV4cHIgc3RkOjpzaXplX3Qgc2l6ZXsgc2l6ZW9mLi4uIChUcykgfTsKCX07CgkKCS8vIC0tLS0tCgkKCXRlbXBsYXRlPHR5cGVuYW1lLCB0eXBlbmFtZT4KCXN0cnVjdCBJbmRleE9mIHt9OwoJCgkvLyBJbmRleE9mIGJhc2UgY2FzZTogZm91bmQgdGhlIHR5cGUgd2UncmUgbG9va2luZyBmb3IuCgl0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUuLi4gVHM+CglzdHJ1Y3QgSW5kZXhPZjxULCBUeXBlTGlzdDxULCBUcy4uLj4+CgkgICAgOiBzdGQ6OmludGVncmFsX2NvbnN0YW50PHN0ZDo6c2l6ZV90LCAwPgoJewoJfTsKCQoJLy8gSW5kZXhPZiByZWN1cnNpdmUgY2FzZTogMSArIEluZGV4T2YgdGhlIHJlc3Qgb2YgdGhlIHR5cGVzLgoJdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIFRPdGhlciwgdHlwZW5hbWUuLi4gVHM+CglzdHJ1Y3QgSW5kZXhPZjxULCBUeXBlTGlzdDxUT3RoZXIsIFRzLi4uPj4KCSAgICA6IHN0ZDo6aW50ZWdyYWxfY29uc3RhbnQ8c3RkOjpzaXplX3QsCgkgICAgMSArIEluZGV4T2Y8VCwgVHlwZUxpc3Q8VHMuLi4+Pjo6dmFsdWU+Cgl7Cgl9Owp9IC8vIG5hbWVzcGFjZSBtcGwKCnN0cnVjdCBUMQogICAgewogICAgfTsKCnN0cnVjdCBUMgogICAgICAgIHsKICAgICAgICB9OwoKc3RydWN0IFQzCiAgICAgICAgewogICAgICAgIH07Cgp1c2luZyBUeXBlcyA9IG1wbDo6VHlwZUxpc3Q8VDEsIFQyLCBUMz47CgppbnQgbWFpbigpIHsKICAgIHVzaW5nIG5hbWVzcGFjZSBtcGw7CiAgICAKICAgIHN0ZDo6Y291dCA8PCAiR2l2ZW4gVHlwZUxpc3Q8VDEsIFQyLCBUMz4uLi4iCiAgICAgICAgICAgICAgPDwgIlxuVDEgaXMgdHlwZSAjIiAgPDwgSW5kZXhPZjxUMSwgVHlwZXM+Ojp2YWx1ZQogICAgICAgICAgICAgIDw8ICJcblQyIGlzIHR5cGUgIyIgIDw8IEluZGV4T2Y8VDIsIFR5cGVzPjo6dmFsdWUKICAgICAgICAgICAgICA8PCAiXG5UMyBpcyB0eXBlICMiICA8PCBJbmRleE9mPFQzLCBUeXBlcz46OnZhbHVlCgoJCQkgIC8vIEJyZWFrcyBpZiB1bmNvbW1lbnRlZC4KICAgICAgICAgICAgICAvLyA8PCAiXG5pbnQgaXMgdHlwZSAjIiA8PCBJbmRleE9mPGludCwgVHlwZXM+Ojp2YWx1ZQoKICAgICAgICAgICAgICA8PCBzdGQ6OmVuZGw7Cn0=