fork(1) download
  1. #include <tuple>
  2. #include <functional>
  3. #include <iostream>
  4. #include <string>
  5. #include <vector>
  6. #include <map>
  7. #include <list>
  8. #include <array>
  9. #include <iterator>
  10.  
  11. // for_each_multi
  12. template<typename Tuple, typename Callable>
  13. Callable for_each_multi(Tuple begins, Tuple ends, Callable fn);
  14.  
  15. // visit_tuple
  16. template<typename Callable, typename Head, typename... Tail>
  17. Callable visit_tuple(Callable fn, Head&& aTuple, Tail&& ...aTail);
  18.  
  19. template<size_t size>
  20. struct visit_tuple_ws;
  21.  
  22. // apply_tuple
  23. template<typename Applicator, typename Tuple, typename Callable>
  24. void apply_tuple(Tuple&& tuple, Callable&& fn);
  25.  
  26. // tuple unpack utils
  27. template<size_t ...>
  28. struct sequence { };
  29.  
  30. template<size_t N, size_t ...S>
  31. struct generate : generate<N-1u, N-1u, S...> { };
  32.  
  33. template<size_t ...S>
  34. struct generate<0u, S...> {
  35. typedef sequence<S...> type;
  36. };
  37.  
  38. struct Dereference
  39. {
  40. template< typename F, typename T, size_t ...S >
  41. static void apply(T&& tuple, F& fn, sequence<S...> )
  42. {
  43. fn( *std::get<S>(tuple) ...);
  44. }
  45. };
  46.  
  47. struct Increment
  48. {
  49. template <typename T>
  50. void operator()(T&& t)
  51. {
  52. ++t;
  53. }
  54. };
  55.  
  56. struct CheckBeginEnd
  57. {
  58. CheckBeginEnd() : BeginIsNotEnd(true) {}
  59.  
  60. template<typename T>
  61. void operator()(T&& begin, T&& end)
  62. {
  63. BeginIsNotEnd &= (begin != end);
  64. }
  65.  
  66. bool BeginIsNotEnd;
  67. };
  68.  
  69. // for_each_multi
  70. template<typename Tuple, typename Callable>
  71. Callable for_each_multi(Tuple begins, Tuple ends, Callable fn)
  72. {
  73. for ( ; visit_tuple(CheckBeginEnd(), begins, ends).BeginIsNotEnd; visit_tuple(Increment(), begins) )
  74. apply_tuple<Dereference>(begins, fn);
  75. return fn;
  76. }
  77.  
  78. template<typename Callable, typename Head, typename... Tail>
  79. Callable for_each_multi(Callable fn, Head&& head, Tail&& ...tail)
  80. {
  81. return for_each_multi( std::make_tuple(begin(head), begin(tail)...), std::make_tuple(end(head), end(tail)...), fn);
  82. }
  83.  
  84. // visit_tuple
  85. template<typename Callable, typename Head, typename... Tail>
  86. Callable visit_tuple(Callable f, Head&& aTuple, Tail&& ...aTail)
  87. {
  88. const size_t size = std::tuple_size<typename std::remove_reference<Head>::type>::value-1;
  89. visit_tuple_ws<size>::visit(f, aTuple, aTail...);
  90. return f;
  91. }
  92.  
  93. template<size_t size>
  94. struct visit_tuple_ws
  95. {
  96. template<typename Callable, typename Head, typename... Tail>
  97. static void visit(Callable& f, Head& aTuple, Tail& ...aTail)
  98. {
  99. visit_tuple_ws<size-1>::visit(f, aTuple, aTail...);
  100. f(std::get<size>(aTuple), std::get<size>(aTail)...);
  101. }
  102. };
  103.  
  104. template<>
  105. struct visit_tuple_ws<0u>
  106. {
  107. template<typename Callable, typename Head, typename... Tail>
  108. static void visit(Callable& f, Head& aTuple, Tail& ...aTail)
  109. {
  110. f(std::get<0>(aTuple), std::get<0>(aTail)...);
  111. }
  112. };
  113.  
  114. // apply_tuple
  115. template<typename Unpacker, typename Tuple, typename Callable>
  116. void apply_tuple(Tuple&& tuple, Callable&& fn)
  117. {
  118. const int size = std::tuple_size<typename std::remove_reference<Tuple>::type>::value;
  119. Unpacker::apply( std::forward<Tuple>(tuple), std::forward<Callable>(fn), typename generate<size>::type() );
  120. }
  121.  
  122.  
  123. using namespace std;
  124.  
  125. // support
  126. template<typename Head, typename ...Tail>
  127. auto begins(Head&& head, Tail&& ...tail)
  128. -> decltype(std::make_tuple(head.begin(), tail.begin()...))
  129. {
  130. return std::make_tuple(head.begin(), tail.begin()...);
  131. }
  132.  
  133. template<typename Head, typename ...Tail>
  134. auto ends(Head&& head, Tail&& ...tail)
  135. -> decltype(std::make_tuple(head.end(), tail.end()...))
  136. {
  137. return std::make_tuple(head.end(), tail.end()...);
  138. }
  139.  
  140. #define ON(...) begins(__VA_ARGS__), ends(__VA_ARGS__)
  141.  
  142. int main()
  143. {
  144. vector<int> vec1 {1,2,3};
  145. list<int> list1 {10, 20 ,30};
  146. array<string, 3> arr {"one", "two", "three"};
  147.  
  148. for_each_multi(ON(vec1, list1, arr), [](int i, int l, const string& s)
  149. {
  150. cout << i << " (" << s << ")" << " * 10 is " << l << endl;
  151. });
  152.  
  153. return 0;
  154. }
Success #stdin #stdout 0s 3020KB
stdin
Standard input is empty
stdout
1 (one) * 10 is 10
2 (two) * 10 is 20
3 (three) * 10 is 30