recursive_iterator_impl.hpp 6.9 KB

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