trie_iterator.hpp 4.3 KB

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