#include <tuple>
#include <iostream>
using namespace std;
typedef std::tuple<int,char,int> TupleType;
template<typename TupleT,typename OnElementHandler, size_t N>
struct TupleIterator{
static void call(const TupleT& tuple, OnElementHandler& OnElement){
auto nthElem = std::get<N>(tuple);
OnElement(nthElem);
TupleIterator<TupleT,OnElementHandler,N-1>::call(tuple,OnElement);
}
};
template<typename TupleT,typename OnElementHandler>
struct TupleIterator<TupleT,OnElementHandler,0>{
static void call(const TupleT& tuple, OnElementHandler& OnElement){
auto firstElem = std::get<0>(tuple);
OnElement(firstElem);
}
};
template<typename T1,typename T2>
struct IsSame{enum{result = 0};};
template<typename T>
struct IsSame<T,T>{ enum{result = 1}; };
template<typename T,size_t TargetCount, size_t BeginIndex, size_t EndIndex, typename Tuple>
T getNthTypeReverse(const Tuple& t, const T& defaultValue = T()){
//assert 0 <= N <= tuple.size
T result = defaultValue;
struct NthGrabber{
T& result;
const size_t n;
size_t count;
NthGrabber(T& r, const size_t n): result(r),n(n),count(0){}
void operator()(const int i){
if(IsSame<T,int>::result){
++count;
if(count == n) result = i;
}
}
void operator()(const char c){
if(IsSame<T,char>::result){
++count;
if(count == n) result = c;
}
}
//overload for other version too...
}OnElement(result,TargetCount+1); //WILL update result if condition meet
const size_t tupleSize = EndIndex - BeginIndex;
TupleIterator<TupleType,NthGrabber,tupleSize>::call(t,OnElement);
return result;
}
int main(){
TupleType t(10,'a',5);
const size_t tupleSize = std::tuple_size<decltype(t)>::value - 1;
int lastInt = getNthTypeReverse<int,0,0,tupleSize,TupleType>(t,-1);
int secondLastInt = getNthTypeReverse<int,1,0,tupleSize,TupleType>(t,-1);
int thirdLastInt = getNthTypeReverse<int,2,0,tupleSize,TupleType>(t,-1);
cout << "lastInt = " << lastInt << endl;
cout << "SecondLast = " << secondLastInt << endl;
cout << "ThirdLast = " << thirdLastInt << endl;
char lastChar = getNthTypeReverse<char,0,0,tupleSize,TupleType>(t,'\0');
cout << "LastChar = " << lastChar << endl;
return 0;
}
I2luY2x1ZGUgPHR1cGxlPgojaW5jbHVkZSA8aW9zdHJlYW0+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgp0eXBlZGVmIHN0ZDo6dHVwbGU8aW50LGNoYXIsaW50PiBUdXBsZVR5cGU7Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBUdXBsZVQsdHlwZW5hbWUgT25FbGVtZW50SGFuZGxlciwgc2l6ZV90IE4+CnN0cnVjdCBUdXBsZUl0ZXJhdG9yeyAgICAKICAgIHN0YXRpYyB2b2lkIGNhbGwoY29uc3QgVHVwbGVUJiB0dXBsZSwgT25FbGVtZW50SGFuZGxlciYgT25FbGVtZW50KXsgCiAgICAgICAgYXV0byBudGhFbGVtID0gc3RkOjpnZXQ8Tj4odHVwbGUpOwogICAgICAgIE9uRWxlbWVudChudGhFbGVtKTsgICAgICAgIAogICAgICAgIFR1cGxlSXRlcmF0b3I8VHVwbGVULE9uRWxlbWVudEhhbmRsZXIsTi0xPjo6Y2FsbCh0dXBsZSxPbkVsZW1lbnQpOwogICAgfQp9Owp0ZW1wbGF0ZTx0eXBlbmFtZSBUdXBsZVQsdHlwZW5hbWUgT25FbGVtZW50SGFuZGxlcj4Kc3RydWN0IFR1cGxlSXRlcmF0b3I8VHVwbGVULE9uRWxlbWVudEhhbmRsZXIsMD57ICAKICAgICBzdGF0aWMgdm9pZCBjYWxsKGNvbnN0IFR1cGxlVCYgdHVwbGUsIE9uRWxlbWVudEhhbmRsZXImIE9uRWxlbWVudCl7IAogICAgICAgIGF1dG8gZmlyc3RFbGVtID0gc3RkOjpnZXQ8MD4odHVwbGUpOyAgICAgICAgCiAgICAgICAgT25FbGVtZW50KGZpcnN0RWxlbSk7CiAgICB9Cn07CnRlbXBsYXRlPHR5cGVuYW1lIFQxLHR5cGVuYW1lIFQyPgpzdHJ1Y3QgSXNTYW1le2VudW17cmVzdWx0ID0gMH07fTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CnN0cnVjdCBJc1NhbWU8VCxUPnsgZW51bXtyZXN1bHQgPSAxfTsgfTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQsc2l6ZV90IFRhcmdldENvdW50LCBzaXplX3QgQmVnaW5JbmRleCwgc2l6ZV90IEVuZEluZGV4LCB0eXBlbmFtZSBUdXBsZT4KVCBnZXROdGhUeXBlUmV2ZXJzZShjb25zdCBUdXBsZSYgdCwgY29uc3QgVCYgZGVmYXVsdFZhbHVlID0gVCgpKXsKICAgIC8vYXNzZXJ0IDAgPD0gTiA8PSB0dXBsZS5zaXplCiAgICBUIHJlc3VsdCA9IGRlZmF1bHRWYWx1ZTsgICAgCiAgICBzdHJ1Y3QgTnRoR3JhYmJlcnsKICAgICAgIFQmIHJlc3VsdDsKICAgICAgIGNvbnN0IHNpemVfdCBuOwogICAgICAgc2l6ZV90IGNvdW50OwogICAgICAgTnRoR3JhYmJlcihUJiByLCBjb25zdCBzaXplX3Qgbik6IHJlc3VsdChyKSxuKG4pLGNvdW50KDApe30KICAgICAgIHZvaWQgb3BlcmF0b3IoKShjb25zdCBpbnQgaSl7CiAgICAgICAgICAgaWYoSXNTYW1lPFQsaW50Pjo6cmVzdWx0KXsKICAgICAgICAgICAgICAgKytjb3VudDsKICAgICAgICAgICAgICAgaWYoY291bnQgPT0gbikgcmVzdWx0ID0gaTsKICAgICAgICAgICB9CiAgICAgICAgICAgCiAgICAgICB9CiAgICAgICB2b2lkIG9wZXJhdG9yKCkoY29uc3QgY2hhciBjKXsKICAgICAgICAgICBpZihJc1NhbWU8VCxjaGFyPjo6cmVzdWx0KXsKICAgICAgICAgICAgICAgKytjb3VudDsKICAgICAgICAgICAgICAgaWYoY291bnQgPT0gbikgcmVzdWx0ID0gYzsKICAgICAgICAgICB9CiAgICAgICB9CiAgICAgICAvL292ZXJsb2FkIGZvciBvdGhlciB2ZXJzaW9uIHRvby4uLgogICAgfU9uRWxlbWVudChyZXN1bHQsVGFyZ2V0Q291bnQrMSk7IC8vV0lMTCB1cGRhdGUgcmVzdWx0IGlmIGNvbmRpdGlvbiBtZWV0CiAgICBjb25zdCBzaXplX3QgdHVwbGVTaXplID0gRW5kSW5kZXggLSBCZWdpbkluZGV4OwogICAgVHVwbGVJdGVyYXRvcjxUdXBsZVR5cGUsTnRoR3JhYmJlcix0dXBsZVNpemU+OjpjYWxsKHQsT25FbGVtZW50KTsgCiAgICByZXR1cm4gcmVzdWx0Owp9CmludCBtYWluKCl7CiAgICBUdXBsZVR5cGUgdCgxMCwnYScsNSk7ICAgIAogICAgY29uc3Qgc2l6ZV90IHR1cGxlU2l6ZSA9IHN0ZDo6dHVwbGVfc2l6ZTxkZWNsdHlwZSh0KT46OnZhbHVlIC0gMTsKICAgIGludCBsYXN0SW50ID0gZ2V0TnRoVHlwZVJldmVyc2U8aW50LDAsMCx0dXBsZVNpemUsVHVwbGVUeXBlPih0LC0xKTsgCiAgICBpbnQgc2Vjb25kTGFzdEludCA9IGdldE50aFR5cGVSZXZlcnNlPGludCwxLDAsdHVwbGVTaXplLFR1cGxlVHlwZT4odCwtMSk7IAoJaW50IHRoaXJkTGFzdEludCA9IGdldE50aFR5cGVSZXZlcnNlPGludCwyLDAsdHVwbGVTaXplLFR1cGxlVHlwZT4odCwtMSk7IAogICAgY291dCA8PCAibGFzdEludCA9ICIgPDwgbGFzdEludCA8PCBlbmRsOwkKCWNvdXQgPDwgIlNlY29uZExhc3QgPSAiIDw8IHNlY29uZExhc3RJbnQgPDwgZW5kbDsKCWNvdXQgPDwgIlRoaXJkTGFzdCA9ICIgPDwgdGhpcmRMYXN0SW50IDw8IGVuZGw7CgkKCWNoYXIgbGFzdENoYXIgPSBnZXROdGhUeXBlUmV2ZXJzZTxjaGFyLDAsMCx0dXBsZVNpemUsVHVwbGVUeXBlPih0LCdcMCcpOyAKCWNvdXQgPDwgIkxhc3RDaGFyID0gIiAgPDwgbGFzdENoYXIgPDwgZW5kbDsKICAgIAogICAgcmV0dXJuIDA7Cn0=