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