mdds
Loading...
Searching...
No Matches
aos/iterator.hpp
1// SPDX-FileCopyrightText: 2012 - 2025 Kohei Yoshida
2//
3// SPDX-License-Identifier: MIT
4
5#pragma once
6
7#include "../iterator_node.hpp"
8
9#include <cstddef>
10
11namespace mdds { namespace mtv { namespace aos { namespace detail {
12
18template<typename Traits>
19class iterator_common_base
20{
21protected:
22 typedef typename Traits::parent parent_type;
23 typedef typename Traits::blocks blocks_type;
24 typedef typename Traits::base_iterator base_iterator_type;
25
26 typedef typename parent_type::size_type size_type;
28
29 iterator_common_base() : m_cur_node(nullptr, 0)
30 {}
31
32 iterator_common_base(
33 const base_iterator_type& pos, const base_iterator_type& end, const parent_type* parent, size_type block_index)
34 : m_cur_node(parent, block_index), m_pos(pos), m_end(end)
35 {
36 if (m_pos != m_end)
37 update_node();
38 }
39
40 iterator_common_base(const iterator_common_base& other)
41 : m_cur_node(other.m_cur_node), m_pos(other.m_pos), m_end(other.m_end)
42 {}
43
44 void update_node()
45 {
46#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG
47 if (m_pos == m_end)
48 throw general_error("Current node position should never equal the end position during node update.");
49#endif
50 // blocks_type::value_type is a pointer to multi_type_vector::block.
51 const typename blocks_type::value_type& blk = *m_pos;
52 if (blk.data)
53 m_cur_node.type = mdds::mtv::get_block_type(*blk.data);
54 else
55 m_cur_node.type = mdds::mtv::element_type_empty;
56
57 m_cur_node.position = blk.position;
58 m_cur_node.size = blk.size;
59 m_cur_node.data = blk.data;
60 }
61
62 node* inc()
63 {
64 ++m_pos;
65 if (m_pos == m_end)
66 return nullptr;
67
68 update_node();
69 return &m_cur_node;
70 }
71
72 node* dec()
73 {
74 --m_pos;
75 update_node();
76 return &m_cur_node;
77 }
78
79 node m_cur_node;
80 base_iterator_type m_pos;
81 base_iterator_type m_end;
82
83public:
84 bool operator==(const iterator_common_base& other) const
85 {
86 if (m_pos != m_end && other.m_pos != other.m_end)
87 {
88 // TODO: Set hard-coded values to the current node for the end
89 // position nodes to remove this if block.
90 if (m_cur_node != other.m_cur_node)
91 return false;
92 }
93 return m_pos == other.m_pos && m_end == other.m_end;
94 }
95
96 bool operator!=(const iterator_common_base& other) const
97 {
98 return !operator==(other);
99 }
100
101 iterator_common_base& operator=(const iterator_common_base& other)
102 {
103 m_cur_node = other.m_cur_node;
104 m_pos = other.m_pos;
105 m_end = other.m_end;
106 return *this;
107 }
108
109 void swap(iterator_common_base& other)
110 {
111 m_cur_node.swap(other.m_cur_node);
112 std::swap(m_pos, other.m_pos);
113 std::swap(m_end, other.m_end);
114 }
115
116 const node& get_node() const
117 {
118 return m_cur_node;
119 }
120 const base_iterator_type& get_pos() const
121 {
122 return m_pos;
123 }
124 const base_iterator_type& get_end() const
125 {
126 return m_end;
127 }
128};
129
130template<typename Traits, typename NodeUpdateFunc>
131class iterator_base : public iterator_common_base<Traits>
132{
133 using parent_type = typename Traits::parent;
134 typedef NodeUpdateFunc node_update_func;
135 typedef iterator_common_base<Traits> common_base;
136
137 typedef typename Traits::base_iterator base_iterator_type;
138 typedef typename common_base::size_type size_type;
139
140 using common_base::dec;
141 using common_base::inc;
142 using common_base::m_cur_node;
143
144public:
145 using common_base::get_end;
146 using common_base::get_pos;
147
148 // iterator traits
149 typedef typename common_base::node value_type;
150 typedef value_type* pointer;
151 typedef value_type& reference;
152 typedef ptrdiff_t difference_type;
153 typedef std::bidirectional_iterator_tag iterator_category;
154
155public:
156 iterator_base()
157 {}
158 iterator_base(
159 const base_iterator_type& pos, const base_iterator_type& end, const parent_type* parent, size_type block_index)
160 : common_base(pos, end, parent, block_index)
161 {}
162
163 value_type& operator*()
164 {
165 return m_cur_node;
166 }
167
168 const value_type& operator*() const
169 {
170 return m_cur_node;
171 }
172
173 value_type* operator->()
174 {
175 return &m_cur_node;
176 }
177
178 const value_type* operator->() const
179 {
180 return &m_cur_node;
181 }
182
183 iterator_base& operator++()
184 {
185 node_update_func::inc(m_cur_node);
186 inc();
187 return *this;
188 }
189
190 iterator_base& operator--()
191 {
192 dec();
193 node_update_func::dec(m_cur_node);
194 return *this;
195 }
196};
197
198template<typename Traits, typename NodeUpdateFunc, typename NonConstItrBase>
199class const_iterator_base : public iterator_common_base<Traits>
200{
201 using parent_type = typename Traits::parent;
202 typedef NodeUpdateFunc node_update_func;
203 typedef iterator_common_base<Traits> common_base;
204
205 typedef typename Traits::base_iterator base_iterator_type;
206 typedef typename common_base::size_type size_type;
207
208 using common_base::dec;
209 using common_base::inc;
210 using common_base::m_cur_node;
211
212public:
213 using common_base::get_end;
214 using common_base::get_pos;
215
216 typedef NonConstItrBase iterator_base;
217
218 // iterator traits
219 typedef typename common_base::node value_type;
220 typedef value_type* pointer;
221 typedef value_type& reference;
222 typedef ptrdiff_t difference_type;
223 typedef std::bidirectional_iterator_tag iterator_category;
224
225public:
226 const_iterator_base() : common_base()
227 {}
228 const_iterator_base(
229 const base_iterator_type& pos, const base_iterator_type& end, const parent_type* parent, size_type block_index)
230 : common_base(pos, end, parent, block_index)
231 {}
232
236 const_iterator_base(const iterator_base& other)
237 : common_base(
238 other.get_pos(), other.get_end(), other.get_node().__private_data.parent,
239 other.get_node().__private_data.block_index)
240 {}
241
242 const value_type& operator*() const
243 {
244 return m_cur_node;
245 }
246
247 const value_type* operator->() const
248 {
249 return &m_cur_node;
250 }
251
252 const_iterator_base& operator++()
253 {
254 node_update_func::inc(m_cur_node);
255 inc();
256 return *this;
257 }
258
259 const_iterator_base& operator--()
260 {
261 dec();
262 node_update_func::dec(m_cur_node);
263 return *this;
264 }
265
266 bool operator==(const const_iterator_base& other) const
267 {
268 return iterator_common_base<Traits>::operator==(other);
269 }
270
271 bool operator!=(const const_iterator_base& other) const
272 {
273 return iterator_common_base<Traits>::operator!=(other);
274 }
275};
276
277}}}} // namespace mdds::mtv::aos::detail
Definition global.hpp:60
const_iterator_base(const iterator_base &other)
Definition aos/iterator.hpp:236
Definition iterator_node.hpp:19