recursive_iterator.hpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  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. template <typename Iterator>
  12. using recursive_iterator_base = end_aware_iterator< Iterator >;
  13. template <typename Iterator>
  14. class recursive_iterator_terminal : public recursive_iterator_base< Iterator > {
  15. private:
  16. using layer = recursive_iterator_base< Iterator >;
  17. public:
  18. using value_type = typename layer::value_type;
  19. using reference = typename layer::reference;
  20. using pointer = typename layer::pointer;
  21. using difference_type = typename layer::difference_type;
  22. using iterator_category = typename layer::iterator_category;
  23. public:
  24. recursive_iterator_terminal() = default;
  25. recursive_iterator_terminal(layer v) : layer(v) {}
  26. reference operator*() {
  27. return layer::operator*();
  28. }
  29. pointer operator->() {
  30. return layer::operator->();
  31. }
  32. bool operator==(recursive_iterator_terminal const & other) const {
  33. return layer::operator==(other);
  34. }
  35. protected:
  36. void next() {
  37. layer::operator++();
  38. }
  39. void assign(layer eat) {
  40. static_cast<layer&>(*this) = eat;
  41. }
  42. bool done() const { return layer::done(); }
  43. };
  44. template <typename Iterator, typename RecursiveIterator_NextLayer>
  45. class recursive_iterator_layer :
  46. public recursive_iterator_base< Iterator >,
  47. public RecursiveIterator_NextLayer {
  48. private:
  49. using next_layer = RecursiveIterator_NextLayer;
  50. using layer = recursive_iterator_base< Iterator >;
  51. public:
  52. using value_type = typename next_layer::value_type;
  53. using reference = typename next_layer::reference;
  54. using pointer = typename next_layer::pointer;
  55. using difference_type = typename next_layer::difference_type;
  56. using iterator_category = typename next_layer::iterator_category;
  57. public:
  58. recursive_iterator_layer() = default;
  59. recursive_iterator_layer(layer v) : layer(v), next_layer() {
  60. if ( !v.done() ) {
  61. next_layer::assign({ std::begin(*v), std::end(*v) });
  62. }
  63. }
  64. reference operator*() {
  65. return next_layer::operator*();
  66. }
  67. pointer operator->() {
  68. return next_layer::operator->();
  69. }
  70. bool operator==(recursive_iterator_layer const & other) const {
  71. return layer::operator==(other) && next_layer::operator==(other);
  72. }
  73. protected:
  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({ std::begin(*self), std::end(*self) });
  79. }
  80. }
  81. void assign(layer eat) {
  82. static_cast<layer&>(*this) = eat;
  83. }
  84. bool done() const { return layer::done(); }
  85. };
  86. template <typename Iterator, std::size_t N, std::size_t Max, typename = void>
  87. class bounded_recursive_iterator_impl :
  88. public recursive_iterator_terminal< Iterator > {
  89. private:
  90. using super = recursive_iterator_terminal< Iterator >;
  91. public:
  92. using super::super;
  93. };
  94. template <typename Iterator, std::size_t N, std::size_t Max>
  95. class bounded_recursive_iterator_impl< Iterator, N, Max, typename std::enable_if<N < Max, typename void_t<value_iterator<Iterator>>::type>::type > :
  96. public recursive_iterator_layer< Iterator , bounded_recursive_iterator_impl< value_iterator<Iterator>, N+1, Max > > {
  97. private:
  98. using next_layer = bounded_recursive_iterator_impl< value_iterator<Iterator>, N+1, Max >;
  99. using super = recursive_iterator_layer< Iterator, next_layer >;
  100. public:
  101. using super::super;
  102. };
  103. template <typename Iterator, typename = void>
  104. class recursive_iterator_impl : public recursive_iterator_terminal< Iterator > {
  105. private:
  106. using super = recursive_iterator_terminal< Iterator >;
  107. public:
  108. using super::super;
  109. };
  110. template <typename Iterator>
  111. class recursive_iterator_impl< Iterator, typename void_t<value_iterator<Iterator>>::type > :
  112. public recursive_iterator_layer< Iterator, recursive_iterator_impl< value_iterator<Iterator> > > {
  113. private:
  114. using next_layer = recursive_iterator_impl< value_iterator<Iterator> >;
  115. using super = recursive_iterator_layer< Iterator, next_layer >;
  116. public:
  117. using super::super;
  118. };
  119. }
  120. template <typename Iterator>
  121. class recursive_iterator : detail::recursive_iterator_impl< Iterator > {
  122. private:
  123. using super = detail::recursive_iterator_impl< Iterator >;
  124. public:
  125. using value_type = typename super::value_type;
  126. using reference = typename super::reference;
  127. using pointer = typename super::pointer;
  128. using difference_type = typename super::difference_type;
  129. using iterator_category = typename super::iterator_category;
  130. public:
  131. using super::super;
  132. recursive_iterator & operator++() {
  133. (void) super::next();
  134. return *this;
  135. }
  136. recursive_iterator operator++(int) {
  137. recursive_iterator tmp{*this};
  138. (void) super::next();
  139. return tmp;
  140. }
  141. using super::operator*;
  142. using super::operator->;
  143. using super::operator==;
  144. bool operator!=(recursive_iterator const & other) { return !(operator==(other)); }
  145. };
  146. template <typename Iterator, std::size_t N>
  147. class recursive_iterator_n : detail::bounded_recursive_iterator_impl< Iterator, 1, N > {
  148. private:
  149. using super = detail::bounded_recursive_iterator_impl< Iterator, 1, N >;
  150. public:
  151. using value_type = typename super::value_type;
  152. using reference = typename super::reference;
  153. using pointer = typename super::pointer;
  154. using difference_type = typename super::difference_type;
  155. using iterator_category = typename super::iterator_category;
  156. public:
  157. using super::super;
  158. recursive_iterator_n & operator++() {
  159. (void) super::next();
  160. return *this;
  161. }
  162. recursive_iterator_n operator++(int) {
  163. recursive_iterator_n tmp{*this};
  164. (void) super::next();
  165. return tmp;
  166. }
  167. using super::operator*;
  168. using super::operator->;
  169. using super::operator==;
  170. bool operator!=(recursive_iterator_n const & other) { return !(operator==(other)); }
  171. };
  172. }