Please, help us to better know about our user community by answering the following short survey: https://forms.gle/wpyrxWi18ox9Z5ae9
Eigen  3.4.0
StlIterators.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2018 Gael Guennebaud <gael.guennebaud@inria.fr>
5 //
6 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 
10 #ifndef EIGEN_STLITERATORS_H
11 #define EIGEN_STLITERATORS_H
12 
13 namespace Eigen {
14 
15 namespace internal {
16 
17 template<typename IteratorType>
18 struct indexed_based_stl_iterator_traits;
19 
20 template<typename Derived>
21 class indexed_based_stl_iterator_base
22 {
23 protected:
24  typedef indexed_based_stl_iterator_traits<Derived> traits;
25  typedef typename traits::XprType XprType;
26  typedef indexed_based_stl_iterator_base<typename traits::non_const_iterator> non_const_iterator;
27  typedef indexed_based_stl_iterator_base<typename traits::const_iterator> const_iterator;
28  typedef typename internal::conditional<internal::is_const<XprType>::value,non_const_iterator,const_iterator>::type other_iterator;
29  // NOTE: in C++03 we cannot declare friend classes through typedefs because we need to write friend class:
30  friend class indexed_based_stl_iterator_base<typename traits::const_iterator>;
31  friend class indexed_based_stl_iterator_base<typename traits::non_const_iterator>;
32 public:
33  typedef Index difference_type;
34  typedef std::random_access_iterator_tag iterator_category;
35 
36  indexed_based_stl_iterator_base() EIGEN_NO_THROW : mp_xpr(0), m_index(0) {}
37  indexed_based_stl_iterator_base(XprType& xpr, Index index) EIGEN_NO_THROW : mp_xpr(&xpr), m_index(index) {}
38 
39  indexed_based_stl_iterator_base(const non_const_iterator& other) EIGEN_NO_THROW
40  : mp_xpr(other.mp_xpr), m_index(other.m_index)
41  {}
42 
43  indexed_based_stl_iterator_base& operator=(const non_const_iterator& other)
44  {
45  mp_xpr = other.mp_xpr;
46  m_index = other.m_index;
47  return *this;
48  }
49 
50  Derived& operator++() { ++m_index; return derived(); }
51  Derived& operator--() { --m_index; return derived(); }
52 
53  Derived operator++(int) { Derived prev(derived()); operator++(); return prev;}
54  Derived operator--(int) { Derived prev(derived()); operator--(); return prev;}
55 
56  friend Derived operator+(const indexed_based_stl_iterator_base& a, Index b) { Derived ret(a.derived()); ret += b; return ret; }
57  friend Derived operator-(const indexed_based_stl_iterator_base& a, Index b) { Derived ret(a.derived()); ret -= b; return ret; }
58  friend Derived operator+(Index a, const indexed_based_stl_iterator_base& b) { Derived ret(b.derived()); ret += a; return ret; }
59  friend Derived operator-(Index a, const indexed_based_stl_iterator_base& b) { Derived ret(b.derived()); ret -= a; return ret; }
60 
61  Derived& operator+=(Index b) { m_index += b; return derived(); }
62  Derived& operator-=(Index b) { m_index -= b; return derived(); }
63 
64  difference_type operator-(const indexed_based_stl_iterator_base& other) const
65  {
66  eigen_assert(mp_xpr == other.mp_xpr);
67  return m_index - other.m_index;
68  }
69 
70  difference_type operator-(const other_iterator& other) const
71  {
72  eigen_assert(mp_xpr == other.mp_xpr);
73  return m_index - other.m_index;
74  }
75 
76  bool operator==(const indexed_based_stl_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index == other.m_index; }
77  bool operator!=(const indexed_based_stl_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index != other.m_index; }
78  bool operator< (const indexed_based_stl_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index < other.m_index; }
79  bool operator<=(const indexed_based_stl_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index <= other.m_index; }
80  bool operator> (const indexed_based_stl_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index > other.m_index; }
81  bool operator>=(const indexed_based_stl_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index >= other.m_index; }
82 
83  bool operator==(const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index == other.m_index; }
84  bool operator!=(const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index != other.m_index; }
85  bool operator< (const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index < other.m_index; }
86  bool operator<=(const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index <= other.m_index; }
87  bool operator> (const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index > other.m_index; }
88  bool operator>=(const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index >= other.m_index; }
89 
90 protected:
91 
92  Derived& derived() { return static_cast<Derived&>(*this); }
93  const Derived& derived() const { return static_cast<const Derived&>(*this); }
94 
95  XprType *mp_xpr;
96  Index m_index;
97 };
98 
99 template<typename Derived>
100 class indexed_based_stl_reverse_iterator_base
101 {
102 protected:
103  typedef indexed_based_stl_iterator_traits<Derived> traits;
104  typedef typename traits::XprType XprType;
105  typedef indexed_based_stl_reverse_iterator_base<typename traits::non_const_iterator> non_const_iterator;
106  typedef indexed_based_stl_reverse_iterator_base<typename traits::const_iterator> const_iterator;
107  typedef typename internal::conditional<internal::is_const<XprType>::value,non_const_iterator,const_iterator>::type other_iterator;
108  // NOTE: in C++03 we cannot declare friend classes through typedefs because we need to write friend class:
109  friend class indexed_based_stl_reverse_iterator_base<typename traits::const_iterator>;
110  friend class indexed_based_stl_reverse_iterator_base<typename traits::non_const_iterator>;
111 public:
112  typedef Index difference_type;
113  typedef std::random_access_iterator_tag iterator_category;
114 
115  indexed_based_stl_reverse_iterator_base() : mp_xpr(0), m_index(0) {}
116  indexed_based_stl_reverse_iterator_base(XprType& xpr, Index index) : mp_xpr(&xpr), m_index(index) {}
117 
118  indexed_based_stl_reverse_iterator_base(const non_const_iterator& other)
119  : mp_xpr(other.mp_xpr), m_index(other.m_index)
120  {}
121 
122  indexed_based_stl_reverse_iterator_base& operator=(const non_const_iterator& other)
123  {
124  mp_xpr = other.mp_xpr;
125  m_index = other.m_index;
126  return *this;
127  }
128 
129  Derived& operator++() { --m_index; return derived(); }
130  Derived& operator--() { ++m_index; return derived(); }
131 
132  Derived operator++(int) { Derived prev(derived()); operator++(); return prev;}
133  Derived operator--(int) { Derived prev(derived()); operator--(); return prev;}
134 
135  friend Derived operator+(const indexed_based_stl_reverse_iterator_base& a, Index b) { Derived ret(a.derived()); ret += b; return ret; }
136  friend Derived operator-(const indexed_based_stl_reverse_iterator_base& a, Index b) { Derived ret(a.derived()); ret -= b; return ret; }
137  friend Derived operator+(Index a, const indexed_based_stl_reverse_iterator_base& b) { Derived ret(b.derived()); ret += a; return ret; }
138  friend Derived operator-(Index a, const indexed_based_stl_reverse_iterator_base& b) { Derived ret(b.derived()); ret -= a; return ret; }
139 
140  Derived& operator+=(Index b) { m_index -= b; return derived(); }
141  Derived& operator-=(Index b) { m_index += b; return derived(); }
142 
143  difference_type operator-(const indexed_based_stl_reverse_iterator_base& other) const
144  {
145  eigen_assert(mp_xpr == other.mp_xpr);
146  return other.m_index - m_index;
147  }
148 
149  difference_type operator-(const other_iterator& other) const
150  {
151  eigen_assert(mp_xpr == other.mp_xpr);
152  return other.m_index - m_index;
153  }
154 
155  bool operator==(const indexed_based_stl_reverse_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index == other.m_index; }
156  bool operator!=(const indexed_based_stl_reverse_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index != other.m_index; }
157  bool operator< (const indexed_based_stl_reverse_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index > other.m_index; }
158  bool operator<=(const indexed_based_stl_reverse_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index >= other.m_index; }
159  bool operator> (const indexed_based_stl_reverse_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index < other.m_index; }
160  bool operator>=(const indexed_based_stl_reverse_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index <= other.m_index; }
161 
162  bool operator==(const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index == other.m_index; }
163  bool operator!=(const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index != other.m_index; }
164  bool operator< (const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index > other.m_index; }
165  bool operator<=(const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index >= other.m_index; }
166  bool operator> (const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index < other.m_index; }
167  bool operator>=(const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index <= other.m_index; }
168 
169 protected:
170 
171  Derived& derived() { return static_cast<Derived&>(*this); }
172  const Derived& derived() const { return static_cast<const Derived&>(*this); }
173 
174  XprType *mp_xpr;
175  Index m_index;
176 };
177 
178 template<typename XprType>
179 class pointer_based_stl_iterator
180 {
181  enum { is_lvalue = internal::is_lvalue<XprType>::value };
182  typedef pointer_based_stl_iterator<typename internal::remove_const<XprType>::type> non_const_iterator;
183  typedef pointer_based_stl_iterator<typename internal::add_const<XprType>::type> const_iterator;
184  typedef typename internal::conditional<internal::is_const<XprType>::value,non_const_iterator,const_iterator>::type other_iterator;
185  // NOTE: in C++03 we cannot declare friend classes through typedefs because we need to write friend class:
186  friend class pointer_based_stl_iterator<typename internal::add_const<XprType>::type>;
187  friend class pointer_based_stl_iterator<typename internal::remove_const<XprType>::type>;
188 public:
189  typedef Index difference_type;
190  typedef typename XprType::Scalar value_type;
191  typedef std::random_access_iterator_tag iterator_category;
192  typedef typename internal::conditional<bool(is_lvalue), value_type*, const value_type*>::type pointer;
193  typedef typename internal::conditional<bool(is_lvalue), value_type&, const value_type&>::type reference;
194 
195 
196  pointer_based_stl_iterator() EIGEN_NO_THROW : m_ptr(0) {}
197  pointer_based_stl_iterator(XprType& xpr, Index index) EIGEN_NO_THROW : m_incr(xpr.innerStride())
198  {
199  m_ptr = xpr.data() + index * m_incr.value();
200  }
201 
202  pointer_based_stl_iterator(const non_const_iterator& other) EIGEN_NO_THROW
203  : m_ptr(other.m_ptr), m_incr(other.m_incr)
204  {}
205 
206  pointer_based_stl_iterator& operator=(const non_const_iterator& other) EIGEN_NO_THROW
207  {
208  m_ptr = other.m_ptr;
209  m_incr.setValue(other.m_incr);
210  return *this;
211  }
212 
213  reference operator*() const { return *m_ptr; }
214  reference operator[](Index i) const { return *(m_ptr+i*m_incr.value()); }
215  pointer operator->() const { return m_ptr; }
216 
217  pointer_based_stl_iterator& operator++() { m_ptr += m_incr.value(); return *this; }
218  pointer_based_stl_iterator& operator--() { m_ptr -= m_incr.value(); return *this; }
219 
220  pointer_based_stl_iterator operator++(int) { pointer_based_stl_iterator prev(*this); operator++(); return prev;}
221  pointer_based_stl_iterator operator--(int) { pointer_based_stl_iterator prev(*this); operator--(); return prev;}
222 
223  friend pointer_based_stl_iterator operator+(const pointer_based_stl_iterator& a, Index b) { pointer_based_stl_iterator ret(a); ret += b; return ret; }
224  friend pointer_based_stl_iterator operator-(const pointer_based_stl_iterator& a, Index b) { pointer_based_stl_iterator ret(a); ret -= b; return ret; }
225  friend pointer_based_stl_iterator operator+(Index a, const pointer_based_stl_iterator& b) { pointer_based_stl_iterator ret(b); ret += a; return ret; }
226  friend pointer_based_stl_iterator operator-(Index a, const pointer_based_stl_iterator& b) { pointer_based_stl_iterator ret(b); ret -= a; return ret; }
227 
228  pointer_based_stl_iterator& operator+=(Index b) { m_ptr += b*m_incr.value(); return *this; }
229  pointer_based_stl_iterator& operator-=(Index b) { m_ptr -= b*m_incr.value(); return *this; }
230 
231  difference_type operator-(const pointer_based_stl_iterator& other) const {
232  return (m_ptr - other.m_ptr)/m_incr.value();
233  }
234 
235  difference_type operator-(const other_iterator& other) const {
236  return (m_ptr - other.m_ptr)/m_incr.value();
237  }
238 
239  bool operator==(const pointer_based_stl_iterator& other) const { return m_ptr == other.m_ptr; }
240  bool operator!=(const pointer_based_stl_iterator& other) const { return m_ptr != other.m_ptr; }
241  bool operator< (const pointer_based_stl_iterator& other) const { return m_ptr < other.m_ptr; }
242  bool operator<=(const pointer_based_stl_iterator& other) const { return m_ptr <= other.m_ptr; }
243  bool operator> (const pointer_based_stl_iterator& other) const { return m_ptr > other.m_ptr; }
244  bool operator>=(const pointer_based_stl_iterator& other) const { return m_ptr >= other.m_ptr; }
245 
246  bool operator==(const other_iterator& other) const { return m_ptr == other.m_ptr; }
247  bool operator!=(const other_iterator& other) const { return m_ptr != other.m_ptr; }
248  bool operator< (const other_iterator& other) const { return m_ptr < other.m_ptr; }
249  bool operator<=(const other_iterator& other) const { return m_ptr <= other.m_ptr; }
250  bool operator> (const other_iterator& other) const { return m_ptr > other.m_ptr; }
251  bool operator>=(const other_iterator& other) const { return m_ptr >= other.m_ptr; }
252 
253 protected:
254 
255  pointer m_ptr;
256  internal::variable_if_dynamic<Index, XprType::InnerStrideAtCompileTime> m_incr;
257 };
258 
259 template<typename _XprType>
260 struct indexed_based_stl_iterator_traits<generic_randaccess_stl_iterator<_XprType> >
261 {
262  typedef _XprType XprType;
263  typedef generic_randaccess_stl_iterator<typename internal::remove_const<XprType>::type> non_const_iterator;
264  typedef generic_randaccess_stl_iterator<typename internal::add_const<XprType>::type> const_iterator;
265 };
266 
267 template<typename XprType>
268 class generic_randaccess_stl_iterator : public indexed_based_stl_iterator_base<generic_randaccess_stl_iterator<XprType> >
269 {
270 public:
271  typedef typename XprType::Scalar value_type;
272 
273 protected:
274 
275  enum {
276  has_direct_access = (internal::traits<XprType>::Flags & DirectAccessBit) ? 1 : 0,
277  is_lvalue = internal::is_lvalue<XprType>::value
278  };
279 
280  typedef indexed_based_stl_iterator_base<generic_randaccess_stl_iterator> Base;
281  using Base::m_index;
282  using Base::mp_xpr;
283 
284  // TODO currently const Transpose/Reshape expressions never returns const references,
285  // so lets return by value too.
286  //typedef typename internal::conditional<bool(has_direct_access), const value_type&, const value_type>::type read_only_ref_t;
287  typedef const value_type read_only_ref_t;
288 
289 public:
290 
291  typedef typename internal::conditional<bool(is_lvalue), value_type *, const value_type *>::type pointer;
292  typedef typename internal::conditional<bool(is_lvalue), value_type&, read_only_ref_t>::type reference;
293 
294  generic_randaccess_stl_iterator() : Base() {}
295  generic_randaccess_stl_iterator(XprType& xpr, Index index) : Base(xpr,index) {}
296  generic_randaccess_stl_iterator(const typename Base::non_const_iterator& other) : Base(other) {}
297  using Base::operator=;
298 
299  reference operator*() const { return (*mp_xpr)(m_index); }
300  reference operator[](Index i) const { return (*mp_xpr)(m_index+i); }
301  pointer operator->() const { return &((*mp_xpr)(m_index)); }
302 };
303 
304 template<typename _XprType, DirectionType Direction>
305 struct indexed_based_stl_iterator_traits<subvector_stl_iterator<_XprType,Direction> >
306 {
307  typedef _XprType XprType;
308  typedef subvector_stl_iterator<typename internal::remove_const<XprType>::type, Direction> non_const_iterator;
309  typedef subvector_stl_iterator<typename internal::add_const<XprType>::type, Direction> const_iterator;
310 };
311 
312 template<typename XprType, DirectionType Direction>
313 class subvector_stl_iterator : public indexed_based_stl_iterator_base<subvector_stl_iterator<XprType,Direction> >
314 {
315 protected:
316 
317  enum { is_lvalue = internal::is_lvalue<XprType>::value };
318 
319  typedef indexed_based_stl_iterator_base<subvector_stl_iterator> Base;
320  using Base::m_index;
321  using Base::mp_xpr;
322 
323  typedef typename internal::conditional<Direction==Vertical,typename XprType::ColXpr,typename XprType::RowXpr>::type SubVectorType;
324  typedef typename internal::conditional<Direction==Vertical,typename XprType::ConstColXpr,typename XprType::ConstRowXpr>::type ConstSubVectorType;
325 
326 
327 public:
328  typedef typename internal::conditional<bool(is_lvalue), SubVectorType, ConstSubVectorType>::type reference;
329  typedef typename reference::PlainObject value_type;
330 
331 private:
332  class subvector_stl_iterator_ptr
333  {
334  public:
335  subvector_stl_iterator_ptr(const reference &subvector) : m_subvector(subvector) {}
336  reference* operator->() { return &m_subvector; }
337  private:
338  reference m_subvector;
339  };
340 public:
341 
342  typedef subvector_stl_iterator_ptr pointer;
343 
344  subvector_stl_iterator() : Base() {}
345  subvector_stl_iterator(XprType& xpr, Index index) : Base(xpr,index) {}
346 
347  reference operator*() const { return (*mp_xpr).template subVector<Direction>(m_index); }
348  reference operator[](Index i) const { return (*mp_xpr).template subVector<Direction>(m_index+i); }
349  pointer operator->() const { return (*mp_xpr).template subVector<Direction>(m_index); }
350 };
351 
352 template<typename _XprType, DirectionType Direction>
353 struct indexed_based_stl_iterator_traits<subvector_stl_reverse_iterator<_XprType,Direction> >
354 {
355  typedef _XprType XprType;
356  typedef subvector_stl_reverse_iterator<typename internal::remove_const<XprType>::type, Direction> non_const_iterator;
357  typedef subvector_stl_reverse_iterator<typename internal::add_const<XprType>::type, Direction> const_iterator;
358 };
359 
360 template<typename XprType, DirectionType Direction>
361 class subvector_stl_reverse_iterator : public indexed_based_stl_reverse_iterator_base<subvector_stl_reverse_iterator<XprType,Direction> >
362 {
363 protected:
364 
365  enum { is_lvalue = internal::is_lvalue<XprType>::value };
366 
367  typedef indexed_based_stl_reverse_iterator_base<subvector_stl_reverse_iterator> Base;
368  using Base::m_index;
369  using Base::mp_xpr;
370 
371  typedef typename internal::conditional<Direction==Vertical,typename XprType::ColXpr,typename XprType::RowXpr>::type SubVectorType;
372  typedef typename internal::conditional<Direction==Vertical,typename XprType::ConstColXpr,typename XprType::ConstRowXpr>::type ConstSubVectorType;
373 
374 
375 public:
376  typedef typename internal::conditional<bool(is_lvalue), SubVectorType, ConstSubVectorType>::type reference;
377  typedef typename reference::PlainObject value_type;
378 
379 private:
380  class subvector_stl_reverse_iterator_ptr
381  {
382  public:
383  subvector_stl_reverse_iterator_ptr(const reference &subvector) : m_subvector(subvector) {}
384  reference* operator->() { return &m_subvector; }
385  private:
386  reference m_subvector;
387  };
388 public:
389 
390  typedef subvector_stl_reverse_iterator_ptr pointer;
391 
392  subvector_stl_reverse_iterator() : Base() {}
393  subvector_stl_reverse_iterator(XprType& xpr, Index index) : Base(xpr,index) {}
394 
395  reference operator*() const { return (*mp_xpr).template subVector<Direction>(m_index); }
396  reference operator[](Index i) const { return (*mp_xpr).template subVector<Direction>(m_index+i); }
397  pointer operator->() const { return (*mp_xpr).template subVector<Direction>(m_index); }
398 };
399 
400 } // namespace internal
401 
402 
407 template<typename Derived>
409 {
410  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
411  return iterator(derived(), 0);
412 }
413 
415 template<typename Derived>
417 {
418  return cbegin();
419 }
420 
425 template<typename Derived>
427 {
428  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
429  return const_iterator(derived(), 0);
430 }
431 
436 template<typename Derived>
438 {
439  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
440  return iterator(derived(), size());
441 }
442 
444 template<typename Derived>
446 {
447  return cend();
448 }
449 
454 template<typename Derived>
456 {
457  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
458  return const_iterator(derived(), size());
459 }
460 
461 } // namespace Eigen
462 
463 #endif // EIGEN_STLITERATORS_H
const unsigned int DirectAccessBit
Definition: Constants.h:155
Namespace containing all symbols from the Eigen library.
Definition: Core:141
random_access_iterator_type const_iterator
Definition: DenseBase.h:622
iterator begin()
Definition: StlIterators.h:408
const Product< MatrixDerived, PermutationDerived, AliasFreeProduct > operator*(const MatrixBase< MatrixDerived > &matrix, const PermutationBase< PermutationDerived > &permutation)
Definition: PermutationMatrix.h:515
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:74
iterator end()
Definition: StlIterators.h:437
Definition: Eigen_Colamd.h:50
random_access_iterator_type iterator
Definition: DenseBase.h:620
const_iterator cbegin() const
Definition: StlIterators.h:426
const_iterator cend() const
Definition: StlIterators.h:455