fork download
  1. #include <tuple>
  2. #include <iostream>
  3. using namespace std;
  4.  
  5. typedef std::tuple<int,char,int> TupleType;
  6.  
  7. template<typename TupleT,typename OnElementHandler, size_t N>
  8. struct TupleIterator{
  9. static void call(const TupleT& tuple, OnElementHandler& OnElement){
  10. auto nthElem = std::get<N>(tuple);
  11. OnElement(nthElem);
  12. TupleIterator<TupleT,OnElementHandler,N-1>::call(tuple,OnElement);
  13. }
  14. };
  15. template<typename TupleT,typename OnElementHandler>
  16. struct TupleIterator<TupleT,OnElementHandler,0>{
  17. static void call(const TupleT& tuple, OnElementHandler& OnElement){
  18. auto firstElem = std::get<0>(tuple);
  19. OnElement(firstElem);
  20. }
  21. };
  22. template<typename T1,typename T2>
  23. struct IsSame{enum{result = 0};};
  24.  
  25. template<typename T>
  26. struct IsSame<T,T>{ enum{result = 1}; };
  27.  
  28. template<typename T,size_t TargetCount, size_t BeginIndex, size_t EndIndex, typename Tuple>
  29. T getNthTypeReverse(const Tuple& t, const T& defaultValue = T()){
  30. //assert 0 <= N <= tuple.size
  31. T result = defaultValue;
  32. struct NthGrabber{
  33. T& result;
  34. const size_t n;
  35. size_t count;
  36. NthGrabber(T& r, const size_t n): result(r),n(n),count(0){}
  37. void operator()(const int i){
  38. if(IsSame<T,int>::result){
  39. ++count;
  40. if(count == n) result = i;
  41. }
  42.  
  43. }
  44. void operator()(const char c){
  45. if(IsSame<T,char>::result){
  46. ++count;
  47. if(count == n) result = c;
  48. }
  49. }
  50. //overload for other version too...
  51. }OnElement(result,TargetCount+1); //WILL update result if condition meet
  52. const size_t tupleSize = EndIndex - BeginIndex;
  53. TupleIterator<TupleType,NthGrabber,tupleSize>::call(t,OnElement);
  54. return result;
  55. }
  56. int main(){
  57. TupleType t(10,'a',5);
  58. const size_t tupleSize = std::tuple_size<decltype(t)>::value - 1;
  59. int lastInt = getNthTypeReverse<int,0,0,tupleSize,TupleType>(t,-1);
  60. int secondLastInt = getNthTypeReverse<int,1,0,tupleSize,TupleType>(t,-1);
  61. int thirdLastInt = getNthTypeReverse<int,2,0,tupleSize,TupleType>(t,-1);
  62. cout << "lastInt = " << lastInt << endl;
  63. cout << "SecondLast = " << secondLastInt << endl;
  64. cout << "ThirdLast = " << thirdLastInt << endl;
  65.  
  66. char lastChar = getNthTypeReverse<char,0,0,tupleSize,TupleType>(t,'\0');
  67. cout << "LastChar = " << lastChar << endl;
  68.  
  69. return 0;
  70. }
Success #stdin #stdout 0s 2896KB
stdin
Standard input is empty
stdout
lastInt = 5
SecondLast = 10
ThirdLast = -1
LastChar = a