mdds
multi_type_vector_itr.hpp
1 /*************************************************************************
2  *
3  * Copyright (c) 2012-2015 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 MDDS_MULTI_TYPE_VECTOR_ITR_HPP
29 #define MDDS_MULTI_TYPE_VECTOR_ITR_HPP
30 
31 #include "multi_type_vector_types.hpp"
32 
33 #include <cstddef>
34 
35 namespace mdds { namespace __mtv {
36 
43 template<typename _SizeT, typename _ElemBlkT>
45 {
46  typedef _SizeT size_type;
47  typedef _ElemBlkT element_block_type;
48 
49  mdds::mtv::element_t type;
50  size_type position;
51  size_type size;
52  element_block_type* data;
53 
54  iterator_value_node(size_type start_pos, size_type block_index) :
55  type(mdds::mtv::element_type_empty), position(start_pos), size(0), data(nullptr), __private_data(block_index) {}
56 
58  type(other.type), position(other.position), size(other.size), data(other.data), __private_data(other.__private_data) {}
59 
60  void swap(iterator_value_node& other)
61  {
62  std::swap(type, other.type);
63  std::swap(position, other.position);
64  std::swap(size, other.size);
65  std::swap(data, other.data);
66 
67  __private_data.swap(other.__private_data);
68  }
69 
70  struct private_data
71  {
72  size_type block_index;
73 
74  private_data() : block_index(0) {}
75  private_data(size_type _block_index) :
76  block_index(_block_index) {}
77  private_data(const private_data& other) :
78  block_index(other.block_index) {}
79 
80  void swap(private_data& other)
81  {
82  std::swap(block_index, other.block_index);
83  }
84  };
85  private_data __private_data;
86 
87  bool operator== (const iterator_value_node& other) const
88  {
89  return type == other.type && position == other.position && size == other.size && data == other.data &&
90  __private_data.block_index == other.__private_data.block_index;
91  }
92 
93  bool operator!= (const iterator_value_node& other) const
94  {
95  return !operator== (other);
96  }
97 };
98 
99 template<typename _NodeT>
101 {
102  typedef _NodeT node_type;
103 
104  static void inc(node_type&) {}
105  static void dec(node_type&) {}
106 };
107 
108 template<typename _NodeT>
110 {
111  typedef _NodeT node_type;
112 
113  static void inc(node_type& nd)
114  {
115  // Called before incrementing the iterator position.
116  ++nd.__private_data.block_index;
117  nd.position += nd.size;
118  }
119 
120  static void dec(node_type& nd)
121  {
122  // Called after decrementing the iterator position.
123  --nd.__private_data.block_index;
124  nd.position -= nd.size;
125  }
126 };
127 
133 template<typename _Trait>
135 {
136 protected:
137  typedef typename _Trait::parent parent_type;
138  typedef typename _Trait::blocks blocks_type;
139  typedef typename _Trait::base_iterator base_iterator_type;
140 
141  typedef typename parent_type::size_type size_type;
143 
144  iterator_common_base() : m_cur_node(0, 0) {}
145 
147  const base_iterator_type& pos, const base_iterator_type& end,
148  size_type start_pos, size_type block_index) :
149  m_cur_node(start_pos, block_index),
150  m_pos(pos),
151  m_end(end)
152  {
153  if (m_pos != m_end)
154  update_node();
155  }
156 
158  m_cur_node(other.m_cur_node),
159  m_pos(other.m_pos),
160  m_end(other.m_end)
161  {
162  }
163 
164  void update_node()
165  {
166 #ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG
167  if (m_pos == m_end)
168  throw general_error("Current node position should never equal the end position during node update.");
169 #endif
170  // blocks_type::value_type is a pointer to multi_type_vector::block.
171  typename blocks_type::value_type blk = *m_pos;
172  if (blk->mp_data)
173  m_cur_node.type = mdds::mtv::get_block_type(*blk->mp_data);
174  else
175  m_cur_node.type = mdds::mtv::element_type_empty;
176 
177  m_cur_node.size = blk->m_size;
178  m_cur_node.data = blk->mp_data;
179  }
180 
181  node* inc()
182  {
183  ++m_pos;
184  if (m_pos == m_end)
185  return nullptr;
186 
187  update_node();
188  return &m_cur_node;
189  }
190 
191  node* dec()
192  {
193  --m_pos;
194  update_node();
195  return &m_cur_node;
196  }
197 
198  node m_cur_node;
199  base_iterator_type m_pos;
200  base_iterator_type m_end;
201 
202 public:
203  bool operator== (const iterator_common_base& other) const
204  {
205  if (m_pos != m_end && other.m_pos != other.m_end)
206  {
207  // TODO: Set hard-coded values to the current node for the end
208  // position nodes to remove this if block.
209  if (m_cur_node != other.m_cur_node)
210  return false;
211  }
212  return m_pos == other.m_pos && m_end == other.m_end;
213  }
214 
215  bool operator!= (const iterator_common_base& other) const
216  {
217  return !operator==(other);
218  }
219 
220  iterator_common_base& operator= (const iterator_common_base& other)
221  {
222  m_cur_node = other.m_cur_node;
223  m_pos = other.m_pos;
224  m_end = other.m_end;
225  return *this;
226  }
227 
228  void swap(iterator_common_base& other)
229  {
230  m_cur_node.swap(other.m_cur_node);
231  std::swap(m_pos, other.m_pos);
232  std::swap(m_end, other.m_end);
233  }
234 
235  const node& get_node() const { return m_cur_node; }
236  const base_iterator_type& get_pos() const { return m_pos; }
237  const base_iterator_type& get_end() const { return m_end; }
238 };
239 
240 template<typename _Trait, typename _NodeUpdateFunc>
241 class iterator_base : public iterator_common_base<_Trait>
242 {
243  typedef _Trait trait;
244  typedef _NodeUpdateFunc node_update_func;
246 
247  typedef typename trait::base_iterator base_iterator_type;
248  typedef typename common_base::size_type size_type;
249 
250  using common_base::inc;
251  using common_base::dec;
252  using common_base::m_cur_node;
253  using common_base::m_pos;
254  using common_base::m_end;
255 
256 public:
257 
258  using common_base::get_pos;
259  using common_base::get_end;
260 
261  // iterator traits
262  typedef typename common_base::node value_type;
263  typedef value_type* pointer;
264  typedef value_type& reference;
265  typedef ptrdiff_t difference_type;
266  typedef std::bidirectional_iterator_tag iterator_category;
267 
268 public:
269  iterator_base() {}
271  const base_iterator_type& pos, const base_iterator_type& end,
272  size_type start_pos, size_type block_index) :
273  common_base(pos, end, start_pos, block_index) {}
274 
275  iterator_base(const iterator_base& other) :
276  common_base(other) {}
277 
278  value_type& operator*()
279  {
280  return m_cur_node;
281  }
282 
283  const value_type& operator*() const
284  {
285  return m_cur_node;
286  }
287 
288  value_type* operator->()
289  {
290  return &m_cur_node;
291  }
292 
293  const value_type* operator->() const
294  {
295  return &m_cur_node;
296  }
297 
298  iterator_base& operator++()
299  {
300  node_update_func::inc(m_cur_node);
301  inc();
302  return *this;
303  }
304 
305  iterator_base& operator--()
306  {
307  dec();
308  node_update_func::dec(m_cur_node);
309  return *this;
310  }
311 };
312 
313 template<typename _Trait, typename _NodeUpdateFunc, typename _NonConstItrBase>
315 {
316  typedef _Trait trait;
317  typedef _NodeUpdateFunc node_update_func;
319 
320  typedef typename trait::base_iterator base_iterator_type;
321  typedef typename common_base::size_type size_type;
322 
323  using common_base::inc;
324  using common_base::dec;
325  using common_base::m_cur_node;
326 
327 public:
328 
329  using common_base::get_pos;
330  using common_base::get_end;
331 
332  typedef _NonConstItrBase iterator_base;
333 
334  // iterator traits
335  typedef typename common_base::node value_type;
336  typedef value_type* pointer;
337  typedef value_type& reference;
338  typedef ptrdiff_t difference_type;
339  typedef std::bidirectional_iterator_tag iterator_category;
340 
341 public:
342  const_iterator_base() : common_base() {}
344  const base_iterator_type& pos, const base_iterator_type& end,
345  size_type start_pos, size_type block_index) :
346  common_base(pos, end, start_pos, block_index) {}
347 
349  common_base(other) {}
350 
354  const_iterator_base(const iterator_base& other) :
355  common_base(
356  other.get_pos(), other.get_end(),
357  other.get_node().position,
358  other.get_node().__private_data.block_index) {}
359 
360  const value_type& operator*() const
361  {
362  return m_cur_node;
363  }
364 
365  const value_type* operator->() const
366  {
367  return &m_cur_node;
368  }
369 
370  const_iterator_base& operator++()
371  {
372  node_update_func::inc(m_cur_node);
373  inc();
374  return *this;
375  }
376 
377  const_iterator_base& operator--()
378  {
379  dec();
380  node_update_func::dec(m_cur_node);
381  return *this;
382  }
383 
384  bool operator== (const const_iterator_base& other) const
385  {
387  }
388 
389  bool operator!= (const const_iterator_base& other) const
390  {
392  }
393 };
394 
395 }}
396 
397 #endif
Definition: multi_type_vector_itr.hpp:109
Definition: multi_type_vector_itr.hpp:44
Definition: multi_type_vector_itr.hpp:100
Definition: multi_type_vector_itr.hpp:241
Definition: multi_type_vector_itr.hpp:314
Definition: global.hpp:58
Definition: default_deleter.hpp:33
Definition: multi_type_vector_itr.hpp:134
Definition: multi_type_vector_itr.hpp:70
const_iterator_base(const iterator_base &other)
Definition: multi_type_vector_itr.hpp:354