fork(2) download
  1. #include <vector>
  2. #include <tuple>
  3. #include <string>
  4. #include <iostream>
  5.  
  6.  
  7. // BORROWED FROM http://stackoverflow.com/a/15036110/592323
  8.  
  9. //===========================================================================
  10. // META-FUNCTIONS FOR CREATING INDEX LISTS
  11.  
  12. // The structure that encapsulates index lists
  13. template <size_t... Is>
  14. struct index_list
  15. {
  16. };
  17.  
  18. // Collects internal details for generating index ranges [MIN, MAX)
  19. namespace detail
  20. {
  21. // Declare primary template for index range builder
  22. template <size_t MIN, size_t N, size_t... Is>
  23. struct range_builder;
  24.  
  25. // Base step
  26. template <size_t MIN, size_t... Is>
  27. struct range_builder<MIN, MIN, Is...>
  28. {
  29. typedef index_list<Is...> type;
  30. };
  31.  
  32. // Induction step
  33. template <size_t MIN, size_t N, size_t... Is>
  34. struct range_builder : public range_builder<MIN, N - 1, N - 1, Is...>
  35. {
  36. };
  37. }
  38.  
  39. // Meta-function that returns a [MIN, MAX) index range
  40. template<size_t MIN, size_t MAX>
  41. using index_range = typename detail::range_builder<MIN, MAX>::type;
  42.  
  43. //===========================================================================
  44.  
  45.  
  46.  
  47. template<std::size_t I = 0, typename ...Ts>
  48. inline typename std::enable_if<I == sizeof...(Ts), void>::type
  49. tupleIncrement(std::tuple<Ts...> &tup)
  50. { }
  51. template<std::size_t I = 0, typename ...Ts>
  52. inline typename std::enable_if<I < sizeof...(Ts), void>::type
  53. tupleIncrement(std::tuple<Ts...> &tup)
  54. {
  55. ++std::get<I>(tup);
  56. tupleIncrement<I + 1, Ts...>(tup);
  57. }
  58.  
  59.  
  60. template<typename ...Ts> // Element types
  61. class WrapMultiVector
  62. {
  63. // references to vectors in a TUPLE
  64. std::tuple<std::vector<Ts>&...> m_vectors;
  65.  
  66. // list of indices
  67. typedef decltype(index_range<0, sizeof...(Ts)>()) IndexList;
  68.  
  69. public:
  70. // references to vectors in multiple arguments
  71. WrapMultiVector(std::vector<Ts> & ...vectors)
  72. : m_vectors(vectors...) // construct tuple from multiple args.
  73. {}
  74.  
  75.  
  76.  
  77. class iterator {
  78. std::tuple<typename std::vector<Ts>::iterator...> m_elemIterators;
  79.  
  80. public:
  81. iterator(std::tuple<typename std::vector<Ts>::iterator...> elemIterators)
  82. : m_elemIterators(elemIterators)
  83. {}
  84.  
  85. bool operator==(const iterator &o) const {
  86. return std::get<0>(m_elemIterators) == std::get<0>(o.m_elemIterators);
  87. }
  88. bool operator!=(const iterator &o) const {
  89. return std::get<0>(m_elemIterators) != std::get<0>(o.m_elemIterators);
  90. }
  91.  
  92. iterator& operator ++() {
  93. tupleIncrement(m_elemIterators);
  94. return *this;
  95. }
  96. iterator operator ++(int) {
  97. iterator old = *this;
  98. tupleIncrement(m_elemIterators);
  99. return old;
  100. }
  101.  
  102. std::tuple<Ts&...> operator*() {
  103. return getElements(IndexList());
  104. }
  105.  
  106. private:
  107. template<size_t ...Is>
  108. std::tuple<Ts&...> getElements(index_list<Is...>) {
  109. return std::tie(*std::get<Is>(m_elemIterators)...);
  110. }
  111. };
  112.  
  113.  
  114. iterator begin() {
  115. return iterator(getBegins(IndexList()));
  116. }
  117. iterator end() {
  118. return iterator(getEnds(IndexList()));
  119. }
  120.  
  121. private:
  122. template<size_t ...Is>
  123. std::tuple<typename std::vector<Ts>::iterator...> getBegins(index_list<Is...>) {
  124. return std::make_tuple(std::get<Is>(m_vectors).begin()...);
  125. }
  126. template<size_t ...Is>
  127. std::tuple<typename std::vector<Ts>::iterator...> getEnds(index_list<Is...>) {
  128. return std::make_tuple(std::get<Is>(m_vectors).end()...);
  129. }
  130. };
  131.  
  132.  
  133.  
  134. template<typename ...Ts>
  135. WrapMultiVector<Ts...> makeWrapper(std::vector<Ts> & ...vectors) {
  136. return WrapMultiVector<Ts...>(vectors...);
  137. }
  138.  
  139.  
  140. int main() {
  141. std::vector<int> id = { 1, 2, 3 };
  142. std::vector<std::string> name = { "Alice", "Bob", "Carol" };
  143. std::vector<int> age = { 30, 42, 55 };
  144.  
  145. auto nameAge = makeWrapper(name, age);
  146. for (auto na : nameAge) {
  147. std::cout << "name: " << std::get<0>(na) << ", age: " << std::get<1>(na) << std::endl;
  148. }
  149. }
  150.  
Success #stdin #stdout 0s 3432KB
stdin
Standard input is empty
stdout
name: Alice, age: 30
name: Bob, age: 42
name: Carol, age: 55