libwordring
tree_iterator.hpp
1 #pragma once
2 
3 #include <deque>
4 #include <iterator>
5 
6 namespace wordring::detail
7 {
12  template <typename Iterator, typename Allocator>
14  {
15  public:
16  explicit tree_iterator_stack(Allocator const& alloc = Allocator())
17  : m_stack(alloc)
18  {
19  }
20 
21  explicit tree_iterator_stack(Iterator const& base, Allocator const& alloc = Allocator())
22  : m_stack(1, base, alloc)
23  {
24  }
25 
26  tree_iterator_stack(Iterator first, Iterator last, Allocator const& alloc = Allocator())
27  : m_stack(alloc)
28  {
29  while (first != last) m_stack.push_back(first++);
30  }
31 
32  Iterator& top() const { return const_cast<std::deque<Iterator>&>(m_stack).front(); }
33 
34  void pop() { m_stack.erase(m_stack.begin()); }
35 
36  void push(Iterator const& it) { m_stack.push_front(it); }
37 
38  void push(Iterator first, Iterator last)
39  {
40  auto pos = m_stack.begin();
41  while (first != last) pos = ++m_stack.insert(pos, first++);
42  }
43 
44  bool empty() const { return m_stack.empty(); }
45 
46  private:
47  std::deque<Iterator> m_stack;
48  };
49 
54  template <typename Iterator, typename Allocator>
56  {
57  public:
58  explicit tree_iterator_queue(Allocator const& alloc = Allocator())
59  : m_queue(alloc)
60  {
61  }
62 
63  explicit tree_iterator_queue(Iterator const& base, Allocator const& alloc = Allocator())
64  : m_queue(1, base, alloc)
65  {
66  }
67 
68  tree_iterator_queue(Iterator first, Iterator last, Allocator const& alloc = Allocator())
69  : m_queue(alloc)
70  {
71  while (first != last) m_queue.push_back(first++);
72  }
73 
74  Iterator& top() const
75  {
76  return const_cast<std::deque<Iterator>&>(m_queue).front();
77  }
78 
79  void pop() { m_queue.erase(m_queue.begin()); }
80 
81  void push(Iterator const& it) { m_queue.push_back(it); }
82 
83  void push(Iterator first, Iterator last)
84  {
85  while (first != last) m_queue.push_back(first++);
86  }
87 
88  bool empty() const { return m_queue.empty(); }
89 
90  private:
91  std::deque<Iterator> m_queue;
92  };
93 }
94 
95 namespace wordring
96 {
134  template <typename Iterator, typename Container, typename Allocator>
136  {
137  template <typename Iterator1, typename Container1, typename Allocator1>
139 
140  template <typename Iterator1, typename Container1, typename Allocator1>
142 
143  public:
144  using base_type = Iterator;
145  using container = Container;
146  using allocator_type = Allocator;
147 
148  using value_type = typename std::iterator_traits<base_type>::value_type;
149  using difference_type = typename std::iterator_traits<base_type>::difference_type;
150  using reference = typename std::iterator_traits<base_type>::reference;
151  using pointer = typename std::iterator_traits<base_type>::pointer;
152  using iterator_category = std::input_iterator_tag;
153 
154  public:
155  explicit basic_tree_iterator(allocator_type const& alloc = allocator_type())
156  : m_c(alloc)
157  {
158  }
159 
167  explicit basic_tree_iterator(base_type const& it, allocator_type const& alloc = allocator_type())
168  : m_c(it, alloc)
169  {
170  }
171 
172  [[deprecated]]
173  basic_tree_iterator(base_type const& first, base_type const& last, allocator_type const& alloc = allocator_type())
174  : m_c(first, last, alloc)
175  {
176  }
177 
178  basic_tree_iterator(basic_tree_iterator const&) = default;
179 
180  basic_tree_iterator(basic_tree_iterator&&) = default;
181 
182  basic_tree_iterator& operator=(basic_tree_iterator const& rhs) = default;
183 
184  basic_tree_iterator& operator=(basic_tree_iterator&& rhs) = default;
185 
188  base_type base() const { return m_c.top(); }
189 
192  reference operator*() const
193  {
194  return const_cast<reference>(*m_c.top());
195  }
196 
199  pointer operator->() const
200  {
201  return const_cast<pointer>(m_c.top().operator->());
202  }
203 
209  {
210  base_type it = m_c.top();
211  m_c.pop();
212  m_c.push(it.begin(), it.end());
213  return *this;
214  }
215 
222  base_type operator++(int)
223  {
224  base_type result = m_c.top();
225  operator++();
226  return result;
227  }
228 
229  private:
230  container m_c;
231  };
232 
233  template <typename Iterator1, typename Container1, typename Allocator1>
234  inline bool operator==(basic_tree_iterator<Iterator1, Container1, Allocator1> const& lhs, basic_tree_iterator<Iterator1, Container1, Allocator1> const& rhs)
235  {
236  return (lhs.m_c.empty() && rhs.m_c.empty())
237  || (!lhs.m_c.empty() && !rhs.m_c.empty() && lhs.base() == rhs.base());
238  }
239 
240  template <typename Iterator1, typename Container1, typename Allocator1>
241  inline bool operator!=(basic_tree_iterator<Iterator1, Container1, Allocator1> const& lhs, basic_tree_iterator<Iterator1, Container1, Allocator1> const& rhs)
242  {
243  return !(lhs == rhs);
244  }
245 
246  template <typename Iterator, typename Allocator = std::allocator<Iterator>>
247  using tree_iterator = basic_tree_iterator<Iterator, detail::tree_iterator_stack<Iterator, Allocator>, Allocator>;
248 
249  template <typename Iterator, typename Allocator = std::allocator<Iterator>>
250  using level_order_tree_iterator = basic_tree_iterator<Iterator, detail::tree_iterator_queue<Iterator, Allocator>, Allocator>;
251 }
wordring::basic_tree_iterator::base
base_type base() const
現在の位置を指す、元となる木のイテレータを返す
Definition: tree_iterator.hpp:188
wordring::detail::tree_iterator_stack
Definition: tree_iterator.hpp:13
wordring
Definition: algorithm_.hpp:10
wordring::basic_tree_iterator::operator->
pointer operator->() const
要素の参照を返す
Definition: tree_iterator.hpp:199
wordring::basic_tree_iterator::basic_tree_iterator
basic_tree_iterator(base_type const &it, allocator_type const &alloc=allocator_type())
親を指すイテレータを指定して構築する
Definition: tree_iterator.hpp:167
wordring::detail::tree_iterator_queue
Definition: tree_iterator.hpp:55
wordring::basic_tree_iterator
プレ・オーダーあるいはレベル・オーダーで木を走査するイテレータ・アダプター
Definition: tree_iterator.hpp:135
wordring::detail
wordring::basic_tree_iterator::operator*
reference operator*() const
要素の逆参照を返す
Definition: tree_iterator.hpp:192
wordring::basic_tree_iterator::operator++
basic_tree_iterator & operator++()
イテレータを進める
Definition: tree_iterator.hpp:208
wordring::basic_tree_iterator::operator++
base_type operator++(int)
イテレータを進める
Definition: tree_iterator.hpp:222