recursive_iterator_impl.hpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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. template <typename Iterator, typeclass = typeclass_t<Iterator>::value>
  14. class recursive_iterator_impl;
  15. /**
  16. * A bounded_recursive_iterator_impl where N == Max is always a terminal node.
  17. */
  18. template <typename Iterator, std::size_t N, std::size_t Max,
  19. typeclass = std::conditional_t<N == Max, typeclass_t<void>,
  20. typeclass_t<Iterator>>::value>
  21. class bounded_recursive_iterator_impl;
  22. /**
  23. * @class recursive_iterator_impl
  24. * @brief The default (terminal) implementation of an unbounded recursive
  25. * iterator.
  26. *
  27. * @see recursive_iterator_base
  28. * @tparam Iterator The iterator type being processed, such as
  29. * std::vector<int>::iterator
  30. */
  31. template <typename Iterator>
  32. class recursive_iterator_impl<Iterator, typeclass::TERMINAL>
  33. : public recursive_iterator_base<Iterator> {
  34. public:
  35. using super = recursive_iterator_base<Iterator>;
  36. public:
  37. using super::super;
  38. recursive_iterator_impl() = default;
  39. protected:
  40. void next() { super::operator++(); }
  41. void assign(super eat) { static_cast<super &>(*this) = eat; }
  42. };
  43. /**
  44. * @class recursive_iterator_impl
  45. *
  46. * An SFINAE specialization of bounded_recursive_iterator_impl for
  47. * non-associative container types.
  48. * @see recursive_iterator_layer
  49. */
  50. template <typename Iterator>
  51. class recursive_iterator_impl<Iterator, typeclass::CONTAINER>
  52. : public recursive_iterator_layer<
  53. Iterator, recursive_iterator_impl<value_iterator<Iterator>>> {
  54. public:
  55. using next_layer = recursive_iterator_impl<value_iterator<Iterator>>;
  56. using super = recursive_iterator_layer<Iterator, next_layer>;
  57. public:
  58. /**
  59. * A special override of operator* that allows collections like
  60. * std::vector<std::vector<std::map<K, V>>> still use the value/reference
  61. * type of the map. Works only for nested collections with one associative
  62. * container at the bottom level.
  63. */
  64. auto operator*() const -> decltype(*(next_layer &)(*this)) {
  65. return next_layer::operator*();
  66. }
  67. using super::super;
  68. recursive_iterator_impl() = default;
  69. };
  70. /**
  71. * @class recursive_iterator_impl
  72. *
  73. * An SFINAE specialization of bounded_recursive_iterator_impl for
  74. * associative container types.
  75. * @see flatten_iterator_layer
  76. */
  77. template <typename Iterator>
  78. class recursive_iterator_impl<Iterator, typeclass::ASSOCIATIVE_CONTAINER>
  79. : public flatten_iterator_layer<
  80. Iterator, recursive_iterator_impl<mapped_iterator<Iterator>>> {
  81. public:
  82. using next_layer = recursive_iterator_impl<mapped_iterator<Iterator>>;
  83. using super = flatten_iterator_layer<Iterator, next_layer>;
  84. public:
  85. using super::super;
  86. recursive_iterator_impl() = default;
  87. };
  88. /**
  89. * @class bounded_recursive_iterator_impl
  90. * @brief The default (terminal) implementation of a recursive iterator up to
  91. * Max levels deep.
  92. *
  93. * @see recursive_iterator_base
  94. * @tparam Iterator The iterator type being processed, such as
  95. * std::vector<int>::iterator
  96. * @tparam N The current layer of depth, starts at 1.
  97. * @tparam Max The maximum recursive depth to dive down, in case you need to
  98. * process some sub-collection in a specific manner.
  99. */
  100. template <typename Iterator, std::size_t N, std::size_t Max>
  101. class bounded_recursive_iterator_impl<Iterator, N, Max, typeclass::TERMINAL>
  102. : public recursive_iterator_base<Iterator> {
  103. public:
  104. using super = recursive_iterator_base<Iterator>;
  105. public:
  106. using super::super;
  107. bounded_recursive_iterator_impl() = default;
  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, N, Max, typeclass::CONTAINER>
  121. : public recursive_iterator_layer<
  122. Iterator, bounded_recursive_iterator_impl<value_iterator<Iterator>,
  123. N + 1, Max>> {
  124. public:
  125. using next_layer =
  126. bounded_recursive_iterator_impl<value_iterator<Iterator>, N + 1, Max>;
  127. using super = recursive_iterator_layer<Iterator, next_layer>;
  128. public:
  129. /**
  130. * A special override of operator* that allows collections like
  131. * std::vector<std::vector<std::map<K, V>>> still use the value/reference
  132. * type of the map. Works only for nested collections with one associative
  133. * container at the bottom/Max level.
  134. */
  135. auto operator*() const -> decltype(*(next_layer &)(*this)) {
  136. return next_layer::operator*();
  137. }
  138. using super::super;
  139. bounded_recursive_iterator_impl() = default;
  140. };
  141. /**
  142. * @class bounded_recursive_iterator_impl
  143. *
  144. * An SFINAE specialization of bounded_recursive_iterator_impl for
  145. * associative container types.
  146. * @see flatten_iterator_layer
  147. */
  148. template <typename Iterator, std::size_t N, std::size_t Max>
  149. class bounded_recursive_iterator_impl<Iterator, N, Max,
  150. typeclass::ASSOCIATIVE_CONTAINER>
  151. : public flatten_iterator_layer<
  152. Iterator, bounded_recursive_iterator_impl<mapped_iterator<Iterator>,
  153. N + 1, Max>> {
  154. public:
  155. using next_layer =
  156. bounded_recursive_iterator_impl<mapped_iterator<Iterator>, N + 1, Max>;
  157. using super = flatten_iterator_layer<Iterator, next_layer>;
  158. public:
  159. using super::super;
  160. bounded_recursive_iterator_impl() = default;
  161. };
  162. }}