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 block_index) :
55 type(mdds::mtv::element_type_empty), position(0), 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) {}
75 void swap(private_data& other)
77 std::swap(block_index, other.block_index);
80 private_data __private_data;
82 bool operator== (
const iterator_value_node& other)
const
84 return type == other.type && position == other.position && size == other.size && data == other.data &&
85 __private_data.block_index == other.__private_data.block_index;
88 bool operator!= (
const iterator_value_node& other)
const
90 return !operator== (other);
94 template<
typename _NodeT>
95 struct private_data_no_update
97 typedef _NodeT node_type;
99 static void inc(node_type&) {}
100 static void dec(node_type&) {}
103 template<
typename _NodeT>
104 struct private_data_forward_update
106 typedef _NodeT node_type;
108 static void inc(node_type& nd)
110 ++nd.__private_data.block_index;
113 static void dec(node_type& nd)
115 --nd.__private_data.block_index;
124 template<
typename _Trait>
125 class iterator_common_base
128 typedef typename _Trait::parent parent_type;
129 typedef typename _Trait::blocks blocks_type;
130 typedef typename _Trait::base_iterator base_iterator_type;
132 typedef typename parent_type::size_type size_type;
133 typedef iterator_value_node<size_type, typename parent_type::element_block_type> node;
135 iterator_common_base() : m_cur_node(0) {}
137 iterator_common_base(
138 const base_iterator_type& pos,
const base_iterator_type& end, size_type block_index) :
139 m_cur_node(block_index),
147 iterator_common_base(
const iterator_common_base& other) :
148 m_cur_node(other.m_cur_node),
156 #ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG
158 throw general_error(
"Current node position should never equal the end position during node update.");
161 const typename blocks_type::value_type& blk = *m_pos;
163 m_cur_node.type = mdds::mtv::get_block_type(*blk.mp_data);
165 m_cur_node.type = mdds::mtv::element_type_empty;
167 m_cur_node.position = blk.m_position;
168 m_cur_node.size = blk.m_size;
169 m_cur_node.data = blk.mp_data;
190 base_iterator_type m_pos;
191 base_iterator_type m_end;
194 bool operator== (
const iterator_common_base& other)
const
196 if (m_pos != m_end && other.m_pos != other.m_end)
200 if (m_cur_node != other.m_cur_node)
203 return m_pos == other.m_pos && m_end == other.m_end;
206 bool operator!= (
const iterator_common_base& other)
const
208 return !operator==(other);
211 iterator_common_base& operator= (
const iterator_common_base& other)
213 m_cur_node = other.m_cur_node;
219 void swap(iterator_common_base& other)
221 m_cur_node.swap(other.m_cur_node);
222 std::swap(m_pos, other.m_pos);
223 std::swap(m_end, other.m_end);
226 const node& get_node()
const {
return m_cur_node; }
227 const base_iterator_type& get_pos()
const {
return m_pos; }
228 const base_iterator_type& get_end()
const {
return m_end; }
231 template<
typename _Trait,
typename _NodeUpdateFunc>
232 class iterator_base :
public iterator_common_base<_Trait>
234 typedef _Trait trait;
235 typedef _NodeUpdateFunc node_update_func;
236 typedef iterator_common_base<trait> common_base;
238 typedef typename trait::base_iterator base_iterator_type;
239 typedef typename common_base::size_type size_type;
241 using common_base::inc;
242 using common_base::dec;
243 using common_base::m_cur_node;
244 using common_base::m_pos;
245 using common_base::m_end;
249 using common_base::get_pos;
250 using common_base::get_end;
253 typedef typename common_base::node value_type;
254 typedef value_type* pointer;
255 typedef value_type& reference;
256 typedef ptrdiff_t difference_type;
257 typedef std::bidirectional_iterator_tag iterator_category;
262 const base_iterator_type& pos,
const base_iterator_type& end, size_type block_index) :
263 common_base(pos, end, block_index) {}
265 value_type& operator*()
270 const value_type& operator*()
const
275 value_type* operator->()
280 const value_type* operator->()
const
285 iterator_base& operator++()
287 node_update_func::inc(m_cur_node);
292 iterator_base& operator--()
295 node_update_func::dec(m_cur_node);
300 template<
typename _Trait,
typename _NodeUpdateFunc,
typename _NonConstItrBase>
301 class const_iterator_base :
public iterator_common_base<_Trait>
303 typedef _Trait trait;
304 typedef _NodeUpdateFunc node_update_func;
307 typedef typename trait::base_iterator base_iterator_type;
308 typedef typename common_base::size_type size_type;
310 using common_base::inc;
311 using common_base::dec;
312 using common_base::m_cur_node;
316 using common_base::get_pos;
317 using common_base::get_end;
325 typedef ptrdiff_t difference_type;
326 typedef std::bidirectional_iterator_tag iterator_category;
331 const base_iterator_type& pos,
const base_iterator_type& end, size_type block_index) :
332 common_base(pos, end, block_index) {}
337 const_iterator_base(
const iterator_base& other) :
341 other.get_node().__private_data.block_index) {}
343 const value_type& operator*()
const
348 const value_type* operator->()
const
353 const_iterator_base& operator++()
355 node_update_func::inc(m_cur_node);
360 const_iterator_base& operator--()
363 node_update_func::dec(m_cur_node);
367 bool operator== (
const const_iterator_base& other)
const
369 return iterator_common_base<_Trait>::operator==(other);