11#ifndef EIGEN_STLITERATORS_H
12#define EIGEN_STLITERATORS_H
15#include "./InternalHeaderCheck.h"
21template <
typename IteratorType>
22struct indexed_based_stl_iterator_traits;
24template <
typename Derived>
25class indexed_based_stl_iterator_base {
27 using traits = indexed_based_stl_iterator_traits<Derived>;
28 using XprType =
typename traits::XprType;
29 using non_const_iterator = indexed_based_stl_iterator_base<typename traits::non_const_iterator>;
30 using const_iterator = indexed_based_stl_iterator_base<typename traits::const_iterator>;
31 using other_iterator = std::conditional_t<std::is_const<XprType>::value, non_const_iterator, const_iterator>;
33 friend class indexed_based_stl_iterator_base<typename traits::const_iterator>;
34 friend class indexed_based_stl_iterator_base<typename traits::non_const_iterator>;
37 using difference_type = Index;
38 using iterator_category = std::random_access_iterator_tag;
40 indexed_based_stl_iterator_base() noexcept = default;
41 indexed_based_stl_iterator_base(XprType& xpr, Index index) noexcept : mp_xpr(&xpr), m_index(index) {}
43 indexed_based_stl_iterator_base(
const non_const_iterator& other) noexcept
44 : mp_xpr(other.mp_xpr), m_index(other.m_index) {}
46 indexed_based_stl_iterator_base& operator=(
const non_const_iterator& other) {
47 mp_xpr = other.mp_xpr;
48 m_index = other.m_index;
52 Derived& operator++() {
56 Derived& operator--() {
61 Derived operator++(
int) {
62 Derived prev(derived());
66 Derived operator--(
int) {
67 Derived prev(derived());
72 friend Derived operator+(
const indexed_based_stl_iterator_base& a, Index b) {
73 Derived ret(a.derived());
77 friend Derived operator-(
const indexed_based_stl_iterator_base& a, Index b) {
78 Derived ret(a.derived());
82 friend Derived operator+(Index a,
const indexed_based_stl_iterator_base& b) {
83 Derived ret(b.derived());
87 friend Derived operator-(Index a,
const indexed_based_stl_iterator_base& b) {
88 Derived ret(b.derived());
93 Derived& operator+=(Index b) {
97 Derived& operator-=(Index b) {
102 difference_type operator-(
const indexed_based_stl_iterator_base& other)
const {
103 eigen_assert(mp_xpr == other.mp_xpr);
104 return m_index - other.m_index;
107 difference_type operator-(
const other_iterator& other)
const {
108 eigen_assert(mp_xpr == other.mp_xpr);
109 return m_index - other.m_index;
112 bool operator==(
const indexed_based_stl_iterator_base& other)
const {
113 eigen_assert(mp_xpr == other.mp_xpr);
114 return m_index == other.m_index;
116 bool operator!=(
const indexed_based_stl_iterator_base& other)
const {
117 eigen_assert(mp_xpr == other.mp_xpr);
118 return m_index != other.m_index;
120 bool operator<(
const indexed_based_stl_iterator_base& other)
const {
121 eigen_assert(mp_xpr == other.mp_xpr);
122 return m_index < other.m_index;
124 bool operator<=(
const indexed_based_stl_iterator_base& other)
const {
125 eigen_assert(mp_xpr == other.mp_xpr);
126 return m_index <= other.m_index;
128 bool operator>(
const indexed_based_stl_iterator_base& other)
const {
129 eigen_assert(mp_xpr == other.mp_xpr);
130 return m_index > other.m_index;
132 bool operator>=(
const indexed_based_stl_iterator_base& other)
const {
133 eigen_assert(mp_xpr == other.mp_xpr);
134 return m_index >= other.m_index;
137 bool operator==(
const other_iterator& other)
const {
138 eigen_assert(mp_xpr == other.mp_xpr);
139 return m_index == other.m_index;
141 bool operator!=(
const other_iterator& other)
const {
142 eigen_assert(mp_xpr == other.mp_xpr);
143 return m_index != other.m_index;
145 bool operator<(
const other_iterator& other)
const {
146 eigen_assert(mp_xpr == other.mp_xpr);
147 return m_index < other.m_index;
149 bool operator<=(
const other_iterator& other)
const {
150 eigen_assert(mp_xpr == other.mp_xpr);
151 return m_index <= other.m_index;
153 bool operator>(
const other_iterator& other)
const {
154 eigen_assert(mp_xpr == other.mp_xpr);
155 return m_index > other.m_index;
157 bool operator>=(
const other_iterator& other)
const {
158 eigen_assert(mp_xpr == other.mp_xpr);
159 return m_index >= other.m_index;
163 Derived& derived() {
return static_cast<Derived&
>(*this); }
164 const Derived& derived()
const {
return static_cast<const Derived&
>(*this); }
166 XprType* mp_xpr =
nullptr;
170template <
typename Derived>
171class indexed_based_stl_reverse_iterator_base {
173 using traits = indexed_based_stl_iterator_traits<Derived>;
174 using XprType =
typename traits::XprType;
175 using non_const_iterator = indexed_based_stl_reverse_iterator_base<typename traits::non_const_iterator>;
176 using const_iterator = indexed_based_stl_reverse_iterator_base<typename traits::const_iterator>;
177 using other_iterator = std::conditional_t<std::is_const<XprType>::value, non_const_iterator, const_iterator>;
179 friend class indexed_based_stl_reverse_iterator_base<typename traits::const_iterator>;
180 friend class indexed_based_stl_reverse_iterator_base<typename traits::non_const_iterator>;
183 using difference_type = Index;
184 using iterator_category = std::random_access_iterator_tag;
186 indexed_based_stl_reverse_iterator_base() = default;
187 indexed_based_stl_reverse_iterator_base(XprType& xpr, Index index) : mp_xpr(&xpr), m_index(index) {}
189 indexed_based_stl_reverse_iterator_base(
const non_const_iterator& other)
190 : mp_xpr(other.mp_xpr), m_index(other.m_index) {}
192 indexed_based_stl_reverse_iterator_base& operator=(
const non_const_iterator& other) {
193 mp_xpr = other.mp_xpr;
194 m_index = other.m_index;
198 Derived& operator++() {
202 Derived& operator--() {
207 Derived operator++(
int) {
208 Derived prev(derived());
212 Derived operator--(
int) {
213 Derived prev(derived());
218 friend Derived operator+(
const indexed_based_stl_reverse_iterator_base& a, Index b) {
219 Derived ret(a.derived());
223 friend Derived operator-(
const indexed_based_stl_reverse_iterator_base& a, Index b) {
224 Derived ret(a.derived());
228 friend Derived operator+(Index a,
const indexed_based_stl_reverse_iterator_base& b) {
229 Derived ret(b.derived());
233 friend Derived operator-(Index a,
const indexed_based_stl_reverse_iterator_base& b) {
234 Derived ret(b.derived());
239 Derived& operator+=(Index b) {
243 Derived& operator-=(Index b) {
248 difference_type operator-(
const indexed_based_stl_reverse_iterator_base& other)
const {
249 eigen_assert(mp_xpr == other.mp_xpr);
250 return other.m_index - m_index;
253 difference_type operator-(
const other_iterator& other)
const {
254 eigen_assert(mp_xpr == other.mp_xpr);
255 return other.m_index - m_index;
258 bool operator==(
const indexed_based_stl_reverse_iterator_base& other)
const {
259 eigen_assert(mp_xpr == other.mp_xpr);
260 return m_index == other.m_index;
262 bool operator!=(
const indexed_based_stl_reverse_iterator_base& other)
const {
263 eigen_assert(mp_xpr == other.mp_xpr);
264 return m_index != other.m_index;
266 bool operator<(
const indexed_based_stl_reverse_iterator_base& other)
const {
267 eigen_assert(mp_xpr == other.mp_xpr);
268 return m_index > other.m_index;
270 bool operator<=(
const indexed_based_stl_reverse_iterator_base& other)
const {
271 eigen_assert(mp_xpr == other.mp_xpr);
272 return m_index >= other.m_index;
274 bool operator>(
const indexed_based_stl_reverse_iterator_base& other)
const {
275 eigen_assert(mp_xpr == other.mp_xpr);
276 return m_index < other.m_index;
278 bool operator>=(
const indexed_based_stl_reverse_iterator_base& other)
const {
279 eigen_assert(mp_xpr == other.mp_xpr);
280 return m_index <= other.m_index;
283 bool operator==(
const other_iterator& other)
const {
284 eigen_assert(mp_xpr == other.mp_xpr);
285 return m_index == other.m_index;
287 bool operator!=(
const other_iterator& other)
const {
288 eigen_assert(mp_xpr == other.mp_xpr);
289 return m_index != other.m_index;
291 bool operator<(
const other_iterator& other)
const {
292 eigen_assert(mp_xpr == other.mp_xpr);
293 return m_index > other.m_index;
295 bool operator<=(
const other_iterator& other)
const {
296 eigen_assert(mp_xpr == other.mp_xpr);
297 return m_index >= other.m_index;
299 bool operator>(
const other_iterator& other)
const {
300 eigen_assert(mp_xpr == other.mp_xpr);
301 return m_index < other.m_index;
303 bool operator>=(
const other_iterator& other)
const {
304 eigen_assert(mp_xpr == other.mp_xpr);
305 return m_index <= other.m_index;
309 Derived& derived() {
return static_cast<Derived&
>(*this); }
310 const Derived& derived()
const {
return static_cast<const Derived&
>(*this); }
312 XprType* mp_xpr =
nullptr;
316template <
typename XprType>
317class pointer_based_stl_iterator {
318 enum { is_lvalue = internal::is_lvalue<XprType>::value };
319 using non_const_iterator = pointer_based_stl_iterator<std::remove_const_t<XprType>>;
320 using const_iterator = pointer_based_stl_iterator<std::add_const_t<XprType>>;
321 using other_iterator = std::conditional_t<std::is_const<XprType>::value, non_const_iterator, const_iterator>;
323 friend class pointer_based_stl_iterator<std::add_const_t<XprType>>;
324 friend class pointer_based_stl_iterator<std::remove_const_t<XprType>>;
327 using difference_type = Index;
328 using value_type = typename XprType::Scalar;
329#if EIGEN_COMP_CXXVER >= 20 && defined(__cpp_lib_concepts) && __cpp_lib_concepts >= 202002L
330 using iterator_category = std::conditional_t<XprType::InnerStrideAtCompileTime == 1, std::contiguous_iterator_tag,
331 std::random_access_iterator_tag>;
333 using iterator_category = std::random_access_iterator_tag;
335 using pointer = std::conditional_t<bool(is_lvalue), value_type*, const value_type*>;
336 using reference = std::conditional_t<bool(is_lvalue), value_type&, const value_type&>;
338 pointer_based_stl_iterator() noexcept = default;
339 pointer_based_stl_iterator(XprType& xpr, Index index) noexcept
340 : m_ptr(xpr.data() + index * xpr.innerStride()), m_incr(xpr.innerStride()) {}
342 pointer_based_stl_iterator(
const non_const_iterator& other) noexcept : m_ptr(other.m_ptr), m_incr(other.m_incr) {}
344 pointer_based_stl_iterator& operator=(
const non_const_iterator& other)
noexcept {
346 m_incr.setValue(other.m_incr);
350 reference operator*()
const {
return *m_ptr; }
351 reference operator[](Index i)
const {
return *(m_ptr + i * m_incr.value()); }
352 pointer operator->()
const {
return m_ptr; }
354 pointer_based_stl_iterator& operator++() {
355 m_ptr += m_incr.value();
358 pointer_based_stl_iterator& operator--() {
359 m_ptr -= m_incr.value();
363 pointer_based_stl_iterator operator++(
int) {
364 pointer_based_stl_iterator prev(*
this);
368 pointer_based_stl_iterator operator--(
int) {
369 pointer_based_stl_iterator prev(*
this);
374 friend pointer_based_stl_iterator operator+(
const pointer_based_stl_iterator& a, Index b) {
375 pointer_based_stl_iterator ret(a);
379 friend pointer_based_stl_iterator operator-(
const pointer_based_stl_iterator& a, Index b) {
380 pointer_based_stl_iterator ret(a);
384 friend pointer_based_stl_iterator operator+(Index a,
const pointer_based_stl_iterator& b) {
385 pointer_based_stl_iterator ret(b);
389 friend pointer_based_stl_iterator operator-(Index a,
const pointer_based_stl_iterator& b) {
390 pointer_based_stl_iterator ret(b);
395 pointer_based_stl_iterator& operator+=(Index b) {
396 m_ptr += b * m_incr.value();
399 pointer_based_stl_iterator& operator-=(Index b) {
400 m_ptr -= b * m_incr.value();
404 difference_type operator-(
const pointer_based_stl_iterator& other)
const {
405 return (m_ptr - other.m_ptr) / m_incr.value();
408 difference_type operator-(
const other_iterator& other)
const {
return (m_ptr - other.m_ptr) / m_incr.value(); }
410 bool operator==(
const pointer_based_stl_iterator& other)
const {
return m_ptr == other.m_ptr; }
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 {
414 return m_incr.value() < 0 ? m_ptr > other.m_ptr : m_ptr < other.m_ptr;
416 bool operator<=(
const pointer_based_stl_iterator& other)
const {
return !(other < *
this); }
417 bool operator>(
const pointer_based_stl_iterator& other)
const {
return other < *
this; }
418 bool operator>=(
const pointer_based_stl_iterator& other)
const {
return !(*
this < other); }
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 {
423 return m_incr.value() < 0 ? m_ptr > other.m_ptr : m_ptr < other.m_ptr;
425 bool operator<=(
const other_iterator& other)
const {
return !(other < *
this); }
426 bool operator>(
const other_iterator& other)
const {
return other < *
this; }
427 bool operator>=(
const other_iterator& other)
const {
return !(*
this < other); }
430 pointer m_ptr =
nullptr;
431 internal::variable_if_dynamic<Index, XprType::InnerStrideAtCompileTime> m_incr{XprType::InnerStrideAtCompileTime};
434template <
typename XprType_>
435struct indexed_based_stl_iterator_traits<generic_randaccess_stl_iterator<XprType_>> {
436 using XprType = XprType_;
437 using non_const_iterator = generic_randaccess_stl_iterator<std::remove_const_t<XprType>>;
438 using const_iterator = generic_randaccess_stl_iterator<std::add_const_t<XprType>>;
441template <
typename XprType>
442class generic_randaccess_stl_iterator
443 :
public indexed_based_stl_iterator_base<generic_randaccess_stl_iterator<XprType>> {
445 using value_type =
typename XprType::Scalar;
449 has_direct_access = (internal::traits<XprType>::Flags &
DirectAccessBit) ? 1 : 0,
450 is_lvalue = internal::is_lvalue<XprType>::value
453 using Base = indexed_based_stl_iterator_base<generic_randaccess_stl_iterator>;
460 using read_only_ref_t =
const value_type;
463 using pointer = std::conditional_t<bool(is_lvalue), value_type*,
const value_type*>;
464 using reference = std::conditional_t<bool(is_lvalue), value_type&, read_only_ref_t>;
466 generic_randaccess_stl_iterator() =
default;
467 generic_randaccess_stl_iterator(XprType& xpr, Index index) : Base(xpr, index) {}
468 generic_randaccess_stl_iterator(
const typename Base::non_const_iterator& other) : Base(other) {}
469 using Base::operator=;
471 reference operator*()
const {
return (*mp_xpr)(m_index); }
472 reference operator[](Index i)
const {
return (*mp_xpr)(m_index + i); }
473 pointer operator->()
const {
return &((*mp_xpr)(m_index)); }
476template <
typename XprType_, DirectionType Direction>
477struct indexed_based_stl_iterator_traits<subvector_stl_iterator<XprType_, Direction>> {
478 using XprType = XprType_;
479 using non_const_iterator = subvector_stl_iterator<std::remove_const_t<XprType>, Direction>;
480 using const_iterator = subvector_stl_iterator<std::add_const_t<XprType>, Direction>;
483template <
typename XprType, DirectionType Direction>
484class subvector_stl_iterator :
public indexed_based_stl_iterator_base<subvector_stl_iterator<XprType, Direction>> {
486 enum { is_lvalue = internal::is_lvalue<XprType>::value };
488 using Base = indexed_based_stl_iterator_base<subvector_stl_iterator>;
492 using SubVectorType = std::conditional_t<Direction == Vertical, typename XprType::ColXpr, typename XprType::RowXpr>;
493 using ConstSubVectorType =
494 std::conditional_t<Direction == Vertical, typename XprType::ConstColXpr, typename XprType::ConstRowXpr>;
497 using reference = std::conditional_t<bool(is_lvalue), SubVectorType, ConstSubVectorType>;
498 using value_type =
typename reference::PlainObject;
501 class subvector_stl_iterator_ptr {
503 subvector_stl_iterator_ptr(
const reference& subvector) : m_subvector(subvector) {}
504 reference* operator->() {
return &m_subvector; }
507 reference m_subvector;
511 using pointer = subvector_stl_iterator_ptr;
513 subvector_stl_iterator() =
default;
514 subvector_stl_iterator(XprType& xpr, Index index) : Base(xpr, index) {}
515 subvector_stl_iterator(
const typename Base::non_const_iterator& other) : Base(other) {}
517 reference operator*()
const {
return (*mp_xpr).template subVector<Direction>(m_index); }
518 reference operator[](Index i)
const {
return (*mp_xpr).template subVector<Direction>(m_index + i); }
519 pointer operator->()
const {
return (*mp_xpr).template subVector<Direction>(m_index); }
522template <
typename XprType_, DirectionType Direction>
523struct indexed_based_stl_iterator_traits<subvector_stl_reverse_iterator<XprType_, Direction>> {
524 using XprType = XprType_;
525 using non_const_iterator = subvector_stl_reverse_iterator<std::remove_const_t<XprType>, Direction>;
526 using const_iterator = subvector_stl_reverse_iterator<std::add_const_t<XprType>, Direction>;
529template <
typename XprType, DirectionType Direction>
530class subvector_stl_reverse_iterator
531 :
public indexed_based_stl_reverse_iterator_base<subvector_stl_reverse_iterator<XprType, Direction>> {
533 enum { is_lvalue = internal::is_lvalue<XprType>::value };
535 using Base = indexed_based_stl_reverse_iterator_base<subvector_stl_reverse_iterator>;
539 using SubVectorType = std::conditional_t<Direction == Vertical, typename XprType::ColXpr, typename XprType::RowXpr>;
540 using ConstSubVectorType =
541 std::conditional_t<Direction == Vertical, typename XprType::ConstColXpr, typename XprType::ConstRowXpr>;
544 using reference = std::conditional_t<bool(is_lvalue), SubVectorType, ConstSubVectorType>;
545 using value_type =
typename reference::PlainObject;
548 class subvector_stl_reverse_iterator_ptr {
550 subvector_stl_reverse_iterator_ptr(
const reference& subvector) : m_subvector(subvector) {}
551 reference* operator->() {
return &m_subvector; }
554 reference m_subvector;
558 using pointer = subvector_stl_reverse_iterator_ptr;
560 subvector_stl_reverse_iterator() =
default;
561 subvector_stl_reverse_iterator(XprType& xpr, Index index) : Base(xpr, index) {}
562 subvector_stl_reverse_iterator(
const typename Base::non_const_iterator& other) : Base(other) {}
564 reference operator*()
const {
return (*mp_xpr).template subVector<Direction>(m_index); }
565 reference operator[](Index i)
const {
return (*mp_xpr).template subVector<Direction>(m_index - i); }
566 pointer operator->()
const {
return (*mp_xpr).template subVector<Direction>(m_index); }
575template <
typename Derived>
577 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
582template <
typename Derived>
591template <
typename Derived>
593 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
601template <
typename Derived>
603 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
608template <
typename Derived>
617template <
typename Derived>
619 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
random_access_iterator_type const_iterator
Definition DenseBase.h:563
iterator begin()
Definition StlIterators.h:576
iterator end()
Definition StlIterators.h:602
const_iterator cbegin() const
Definition StlIterators.h:592
const_iterator cend() const
Definition StlIterators.h:618
random_access_iterator_type iterator
Definition DenseBase.h:561
constexpr unsigned int DirectAccessBit
Definition Constants.h:160