trie_iterator.hpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. //
  2. // trie_iterator.hpp
  3. // trie
  4. //
  5. // Created by Sam Jaffe on 6/16/17.
  6. //
  7. #pragma once
  8. #include "trie.hpp"
  9. #include "iterator/end_aware_iterator.hpp"
  10. #include <list>
  11. #include <stack>
  12. namespace detail {
  13. template <typename Iter> struct trie_iterator_next {
  14. using iter_t = ::iterator::end_aware_iterator<Iter>;
  15. template <typename Trie> iter_t operator()(Trie & tr) {
  16. return {tr.local_begin(), tr.local_end()};
  17. }
  18. };
  19. template <typename Iter>
  20. struct trie_iterator_next<std::reverse_iterator<Iter>> {
  21. using iter_t = ::iterator::end_aware_iterator<std::reverse_iterator<Iter>>;
  22. template <typename Trie> iter_t operator()(Trie & tr) {
  23. return {tr.local_rbegin(), tr.local_rend()};
  24. }
  25. };
  26. template <typename Trie, typename Iter> class trie_iterator_base {
  27. protected:
  28. using helper = trie_iterator_next<Iter>;
  29. using impl_t = typename helper::iter_t;
  30. std::stack<Trie *> stk;
  31. std::list<typename Trie::key_type> keys;
  32. std::stack<impl_t> iters;
  33. bool done{false};
  34. public:
  35. using reference = decltype(std::declval<Trie>().value());
  36. using value_type = std::remove_reference_t<reference>;
  37. using pointer = value_type *;
  38. using difference_type = std::ptrdiff_t;
  39. using iterator_category = std::forward_iterator_tag;
  40. public:
  41. trie_iterator_base() : done{true} {}
  42. trie_iterator_base(Trie * tr) { stk.push(tr); }
  43. auto operator*() const -> reference { return root(); }
  44. auto operator-> () const -> pointer { return std::addressof(operator*()); }
  45. Trie & root() const {
  46. if (stk.empty()) {
  47. throw std::runtime_error("Dereferencing invalid iterator");
  48. }
  49. return *stk.top();
  50. }
  51. trie_iterator_base parent() const {
  52. trie_iterator_base tmp{*this};
  53. tmp.pop();
  54. return tmp;
  55. }
  56. protected:
  57. void push(impl_t it) {
  58. if (it.done()) {
  59. done = true;
  60. return;
  61. }
  62. iters.push(it);
  63. keys.push_back(it->first);
  64. stk.push(it->second.get());
  65. }
  66. void pop() {
  67. stk.pop();
  68. iters.pop();
  69. keys.pop_back();
  70. }
  71. bool poping_empty() {
  72. if (!iters.top().done()) { return false; }
  73. pop();
  74. return !iters.empty();
  75. }
  76. void assign() {
  77. if (iters.empty()) { return; }
  78. stk.top() = iters.top()->second.get();
  79. keys.back() = iters.top()->first;
  80. }
  81. bool can_recurse() { return !next().done(); }
  82. void recurse() { push(next()); }
  83. impl_t next() { return helper()(root()); }
  84. friend bool operator!=(trie_iterator_base const & lhs,
  85. trie_iterator_base const & rhs) {
  86. return !(lhs == rhs);
  87. }
  88. friend bool operator==(trie_iterator_base const & lhs,
  89. trie_iterator_base const & rhs) {
  90. return (lhs.done && rhs.done) ||
  91. (lhs.keys == rhs.keys && lhs.done == rhs.done && *lhs == *rhs);
  92. }
  93. friend Trie;
  94. template <typename Self, typename _Trie, typename KS>
  95. friend Self find_impl(_Trie * tr, KS const & keys);
  96. };
  97. }
  98. template <typename Trie, typename Iter>
  99. class trie_iterator : public detail::trie_iterator_base<Trie, Iter> {
  100. private:
  101. using super = detail::trie_iterator_base<Trie, Iter>;
  102. public:
  103. trie_iterator() : super() {}
  104. trie_iterator(Trie * tr) : super(tr) {}
  105. trie_iterator(super && take) : super(std::move(take)) {}
  106. trie_iterator & operator++() {
  107. if (super::done) return *this;
  108. if (super::iters.empty() || super::can_recurse()) {
  109. super::recurse();
  110. } else {
  111. advance();
  112. }
  113. return *this;
  114. }
  115. private:
  116. void advance() {
  117. ++super::iters.top();
  118. while (super::poping_empty()) {
  119. ++super::iters.top();
  120. }
  121. super::assign();
  122. super::done = super::iters.empty();
  123. }
  124. friend Trie;
  125. };
  126. template <typename Trie, typename Iter>
  127. class trie_reverse_iterator : public detail::trie_iterator_base<Trie, Iter> {
  128. private:
  129. using super = detail::trie_iterator_base<Trie, Iter>;
  130. public:
  131. trie_reverse_iterator() : super() {}
  132. trie_reverse_iterator(Trie * tr) : super(tr) {
  133. if (super::can_recurse()) recurse();
  134. }
  135. trie_reverse_iterator & operator++() {
  136. if (super::done || super::iters.empty()) {
  137. super::done = true;
  138. } else {
  139. advance();
  140. }
  141. return *this;
  142. }
  143. private:
  144. void recurse() {
  145. do {
  146. super::recurse();
  147. } while (super::can_recurse());
  148. }
  149. void advance() {
  150. ++super::iters.top();
  151. if (super::iters.top().done()) {
  152. while (super::poping_empty())
  153. ;
  154. super::assign();
  155. } else {
  156. super::assign();
  157. if (super::can_recurse()) recurse();
  158. }
  159. }
  160. friend Trie;
  161. };