recursive_iterator.hpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. //
  2. // recursive_iterator.hpp
  3. // iterator
  4. //
  5. // Created by Sam Jaffe on 2/17/17.
  6. //
  7. #pragma once
  8. #include "iterator_fwd.hpp"
  9. namespace iterator {
  10. namespace detail {
  11. struct terminal_layer_tag_t;
  12. struct continue_layer_tag_t;
  13. template <typename Iterator, typename = void>
  14. class recursive_iterator_base : public end_aware_iterator<Iterator> {
  15. private:
  16. using super = end_aware_iterator<Iterator>;
  17. protected:
  18. using recursive_category = terminal_layer_tag_t;
  19. public:
  20. using super::super;
  21. protected:
  22. typename super::reference get() { return super::operator*(); }
  23. };
  24. template <typename Iterator>
  25. class recursive_iterator_base<Iterator, typename std::enable_if<std::is_const<typename end_aware_iterator<Iterator>::value_type::first_type>::value>::type> : public end_aware_iterator<Iterator> {
  26. private:
  27. using super = end_aware_iterator<Iterator>;
  28. using first_type = decltype((std::declval<Iterator>()->first));
  29. using second_type = decltype((std::declval<Iterator>()->second));
  30. protected:
  31. using recursive_category = continue_layer_tag_t;
  32. public:
  33. using value_type = std::tuple<first_type, second_type>;
  34. using reference = std::tuple<first_type &, second_type &>;
  35. public:
  36. using super::super;
  37. protected:
  38. reference get() {
  39. auto & pair = super::operator*();
  40. return std::tie(pair.first, pair.second);
  41. }
  42. };
  43. template <typename Iterator, typename RecursiveIterator_NextLayer>
  44. class recursive_iterator_layer :
  45. public recursive_iterator_base< Iterator >,
  46. public RecursiveIterator_NextLayer {
  47. private:
  48. using next_layer = RecursiveIterator_NextLayer;
  49. using layer = recursive_iterator_base< Iterator >;
  50. protected:
  51. using recursive_category = continue_layer_tag_t;
  52. public:
  53. using value_type = typename next_layer::value_type;
  54. using reference = typename next_layer::reference;
  55. using pointer = typename next_layer::pointer;
  56. using difference_type = typename next_layer::difference_type;
  57. using iterator_category = typename next_layer::iterator_category;
  58. public:
  59. recursive_iterator_layer() = default;
  60. recursive_iterator_layer(layer v) : recursive_iterator_layer() {
  61. assign(v);
  62. }
  63. reference operator*() {
  64. return next_layer::get();
  65. }
  66. pointer operator->() {
  67. return next_layer::operator->();
  68. }
  69. bool operator==(recursive_iterator_layer const & other) const {
  70. return layer::operator==(other) && next_layer::operator==(other);
  71. }
  72. protected:
  73. reference get() { return operator*(); }
  74. void next() {
  75. layer & self = static_cast<layer&>(*this);
  76. next_layer::next();
  77. while ( next_layer::done() && !(++self).done() ) {
  78. next_layer::assign(make_end_aware_iterator(*self));
  79. }
  80. }
  81. void assign(layer v) {
  82. static_cast<layer&>(*this) = v;
  83. if (!v.done()) {
  84. next_layer::assign(make_end_aware_iterator(*v));
  85. }
  86. }
  87. bool done() const { return layer::done(); }
  88. };
  89. template <typename V, typename Tag>
  90. struct next_layer_type { using type = std::tuple<V>; };
  91. template <typename V>
  92. struct next_layer_type<V, continue_layer_tag_t> { using type = V; };
  93. template <typename Iterator, typename RecursiveIterator_NextLayer>
  94. class flatten_iterator_layer :
  95. recursive_iterator_base< Iterator >,
  96. RecursiveIterator_NextLayer {
  97. private:
  98. using next_layer = RecursiveIterator_NextLayer;
  99. using layer = recursive_iterator_base< Iterator >;
  100. using key_type = typename std::tuple_element<0, typename layer::value_type>::type;
  101. protected:
  102. using recursive_category = continue_layer_tag_t;
  103. using next_value_type = typename next_layer_type<typename next_layer::value_type, typename next_layer::recursive_category>::type;
  104. using next_reference = typename next_layer_type<typename next_layer::reference, typename next_layer::recursive_category>::type;
  105. public:
  106. using value_type = decltype(std::tuple_cat(std::make_tuple(std::declval<key_type>()),
  107. std::declval<next_value_type>()));
  108. using reference = decltype(std::tuple_cat(std::tie(std::declval<key_type>()),
  109. std::declval<next_reference>()));
  110. using pointer = void;
  111. using difference_type = typename next_layer::difference_type;
  112. using iterator_category = typename next_layer::iterator_category;
  113. public:
  114. flatten_iterator_layer() = default;
  115. flatten_iterator_layer(layer v) : flatten_iterator_layer() {
  116. assign(v);
  117. }
  118. reference operator*() {
  119. return std::tuple_cat(std::forward_as_tuple(std::get<0>(layer::get())),
  120. next_reference(next_layer::get()));
  121. }
  122. pointer operator->();
  123. bool operator==(flatten_iterator_layer const & other) const {
  124. return layer::operator==(other) && next_layer::operator==(other);
  125. }
  126. protected:
  127. reference get() { return operator*(); }
  128. void next() {
  129. layer & self = static_cast<layer&>(*this);
  130. next_layer::next();
  131. while ( next_layer::done() && !(++self).done() ) {
  132. next_layer::assign(make_end_aware_iterator(self->second));
  133. }
  134. }
  135. void assign(layer v) {
  136. static_cast<layer&>(*this) = v;
  137. if ( !v.done() ) {
  138. next_layer::assign(make_end_aware_iterator(v->second));
  139. }
  140. }
  141. bool done() const { return layer::done(); }
  142. };
  143. template <typename Iterator, std::size_t N, std::size_t Max, typename = void>
  144. class bounded_recursive_iterator_impl :
  145. public recursive_iterator_base< Iterator > {
  146. private:
  147. using super = recursive_iterator_base< Iterator >;
  148. public:
  149. using super::super;
  150. protected:
  151. void next() { super::operator++(); }
  152. void assign(super eat) { static_cast<super&>(*this) = eat; }
  153. };
  154. template <typename Iterator, std::size_t N, std::size_t Max>
  155. class bounded_recursive_iterator_impl< Iterator, N, Max, typename std::enable_if<N < Max, typename void_t<value_iterator<Iterator>>::type>::type > :
  156. public recursive_iterator_layer< Iterator , bounded_recursive_iterator_impl< value_iterator<Iterator>, N+1, Max > > {
  157. private:
  158. using next_layer = bounded_recursive_iterator_impl< value_iterator<Iterator>, N+1, Max >;
  159. using super = recursive_iterator_layer< Iterator, next_layer >;
  160. public:
  161. auto operator*() -> decltype(*(next_layer&)(*this)) { return next_layer::operator*(); }
  162. using super::super;
  163. };
  164. template <typename Iterator, typename = void>
  165. class recursive_iterator_impl : public recursive_iterator_base< Iterator > {
  166. private:
  167. using super = recursive_iterator_base< Iterator >;
  168. public:
  169. using super::super;
  170. protected:
  171. void next() { super::operator++(); }
  172. void assign(super eat) { static_cast<super&>(*this) = eat; }
  173. };
  174. template <typename Iterator>
  175. class recursive_iterator_impl< Iterator, typename void_t<value_iterator<Iterator>>::type > :
  176. public recursive_iterator_layer< Iterator, recursive_iterator_impl< value_iterator<Iterator> > > {
  177. private:
  178. using next_layer = recursive_iterator_impl< value_iterator<Iterator> >;
  179. using super = recursive_iterator_layer< Iterator, next_layer >;
  180. public:
  181. auto operator*() -> decltype(*(next_layer&)(*this)) { return next_layer::operator*(); }
  182. using super::super;
  183. };
  184. template <typename Iterator, std::size_t N, std::size_t Max>
  185. class bounded_recursive_iterator_impl< Iterator, N, Max, typename std::enable_if<N < Max, typename void_t<mapped_iterator<Iterator>>::type>::type > :
  186. public flatten_iterator_layer< Iterator , bounded_recursive_iterator_impl< mapped_iterator<Iterator>, N+1, Max > > {
  187. private:
  188. using next_layer = bounded_recursive_iterator_impl< mapped_iterator<Iterator>, N+1, Max >;
  189. using super = flatten_iterator_layer< Iterator, next_layer >;
  190. public:
  191. using super::super;
  192. };
  193. template <typename Iterator>
  194. class recursive_iterator_impl< Iterator, typename void_t<mapped_iterator<Iterator>>::type > :
  195. public flatten_iterator_layer< Iterator, recursive_iterator_impl< mapped_iterator<Iterator> > > {
  196. private:
  197. using next_layer = recursive_iterator_impl< mapped_iterator<Iterator> >;
  198. using super = flatten_iterator_layer< Iterator, next_layer >;
  199. public:
  200. using super::super;
  201. };
  202. }
  203. template <typename Iterator>
  204. class recursive_iterator : public detail::recursive_iterator_impl< Iterator > {
  205. private:
  206. using super = detail::recursive_iterator_impl< Iterator >;
  207. public:
  208. using super::super;
  209. recursive_iterator & operator++() {
  210. (void) super::next();
  211. return *this;
  212. }
  213. recursive_iterator operator++(int) {
  214. recursive_iterator tmp{*this};
  215. (void) super::next();
  216. return tmp;
  217. }
  218. bool operator!=(recursive_iterator const & other) { return !(super::operator==(other)); }
  219. };
  220. template <typename Iterator, std::size_t N>
  221. class recursive_iterator_n : public detail::bounded_recursive_iterator_impl< Iterator, 1, N > {
  222. private:
  223. using super = detail::bounded_recursive_iterator_impl< Iterator, 1, N >;
  224. public:
  225. using super::super;
  226. recursive_iterator_n & operator++() {
  227. (void) super::next();
  228. return *this;
  229. }
  230. recursive_iterator_n operator++(int) {
  231. recursive_iterator_n tmp{*this};
  232. (void) super::next();
  233. return tmp;
  234. }
  235. bool operator!=(recursive_iterator_n const & other) { return !(super::operator==(other)); }
  236. };
  237. }
  238. template <typename C>
  239. auto make_recursive_iterator(C & collect) -> iterator::recursive_iterator<decltype(std::begin(collect))> {
  240. return { make_end_aware_iterator(collect)};
  241. }
  242. template <typename C>
  243. auto make_recursive_iterator(C const & collect) -> iterator::recursive_iterator<decltype(std::begin(collect))> {
  244. return { make_end_aware_iterator(collect) };
  245. }
  246. template <std::size_t Max, typename C>
  247. auto make_recursive_iterator(C & collect) -> iterator::recursive_iterator_n<decltype(std::begin(collect)), Max> {
  248. return { make_end_aware_iterator(collect) };
  249. }
  250. template <std::size_t Max, typename C>
  251. auto make_recursive_iterator(C const & collect) -> iterator::recursive_iterator_n<decltype(std::begin(collect)), Max> {
  252. return { make_end_aware_iterator(collect) };
  253. }