Please, help us to better know about our user community by answering the following short survey: https://forms.gle/wpyrxWi18ox9Z5ae9
Eigen  3.4.0
 
Loading...
Searching...
No Matches
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
13namespace Eigen {
14
15namespace internal {
16
17template<typename IteratorType>
18struct indexed_based_stl_iterator_traits;
19
20template<typename Derived>
21class indexed_based_stl_iterator_base
22{
23protected:
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>;
32public:
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
90protected:
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
99template<typename Derived>
100class indexed_based_stl_reverse_iterator_base
101{
102protected:
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>;
111public:
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
169protected:
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
178template<typename XprType>
179class 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>;
188public:
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
253protected:
254
255 pointer m_ptr;
256 internal::variable_if_dynamic<Index, XprType::InnerStrideAtCompileTime> m_incr;
257};
258
259template<typename _XprType>
260struct 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
267template<typename XprType>
268class generic_randaccess_stl_iterator : public indexed_based_stl_iterator_base<generic_randaccess_stl_iterator<XprType> >
269{
270public:
271 typedef typename XprType::Scalar value_type;
272
273protected:
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
289public:
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
304template<typename _XprType, DirectionType Direction>
305struct 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
312template<typename XprType, DirectionType Direction>
313class subvector_stl_iterator : public indexed_based_stl_iterator_base<subvector_stl_iterator<XprType,Direction> >
314{
315protected:
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
327public:
328 typedef typename internal::conditional<bool(is_lvalue), SubVectorType, ConstSubVectorType>::type reference;
329 typedef typename reference::PlainObject value_type;
330
331private:
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 };
340public:
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
352template<typename _XprType, DirectionType Direction>
353struct 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
360template<typename XprType, DirectionType Direction>
361class subvector_stl_reverse_iterator : public indexed_based_stl_reverse_iterator_base<subvector_stl_reverse_iterator<XprType,Direction> >
362{
363protected:
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
375public:
376 typedef typename internal::conditional<bool(is_lvalue), SubVectorType, ConstSubVectorType>::type reference;
377 typedef typename reference::PlainObject value_type;
378
379private:
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 };
388public:
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
407template<typename Derived>
409{
410 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
411 return iterator(derived(), 0);
412}
413
415template<typename Derived>
417{
418 return cbegin();
419}
420
425template<typename Derived>
427{
428 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
429 return const_iterator(derived(), 0);
430}
431
436template<typename Derived>
438{
439 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
440 return iterator(derived(), size());
441}
442
444template<typename Derived>
446{
447 return cend();
448}
449
454template<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
Base class for all dense matrices, vectors, and arrays.
Definition: DenseBase.h:47
random_access_iterator_type const_iterator
Definition: DenseBase.h:622
random_access_iterator_type iterator
Definition: DenseBase.h:620
const unsigned int DirectAccessBit
Definition: Constants.h:155
Namespace containing all symbols from the Eigen library.
Definition: Core:141
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:74