mdds
aos/iterator.hpp
1/*************************************************************************
2 *
3 * Copyright (c) 2012-2021 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#ifndef INCLUDED_MDDS_MULTI_TYPE_VECTOR_DIR_AOS_ITERATOR_HPP
29#define INCLUDED_MDDS_MULTI_TYPE_VECTOR_DIR_AOS_ITERATOR_HPP
30
31#include "../iterator_node.hpp"
32
33#include <cstddef>
34
35namespace mdds { namespace mtv { namespace aos { namespace detail {
36
42template<typename Traits>
44{
45protected:
46 typedef typename Traits::parent parent_type;
47 typedef typename Traits::blocks blocks_type;
48 typedef typename Traits::base_iterator base_iterator_type;
49
50 typedef typename parent_type::size_type size_type;
52
53 iterator_common_base() : m_cur_node(nullptr, 0)
54 {}
55
57 const base_iterator_type& pos, const base_iterator_type& end, const parent_type* parent, size_type block_index)
58 : m_cur_node(parent, block_index), m_pos(pos), m_end(end)
59 {
60 if (m_pos != m_end)
61 update_node();
62 }
63
65 : m_cur_node(other.m_cur_node), m_pos(other.m_pos), m_end(other.m_end)
66 {}
67
68 void update_node()
69 {
70#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG
71 if (m_pos == m_end)
72 throw general_error("Current node position should never equal the end position during node update.");
73#endif
74 // blocks_type::value_type is a pointer to multi_type_vector::block.
75 const typename blocks_type::value_type& blk = *m_pos;
76 if (blk.data)
77 m_cur_node.type = mdds::mtv::get_block_type(*blk.data);
78 else
79 m_cur_node.type = mdds::mtv::element_type_empty;
80
81 m_cur_node.position = blk.position;
82 m_cur_node.size = blk.size;
83 m_cur_node.data = blk.data;
84 }
85
86 node* inc()
87 {
88 ++m_pos;
89 if (m_pos == m_end)
90 return nullptr;
91
92 update_node();
93 return &m_cur_node;
94 }
95
96 node* dec()
97 {
98 --m_pos;
99 update_node();
100 return &m_cur_node;
101 }
102
103 node m_cur_node;
104 base_iterator_type m_pos;
105 base_iterator_type m_end;
106
107public:
108 bool operator==(const iterator_common_base& other) const
109 {
110 if (m_pos != m_end && other.m_pos != other.m_end)
111 {
112 // TODO: Set hard-coded values to the current node for the end
113 // position nodes to remove this if block.
114 if (m_cur_node != other.m_cur_node)
115 return false;
116 }
117 return m_pos == other.m_pos && m_end == other.m_end;
118 }
119
120 bool operator!=(const iterator_common_base& other) const
121 {
122 return !operator==(other);
123 }
124
125 iterator_common_base& operator=(const iterator_common_base& other)
126 {
127 m_cur_node = other.m_cur_node;
128 m_pos = other.m_pos;
129 m_end = other.m_end;
130 return *this;
131 }
132
133 void swap(iterator_common_base& other)
134 {
135 m_cur_node.swap(other.m_cur_node);
136 std::swap(m_pos, other.m_pos);
137 std::swap(m_end, other.m_end);
138 }
139
140 const node& get_node() const
141 {
142 return m_cur_node;
143 }
144 const base_iterator_type& get_pos() const
145 {
146 return m_pos;
147 }
148 const base_iterator_type& get_end() const
149 {
150 return m_end;
151 }
152};
153
154template<typename Traits, typename NodeUpdateFunc>
156{
157 using parent_type = typename Traits::parent;
158 typedef NodeUpdateFunc node_update_func;
160
161 typedef typename Traits::base_iterator base_iterator_type;
162 typedef typename common_base::size_type size_type;
163
164 using common_base::dec;
165 using common_base::inc;
166 using common_base::m_cur_node;
167
168public:
169 using common_base::get_end;
170 using common_base::get_pos;
171
172 // iterator traits
173 typedef typename common_base::node value_type;
174 typedef value_type* pointer;
175 typedef value_type& reference;
176 typedef ptrdiff_t difference_type;
177 typedef std::bidirectional_iterator_tag iterator_category;
178
179public:
181 {}
183 const base_iterator_type& pos, const base_iterator_type& end, const parent_type* parent, size_type block_index)
184 : common_base(pos, end, parent, block_index)
185 {}
186
187 value_type& operator*()
188 {
189 return m_cur_node;
190 }
191
192 const value_type& operator*() const
193 {
194 return m_cur_node;
195 }
196
197 value_type* operator->()
198 {
199 return &m_cur_node;
200 }
201
202 const value_type* operator->() const
203 {
204 return &m_cur_node;
205 }
206
207 iterator_base& operator++()
208 {
209 node_update_func::inc(m_cur_node);
210 inc();
211 return *this;
212 }
213
214 iterator_base& operator--()
215 {
216 dec();
217 node_update_func::dec(m_cur_node);
218 return *this;
219 }
220};
221
222template<typename Traits, typename NodeUpdateFunc, typename NonConstItrBase>
224{
225 using parent_type = typename Traits::parent;
226 typedef NodeUpdateFunc node_update_func;
228
229 typedef typename Traits::base_iterator base_iterator_type;
230 typedef typename common_base::size_type size_type;
231
232 using common_base::dec;
233 using common_base::inc;
234 using common_base::m_cur_node;
235
236public:
237 using common_base::get_end;
238 using common_base::get_pos;
239
240 typedef NonConstItrBase iterator_base;
241
242 // iterator traits
243 typedef typename common_base::node value_type;
244 typedef value_type* pointer;
245 typedef value_type& reference;
246 typedef ptrdiff_t difference_type;
247 typedef std::bidirectional_iterator_tag iterator_category;
248
249public:
251 {}
253 const base_iterator_type& pos, const base_iterator_type& end, const parent_type* parent, size_type block_index)
254 : common_base(pos, end, parent, block_index)
255 {}
256
260 const_iterator_base(const iterator_base& other)
261 : common_base(
262 other.get_pos(), other.get_end(), other.get_node().__private_data.parent,
263 other.get_node().__private_data.block_index)
264 {}
265
266 const value_type& operator*() const
267 {
268 return m_cur_node;
269 }
270
271 const value_type* operator->() const
272 {
273 return &m_cur_node;
274 }
275
276 const_iterator_base& operator++()
277 {
278 node_update_func::inc(m_cur_node);
279 inc();
280 return *this;
281 }
282
283 const_iterator_base& operator--()
284 {
285 dec();
286 node_update_func::dec(m_cur_node);
287 return *this;
288 }
289
290 bool operator==(const const_iterator_base& other) const
291 {
292 return iterator_common_base<Traits>::operator==(other);
293 }
294
295 bool operator!=(const const_iterator_base& other) const
296 {
297 return iterator_common_base<Traits>::operator!=(other);
298 }
299};
300
301}}}} // namespace mdds::mtv::aos::detail
302
303#endif
Definition: global.hpp:84
Definition: aos/iterator.hpp:224
const_iterator_base(const iterator_base &other)
Definition: aos/iterator.hpp:260
Definition: aos/iterator.hpp:156
Definition: aos/iterator.hpp:44