fork download
  1. #include <tuple>
  2. #include <iostream>
  3.  
  4. struct A {
  5. static void tip();
  6. };
  7.  
  8. struct B {
  9. static void tip();
  10. };
  11.  
  12. struct Z {
  13. };
  14.  
  15. // Indicates whether the template parameter contains a static member named tip.
  16. template<class T>
  17. struct has_tip {
  18. template<class U>
  19. struct clean_type {
  20. typedef typename std::remove_const<typename std::remove_reference<U>::type>::type type;
  21. };
  22.  
  23. template<class U>
  24. static char test(decltype(&U::tip));
  25.  
  26. template<class U>
  27. static float test(...);
  28.  
  29. static const bool value = sizeof(test<typename clean_type<T>::type>(0)) == sizeof(char);
  30. };
  31.  
  32. // Indicates whether the n-th type contains a tip static member
  33. template<size_t n, typename... Ts>
  34. struct nth_type_has_tip {
  35. static const bool value = has_tip<typename std::tuple_element<n, std::tuple<Ts...>>::type>::value;
  36. };
  37.  
  38. // Generic iteration
  39. template<size_t index, size_t n>
  40. struct TupleIter
  41. {
  42. template< typename... Ts >
  43. typename std::enable_if< nth_type_has_tip<index, Ts...>::value , void >::type
  44. static Iter(const std::tuple<Ts...>& tpl)
  45. {
  46. std::cout << "tip\n";
  47. TupleIter<index + 1, n>::Iter(tpl );
  48. }
  49.  
  50. template< typename... Ts >
  51. typename std::enable_if< !nth_type_has_tip<index, Ts...>::value , void >::type
  52. static Iter(const std::tuple<Ts...>& tpl) {
  53. std::cout << "no tip\n";
  54. TupleIter<index + 1, n>::Iter(tpl );
  55. }
  56. };
  57.  
  58. // Base class, we've reached the tuple end
  59. template<size_t n>
  60. struct TupleIter<n, n>
  61. {
  62. template<typename... Ts >
  63. static void Iter( const std::tuple<Ts...>& tpl ) {
  64. std::cout << "end\n";
  65. }
  66. };
  67.  
  68. // Helper function that forwards the first call to TupleIter<>::Iter
  69. template<typename... Ts>
  70. void iterate(const std::tuple<Ts...> &tup) {
  71. TupleIter<0, sizeof...(Ts)>::Iter(tup);
  72. }
  73.  
  74. int main() {
  75. A a;
  76. B b;
  77. Z z;
  78. std::tuple<const A&,const B&,const Z&> tup(a,b,z);
  79. iterate(tup);
  80. }
  81.  
Success #stdin #stdout 0s 2928KB
stdin
Standard input is empty
stdout
tip
tip
no tip
end