#include <cstddef>
#include <type_traits>
#include <iostream>
namespace detail {
template<typename>
constexpr std::size_t locate(std::size_t ind) {
return static_cast<std::size_t>(-1);
}
template<typename IndexedType, typename T, typename... Ts>
constexpr std::size_t locate(std::size_t ind = 0) {
if (std::is_same<IndexedType, T>::value) {
return ind;
} else {
return locate<IndexedType, Ts...>(ind + 1);
}
}
// This could also be useful.
// From a previous version of IndexOf, not used in the current version.
/*
template<typename IndexedType, typename...>
struct is_in : std::false_type {};
template<typename IndexedType, typename Item, typename... Items>
struct is_in<IndexedType, Item, Items...>
: std::integral_constant<bool,
std::is_same<IndexedType, Item>::value ||
is_in<IndexedType, Items...>::value> {};
*/
} // namespace detail
namespace mpl {
template<typename... Ts>
struct TypeList
{
static constexpr std::size_t size{ sizeof... (Ts) };
};
// -----
template<typename T, typename>
struct IndexOf;
template<typename T, typename... ListedTypes>
struct IndexOf<T, mpl::TypeList<ListedTypes...>>
: std::integral_constant<std::size_t, detail::locate<T, ListedTypes...>()>
{
};
} // 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
<< "\nint is type #" << IndexOf<int, Types>::value
<< std::endl;
// Double-checking with a different TypeList.
if (IndexOf<int, TypeList<char, bool, int, double>>::value == 2) {
std::cout << "Huzzah!\n";
}
}
I2luY2x1ZGUgPGNzdGRkZWY+CiNpbmNsdWRlIDx0eXBlX3RyYWl0cz4KI2luY2x1ZGUgPGlvc3RyZWFtPgoKbmFtZXNwYWNlIGRldGFpbCB7CiAgICB0ZW1wbGF0ZTx0eXBlbmFtZT4KICAgIGNvbnN0ZXhwciBzdGQ6OnNpemVfdCBsb2NhdGUoc3RkOjpzaXplX3QgaW5kKSB7CiAgICAgICAgcmV0dXJuIHN0YXRpY19jYXN0PHN0ZDo6c2l6ZV90PigtMSk7CiAgICB9CiAgICAKICAgIHRlbXBsYXRlPHR5cGVuYW1lIEluZGV4ZWRUeXBlLCB0eXBlbmFtZSBULCB0eXBlbmFtZS4uLiBUcz4KICAgIGNvbnN0ZXhwciBzdGQ6OnNpemVfdCBsb2NhdGUoc3RkOjpzaXplX3QgaW5kID0gMCkgewogICAgICAgIGlmIChzdGQ6OmlzX3NhbWU8SW5kZXhlZFR5cGUsIFQ+Ojp2YWx1ZSkgewogICAgICAgICAgICByZXR1cm4gaW5kOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBsb2NhdGU8SW5kZXhlZFR5cGUsIFRzLi4uPihpbmQgKyAxKTsKICAgICAgICB9CiAgICB9CiAgICAKICAgIC8vIFRoaXMgY291bGQgYWxzbyBiZSB1c2VmdWwuCiAgICAvLyBGcm9tIGEgcHJldmlvdXMgdmVyc2lvbiBvZiBJbmRleE9mLCBub3QgdXNlZCBpbiB0aGUgY3VycmVudCB2ZXJzaW9uLgovKgogICAgdGVtcGxhdGU8dHlwZW5hbWUgSW5kZXhlZFR5cGUsIHR5cGVuYW1lLi4uPgogICAgc3RydWN0IGlzX2luIDogc3RkOjpmYWxzZV90eXBlIHt9OwogICAgCiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBJbmRleGVkVHlwZSwgdHlwZW5hbWUgSXRlbSwgdHlwZW5hbWUuLi4gSXRlbXM+CiAgICBzdHJ1Y3QgaXNfaW48SW5kZXhlZFR5cGUsIEl0ZW0sIEl0ZW1zLi4uPgogICAgICA6IHN0ZDo6aW50ZWdyYWxfY29uc3RhbnQ8Ym9vbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6aXNfc2FtZTxJbmRleGVkVHlwZSwgSXRlbT46OnZhbHVlIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzX2luPEluZGV4ZWRUeXBlLCBJdGVtcy4uLj46OnZhbHVlPiB7fTsKICovCn0gLy8gbmFtZXNwYWNlIGRldGFpbAoKCm5hbWVzcGFjZSBtcGwgewogICAgdGVtcGxhdGU8dHlwZW5hbWUuLi4gVHM+CiAgICBzdHJ1Y3QgVHlwZUxpc3QKICAgIHsKICAgICAgICBzdGF0aWMgY29uc3RleHByIHN0ZDo6c2l6ZV90IHNpemV7IHNpemVvZi4uLiAoVHMpIH07CiAgICB9OwogICAgCiAgICAvLyAtLS0tLQoKICAgIHRlbXBsYXRlPHR5cGVuYW1lIFQsIHR5cGVuYW1lPgogICAgc3RydWN0IEluZGV4T2Y7CiAgICAKICAgIHRlbXBsYXRlPHR5cGVuYW1lIFQsIHR5cGVuYW1lLi4uIExpc3RlZFR5cGVzPgogICAgc3RydWN0IEluZGV4T2Y8VCwgbXBsOjpUeXBlTGlzdDxMaXN0ZWRUeXBlcy4uLj4+CiAgICAgIDogc3RkOjppbnRlZ3JhbF9jb25zdGFudDxzdGQ6OnNpemVfdCwgZGV0YWlsOjpsb2NhdGU8VCwgTGlzdGVkVHlwZXMuLi4+KCk+CiAgICB7CiAgICB9Owp9IC8vIG5hbWVzcGFjZSBtcGwKCnN0cnVjdCBUMQogICAgewogICAgfTsKCnN0cnVjdCBUMgogICAgICAgIHsKICAgICAgICB9OwoKc3RydWN0IFQzCiAgICAgICAgewogICAgICAgIH07Cgp1c2luZyBUeXBlcyA9IG1wbDo6VHlwZUxpc3Q8VDEsIFQyLCBUMz47CgppbnQgbWFpbigpIHsKICAgIHVzaW5nIG5hbWVzcGFjZSBtcGw7CiAgICAKICAgIHN0ZDo6Y291dCA8PCAiR2l2ZW4gVHlwZUxpc3Q8VDEsIFQyLCBUMz4uLi4iCiAgICAgICAgICAgICAgPDwgIlxuVDEgaXMgdHlwZSAjIiAgPDwgSW5kZXhPZjxUMSwgVHlwZXM+Ojp2YWx1ZQogICAgICAgICAgICAgIDw8ICJcblQyIGlzIHR5cGUgIyIgIDw8IEluZGV4T2Y8VDIsIFR5cGVzPjo6dmFsdWUKICAgICAgICAgICAgICA8PCAiXG5UMyBpcyB0eXBlICMiICA8PCBJbmRleE9mPFQzLCBUeXBlcz46OnZhbHVlCiAgICAgICAgICAgICAgPDwgIlxuaW50IGlzIHR5cGUgIyIgPDwgSW5kZXhPZjxpbnQsIFR5cGVzPjo6dmFsdWUKICAgICAgICAgICAgICA8PCBzdGQ6OmVuZGw7CiAgICAgICAgICAgICAgCiAgICAvLyBEb3VibGUtY2hlY2tpbmcgd2l0aCBhIGRpZmZlcmVudCBUeXBlTGlzdC4KICAgIGlmIChJbmRleE9mPGludCwgVHlwZUxpc3Q8Y2hhciwgYm9vbCwgaW50LCBkb3VibGU+Pjo6dmFsdWUgPT0gMikgewogICAgICAgIHN0ZDo6Y291dCA8PCAiSHV6emFoIVxuIjsKICAgIH0KfQ==