28 #ifndef INCLUDED_MDDS_MULTI_TYPE_VECTOR_ITR_HPP
29 #define INCLUDED_MDDS_MULTI_TYPE_VECTOR_ITR_HPP
31 #include "multi_type_vector_types.hpp"
35 namespace mdds {
namespace detail {
namespace mtv {
43 template<
typename _SizeT,
typename _ElemBlkT>
44 struct iterator_value_node
46 typedef _SizeT size_type;
47 typedef _ElemBlkT element_block_type;
49 mdds::mtv::element_t type;
52 element_block_type* data;
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) {}
57 void swap(iterator_value_node& other)
59 std::swap(type, other.type);
60 std::swap(position, other.position);
61 std::swap(size, other.size);
62 std::swap(data, other.data);
64 __private_data.swap(other.__private_data);
69 size_type block_index;
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) {}
77 void swap(private_data& other)
79 std::swap(block_index, other.block_index);
82 private_data __private_data;
84 bool operator== (
const iterator_value_node& other)
const
86 return type == other.type && position == other.position && size == other.size && data == other.data &&
87 __private_data.block_index == other.__private_data.block_index;
90 bool operator!= (
const iterator_value_node& other)
const
92 return !operator== (other);
96 template<
typename _NodeT>
97 struct private_data_no_update
99 typedef _NodeT node_type;
101 static void inc(node_type&) {}
102 static void dec(node_type&) {}
105 template<
typename _NodeT>
106 struct private_data_forward_update
108 typedef _NodeT node_type;
110 static void inc(node_type& nd)
113 ++nd.__private_data.block_index;
114 nd.position += nd.size;
117 static void dec(node_type& nd)
120 --nd.__private_data.block_index;
121 nd.position -= nd.size;
130 template<
typename _Trait>
131 class iterator_common_base
134 typedef typename _Trait::parent parent_type;
135 typedef typename _Trait::blocks blocks_type;
136 typedef typename _Trait::base_iterator base_iterator_type;
138 typedef typename parent_type::size_type size_type;
139 typedef iterator_value_node<size_type, typename parent_type::element_block_type> node;
141 iterator_common_base() : m_cur_node(0, 0) {}
143 iterator_common_base(
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),
154 iterator_common_base(
const iterator_common_base& other) :
155 m_cur_node(other.m_cur_node),
163 #ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG
165 throw general_error(
"Current node position should never equal the end position during node update.");
168 const typename blocks_type::value_type& blk = *m_pos;
170 m_cur_node.type = mdds::mtv::get_block_type(*blk.mp_data);
172 m_cur_node.type = mdds::mtv::element_type_empty;
174 m_cur_node.size = blk.m_size;
175 m_cur_node.data = blk.mp_data;
196 base_iterator_type m_pos;
197 base_iterator_type m_end;
200 bool operator== (
const iterator_common_base& other)
const
202 if (m_pos != m_end && other.m_pos != other.m_end)
206 if (m_cur_node != other.m_cur_node)
209 return m_pos == other.m_pos && m_end == other.m_end;
212 bool operator!= (
const iterator_common_base& other)
const
214 return !operator==(other);
217 iterator_common_base& operator= (
const iterator_common_base& other)
219 m_cur_node = other.m_cur_node;
225 void swap(iterator_common_base& other)
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);
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; }
237 template<
typename _Trait,
typename _NodeUpdateFunc>
238 class iterator_base :
public iterator_common_base<_Trait>
240 typedef _Trait trait;
241 typedef _NodeUpdateFunc node_update_func;
242 typedef iterator_common_base<trait> common_base;
244 typedef typename trait::base_iterator base_iterator_type;
245 typedef typename common_base::size_type size_type;
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;
255 using common_base::get_pos;
256 using common_base::get_end;
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;
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) {}
272 value_type& operator*()
277 const value_type& operator*()
const
282 value_type* operator->()
287 const value_type* operator->()
const
292 iterator_base& operator++()
294 node_update_func::inc(m_cur_node);
299 iterator_base& operator--()
302 node_update_func::dec(m_cur_node);
307 template<
typename _Trait,
typename _NodeUpdateFunc,
typename _NonConstItrBase>
308 class const_iterator_base :
public iterator_common_base<_Trait>
310 typedef _Trait trait;
311 typedef _NodeUpdateFunc node_update_func;
312 typedef iterator_common_base<trait> common_base;
314 typedef typename trait::base_iterator base_iterator_type;
315 typedef typename common_base::size_type size_type;
317 using common_base::inc;
318 using common_base::dec;
319 using common_base::m_cur_node;
323 using common_base::get_pos;
324 using common_base::get_end;
332 typedef ptrdiff_t difference_type;
333 typedef std::bidirectional_iterator_tag iterator_category;
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) {}
345 const_iterator_base(
const iterator_base& other) :
347 other.get_pos(), other.get_end(),
348 other.get_node().position,
349 other.get_node().__private_data.block_index) {}
351 const value_type& operator*()
const
356 const value_type* operator->()
const
361 const_iterator_base& operator++()
363 node_update_func::inc(m_cur_node);
368 const_iterator_base& operator--()
371 node_update_func::dec(m_cur_node);
375 bool operator== (
const const_iterator_base& other)
const
377 return iterator_common_base<_Trait>::operator==(other);
380 bool operator!= (
const const_iterator_base& other)
const
382 return iterator_common_base<_Trait>::operator!=(other);