/src/mdds-3.1.0/include/mdds/flat_segment_tree_itr.hpp
Line | Count | Source |
1 | | /************************************************************************* |
2 | | * |
3 | | * Copyright (c) 2010-2023 Kohei Yoshida |
4 | | * |
5 | | * Permission is hereby granted, free of charge, to any person |
6 | | * obtaining a copy of this software and associated documentation |
7 | | * files (the "Software"), to deal in the Software without |
8 | | * restriction, including without limitation the rights to use, |
9 | | * copy, modify, merge, publish, distribute, sublicense, and/or sell |
10 | | * copies of the Software, and to permit persons to whom the |
11 | | * Software is furnished to do so, subject to the following |
12 | | * conditions: |
13 | | * |
14 | | * The above copyright notice and this permission notice shall be |
15 | | * included in all copies or substantial portions of the Software. |
16 | | * |
17 | | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
18 | | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
19 | | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
20 | | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
21 | | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
22 | | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
23 | | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
24 | | * OTHER DEALINGS IN THE SOFTWARE. |
25 | | * |
26 | | ************************************************************************/ |
27 | | |
28 | | #pragma once |
29 | | |
30 | | #include "./ref_pair.hpp" |
31 | | #include <type_traits> |
32 | | |
33 | | namespace mdds { namespace fst { namespace detail { |
34 | | |
35 | | /** |
36 | | * Handler for forward iterator |
37 | | */ |
38 | | template<typename FstType> |
39 | | struct forward_itr_handler |
40 | | { |
41 | | using fst_type = FstType; |
42 | | |
43 | | static const typename fst_type::node* init_pos(const fst_type* _db, bool _end) |
44 | 1.27k | { |
45 | 1.27k | return _end ? _db->m_right_leaf.get() : _db->m_left_leaf.get(); |
46 | 1.27k | } mdds::fst::detail::forward_itr_handler<mdds::flat_segment_tree<unsigned int, float> >::init_pos(mdds::flat_segment_tree<unsigned int, float> const*, bool) Line | Count | Source | 44 | 1.27k | { | 45 | 1.27k | return _end ? _db->m_right_leaf.get() : _db->m_left_leaf.get(); | 46 | 1.27k | } |
Unexecuted instantiation: mdds::fst::detail::forward_itr_handler<mdds::flat_segment_tree<unsigned int, bool> >::init_pos(mdds::flat_segment_tree<unsigned int, bool> const*, bool) Unexecuted instantiation: mdds::fst::detail::forward_itr_handler<mdds::flat_segment_tree<unsigned int, std::__1::shared_ptr<libetonyek::IWORKStyle> > >::init_pos(mdds::flat_segment_tree<unsigned int, std::__1::shared_ptr<libetonyek::IWORKStyle> > const*, bool) |
47 | | |
48 | | static void inc(const fst_type* _db, const typename fst_type::node*& p, bool& end) |
49 | 449 | { |
50 | 449 | if (p == _db->m_right_leaf.get()) |
51 | 190 | end = true; |
52 | 259 | else |
53 | 259 | p = p->next.get(); |
54 | 449 | } |
55 | | |
56 | | static void dec(const typename fst_type::node*& p, bool& end) |
57 | | { |
58 | | if (end) |
59 | | end = false; |
60 | | else |
61 | | p = p->prev.get(); |
62 | | } |
63 | | }; |
64 | | |
65 | | /** |
66 | | * Handler for reverse iterator |
67 | | */ |
68 | | template<typename FstType> |
69 | | struct reverse_itr_handler |
70 | | { |
71 | | using fst_type = FstType; |
72 | | |
73 | | static const typename fst_type::node* init_pos(const fst_type* _db, bool _end) |
74 | | { |
75 | | return _end ? _db->m_left_leaf.get() : _db->m_right_leaf.get(); |
76 | | } |
77 | | |
78 | | static void inc(const fst_type* _db, const typename fst_type::node*& p, bool& end) |
79 | | { |
80 | | if (p == _db->m_left_leaf.get()) |
81 | | end = true; |
82 | | else |
83 | | p = p->prev.get(); |
84 | | } |
85 | | |
86 | | static void dec(const typename fst_type::node*& p, bool& end) |
87 | | { |
88 | | if (end) |
89 | | end = false; |
90 | | else |
91 | | p = p->next.get(); |
92 | | } |
93 | | }; |
94 | | |
95 | | template<typename FstType, typename Hdl> |
96 | | class const_iterator_base |
97 | | { |
98 | | typedef Hdl handler_type; |
99 | | |
100 | | public: |
101 | | typedef FstType fst_type; |
102 | | |
103 | | // iterator traits |
104 | | using value_type = mdds::detail::ref_pair< |
105 | | std::add_const_t<typename fst_type::key_type>, std::add_const_t<typename fst_type::value_type>>; |
106 | | using pointer = value_type*; |
107 | | using reference = value_type&; |
108 | | using difference_type = ptrdiff_t; |
109 | | using iterator_category = ::std::bidirectional_iterator_tag; |
110 | | |
111 | 1.27k | explicit const_iterator_base(const fst_type* _db, bool _end) : m_db(_db), m_end_pos(_end) |
112 | 1.27k | { |
113 | 1.27k | if (!_db) |
114 | 0 | return; |
115 | | |
116 | 1.27k | m_pos = handler_type::init_pos(_db, _end); |
117 | 1.27k | } mdds::fst::detail::const_iterator_base<mdds::flat_segment_tree<unsigned int, float>, mdds::fst::detail::forward_itr_handler<mdds::flat_segment_tree<unsigned int, float> > >::const_iterator_base(mdds::flat_segment_tree<unsigned int, float> const*, bool) Line | Count | Source | 111 | 1.27k | explicit const_iterator_base(const fst_type* _db, bool _end) : m_db(_db), m_end_pos(_end) | 112 | 1.27k | { | 113 | 1.27k | if (!_db) | 114 | 0 | return; | 115 | | | 116 | 1.27k | m_pos = handler_type::init_pos(_db, _end); | 117 | 1.27k | } |
Unexecuted instantiation: mdds::fst::detail::const_iterator_base<mdds::flat_segment_tree<unsigned int, bool>, mdds::fst::detail::forward_itr_handler<mdds::flat_segment_tree<unsigned int, bool> > >::const_iterator_base(mdds::flat_segment_tree<unsigned int, bool> const*, bool) Unexecuted instantiation: mdds::fst::detail::const_iterator_base<mdds::flat_segment_tree<unsigned int, std::__1::shared_ptr<libetonyek::IWORKStyle> >, mdds::fst::detail::forward_itr_handler<mdds::flat_segment_tree<unsigned int, std::__1::shared_ptr<libetonyek::IWORKStyle> > > >::const_iterator_base(mdds::flat_segment_tree<unsigned int, std::__1::shared_ptr<libetonyek::IWORKStyle> > const*, bool) |
118 | | |
119 | 2.16k | explicit const_iterator_base(const fst_type* _db, const typename fst_type::node* pos) : m_db(_db), m_pos(pos) |
120 | 2.16k | {}mdds::fst::detail::const_iterator_base<mdds::flat_segment_tree<unsigned int, float>, mdds::fst::detail::forward_itr_handler<mdds::flat_segment_tree<unsigned int, float> > >::const_iterator_base(mdds::flat_segment_tree<unsigned int, float> const*, mdds::st::detail::node<unsigned int, mdds::flat_segment_tree<unsigned int, float>::leaf_value_type> const*) Line | Count | Source | 119 | 656 | explicit const_iterator_base(const fst_type* _db, const typename fst_type::node* pos) : m_db(_db), m_pos(pos) | 120 | 656 | {} |
mdds::fst::detail::const_iterator_base<mdds::flat_segment_tree<unsigned int, bool>, mdds::fst::detail::forward_itr_handler<mdds::flat_segment_tree<unsigned int, bool> > >::const_iterator_base(mdds::flat_segment_tree<unsigned int, bool> const*, mdds::st::detail::node<unsigned int, mdds::flat_segment_tree<unsigned int, bool>::leaf_value_type> const*) Line | Count | Source | 119 | 651 | explicit const_iterator_base(const fst_type* _db, const typename fst_type::node* pos) : m_db(_db), m_pos(pos) | 120 | 651 | {} |
mdds::fst::detail::const_iterator_base<mdds::flat_segment_tree<unsigned int, std::__1::shared_ptr<libetonyek::IWORKStyle> >, mdds::fst::detail::forward_itr_handler<mdds::flat_segment_tree<unsigned int, std::__1::shared_ptr<libetonyek::IWORKStyle> > > >::const_iterator_base(mdds::flat_segment_tree<unsigned int, std::__1::shared_ptr<libetonyek::IWORKStyle> > const*, mdds::st::detail::node<unsigned int, mdds::flat_segment_tree<unsigned int, std::__1::shared_ptr<libetonyek::IWORKStyle> >::leaf_value_type> const*) Line | Count | Source | 119 | 861 | explicit const_iterator_base(const fst_type* _db, const typename fst_type::node* pos) : m_db(_db), m_pos(pos) | 120 | 861 | {} |
|
121 | | |
122 | 2.16k | 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) |
123 | 2.16k | {}mdds::fst::detail::const_iterator_base<mdds::flat_segment_tree<unsigned int, float>, mdds::fst::detail::forward_itr_handler<mdds::flat_segment_tree<unsigned int, float> > >::const_iterator_base(mdds::fst::detail::const_iterator_base<mdds::flat_segment_tree<unsigned int, float>, mdds::fst::detail::forward_itr_handler<mdds::flat_segment_tree<unsigned int, float> > > const&) Line | Count | Source | 122 | 656 | 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) | 123 | 656 | {} |
mdds::fst::detail::const_iterator_base<mdds::flat_segment_tree<unsigned int, bool>, mdds::fst::detail::forward_itr_handler<mdds::flat_segment_tree<unsigned int, bool> > >::const_iterator_base(mdds::fst::detail::const_iterator_base<mdds::flat_segment_tree<unsigned int, bool>, mdds::fst::detail::forward_itr_handler<mdds::flat_segment_tree<unsigned int, bool> > > const&) Line | Count | Source | 122 | 651 | 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) | 123 | 651 | {} |
mdds::fst::detail::const_iterator_base<mdds::flat_segment_tree<unsigned int, std::__1::shared_ptr<libetonyek::IWORKStyle> >, mdds::fst::detail::forward_itr_handler<mdds::flat_segment_tree<unsigned int, std::__1::shared_ptr<libetonyek::IWORKStyle> > > >::const_iterator_base(mdds::fst::detail::const_iterator_base<mdds::flat_segment_tree<unsigned int, std::__1::shared_ptr<libetonyek::IWORKStyle> >, mdds::fst::detail::forward_itr_handler<mdds::flat_segment_tree<unsigned int, std::__1::shared_ptr<libetonyek::IWORKStyle> > > > const&) Line | Count | Source | 122 | 861 | 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) | 123 | 861 | {} |
|
124 | | |
125 | | const_iterator_base& operator=(const const_iterator_base& r) |
126 | | { |
127 | | m_db = r.m_db; |
128 | | m_pos = r.m_pos; |
129 | | m_end_pos = r.m_end_pos; |
130 | | return *this; |
131 | | } |
132 | | |
133 | | const_iterator_base& operator++() |
134 | 449 | { |
135 | 449 | assert(m_pos); |
136 | 449 | handler_type::inc(m_db, m_pos, m_end_pos); |
137 | 449 | return *this; |
138 | 449 | } |
139 | | |
140 | | const_iterator_base& operator--() |
141 | | { |
142 | | assert(m_pos); |
143 | | handler_type::dec(m_pos, m_end_pos); |
144 | | return *this; |
145 | | } |
146 | | |
147 | | bool operator==(const const_iterator_base& r) const |
148 | 1.08k | { |
149 | 1.08k | if (m_db != r.m_db) |
150 | 0 | return false; |
151 | | |
152 | 1.08k | return (m_pos == r.m_pos) && (m_end_pos == r.m_end_pos); |
153 | 1.08k | } |
154 | | |
155 | | bool operator!=(const const_iterator_base& r) const |
156 | 639 | { |
157 | 639 | return !operator==(r); |
158 | 639 | } |
159 | | |
160 | | value_type operator*() |
161 | | { |
162 | | return value_type(m_pos->key, m_pos->value_leaf.value); |
163 | | } |
164 | | |
165 | | value_type operator->() |
166 | 1.15k | { |
167 | 1.15k | return value_type(m_pos->key, m_pos->value_leaf.value); |
168 | 1.15k | } |
169 | | |
170 | | protected: |
171 | | const typename fst_type::node* get_pos() const |
172 | | { |
173 | | return m_pos; |
174 | | } |
175 | | |
176 | | const fst_type* get_parent() const |
177 | | { |
178 | | return m_db; |
179 | | } |
180 | | |
181 | | bool is_end_pos() const |
182 | | { |
183 | | return m_end_pos; |
184 | | } |
185 | | |
186 | | private: |
187 | | const fst_type* m_db = nullptr; |
188 | | const typename fst_type::node* m_pos = nullptr; |
189 | | bool m_end_pos = false; |
190 | | }; |
191 | | |
192 | | template<typename FstType> |
193 | | class const_segment_iterator |
194 | | { |
195 | | typedef FstType fst_type; |
196 | | friend fst_type; |
197 | | |
198 | | const_segment_iterator(const typename fst_type::node* start, const typename fst_type::node* end) |
199 | | : m_start(start), m_end(end) |
200 | | { |
201 | | update_node(); |
202 | | } |
203 | | |
204 | | public: |
205 | | struct value_type |
206 | | { |
207 | | typename fst_type::key_type start; |
208 | | typename fst_type::key_type end; |
209 | | typename fst_type::value_type value; |
210 | | |
211 | | value_type() : start(), end(), value() |
212 | | {} |
213 | | |
214 | | value_type( |
215 | | typename fst_type::key_type _start, typename fst_type::key_type _end, typename fst_type::value_type _value) |
216 | | : start(std::move(_start)), end(std::move(_end)), value(std::move(_value)) |
217 | | {} |
218 | | |
219 | | bool operator==(const value_type& other) const |
220 | | { |
221 | | return start == other.start && end == other.end && value == other.value; |
222 | | } |
223 | | |
224 | | bool operator!=(const value_type& other) const |
225 | | { |
226 | | return !operator==(other); |
227 | | } |
228 | | }; |
229 | | |
230 | | const_segment_iterator() : m_start(nullptr), m_end(nullptr) |
231 | | {} |
232 | | const_segment_iterator(const const_segment_iterator& other) : m_start(other.m_start), m_end(other.m_end) |
233 | | { |
234 | | if (m_start) |
235 | | update_node(); |
236 | | } |
237 | | const_segment_iterator(const_segment_iterator&& other) |
238 | | : m_start(std::move(other.m_start)), m_end(std::move(other.m_end)) |
239 | | { |
240 | | if (m_start) |
241 | | update_node(); |
242 | | } |
243 | | |
244 | | ~const_segment_iterator() |
245 | | {} |
246 | | |
247 | | bool operator==(const const_segment_iterator& other) const |
248 | | { |
249 | | return m_start == other.m_start && m_end == other.m_end; |
250 | | } |
251 | | |
252 | | bool operator!=(const const_segment_iterator& other) const |
253 | | { |
254 | | return !operator==(other); |
255 | | } |
256 | | |
257 | | const_segment_iterator& operator=(const const_segment_iterator& other) |
258 | | { |
259 | | m_start = other.m_start; |
260 | | m_end = other.m_end; |
261 | | if (m_start) |
262 | | update_node(); |
263 | | return *this; |
264 | | } |
265 | | |
266 | | const_segment_iterator& operator=(const_segment_iterator&& other) |
267 | | { |
268 | | m_start = std::move(other.m_start); |
269 | | m_end = std::move(other.m_end); |
270 | | if (m_start) |
271 | | update_node(); |
272 | | return *this; |
273 | | } |
274 | | |
275 | | const value_type& operator*() |
276 | | { |
277 | | return m_node; |
278 | | } |
279 | | |
280 | | const value_type* operator->() |
281 | | { |
282 | | return &m_node; |
283 | | } |
284 | | |
285 | | const_segment_iterator& operator++() |
286 | | { |
287 | | assert(m_start); |
288 | | m_start = m_start->next.get(); |
289 | | m_end = m_start->next.get(); |
290 | | update_node(); |
291 | | return *this; |
292 | | } |
293 | | |
294 | | const_segment_iterator operator++(int) |
295 | | { |
296 | | assert(m_start); |
297 | | const_segment_iterator ret = *this; |
298 | | m_start = m_start->next.get(); |
299 | | m_end = m_start->next.get(); |
300 | | update_node(); |
301 | | return ret; |
302 | | } |
303 | | |
304 | | const_segment_iterator& operator--() |
305 | | { |
306 | | assert(m_start); |
307 | | m_start = m_start->prev.get(); |
308 | | m_end = m_start->next.get(); |
309 | | update_node(); |
310 | | return *this; |
311 | | } |
312 | | |
313 | | const_segment_iterator operator--(int) |
314 | | { |
315 | | assert(m_start); |
316 | | const_segment_iterator ret = *this; |
317 | | m_start = m_start->prev.get(); |
318 | | m_end = m_start->next.get(); |
319 | | update_node(); |
320 | | return ret; |
321 | | } |
322 | | |
323 | | private: |
324 | | void update_node() |
325 | | { |
326 | | if (!m_end) |
327 | | // The iterator is at its end position. Nothing to do. |
328 | | return; |
329 | | |
330 | | m_node.start = m_start->key; |
331 | | m_node.end = m_end->key; |
332 | | m_node.value = m_start->value_leaf.value; |
333 | | } |
334 | | |
335 | | private: |
336 | | const typename fst_type::node* m_start; |
337 | | const typename fst_type::node* m_end; |
338 | | value_type m_node; |
339 | | }; |
340 | | |
341 | | }}} // namespace mdds::fst::detail |