#include<tuple>
#include<type_traits>
#include<string>
#include<iostream>
template<bool b, typename T=void>
using EnableIf = typename std::enable_if<b,T>::type;
template<int Index, template<typename T>class Search, int Which, typename, class First, class... Types>
struct get_internal:
get_internal<Index + 1, Search, Which, void, Types...>
{};
template<int Index, template<typename T>class Search, int Which, class First, class... Types>
struct get_internal<Index, Search, Which, EnableIf<!Search<First>::value>, First, Types...>:
get_internal<Index + 1, Search, Which, void, Types...>
{};
template<int Index, template<typename T>class Search, int Which, class First, class... Types>
struct get_internal<Index, Search, Which, EnableIf<Search<First>::value>, First, Types...>:
get_internal<Index + 1, Search, Which-1, void, Types...>
{};
template<int Index, template<typename T>class Search, class First, class... Types>
struct get_internal<Index, Search, 0, EnableIf<Search<First>::value>, First, Types...>:
std::integral_constant<int, Index>
{
typedef get_internal type;
};
template<template<typename>class Test, int Which=0, class... Types>
auto get(std::tuple<Types...> tuple)->
decltype(std::get<get_internal<0,Test,Which,void,Types...>::value>(tuple))
{
return std::get<get_internal<0,Test,Which,void,Types...>::value>(tuple);
}
template<typename T>
struct is_type {
template<typename U>
using test = std::is_same<T,U>;
};
template<class T, int Which=0, class... Types>
T get(std::tuple<Types...> tuple)
{
return get<is_type<T>::template test,Which>(tuple);
}
int main()
{
std::tuple<int, double, std::string, int, long> test{1, 1.7, "test", 7, 3};
std::cout<<"get<0> == get<int> :"<< (std::get<0>(test) == get<int>(test))<< "\n";
std::cout<<"get<3> == get<int,1> :"<< (std::get<3>(test) == get<int,1>(test))<< "\n";
std::cout<<"get<1> == get<double> :"<<(std::get<1>(test) == get<double>(test))<< "\n";
std::cout<<"get<2> == get<std::string> :"<<(std::get<2>(test) == get<std::string>(test))<< "\n";
std::cout<<"get<0> == get<std::is_integral> :"<< (std::get<0>(test) == get<std::is_integral>(test))<< "\n";
std::cout<<"get<3> == get<std::is_integral,1> :"<< (std::get<3>(test) == get<std::is_integral,1>(test))<< "\n";
std::cout<<"get<4> == get<std::is_integral,2> :"<< (std::get<4>(test) == get<std::is_integral,2>(test))<< "\n";
}
I2luY2x1ZGU8dHVwbGU+CiNpbmNsdWRlPHR5cGVfdHJhaXRzPgojaW5jbHVkZTxzdHJpbmc+CiNpbmNsdWRlPGlvc3RyZWFtPgoKdGVtcGxhdGU8Ym9vbCBiLCB0eXBlbmFtZSBUPXZvaWQ+CnVzaW5nIEVuYWJsZUlmID0gdHlwZW5hbWUgc3RkOjplbmFibGVfaWY8YixUPjo6dHlwZTsKCnRlbXBsYXRlPGludCBJbmRleCwgdGVtcGxhdGU8dHlwZW5hbWUgVD5jbGFzcyBTZWFyY2gsIGludCBXaGljaCwgdHlwZW5hbWUsIGNsYXNzIEZpcnN0LCBjbGFzcy4uLiBUeXBlcz4Kc3RydWN0IGdldF9pbnRlcm5hbDoKICAgIGdldF9pbnRlcm5hbDxJbmRleCArIDEsIFNlYXJjaCwgV2hpY2gsIHZvaWQsIFR5cGVzLi4uPgp7fTsKCnRlbXBsYXRlPGludCBJbmRleCwgdGVtcGxhdGU8dHlwZW5hbWUgVD5jbGFzcyBTZWFyY2gsIGludCBXaGljaCwgY2xhc3MgRmlyc3QsIGNsYXNzLi4uIFR5cGVzPgpzdHJ1Y3QgZ2V0X2ludGVybmFsPEluZGV4LCBTZWFyY2gsIFdoaWNoLCBFbmFibGVJZjwhU2VhcmNoPEZpcnN0Pjo6dmFsdWU+LCBGaXJzdCwgVHlwZXMuLi4+OgogICAgZ2V0X2ludGVybmFsPEluZGV4ICsgMSwgU2VhcmNoLCBXaGljaCwgdm9pZCwgVHlwZXMuLi4+Cnt9Owp0ZW1wbGF0ZTxpbnQgSW5kZXgsIHRlbXBsYXRlPHR5cGVuYW1lIFQ+Y2xhc3MgU2VhcmNoLCBpbnQgV2hpY2gsIGNsYXNzIEZpcnN0LCBjbGFzcy4uLiBUeXBlcz4Kc3RydWN0IGdldF9pbnRlcm5hbDxJbmRleCwgU2VhcmNoLCBXaGljaCwgRW5hYmxlSWY8U2VhcmNoPEZpcnN0Pjo6dmFsdWU+LCBGaXJzdCwgVHlwZXMuLi4+OgogICAgZ2V0X2ludGVybmFsPEluZGV4ICsgMSwgU2VhcmNoLCBXaGljaC0xLCB2b2lkLCBUeXBlcy4uLj4Ke307CnRlbXBsYXRlPGludCBJbmRleCwgdGVtcGxhdGU8dHlwZW5hbWUgVD5jbGFzcyBTZWFyY2gsIGNsYXNzIEZpcnN0LCBjbGFzcy4uLiBUeXBlcz4Kc3RydWN0IGdldF9pbnRlcm5hbDxJbmRleCwgU2VhcmNoLCAwLCBFbmFibGVJZjxTZWFyY2g8Rmlyc3Q+Ojp2YWx1ZT4sIEZpcnN0LCBUeXBlcy4uLj46CiAgICBzdGQ6OmludGVncmFsX2NvbnN0YW50PGludCwgSW5kZXg+CnsKICAgIHR5cGVkZWYgZ2V0X2ludGVybmFsIHR5cGU7Cn07Cgp0ZW1wbGF0ZTx0ZW1wbGF0ZTx0eXBlbmFtZT5jbGFzcyBUZXN0LCBpbnQgV2hpY2g9MCwgY2xhc3MuLi4gVHlwZXM+CmF1dG8gZ2V0KHN0ZDo6dHVwbGU8VHlwZXMuLi4+IHR1cGxlKS0+CiAgZGVjbHR5cGUoc3RkOjpnZXQ8Z2V0X2ludGVybmFsPDAsVGVzdCxXaGljaCx2b2lkLFR5cGVzLi4uPjo6dmFsdWU+KHR1cGxlKSkKewogICAgcmV0dXJuIHN0ZDo6Z2V0PGdldF9pbnRlcm5hbDwwLFRlc3QsV2hpY2gsdm9pZCxUeXBlcy4uLj46OnZhbHVlPih0dXBsZSk7Cn0KCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CnN0cnVjdCBpc190eXBlIHsKICB0ZW1wbGF0ZTx0eXBlbmFtZSBVPgogIHVzaW5nIHRlc3QgPSBzdGQ6OmlzX3NhbWU8VCxVPjsKfTsKCnRlbXBsYXRlPGNsYXNzIFQsIGludCBXaGljaD0wLCBjbGFzcy4uLiBUeXBlcz4KVCBnZXQoc3RkOjp0dXBsZTxUeXBlcy4uLj4gdHVwbGUpCnsKICAgIHJldHVybiBnZXQ8aXNfdHlwZTxUPjo6dGVtcGxhdGUgdGVzdCxXaGljaD4odHVwbGUpOwp9CgppbnQgbWFpbigpCnsKICAgIHN0ZDo6dHVwbGU8aW50LCBkb3VibGUsIHN0ZDo6c3RyaW5nLCBpbnQsIGxvbmc+IHRlc3R7MSwgMS43LCAidGVzdCIsIDcsIDN9OwogICAgc3RkOjpjb3V0PDwiZ2V0PDA+ID09IGdldDxpbnQ+IDoiPDwgKHN0ZDo6Z2V0PDA+KHRlc3QpID09IGdldDxpbnQ+KHRlc3QpKTw8ICJcbiI7CiAgICBzdGQ6OmNvdXQ8PCJnZXQ8Mz4gPT0gZ2V0PGludCwxPiA6Ijw8IChzdGQ6OmdldDwzPih0ZXN0KSA9PSBnZXQ8aW50LDE+KHRlc3QpKTw8ICJcbiI7CiAgICBzdGQ6OmNvdXQ8PCJnZXQ8MT4gPT0gZ2V0PGRvdWJsZT4gOiI8PChzdGQ6OmdldDwxPih0ZXN0KSA9PSBnZXQ8ZG91YmxlPih0ZXN0KSk8PCAiXG4iOwogICAgc3RkOjpjb3V0PDwiZ2V0PDI+ID09IGdldDxzdGQ6OnN0cmluZz4gOiI8PChzdGQ6OmdldDwyPih0ZXN0KSA9PSBnZXQ8c3RkOjpzdHJpbmc+KHRlc3QpKTw8ICJcbiI7CiAgICBzdGQ6OmNvdXQ8PCJnZXQ8MD4gPT0gZ2V0PHN0ZDo6aXNfaW50ZWdyYWw+IDoiPDwgKHN0ZDo6Z2V0PDA+KHRlc3QpID09IGdldDxzdGQ6OmlzX2ludGVncmFsPih0ZXN0KSk8PCAiXG4iOwogICAgc3RkOjpjb3V0PDwiZ2V0PDM+ID09IGdldDxzdGQ6OmlzX2ludGVncmFsLDE+IDoiPDwgKHN0ZDo6Z2V0PDM+KHRlc3QpID09IGdldDxzdGQ6OmlzX2ludGVncmFsLDE+KHRlc3QpKTw8ICJcbiI7CiAgICBzdGQ6OmNvdXQ8PCJnZXQ8ND4gPT0gZ2V0PHN0ZDo6aXNfaW50ZWdyYWwsMj4gOiI8PCAoc3RkOjpnZXQ8ND4odGVzdCkgPT0gZ2V0PHN0ZDo6aXNfaW50ZWdyYWwsMj4odGVzdCkpPDwgIlxuIjsKfQ==