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