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(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 
107 public:
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 
154 template<typename Trait, typename NodeUpdateFunc>
155 class iterator_base : public iterator_common_base<Trait>
156 {
157  using parent_type = typename Trait::parent;
158  typedef NodeUpdateFunc node_update_func;
160 
161  typedef typename Trait::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 
168 public:
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 
179 public:
180  iterator_base()
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 
222 template<typename Trait, typename NodeUpdateFunc, typename NonConstItrBase>
224 {
225  using parent_type = typename Trait::parent;
226  typedef NodeUpdateFunc node_update_func;
228 
229  typedef typename Trait::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 
236 public:
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 
249 public:
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<Trait>::operator==(other);
293  }
294 
295  bool operator!=(const const_iterator_base& other) const
296  {
297  return iterator_common_base<Trait>::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