mdds
iterator.hpp
1 // SPDX-FileCopyrightText: 2012 - 2025 Kohei Yoshida
2 //
3 // SPDX-License-Identifier: MIT
4 
5 #pragma once
6 
7 #include "../iterator_node.hpp"
8 
9 #include <cstddef>
10 
11 namespace mdds { namespace mtv { namespace aos { namespace detail {
12 
18 template<typename Traits>
20 {
21 protected:
22  typedef typename Traits::parent parent_type;
23  typedef typename Traits::blocks blocks_type;
24  typedef typename Traits::base_iterator base_iterator_type;
25 
26  typedef typename parent_type::size_type size_type;
28 
29  iterator_common_base() : m_cur_node(nullptr, 0)
30  {}
31 
33  const base_iterator_type& pos, const base_iterator_type& end, const parent_type* parent, size_type block_index)
34  : m_cur_node(parent, block_index), m_pos(pos), m_end(end)
35  {
36  if (m_pos != m_end)
37  update_node();
38  }
39 
41  : m_cur_node(other.m_cur_node), m_pos(other.m_pos), m_end(other.m_end)
42  {}
43 
44  void update_node()
45  {
46 #ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG
47  if (m_pos == m_end)
48  throw general_error("Current node position should never equal the end position during node update.");
49 #endif
50  // blocks_type::value_type is a pointer to multi_type_vector::block.
51  const typename blocks_type::value_type& blk = *m_pos;
52  if (blk.data)
53  m_cur_node.type = mdds::mtv::get_block_type(*blk.data);
54  else
55  m_cur_node.type = mdds::mtv::element_type_empty;
56 
57  m_cur_node.position = blk.position;
58  m_cur_node.size = blk.size;
59  m_cur_node.data = blk.data;
60  }
61 
62  node* inc()
63  {
64  ++m_pos;
65  if (m_pos == m_end)
66  return nullptr;
67 
68  update_node();
69  return &m_cur_node;
70  }
71 
72  node* dec()
73  {
74  --m_pos;
75  update_node();
76  return &m_cur_node;
77  }
78 
79  node m_cur_node;
80  base_iterator_type m_pos;
81  base_iterator_type m_end;
82 
83 public:
84  bool operator==(const iterator_common_base& other) const
85  {
86  if (m_pos != m_end && other.m_pos != other.m_end)
87  {
88  // TODO: Set hard-coded values to the current node for the end
89  // position nodes to remove this if block.
90  if (m_cur_node != other.m_cur_node)
91  return false;
92  }
93  return m_pos == other.m_pos && m_end == other.m_end;
94  }
95 
96  bool operator!=(const iterator_common_base& other) const
97  {
98  return !operator==(other);
99  }
100 
101  iterator_common_base& operator=(const iterator_common_base& other)
102  {
103  m_cur_node = other.m_cur_node;
104  m_pos = other.m_pos;
105  m_end = other.m_end;
106  return *this;
107  }
108 
109  void swap(iterator_common_base& other)
110  {
111  m_cur_node.swap(other.m_cur_node);
112  std::swap(m_pos, other.m_pos);
113  std::swap(m_end, other.m_end);
114  }
115 
116  const node& get_node() const
117  {
118  return m_cur_node;
119  }
120  const base_iterator_type& get_pos() const
121  {
122  return m_pos;
123  }
124  const base_iterator_type& get_end() const
125  {
126  return m_end;
127  }
128 };
129 
130 template<typename Traits, typename NodeUpdateFunc>
131 class iterator_base : public iterator_common_base<Traits>
132 {
133  using parent_type = typename Traits::parent;
134  typedef NodeUpdateFunc node_update_func;
136 
137  typedef typename Traits::base_iterator base_iterator_type;
138  typedef typename common_base::size_type size_type;
139 
140  using common_base::dec;
141  using common_base::inc;
142  using common_base::m_cur_node;
143 
144 public:
145  using common_base::get_end;
146  using common_base::get_pos;
147 
148  // iterator traits
149  typedef typename common_base::node value_type;
150  typedef value_type* pointer;
151  typedef value_type& reference;
152  typedef ptrdiff_t difference_type;
153  typedef std::bidirectional_iterator_tag iterator_category;
154 
155 public:
156  iterator_base()
157  {}
159  const base_iterator_type& pos, const base_iterator_type& end, const parent_type* parent, size_type block_index)
160  : common_base(pos, end, parent, block_index)
161  {}
162 
163  value_type& operator*()
164  {
165  return m_cur_node;
166  }
167 
168  const value_type& operator*() const
169  {
170  return m_cur_node;
171  }
172 
173  value_type* operator->()
174  {
175  return &m_cur_node;
176  }
177 
178  const value_type* operator->() const
179  {
180  return &m_cur_node;
181  }
182 
183  iterator_base& operator++()
184  {
185  node_update_func::inc(m_cur_node);
186  inc();
187  return *this;
188  }
189 
190  iterator_base& operator--()
191  {
192  dec();
193  node_update_func::dec(m_cur_node);
194  return *this;
195  }
196 };
197 
198 template<typename Traits, typename NodeUpdateFunc, typename NonConstItrBase>
200 {
201  using parent_type = typename Traits::parent;
202  typedef NodeUpdateFunc node_update_func;
204 
205  typedef typename Traits::base_iterator base_iterator_type;
206  typedef typename common_base::size_type size_type;
207 
208  using common_base::dec;
209  using common_base::inc;
210  using common_base::m_cur_node;
211 
212 public:
213  using common_base::get_end;
214  using common_base::get_pos;
215 
216  typedef NonConstItrBase iterator_base;
217 
218  // iterator traits
219  typedef typename common_base::node value_type;
220  typedef value_type* pointer;
221  typedef value_type& reference;
222  typedef ptrdiff_t difference_type;
223  typedef std::bidirectional_iterator_tag iterator_category;
224 
225 public:
226  const_iterator_base() : common_base()
227  {}
229  const base_iterator_type& pos, const base_iterator_type& end, const parent_type* parent, size_type block_index)
230  : common_base(pos, end, parent, block_index)
231  {}
232 
236  const_iterator_base(const iterator_base& other)
237  : common_base(
238  other.get_pos(), other.get_end(), other.get_node().__private_data.parent,
239  other.get_node().__private_data.block_index)
240  {}
241 
242  const value_type& operator*() const
243  {
244  return m_cur_node;
245  }
246 
247  const value_type* operator->() const
248  {
249  return &m_cur_node;
250  }
251 
252  const_iterator_base& operator++()
253  {
254  node_update_func::inc(m_cur_node);
255  inc();
256  return *this;
257  }
258 
259  const_iterator_base& operator--()
260  {
261  dec();
262  node_update_func::dec(m_cur_node);
263  return *this;
264  }
265 
266  bool operator==(const const_iterator_base& other) const
267  {
268  return iterator_common_base<Traits>::operator==(other);
269  }
270 
271  bool operator!=(const const_iterator_base& other) const
272  {
273  return iterator_common_base<Traits>::operator!=(other);
274  }
275 };
276 
277 }}}} // namespace mdds::mtv::aos::detail
Definition: iterator.hpp:131
const_iterator_base(const iterator_base &other)
Definition: iterator.hpp:236
Definition: global.hpp:59
Definition: cref_wrapper.hpp:12