trie_iterator.hpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  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 <stack>
  11. namespace detail {
  12. template <typename Iter>
  13. struct trie_iterator_next {
  14. template <typename Trie>
  15. ::iterator::end_aware_iterator<Iter> 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. template <typename Trie>
  22. ::iterator::end_aware_iterator<std::reverse_iterator<Iter>> operator()(Trie & tr) {
  23. return { tr.local_rbegin(), tr.local_rend() };
  24. }
  25. };
  26. }
  27. template <typename Trie, typename V, typename Iter>
  28. class trie_iterator {
  29. private:
  30. using impl_t = ::iterator::end_aware_iterator<Iter>;
  31. public:
  32. using value_type = V;
  33. using reference = value_type &;
  34. using pointer = value_type *;
  35. using difference_type = std::ptrdiff_t;
  36. using iterator_category = std::forward_iterator_tag;
  37. public:
  38. trie_iterator() : done{true} {}
  39. trie_iterator(Trie * tr) { stk.push(tr); }
  40. reference operator*() const { return *stk.top(); }
  41. trie_iterator & operator++() {
  42. if (done) return *this;
  43. if ( iters.empty() || can_recurse() ) { recurse(); }
  44. else { advance(); }
  45. return *this;
  46. }
  47. private:
  48. bool can_recurse() { return !next().done(); }
  49. void recurse() {
  50. auto it = next();
  51. iters.push(it);
  52. keys.push_back(it->first);
  53. stk.push(it->second.get());
  54. }
  55. impl_t next() { return detail::trie_iterator_next<Iter>()(*stk.top()); }
  56. void advance() {
  57. ++iters.top();
  58. while (iters.top().done()) {
  59. stk.pop();
  60. iters.pop();
  61. keys.pop_back();
  62. if ( iters.empty() ) break;
  63. ++iters.top();
  64. }
  65. if (!iters.empty()) {
  66. stk.top() = iters.top()->second.get();
  67. keys.back() = iters.top()->first;
  68. } else {
  69. done = true;
  70. }
  71. }
  72. friend bool operator!=(trie_iterator const & lhs, trie_iterator const & rhs) {
  73. return !(lhs == rhs);
  74. }
  75. friend bool operator==(trie_iterator const & lhs, trie_iterator const & rhs) {
  76. if ( lhs.done && rhs.done ) return true;
  77. else if (lhs.keys != rhs.keys) return false;
  78. else if ( lhs.done != rhs.done ) return false;
  79. else return *lhs == *rhs;
  80. }
  81. friend Trie;
  82. std::stack<Trie *> stk;
  83. std::list<typename Trie::key_type> keys;
  84. std::stack<impl_t> iters;
  85. bool done{false};
  86. };
  87. template <typename Trie, typename V, typename Iter>
  88. class trie_reverse_iterator {
  89. private:
  90. using impl_t = ::iterator::end_aware_iterator<Iter>;
  91. public:
  92. using value_type = V;
  93. using reference = value_type &;
  94. using pointer = value_type *;
  95. using difference_type = std::ptrdiff_t;
  96. using iterator_category = std::forward_iterator_tag;
  97. public:
  98. trie_reverse_iterator() : done{true} {}
  99. trie_reverse_iterator(Trie * tr) {
  100. stk.push(tr);
  101. if (can_recurse()) recurse();
  102. }
  103. reference operator*() const { return *stk.top(); }
  104. trie_reverse_iterator & operator++() {
  105. if (done || iters.empty()) { done = true; return *this; }
  106. advance();
  107. return *this;
  108. }
  109. private:
  110. bool can_recurse() { return !next().done(); }
  111. void recurse() {
  112. do {
  113. auto it = next();
  114. iters.push(it);
  115. keys.push_back(it->first);
  116. stk.push(it->second.get());
  117. } while ( can_recurse() );
  118. }
  119. impl_t next() { return detail::trie_iterator_next<Iter>()(*stk.top()); }
  120. void advance() {
  121. ++iters.top();
  122. if (iters.top().done()) {
  123. while (iters.top().done()) {
  124. stk.pop();
  125. iters.pop();
  126. keys.pop_back();
  127. if ( iters.empty() ) break;
  128. }
  129. if (!iters.empty()) {
  130. stk.top() = iters.top()->second.get();
  131. keys.back() = iters.top()->first;
  132. }
  133. } else {
  134. stk.top() = iters.top()->second.get();
  135. keys.back() = iters.top()->first;
  136. if (can_recurse()) recurse();
  137. }
  138. }
  139. friend bool operator!=(trie_reverse_iterator const & lhs, trie_reverse_iterator const & rhs) {
  140. return !(lhs == rhs);
  141. }
  142. friend bool operator==(trie_reverse_iterator const & lhs, trie_reverse_iterator const & rhs) {
  143. if ( lhs.done && rhs.done ) return true;
  144. else if (lhs.keys != rhs.keys) return false;
  145. else if ( lhs.done != rhs.done ) return false;
  146. else return *lhs == *rhs;
  147. }
  148. friend Trie;
  149. std::stack<Trie *> stk;
  150. std::list<typename Trie::key_type> keys;
  151. std::stack<impl_t> iters;
  152. bool done{false};
  153. };