trie_iterator.hpp 4.5 KB

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