10#ifndef EIGEN_STLITERATORS_H
11#define EIGEN_STLITERATORS_H
14#include "./InternalHeaderCheck.h"
20template <
typename IteratorType>
21struct indexed_based_stl_iterator_traits;
23template <
typename Derived>
24class indexed_based_stl_iterator_base {
26 typedef indexed_based_stl_iterator_traits<Derived> traits;
27 typedef typename traits::XprType XprType;
28 typedef indexed_based_stl_iterator_base<typename traits::non_const_iterator> non_const_iterator;
29 typedef indexed_based_stl_iterator_base<typename traits::const_iterator> const_iterator;
30 typedef std::conditional_t<internal::is_const<XprType>::value, non_const_iterator, const_iterator> other_iterator;
32 friend class indexed_based_stl_iterator_base<typename traits::const_iterator>;
33 friend class indexed_based_stl_iterator_base<typename traits::non_const_iterator>;
36 typedef
Index difference_type;
37 typedef std::random_access_iterator_tag iterator_category;
39 indexed_based_stl_iterator_base() noexcept : mp_xpr(0), m_index(0) {}
40 indexed_based_stl_iterator_base(XprType& xpr,
Index index) noexcept : mp_xpr(&xpr), m_index(index) {}
42 indexed_based_stl_iterator_base(
const non_const_iterator& other) noexcept
43 : mp_xpr(other.mp_xpr), m_index(other.m_index) {}
45 indexed_based_stl_iterator_base& operator=(
const non_const_iterator& other) {
46 mp_xpr = other.mp_xpr;
47 m_index = other.m_index;
51 Derived& operator++() {
55 Derived& operator--() {
60 Derived operator++(
int) {
61 Derived prev(derived());
65 Derived operator--(
int) {
66 Derived prev(derived());
71 friend Derived operator+(
const indexed_based_stl_iterator_base& a,
Index b) {
72 Derived ret(a.derived());
76 friend Derived operator-(
const indexed_based_stl_iterator_base& a,
Index b) {
77 Derived ret(a.derived());
81 friend Derived operator+(
Index a,
const indexed_based_stl_iterator_base& b) {
82 Derived ret(b.derived());
86 friend Derived operator-(
Index a,
const indexed_based_stl_iterator_base& b) {
87 Derived ret(b.derived());
92 Derived& operator+=(
Index b) {
96 Derived& operator-=(
Index b) {
101 difference_type operator-(
const indexed_based_stl_iterator_base& other)
const {
102 eigen_assert(mp_xpr == other.mp_xpr);
103 return m_index - other.m_index;
106 difference_type operator-(
const other_iterator& other)
const {
107 eigen_assert(mp_xpr == other.mp_xpr);
108 return m_index - other.m_index;
111 bool operator==(
const indexed_based_stl_iterator_base& other)
const {
112 eigen_assert(mp_xpr == other.mp_xpr);
113 return m_index == other.m_index;
115 bool operator!=(
const indexed_based_stl_iterator_base& other)
const {
116 eigen_assert(mp_xpr == other.mp_xpr);
117 return m_index != other.m_index;
119 bool operator<(
const indexed_based_stl_iterator_base& other)
const {
120 eigen_assert(mp_xpr == other.mp_xpr);
121 return m_index < other.m_index;
123 bool operator<=(
const indexed_based_stl_iterator_base& other)
const {
124 eigen_assert(mp_xpr == other.mp_xpr);
125 return m_index <= other.m_index;
127 bool operator>(
const indexed_based_stl_iterator_base& other)
const {
128 eigen_assert(mp_xpr == other.mp_xpr);
129 return m_index > other.m_index;
131 bool operator>=(
const indexed_based_stl_iterator_base& other)
const {
132 eigen_assert(mp_xpr == other.mp_xpr);
133 return m_index >= other.m_index;
136 bool operator==(
const other_iterator& other)
const {
137 eigen_assert(mp_xpr == other.mp_xpr);
138 return m_index == other.m_index;
140 bool operator!=(
const other_iterator& other)
const {
141 eigen_assert(mp_xpr == other.mp_xpr);
142 return m_index != other.m_index;
144 bool operator<(
const other_iterator& other)
const {
145 eigen_assert(mp_xpr == other.mp_xpr);
146 return m_index < other.m_index;
148 bool operator<=(
const other_iterator& other)
const {
149 eigen_assert(mp_xpr == other.mp_xpr);
150 return m_index <= other.m_index;
152 bool operator>(
const other_iterator& other)
const {
153 eigen_assert(mp_xpr == other.mp_xpr);
154 return m_index > other.m_index;
156 bool operator>=(
const other_iterator& other)
const {
157 eigen_assert(mp_xpr == other.mp_xpr);
158 return m_index >= other.m_index;
162 Derived& derived() {
return static_cast<Derived&
>(*this); }
163 const Derived& derived()
const {
return static_cast<const Derived&
>(*this); }
169template <
typename Derived>
170class indexed_based_stl_reverse_iterator_base {
172 typedef indexed_based_stl_iterator_traits<Derived> traits;
173 typedef typename traits::XprType XprType;
174 typedef indexed_based_stl_reverse_iterator_base<typename traits::non_const_iterator> non_const_iterator;
175 typedef indexed_based_stl_reverse_iterator_base<typename traits::const_iterator> const_iterator;
176 typedef std::conditional_t<internal::is_const<XprType>::value, non_const_iterator, const_iterator> other_iterator;
178 friend class indexed_based_stl_reverse_iterator_base<typename traits::const_iterator>;
179 friend class indexed_based_stl_reverse_iterator_base<typename traits::non_const_iterator>;
182 typedef
Index difference_type;
183 typedef std::random_access_iterator_tag iterator_category;
185 indexed_based_stl_reverse_iterator_base() : mp_xpr(0), m_index(0) {}
186 indexed_based_stl_reverse_iterator_base(XprType& xpr,
Index index) : mp_xpr(&xpr), m_index(index) {}
188 indexed_based_stl_reverse_iterator_base(
const non_const_iterator& other)
189 : mp_xpr(other.mp_xpr), m_index(other.m_index) {}
191 indexed_based_stl_reverse_iterator_base& operator=(
const non_const_iterator& other) {
192 mp_xpr = other.mp_xpr;
193 m_index = other.m_index;
197 Derived& operator++() {
201 Derived& operator--() {
206 Derived operator++(
int) {
207 Derived prev(derived());
211 Derived operator--(
int) {
212 Derived prev(derived());
217 friend Derived operator+(
const indexed_based_stl_reverse_iterator_base& a,
Index b) {
218 Derived ret(a.derived());
222 friend Derived operator-(
const indexed_based_stl_reverse_iterator_base& a,
Index b) {
223 Derived ret(a.derived());
227 friend Derived operator+(
Index a,
const indexed_based_stl_reverse_iterator_base& b) {
228 Derived ret(b.derived());
232 friend Derived operator-(
Index a,
const indexed_based_stl_reverse_iterator_base& b) {
233 Derived ret(b.derived());
238 Derived& operator+=(
Index b) {
242 Derived& operator-=(
Index b) {
247 difference_type operator-(
const indexed_based_stl_reverse_iterator_base& other)
const {
248 eigen_assert(mp_xpr == other.mp_xpr);
249 return other.m_index - m_index;
252 difference_type operator-(
const other_iterator& other)
const {
253 eigen_assert(mp_xpr == other.mp_xpr);
254 return other.m_index - m_index;
257 bool operator==(
const indexed_based_stl_reverse_iterator_base& other)
const {
258 eigen_assert(mp_xpr == other.mp_xpr);
259 return m_index == other.m_index;
261 bool operator!=(
const indexed_based_stl_reverse_iterator_base& other)
const {
262 eigen_assert(mp_xpr == other.mp_xpr);
263 return m_index != other.m_index;
265 bool operator<(
const indexed_based_stl_reverse_iterator_base& other)
const {
266 eigen_assert(mp_xpr == other.mp_xpr);
267 return m_index > other.m_index;
269 bool operator<=(
const indexed_based_stl_reverse_iterator_base& other)
const {
270 eigen_assert(mp_xpr == other.mp_xpr);
271 return m_index >= other.m_index;
273 bool operator>(
const indexed_based_stl_reverse_iterator_base& other)
const {
274 eigen_assert(mp_xpr == other.mp_xpr);
275 return m_index < other.m_index;
277 bool operator>=(
const indexed_based_stl_reverse_iterator_base& other)
const {
278 eigen_assert(mp_xpr == other.mp_xpr);
279 return m_index <= other.m_index;
282 bool operator==(
const other_iterator& other)
const {
283 eigen_assert(mp_xpr == other.mp_xpr);
284 return m_index == other.m_index;
286 bool operator!=(
const other_iterator& other)
const {
287 eigen_assert(mp_xpr == other.mp_xpr);
288 return m_index != other.m_index;
290 bool operator<(
const other_iterator& other)
const {
291 eigen_assert(mp_xpr == other.mp_xpr);
292 return m_index > other.m_index;
294 bool operator<=(
const other_iterator& other)
const {
295 eigen_assert(mp_xpr == other.mp_xpr);
296 return m_index >= other.m_index;
298 bool operator>(
const other_iterator& other)
const {
299 eigen_assert(mp_xpr == other.mp_xpr);
300 return m_index < other.m_index;
302 bool operator>=(
const other_iterator& other)
const {
303 eigen_assert(mp_xpr == other.mp_xpr);
304 return m_index <= other.m_index;
308 Derived& derived() {
return static_cast<Derived&
>(*this); }
309 const Derived& derived()
const {
return static_cast<const Derived&
>(*this); }
315template <
typename XprType>
316class pointer_based_stl_iterator {
317 enum { is_lvalue = internal::is_lvalue<XprType>::value };
318 typedef pointer_based_stl_iterator<std::remove_const_t<XprType>> non_const_iterator;
319 typedef pointer_based_stl_iterator<std::add_const_t<XprType>> const_iterator;
320 typedef std::conditional_t<internal::is_const<XprType>::value, non_const_iterator, const_iterator> other_iterator;
322 friend class pointer_based_stl_iterator<std::add_const_t<XprType>>;
323 friend class pointer_based_stl_iterator<std::remove_const_t<XprType>>;
326 typedef
Index difference_type;
327 typedef typename XprType::Scalar value_type;
328#if EIGEN_COMP_CXXVER >= 20 && defined(__cpp_lib_concepts) && __cpp_lib_concepts >= 202002L
329 typedef std::conditional_t<XprType::InnerStrideAtCompileTime == 1, std::contiguous_iterator_tag,
330 std::random_access_iterator_tag>
333 typedef std::random_access_iterator_tag iterator_category;
335 typedef std::conditional_t<bool(is_lvalue), value_type*, const value_type*> pointer;
336 typedef std::conditional_t<bool(is_lvalue), value_type&, const value_type&> reference;
338 pointer_based_stl_iterator() noexcept : m_ptr(0) {}
339 pointer_based_stl_iterator(XprType& xpr,
Index index) noexcept : m_incr(xpr.innerStride()) {
340 m_ptr = xpr.data() + index * m_incr.value();
343 pointer_based_stl_iterator(
const non_const_iterator& other) noexcept : m_ptr(other.m_ptr), m_incr(other.m_incr) {}
345 pointer_based_stl_iterator& operator=(
const non_const_iterator& other)
noexcept {
347 m_incr.setValue(other.m_incr);
351 reference operator*()
const {
return *m_ptr; }
352 reference operator[](
Index i)
const {
return *(m_ptr + i * m_incr.value()); }
353 pointer operator->()
const {
return m_ptr; }
355 pointer_based_stl_iterator& operator++() {
356 m_ptr += m_incr.value();
359 pointer_based_stl_iterator& operator--() {
360 m_ptr -= m_incr.value();
364 pointer_based_stl_iterator operator++(
int) {
365 pointer_based_stl_iterator prev(*
this);
369 pointer_based_stl_iterator operator--(
int) {
370 pointer_based_stl_iterator prev(*
this);
375 friend pointer_based_stl_iterator operator+(
const pointer_based_stl_iterator& a,
Index b) {
376 pointer_based_stl_iterator ret(a);
380 friend pointer_based_stl_iterator operator-(
const pointer_based_stl_iterator& a,
Index b) {
381 pointer_based_stl_iterator ret(a);
385 friend pointer_based_stl_iterator operator+(
Index a,
const pointer_based_stl_iterator& b) {
386 pointer_based_stl_iterator ret(b);
390 friend pointer_based_stl_iterator operator-(
Index a,
const pointer_based_stl_iterator& b) {
391 pointer_based_stl_iterator ret(b);
396 pointer_based_stl_iterator& operator+=(
Index b) {
397 m_ptr += b * m_incr.value();
400 pointer_based_stl_iterator& operator-=(
Index b) {
401 m_ptr -= b * m_incr.value();
405 difference_type operator-(
const pointer_based_stl_iterator& other)
const {
406 return (m_ptr - other.m_ptr) / m_incr.value();
409 difference_type operator-(
const other_iterator& other)
const {
return (m_ptr - other.m_ptr) / m_incr.value(); }
411 bool operator==(
const pointer_based_stl_iterator& other)
const {
return m_ptr == other.m_ptr; }
412 bool operator!=(
const pointer_based_stl_iterator& other)
const {
return m_ptr != other.m_ptr; }
413 bool operator<(
const pointer_based_stl_iterator& other)
const {
return m_ptr < other.m_ptr; }
414 bool operator<=(
const pointer_based_stl_iterator& other)
const {
return m_ptr <= other.m_ptr; }
415 bool operator>(
const pointer_based_stl_iterator& other)
const {
return m_ptr > other.m_ptr; }
416 bool operator>=(
const pointer_based_stl_iterator& other)
const {
return m_ptr >= other.m_ptr; }
418 bool operator==(
const other_iterator& other)
const {
return m_ptr == other.m_ptr; }
419 bool operator!=(
const other_iterator& other)
const {
return m_ptr != other.m_ptr; }
420 bool operator<(
const other_iterator& other)
const {
return m_ptr < other.m_ptr; }
421 bool operator<=(
const other_iterator& other)
const {
return m_ptr <= other.m_ptr; }
422 bool operator>(
const other_iterator& other)
const {
return m_ptr > other.m_ptr; }
423 bool operator>=(
const other_iterator& other)
const {
return m_ptr >= other.m_ptr; }
427 internal::variable_if_dynamic<Index, XprType::InnerStrideAtCompileTime> m_incr;
430template <
typename XprType_>
431struct indexed_based_stl_iterator_traits<generic_randaccess_stl_iterator<XprType_>> {
432 typedef XprType_ XprType;
433 typedef generic_randaccess_stl_iterator<std::remove_const_t<XprType>> non_const_iterator;
434 typedef generic_randaccess_stl_iterator<std::add_const_t<XprType>> const_iterator;
437template <
typename XprType>
438class generic_randaccess_stl_iterator
439 :
public indexed_based_stl_iterator_base<generic_randaccess_stl_iterator<XprType>> {
441 typedef typename XprType::Scalar value_type;
445 has_direct_access = (internal::traits<XprType>::Flags &
DirectAccessBit) ? 1 : 0,
446 is_lvalue = internal::is_lvalue<XprType>::value
449 typedef indexed_based_stl_iterator_base<generic_randaccess_stl_iterator> Base;
456 typedef const value_type read_only_ref_t;
459 typedef std::conditional_t<bool(is_lvalue), value_type*,
const value_type*> pointer;
460 typedef std::conditional_t<bool(is_lvalue), value_type&, read_only_ref_t> reference;
462 generic_randaccess_stl_iterator() : Base() {}
463 generic_randaccess_stl_iterator(XprType& xpr,
Index index) : Base(xpr, index) {}
464 generic_randaccess_stl_iterator(
const typename Base::non_const_iterator& other) : Base(other) {}
465 using Base::operator=;
467 reference operator*()
const {
return (*mp_xpr)(m_index); }
468 reference operator[](
Index i)
const {
return (*mp_xpr)(m_index + i); }
469 pointer operator->()
const {
return &((*mp_xpr)(m_index)); }
472template <
typename XprType_, DirectionType Direction>
473struct indexed_based_stl_iterator_traits<subvector_stl_iterator<XprType_, Direction>> {
474 typedef XprType_ XprType;
475 typedef subvector_stl_iterator<std::remove_const_t<XprType>, Direction> non_const_iterator;
476 typedef subvector_stl_iterator<std::add_const_t<XprType>, Direction> const_iterator;
479template <
typename XprType, DirectionType Direction>
480class subvector_stl_iterator :
public indexed_based_stl_iterator_base<subvector_stl_iterator<XprType, Direction>> {
482 enum { is_lvalue = internal::is_lvalue<XprType>::value };
484 typedef indexed_based_stl_iterator_base<subvector_stl_iterator> Base;
488 typedef std::conditional_t<Direction == Vertical, typename XprType::ColXpr, typename XprType::RowXpr> SubVectorType;
489 typedef std::conditional_t<Direction == Vertical, typename XprType::ConstColXpr, typename XprType::ConstRowXpr>
493 typedef std::conditional_t<bool(is_lvalue), SubVectorType, ConstSubVectorType> reference;
494 typedef typename reference::PlainObject value_type;
497 class subvector_stl_iterator_ptr {
499 subvector_stl_iterator_ptr(
const reference& subvector) : m_subvector(subvector) {}
500 reference* operator->() {
return &m_subvector; }
503 reference m_subvector;
507 typedef subvector_stl_iterator_ptr pointer;
509 subvector_stl_iterator() : Base() {}
510 subvector_stl_iterator(XprType& xpr, Index index) : Base(xpr, index) {}
512 reference operator*()
const {
return (*mp_xpr).template subVector<Direction>(m_index); }
513 reference operator[](Index i)
const {
return (*mp_xpr).template subVector<Direction>(m_index + i); }
514 pointer operator->()
const {
return (*mp_xpr).template subVector<Direction>(m_index); }
517template <
typename XprType_, DirectionType Direction>
518struct indexed_based_stl_iterator_traits<subvector_stl_reverse_iterator<XprType_, Direction>> {
519 typedef XprType_ XprType;
520 typedef subvector_stl_reverse_iterator<std::remove_const_t<XprType>, Direction> non_const_iterator;
521 typedef subvector_stl_reverse_iterator<std::add_const_t<XprType>, Direction> const_iterator;
524template <
typename XprType, DirectionType Direction>
525class subvector_stl_reverse_iterator
526 :
public indexed_based_stl_reverse_iterator_base<subvector_stl_reverse_iterator<XprType, Direction>> {
528 enum { is_lvalue = internal::is_lvalue<XprType>::value };
530 typedef indexed_based_stl_reverse_iterator_base<subvector_stl_reverse_iterator> Base;
534 typedef std::conditional_t<Direction == Vertical, typename XprType::ColXpr, typename XprType::RowXpr> SubVectorType;
535 typedef std::conditional_t<Direction == Vertical, typename XprType::ConstColXpr, typename XprType::ConstRowXpr>
539 typedef std::conditional_t<bool(is_lvalue), SubVectorType, ConstSubVectorType> reference;
540 typedef typename reference::PlainObject value_type;
543 class subvector_stl_reverse_iterator_ptr {
545 subvector_stl_reverse_iterator_ptr(
const reference& subvector) : m_subvector(subvector) {}
546 reference* operator->() {
return &m_subvector; }
549 reference m_subvector;
553 typedef subvector_stl_reverse_iterator_ptr pointer;
555 subvector_stl_reverse_iterator() : Base() {}
556 subvector_stl_reverse_iterator(XprType& xpr, Index index) : Base(xpr, index) {}
558 reference operator*()
const {
return (*mp_xpr).template subVector<Direction>(m_index); }
559 reference operator[](Index i)
const {
return (*mp_xpr).template subVector<Direction>(m_index + i); }
560 pointer operator->()
const {
return (*mp_xpr).template subVector<Direction>(m_index); }
569template <
typename Derived>
571 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
576template <
typename Derived>
585template <
typename Derived>
587 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
595template <
typename Derived>
597 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
602template <
typename Derived>
611template <
typename Derived>
613 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
random_access_iterator_type const_iterator
Definition DenseBase.h:579
iterator begin()
Definition StlIterators.h:570
iterator end()
Definition StlIterators.h:596
const_iterator cbegin() const
Definition StlIterators.h:586
const_iterator cend() const
Definition StlIterators.h:612
random_access_iterator_type iterator
Definition DenseBase.h:577
const unsigned int DirectAccessBit
Definition Constants.h:159
Namespace containing all symbols from the Eigen library.
Definition B01_Experimental.dox:1
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:82