35 using parent_type =
typename Traits::parent;
36 using positions_type =
typename Traits::positions_type;
37 using sizes_type =
typename Traits::sizes_type;
38 using element_blocks_type =
typename Traits::element_blocks_type;
39 using size_type =
typename Traits::parent::size_type;
43 using positions_iterator_type =
typename Traits::positions_iterator_type;
44 using sizes_iterator_type =
typename Traits::sizes_iterator_type;
45 using element_blocks_iterator_type =
typename Traits::element_blocks_iterator_type;
51 struct grouped_iterator_type
53 positions_iterator_type position_iterator;
54 sizes_iterator_type size_iterator;
55 element_blocks_iterator_type element_block_iterator;
61 ++element_block_iterator;
68 --element_block_iterator;
71 bool operator==(
const grouped_iterator_type& other)
const
73 return position_iterator == other.position_iterator && size_iterator == other.size_iterator &&
74 element_block_iterator == other.element_block_iterator;
77 bool operator!=(
const grouped_iterator_type& other)
const
79 return !operator==(other);
82 grouped_iterator_type() =
default;
84 grouped_iterator_type(
85 const positions_iterator_type& itr_pos,
const sizes_iterator_type& itr_size,
86 const element_blocks_iterator_type& itr_elem_blocks)
87 : position_iterator(itr_pos), size_iterator(itr_size), element_block_iterator(itr_elem_blocks)
95 iterator_updater() : m_cur_node(nullptr, 0)
99 const grouped_iterator_type& pos,
const grouped_iterator_type& end,
const parent_type* parent,
100 size_type block_index)
101 : m_cur_node(parent, block_index), m_pos(pos), m_end(end)
108 const positions_iterator_type& positions_pos,
const sizes_iterator_type& sizes_pos,
109 const element_blocks_iterator_type& eb_pos,
const positions_iterator_type& positions_end,
110 const sizes_iterator_type& sizes_end,
const element_blocks_iterator_type& eb_end,
const parent_type* parent,
111 size_type block_index)
112 : iterator_updater({positions_pos, sizes_pos, eb_pos}, {positions_end, sizes_end, eb_end}, parent, block_index)
115 iterator_updater(
const iterator_updater& other)
116 : m_cur_node(other.m_cur_node), m_pos(other.m_pos), m_end(other.m_end)
121#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG
123 throw general_error(
"Current node position should never equal the end position during node update.");
126 m_cur_node.position = *m_pos.position_iterator;
127 m_cur_node.size = *m_pos.size_iterator;
128 m_cur_node.data = *m_pos.element_block_iterator;
131 m_cur_node.type = mdds::mtv::get_block_type(*m_cur_node.data);
133 m_cur_node.type = mdds::mtv::element_type_empty;
153 void _print_state(std::ostream& os)
const
155 auto prev_flags = os.flags();
156 os <<
"parent=" << std::hex << m_cur_node.__private_data.parent
157 <<
"; block-index=" << m_cur_node.__private_data.block_index <<
"; position=" << m_cur_node.position
158 <<
"; size=" << m_cur_node.size <<
"; type=" << m_cur_node.type <<
"; data=" << m_cur_node.data;
159 os.flags(prev_flags);
163 bool operator==(
const iterator_updater& other)
const
165 if (m_pos != m_end && other.m_pos != other.m_end)
169 if (m_cur_node != other.m_cur_node)
172 return m_pos == other.m_pos && m_end == other.m_end;
175 bool operator!=(
const iterator_updater& other)
const
177 return !operator==(other);
180 iterator_updater& operator=(
const iterator_updater& other)
182 m_cur_node = other.m_cur_node;
188 void swap(iterator_updater& other)
190 m_cur_node.swap(other.m_cur_node);
191 std::swap(m_pos, other.m_pos);
192 std::swap(m_end, other.m_end);
195 const node& get_node()
const
210class iterator_base :
public iterator_updater<Traits>
212 using parent_type =
typename Traits::parent;
213 using node_update_func =
typename Traits::private_data_update;
214 using updater = iterator_updater<Traits>;
217 using size_type =
typename updater::size_type;
221 using updater::m_cur_node;
224 using updater::get_end;
225 using updater::get_pos;
228 using value_type =
typename updater::node;
229 using pointer = value_type*;
230 using reference = value_type&;
231 using difference_type = ptrdiff_t;
232 using iterator_category = std::bidirectional_iterator_tag;
238 const grouped_iterator_type& pos,
const grouped_iterator_type& end,
const parent_type* parent,
239 size_type block_index)
240 : updater(pos, end, parent, block_index)
243 value_type& operator*()
248 const value_type& operator*()
const
253 value_type* operator->()
258 const value_type* operator->()
const
263 iterator_base& operator++()
265 node_update_func::inc(m_cur_node);
270 iterator_base& operator--()
273 node_update_func::dec(m_cur_node);
277 void _print_state(std::ostream& os)
const
280 updater::_print_state(os);
286class const_iterator_base :
public iterator_updater<Traits>
288 using parent_type =
typename Traits::parent;
289 using node_update_func =
typename Traits::private_data_update;
290 using updater = iterator_updater<Traits>;
293 using size_type =
typename updater::size_type;
297 using updater::m_cur_node;
300 using updater::get_end;
301 using updater::get_pos;
303 using iterator_base = NonConstItrBase;
306 using value_type =
typename updater::node;
307 using pointer = value_type*;
308 using reference = value_type&;
309 using difference_type = ptrdiff_t;
310 using iterator_category = std::bidirectional_iterator_tag;
313 const_iterator_base() : updater()
316 const grouped_iterator_type& pos,
const grouped_iterator_type& end,
const parent_type* parent,
317 size_type block_index)
318 : updater(pos, end, parent, block_index)
326 other.get_pos().position_iterator, other.get_pos().size_iterator, other.get_pos().element_block_iterator,
327 other.get_end().position_iterator, other.get_end().size_iterator, other.get_end().element_block_iterator,
328 other.get_node().__private_data.parent, other.get_node().__private_data.block_index)
341 const_iterator_base& operator++()
343 node_update_func::inc(m_cur_node);
348 const_iterator_base& operator--()
351 node_update_func::dec(m_cur_node);
355 bool operator==(
const const_iterator_base& other)
const
357 return updater::operator==(other);
360 bool operator!=(
const const_iterator_base& other)
const
362 return updater::operator!=(other);
365 void _print_state(std::ostream& os)
const
367 os <<
"(const-iterator: ";
368 updater::_print_state(os);