|
|
@@ -10,6 +10,7 @@
|
|
|
#include "trie.hpp"
|
|
|
|
|
|
#include "iterator/end_aware_iterator.hpp"
|
|
|
+#include <list>
|
|
|
#include <stack>
|
|
|
|
|
|
namespace detail {
|
|
|
@@ -38,10 +39,23 @@ namespace detail {
|
|
|
std::list<typename Trie::key_type> keys;
|
|
|
std::stack<impl_t> iters;
|
|
|
bool done{false};
|
|
|
+ public:
|
|
|
+ using reference = decltype(std::declval<Trie>().value());
|
|
|
+ using value_type = std::remove_reference_t<reference>;
|
|
|
+ using pointer = value_type *;
|
|
|
+ using difference_type = std::ptrdiff_t;
|
|
|
+ using iterator_category = std::forward_iterator_tag;
|
|
|
public:
|
|
|
trie_iterator_base() : done{true} {}
|
|
|
trie_iterator_base(Trie * tr) { stk.push(tr); }
|
|
|
- auto operator*() const -> decltype(this->stk.top()->value()) { return *stk.top(); }
|
|
|
+ auto operator*() const -> reference { return root(); }
|
|
|
+ auto operator->() const -> pointer { return std::addressof(operator*()); }
|
|
|
+ Trie & root() const { return *stk.top(); }
|
|
|
+ trie_iterator_base parent() const {
|
|
|
+ trie_iterator_base tmp{*this};
|
|
|
+ tmp.pop();
|
|
|
+ return tmp;
|
|
|
+ }
|
|
|
protected:
|
|
|
void push(impl_t it) {
|
|
|
iters.push(it);
|
|
|
@@ -65,7 +79,7 @@ namespace detail {
|
|
|
}
|
|
|
bool can_recurse() { return !next().done(); }
|
|
|
void recurse() { push(next()); }
|
|
|
- impl_t next() { return helper()(*stk.top()); }
|
|
|
+ impl_t next() { return helper()(root()); }
|
|
|
friend bool operator!=(trie_iterator_base const & lhs, trie_iterator_base const & rhs) {
|
|
|
return !(lhs == rhs);
|
|
|
}
|
|
|
@@ -85,12 +99,6 @@ template <typename Trie, typename Iter>
|
|
|
class trie_iterator : public detail::trie_iterator_base<Trie, Iter> {
|
|
|
private:
|
|
|
using super = detail::trie_iterator_base<Trie, Iter>;
|
|
|
-public:
|
|
|
- using reference = decltype(*(std::declval<super>()));
|
|
|
- using value_type = std::remove_reference_t<reference>;
|
|
|
- using pointer = value_type *;
|
|
|
- using difference_type = std::ptrdiff_t;
|
|
|
- using iterator_category = std::forward_iterator_tag;
|
|
|
public:
|
|
|
trie_iterator() : super() {}
|
|
|
trie_iterator(Trie * tr) : super(tr) { }
|
|
|
@@ -117,12 +125,6 @@ template <typename Trie, typename Iter>
|
|
|
class trie_reverse_iterator : public detail::trie_iterator_base<Trie, Iter> {
|
|
|
private:
|
|
|
using super = detail::trie_iterator_base<Trie, Iter>;
|
|
|
-public:
|
|
|
- using reference = decltype(*(std::declval<super>()));
|
|
|
- using value_type = std::remove_reference_t<reference>;
|
|
|
- using pointer = value_type *;
|
|
|
- using difference_type = std::ptrdiff_t;
|
|
|
- using iterator_category = std::forward_iterator_tag;
|
|
|
public:
|
|
|
trie_reverse_iterator() : super() {}
|
|
|
trie_reverse_iterator(Trie * tr) : super(tr) {
|