mdds
flat_segment_tree_itr.hpp
1 // SPDX-FileCopyrightText: 2010 - 2025 Kohei Yoshida
2 //
3 // SPDX-License-Identifier: MIT
4 
5 #pragma once
6 
7 #include "./ref_pair.hpp"
8 #include <type_traits>
9 
10 namespace mdds { namespace fst { namespace detail {
11 
15 template<typename FstType>
17 {
18  using fst_type = FstType;
19 
20  static const typename fst_type::node* init_pos(const fst_type* _db, bool _end)
21  {
22  return _end ? _db->m_right_leaf.get() : _db->m_left_leaf.get();
23  }
24 
25  static void inc(const fst_type* _db, const typename fst_type::node*& p, bool& end)
26  {
27  if (p == _db->m_right_leaf.get())
28  end = true;
29  else
30  p = p->next.get();
31  }
32 
33  static void dec(const typename fst_type::node*& p, bool& end)
34  {
35  if (end)
36  end = false;
37  else
38  p = p->prev.get();
39  }
40 };
41 
45 template<typename FstType>
47 {
48  using fst_type = FstType;
49 
50  static const typename fst_type::node* init_pos(const fst_type* _db, bool _end)
51  {
52  return _end ? _db->m_left_leaf.get() : _db->m_right_leaf.get();
53  }
54 
55  static void inc(const fst_type* _db, const typename fst_type::node*& p, bool& end)
56  {
57  if (p == _db->m_left_leaf.get())
58  end = true;
59  else
60  p = p->prev.get();
61  }
62 
63  static void dec(const typename fst_type::node*& p, bool& end)
64  {
65  if (end)
66  end = false;
67  else
68  p = p->next.get();
69  }
70 };
71 
72 template<typename FstType, typename Hdl>
74 {
75  typedef Hdl handler_type;
76 
77 public:
78  typedef FstType fst_type;
79 
80  // iterator traits
82  std::add_const_t<typename fst_type::key_type>, std::add_const_t<typename fst_type::value_type>>;
83  using pointer = value_type*;
84  using reference = value_type&;
85  using difference_type = ptrdiff_t;
86  using iterator_category = ::std::bidirectional_iterator_tag;
87 
88  explicit const_iterator_base(const fst_type* _db, bool _end) : m_db(_db), m_end_pos(_end)
89  {
90  if (!_db)
91  return;
92 
93  m_pos = handler_type::init_pos(_db, _end);
94  }
95 
96  explicit const_iterator_base(const fst_type* _db, const typename fst_type::node* pos) : m_db(_db), m_pos(pos)
97  {}
98 
99  const_iterator_base(const const_iterator_base& r) : m_db(r.m_db), m_pos(r.m_pos), m_end_pos(r.m_end_pos)
100  {}
101 
102  const_iterator_base& operator=(const const_iterator_base& r)
103  {
104  m_db = r.m_db;
105  m_pos = r.m_pos;
106  m_end_pos = r.m_end_pos;
107  return *this;
108  }
109 
110  const_iterator_base& operator++()
111  {
112  assert(m_pos);
113  handler_type::inc(m_db, m_pos, m_end_pos);
114  return *this;
115  }
116 
117  const_iterator_base& operator--()
118  {
119  assert(m_pos);
120  handler_type::dec(m_pos, m_end_pos);
121  return *this;
122  }
123 
124  bool operator==(const const_iterator_base& r) const
125  {
126  if (m_db != r.m_db)
127  return false;
128 
129  return (m_pos == r.m_pos) && (m_end_pos == r.m_end_pos);
130  }
131 
132  bool operator!=(const const_iterator_base& r) const
133  {
134  return !operator==(r);
135  }
136 
137  value_type operator*()
138  {
139  return value_type(m_pos->key, m_pos->value_leaf.value);
140  }
141 
142  value_type operator->()
143  {
144  return value_type(m_pos->key, m_pos->value_leaf.value);
145  }
146 
147 protected:
148  const typename fst_type::node* get_pos() const
149  {
150  return m_pos;
151  }
152 
153  const fst_type* get_parent() const
154  {
155  return m_db;
156  }
157 
158  bool is_end_pos() const
159  {
160  return m_end_pos;
161  }
162 
163 private:
164  const fst_type* m_db = nullptr;
165  const typename fst_type::node* m_pos = nullptr;
166  bool m_end_pos = false;
167 };
168 
169 template<typename FstType>
171 {
172  typedef FstType fst_type;
173  friend fst_type;
174 
175  const_segment_iterator(const typename fst_type::node* start, const typename fst_type::node* end)
176  : m_start(start), m_end(end)
177  {
178  update_node();
179  }
180 
181 public:
182  struct value_type
183  {
184  typename fst_type::key_type start;
185  typename fst_type::key_type end;
186  typename fst_type::value_type value;
187 
188  value_type() : start(), end(), value()
189  {}
190 
191  value_type(
192  typename fst_type::key_type _start, typename fst_type::key_type _end, typename fst_type::value_type _value)
193  : start(std::move(_start)), end(std::move(_end)), value(std::move(_value))
194  {}
195 
196  bool operator==(const value_type& other) const
197  {
198  return start == other.start && end == other.end && value == other.value;
199  }
200 
201  bool operator!=(const value_type& other) const
202  {
203  return !operator==(other);
204  }
205  };
206 
207  const_segment_iterator() : m_start(nullptr), m_end(nullptr)
208  {}
209  const_segment_iterator(const const_segment_iterator& other) : m_start(other.m_start), m_end(other.m_end)
210  {
211  if (m_start)
212  update_node();
213  }
214  const_segment_iterator(const_segment_iterator&& other)
215  : m_start(std::move(other.m_start)), m_end(std::move(other.m_end))
216  {
217  if (m_start)
218  update_node();
219  }
220 
221  ~const_segment_iterator()
222  {}
223 
224  bool operator==(const const_segment_iterator& other) const
225  {
226  return m_start == other.m_start && m_end == other.m_end;
227  }
228 
229  bool operator!=(const const_segment_iterator& other) const
230  {
231  return !operator==(other);
232  }
233 
234  const_segment_iterator& operator=(const const_segment_iterator& other)
235  {
236  m_start = other.m_start;
237  m_end = other.m_end;
238  if (m_start)
239  update_node();
240  return *this;
241  }
242 
243  const_segment_iterator& operator=(const_segment_iterator&& other)
244  {
245  m_start = std::move(other.m_start);
246  m_end = std::move(other.m_end);
247  if (m_start)
248  update_node();
249  return *this;
250  }
251 
252  const value_type& operator*()
253  {
254  return m_node;
255  }
256 
257  const value_type* operator->()
258  {
259  return &m_node;
260  }
261 
262  const_segment_iterator& operator++()
263  {
264  assert(m_start);
265  m_start = m_start->next.get();
266  m_end = m_start->next.get();
267  update_node();
268  return *this;
269  }
270 
271  const_segment_iterator operator++(int)
272  {
273  assert(m_start);
274  const_segment_iterator ret = *this;
275  m_start = m_start->next.get();
276  m_end = m_start->next.get();
277  update_node();
278  return ret;
279  }
280 
281  const_segment_iterator& operator--()
282  {
283  assert(m_start);
284  m_start = m_start->prev.get();
285  m_end = m_start->next.get();
286  update_node();
287  return *this;
288  }
289 
290  const_segment_iterator operator--(int)
291  {
292  assert(m_start);
293  const_segment_iterator ret = *this;
294  m_start = m_start->prev.get();
295  m_end = m_start->next.get();
296  update_node();
297  return ret;
298  }
299 
300 private:
301  void update_node()
302  {
303  if (!m_end)
304  // The iterator is at its end position. Nothing to do.
305  return;
306 
307  m_node.start = m_start->key;
308  m_node.end = m_end->key;
309  m_node.value = m_start->value_leaf.value;
310  }
311 
312 private:
313  const typename fst_type::node* m_start;
314  const typename fst_type::node* m_end;
315  value_type m_node;
316 };
317 
318 }}} // namespace mdds::fst::detail
Definition: flat_segment_tree_itr.hpp:46
Definition: ref_pair.hpp:14
Definition: flat_segment_tree_itr.hpp:182
Definition: flat_segment_tree_itr.hpp:73
Definition: flat_segment_tree_itr.hpp:16
Definition: flat_segment_tree_itr.hpp:170
Definition: cref_wrapper.hpp:12