recursive_iterator_meta.hpp 7.7 KB

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