mdds
Loading...
Searching...
No Matches
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
10namespace mdds { namespace fst { namespace detail {
11
15template<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
45template<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
72template<typename FstType, typename Hdl>
73class const_iterator_base
74{
75 typedef Hdl handler_type;
76
77public:
78 typedef FstType fst_type;
79
80 // iterator traits
81 using value_type = mdds::detail::ref_pair<
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
147protected:
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
163private:
164 const fst_type* m_db = nullptr;
165 const typename fst_type::node* m_pos = nullptr;
166 bool m_end_pos = false;
167};
168
169template<typename FstType>
170class const_segment_iterator
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
181public:
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
300private:
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
312private:
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:171
Definition ref_pair.hpp:15
Definition flat_segment_tree_itr.hpp:183
Definition flat_segment_tree_itr.hpp:17
Definition flat_segment_tree_itr.hpp:47