recursive_iterator_meta.hpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. //
  2. // recursive_iterator_meta.hpp
  3. // iterator
  4. //
  5. // Created by Sam Jaffe on 2/21/17.
  6. //
  7. #pragma once
  8. namespace iterator { namespace detail {
  9. /**
  10. * @class recursive_iterator_impl
  11. * @brief The default (terminal) implementation of an unbounded recursive iterator.
  12. *
  13. * @see recursive_iterator_base
  14. * @param Iterator The iterator type being processed, such as std::vector<int>::iterator
  15. */
  16. template <typename Iterator, typename = void>
  17. class recursive_iterator_impl : public recursive_iterator_base< Iterator > {
  18. public:
  19. using super = recursive_iterator_base< Iterator >;
  20. public:
  21. using super::super;
  22. recursive_iterator_impl() = default;
  23. template <typename OIter>
  24. recursive_iterator_impl(in_place_t, OIter && iter)
  25. : super(std::forward<OIter>(iter)) {}
  26. protected:
  27. void next() { super::operator++(); }
  28. void assign(super eat) { static_cast<super&>(*this) = eat; }
  29. };
  30. /**
  31. * @class recursive_iterator_impl
  32. *
  33. * An SFINAE specialization of bounded_recursive_iterator_impl for
  34. * non-associative container types.
  35. * @see recursive_iterator_layer
  36. */
  37. template <typename Iterator>
  38. class recursive_iterator_impl< Iterator, typename void_t<value_iterator<Iterator>>::type > :
  39. public recursive_iterator_layer< Iterator, recursive_iterator_impl< value_iterator<Iterator> > > {
  40. public:
  41. using next_layer = recursive_iterator_impl< value_iterator<Iterator> >;
  42. using super = recursive_iterator_layer< Iterator, next_layer >;
  43. public:
  44. /**
  45. * A special override of operator* that allows collections like
  46. * std::vector<std::vector<std::map<K, V>>> still use the value/reference
  47. * type of the map. Works only for nested collections with one associative
  48. * container at the bottom level.
  49. */
  50. auto operator*() const -> decltype(*(next_layer&)(*this)) { return next_layer::operator*(); }
  51. using super::super;
  52. recursive_iterator_impl() = default;
  53. template <typename... Iterators>
  54. recursive_iterator_impl(in_place_t, Iterators && ...iter)
  55. : super(in_place, std::forward<Iterators>(iter)...) {}
  56. };
  57. /**
  58. * @class recursive_iterator_impl
  59. *
  60. * An SFINAE specialization of bounded_recursive_iterator_impl for
  61. * associative container types.
  62. * @see flatten_iterator_layer
  63. */
  64. template <typename Iterator>
  65. class recursive_iterator_impl< Iterator, typename void_t<mapped_iterator<Iterator>>::type > :
  66. public flatten_iterator_layer< Iterator, recursive_iterator_impl< mapped_iterator<Iterator> > > {
  67. public:
  68. using next_layer = recursive_iterator_impl< mapped_iterator<Iterator> >;
  69. using super = flatten_iterator_layer< Iterator, next_layer >;
  70. public:
  71. using super::super;
  72. recursive_iterator_impl() = default;
  73. template <typename... Iterators>
  74. recursive_iterator_impl(in_place_t, Iterators && ...iter)
  75. : super(in_place, std::forward<Iterators>(iter)...) {}
  76. };
  77. /**
  78. * @class bounded_recursive_iterator_impl
  79. * @brief The default (terminal) implementation of a recursive iterator up to Max levels deep.
  80. *
  81. * @see recursive_iterator_base
  82. * @param Iterator The iterator type being processed, such as std::vector<int>::iterator
  83. * @param N The current layer of depth, starts at 1.
  84. * @param Max The maximum recursive depth to dive down, in case you need to process some sub-collection in a specific manner.
  85. */
  86. template <typename Iterator, std::size_t N, std::size_t Max, typename = void>
  87. class bounded_recursive_iterator_impl :
  88. public recursive_iterator_base< Iterator > {
  89. public:
  90. using super = recursive_iterator_base< Iterator >;
  91. public:
  92. using super::super;
  93. bounded_recursive_iterator_impl() = default;
  94. template <typename OIter>
  95. bounded_recursive_iterator_impl(in_place_t, OIter && iter)
  96. : super(std::forward<OIter>(iter)) {}
  97. protected:
  98. void next() { super::operator++(); }
  99. void assign(super eat) { static_cast<super&>(*this) = eat; }
  100. };
  101. /**
  102. * @class bounded_recursive_iterator_impl
  103. *
  104. * An SFINAE specialization of bounded_recursive_iterator_impl for
  105. * non-associative container types.
  106. * @see recursive_iterator_layer
  107. */
  108. template <typename Iterator, std::size_t N, std::size_t Max>
  109. class bounded_recursive_iterator_impl< Iterator, N, Max, typename std::enable_if<N < Max, typename void_t<value_iterator<Iterator>>::type>::type > :
  110. public recursive_iterator_layer< Iterator , bounded_recursive_iterator_impl< value_iterator<Iterator>, N+1, Max > > {
  111. public:
  112. using next_layer = bounded_recursive_iterator_impl< value_iterator<Iterator>, N+1, Max >;
  113. using super = recursive_iterator_layer< Iterator, next_layer >;
  114. public:
  115. /**
  116. * A special override of operator* that allows collections like
  117. * std::vector<std::vector<std::map<K, V>>> still use the value/reference
  118. * type of the map. Works only for nested collections with one associative
  119. * container at the bottom/Max level.
  120. */
  121. auto operator*() const -> decltype(*(next_layer&)(*this)) { return next_layer::operator*(); }
  122. using super::super;
  123. bounded_recursive_iterator_impl() = default;
  124. template <typename... Iterators>
  125. bounded_recursive_iterator_impl(in_place_t, Iterators && ...iter)
  126. : super(in_place, std::forward<Iterators>(iter)...) {}
  127. };
  128. /**
  129. * @class bounded_recursive_iterator_impl
  130. *
  131. * An SFINAE specialization of bounded_recursive_iterator_impl for
  132. * associative container types.
  133. * @see flatten_iterator_layer
  134. */
  135. template <typename Iterator, std::size_t N, std::size_t Max>
  136. class bounded_recursive_iterator_impl< Iterator, N, Max, typename std::enable_if<N < Max, typename void_t<mapped_iterator<Iterator>>::type>::type > :
  137. public flatten_iterator_layer< Iterator , bounded_recursive_iterator_impl< mapped_iterator<Iterator>, N+1, Max > > {
  138. public:
  139. using next_layer = bounded_recursive_iterator_impl< mapped_iterator<Iterator>, N+1, Max >;
  140. using super = flatten_iterator_layer< Iterator, next_layer >;
  141. public:
  142. using super::super;
  143. bounded_recursive_iterator_impl() = default;
  144. template <typename... Iterators>
  145. bounded_recursive_iterator_impl(in_place_t, Iterators && ...iter)
  146. : super(in_place, std::forward<Iterators>(iter)...) {}
  147. };
  148. } }
  149. namespace iterator { namespace detail {
  150. template <std::size_t I, typename It, typename = void>
  151. struct accessor;
  152. template <typename It>
  153. struct accessor<0, end_aware_iterator<It>> {
  154. using type = end_aware_iterator<It>;
  155. };
  156. template <typename It, typename Rec>
  157. struct accessor<0, recursive_iterator_layer<It, Rec>> {
  158. using type = end_aware_iterator<It>;
  159. };
  160. template <typename It, typename Rec>
  161. struct accessor<0, flatten_iterator_layer<It, Rec>> {
  162. using type = end_aware_iterator<It>;
  163. };
  164. template <typename It>
  165. struct accessor<0, It> {
  166. using type = typename accessor<0, typename It::super>::type;
  167. };
  168. template <std::size_t I, typename It>
  169. struct accessor<I, It, typename std::enable_if<I != 0>::type> {
  170. using type = typename accessor<I, typename It::super>::type;
  171. };
  172. template <std::size_t I, typename It, typename Rec>
  173. struct accessor<I, recursive_iterator_layer<It, Rec>, typename std::enable_if<I != 0>::type> {
  174. using type = typename accessor<I-1, Rec>::type;
  175. };
  176. template <std::size_t I, typename It, typename Rec>
  177. struct accessor<I, flatten_iterator_layer<It, Rec>, typename std::enable_if<I != 0>::type> {
  178. using type = typename accessor<I-1, Rec>::type;
  179. };
  180. } }