recursive_iterator_meta.hpp 6.8 KB

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