File indexing completed on 2025-01-18 09:56:18
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef EIGEN_STLITERATORS_H
0011 #define EIGEN_STLITERATORS_H
0012
0013 namespace Eigen {
0014
0015 namespace internal {
0016
0017 template<typename IteratorType>
0018 struct indexed_based_stl_iterator_traits;
0019
0020 template<typename Derived>
0021 class indexed_based_stl_iterator_base
0022 {
0023 protected:
0024 typedef indexed_based_stl_iterator_traits<Derived> traits;
0025 typedef typename traits::XprType XprType;
0026 typedef indexed_based_stl_iterator_base<typename traits::non_const_iterator> non_const_iterator;
0027 typedef indexed_based_stl_iterator_base<typename traits::const_iterator> const_iterator;
0028 typedef typename internal::conditional<internal::is_const<XprType>::value,non_const_iterator,const_iterator>::type other_iterator;
0029
0030 friend class indexed_based_stl_iterator_base<typename traits::const_iterator>;
0031 friend class indexed_based_stl_iterator_base<typename traits::non_const_iterator>;
0032 public:
0033 typedef Index difference_type;
0034 typedef std::random_access_iterator_tag iterator_category;
0035
0036 indexed_based_stl_iterator_base() EIGEN_NO_THROW : mp_xpr(0), m_index(0) {}
0037 indexed_based_stl_iterator_base(XprType& xpr, Index index) EIGEN_NO_THROW : mp_xpr(&xpr), m_index(index) {}
0038
0039 indexed_based_stl_iterator_base(const non_const_iterator& other) EIGEN_NO_THROW
0040 : mp_xpr(other.mp_xpr), m_index(other.m_index)
0041 {}
0042
0043 indexed_based_stl_iterator_base& operator=(const non_const_iterator& other)
0044 {
0045 mp_xpr = other.mp_xpr;
0046 m_index = other.m_index;
0047 return *this;
0048 }
0049
0050 Derived& operator++() { ++m_index; return derived(); }
0051 Derived& operator--() { --m_index; return derived(); }
0052
0053 Derived operator++(int) { Derived prev(derived()); operator++(); return prev;}
0054 Derived operator--(int) { Derived prev(derived()); operator--(); return prev;}
0055
0056 friend Derived operator+(const indexed_based_stl_iterator_base& a, Index b) { Derived ret(a.derived()); ret += b; return ret; }
0057 friend Derived operator-(const indexed_based_stl_iterator_base& a, Index b) { Derived ret(a.derived()); ret -= b; return ret; }
0058 friend Derived operator+(Index a, const indexed_based_stl_iterator_base& b) { Derived ret(b.derived()); ret += a; return ret; }
0059 friend Derived operator-(Index a, const indexed_based_stl_iterator_base& b) { Derived ret(b.derived()); ret -= a; return ret; }
0060
0061 Derived& operator+=(Index b) { m_index += b; return derived(); }
0062 Derived& operator-=(Index b) { m_index -= b; return derived(); }
0063
0064 difference_type operator-(const indexed_based_stl_iterator_base& other) const
0065 {
0066 eigen_assert(mp_xpr == other.mp_xpr);
0067 return m_index - other.m_index;
0068 }
0069
0070 difference_type operator-(const other_iterator& other) const
0071 {
0072 eigen_assert(mp_xpr == other.mp_xpr);
0073 return m_index - other.m_index;
0074 }
0075
0076 bool operator==(const indexed_based_stl_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index == other.m_index; }
0077 bool operator!=(const indexed_based_stl_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index != other.m_index; }
0078 bool operator< (const indexed_based_stl_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index < other.m_index; }
0079 bool operator<=(const indexed_based_stl_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index <= other.m_index; }
0080 bool operator> (const indexed_based_stl_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index > other.m_index; }
0081 bool operator>=(const indexed_based_stl_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index >= other.m_index; }
0082
0083 bool operator==(const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index == other.m_index; }
0084 bool operator!=(const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index != other.m_index; }
0085 bool operator< (const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index < other.m_index; }
0086 bool operator<=(const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index <= other.m_index; }
0087 bool operator> (const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index > other.m_index; }
0088 bool operator>=(const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index >= other.m_index; }
0089
0090 protected:
0091
0092 Derived& derived() { return static_cast<Derived&>(*this); }
0093 const Derived& derived() const { return static_cast<const Derived&>(*this); }
0094
0095 XprType *mp_xpr;
0096 Index m_index;
0097 };
0098
0099 template<typename Derived>
0100 class indexed_based_stl_reverse_iterator_base
0101 {
0102 protected:
0103 typedef indexed_based_stl_iterator_traits<Derived> traits;
0104 typedef typename traits::XprType XprType;
0105 typedef indexed_based_stl_reverse_iterator_base<typename traits::non_const_iterator> non_const_iterator;
0106 typedef indexed_based_stl_reverse_iterator_base<typename traits::const_iterator> const_iterator;
0107 typedef typename internal::conditional<internal::is_const<XprType>::value,non_const_iterator,const_iterator>::type other_iterator;
0108
0109 friend class indexed_based_stl_reverse_iterator_base<typename traits::const_iterator>;
0110 friend class indexed_based_stl_reverse_iterator_base<typename traits::non_const_iterator>;
0111 public:
0112 typedef Index difference_type;
0113 typedef std::random_access_iterator_tag iterator_category;
0114
0115 indexed_based_stl_reverse_iterator_base() : mp_xpr(0), m_index(0) {}
0116 indexed_based_stl_reverse_iterator_base(XprType& xpr, Index index) : mp_xpr(&xpr), m_index(index) {}
0117
0118 indexed_based_stl_reverse_iterator_base(const non_const_iterator& other)
0119 : mp_xpr(other.mp_xpr), m_index(other.m_index)
0120 {}
0121
0122 indexed_based_stl_reverse_iterator_base& operator=(const non_const_iterator& other)
0123 {
0124 mp_xpr = other.mp_xpr;
0125 m_index = other.m_index;
0126 return *this;
0127 }
0128
0129 Derived& operator++() { --m_index; return derived(); }
0130 Derived& operator--() { ++m_index; return derived(); }
0131
0132 Derived operator++(int) { Derived prev(derived()); operator++(); return prev;}
0133 Derived operator--(int) { Derived prev(derived()); operator--(); return prev;}
0134
0135 friend Derived operator+(const indexed_based_stl_reverse_iterator_base& a, Index b) { Derived ret(a.derived()); ret += b; return ret; }
0136 friend Derived operator-(const indexed_based_stl_reverse_iterator_base& a, Index b) { Derived ret(a.derived()); ret -= b; return ret; }
0137 friend Derived operator+(Index a, const indexed_based_stl_reverse_iterator_base& b) { Derived ret(b.derived()); ret += a; return ret; }
0138 friend Derived operator-(Index a, const indexed_based_stl_reverse_iterator_base& b) { Derived ret(b.derived()); ret -= a; return ret; }
0139
0140 Derived& operator+=(Index b) { m_index -= b; return derived(); }
0141 Derived& operator-=(Index b) { m_index += b; return derived(); }
0142
0143 difference_type operator-(const indexed_based_stl_reverse_iterator_base& other) const
0144 {
0145 eigen_assert(mp_xpr == other.mp_xpr);
0146 return other.m_index - m_index;
0147 }
0148
0149 difference_type operator-(const other_iterator& other) const
0150 {
0151 eigen_assert(mp_xpr == other.mp_xpr);
0152 return other.m_index - m_index;
0153 }
0154
0155 bool operator==(const indexed_based_stl_reverse_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index == other.m_index; }
0156 bool operator!=(const indexed_based_stl_reverse_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index != other.m_index; }
0157 bool operator< (const indexed_based_stl_reverse_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index > other.m_index; }
0158 bool operator<=(const indexed_based_stl_reverse_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index >= other.m_index; }
0159 bool operator> (const indexed_based_stl_reverse_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index < other.m_index; }
0160 bool operator>=(const indexed_based_stl_reverse_iterator_base& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index <= other.m_index; }
0161
0162 bool operator==(const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index == other.m_index; }
0163 bool operator!=(const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index != other.m_index; }
0164 bool operator< (const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index > other.m_index; }
0165 bool operator<=(const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index >= other.m_index; }
0166 bool operator> (const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index < other.m_index; }
0167 bool operator>=(const other_iterator& other) const { eigen_assert(mp_xpr == other.mp_xpr); return m_index <= other.m_index; }
0168
0169 protected:
0170
0171 Derived& derived() { return static_cast<Derived&>(*this); }
0172 const Derived& derived() const { return static_cast<const Derived&>(*this); }
0173
0174 XprType *mp_xpr;
0175 Index m_index;
0176 };
0177
0178 template<typename XprType>
0179 class pointer_based_stl_iterator
0180 {
0181 enum { is_lvalue = internal::is_lvalue<XprType>::value };
0182 typedef pointer_based_stl_iterator<typename internal::remove_const<XprType>::type> non_const_iterator;
0183 typedef pointer_based_stl_iterator<typename internal::add_const<XprType>::type> const_iterator;
0184 typedef typename internal::conditional<internal::is_const<XprType>::value,non_const_iterator,const_iterator>::type other_iterator;
0185
0186 friend class pointer_based_stl_iterator<typename internal::add_const<XprType>::type>;
0187 friend class pointer_based_stl_iterator<typename internal::remove_const<XprType>::type>;
0188 public:
0189 typedef Index difference_type;
0190 typedef typename XprType::Scalar value_type;
0191 typedef std::random_access_iterator_tag iterator_category;
0192 typedef typename internal::conditional<bool(is_lvalue), value_type*, const value_type*>::type pointer;
0193 typedef typename internal::conditional<bool(is_lvalue), value_type&, const value_type&>::type reference;
0194
0195
0196 pointer_based_stl_iterator() EIGEN_NO_THROW : m_ptr(0) {}
0197 pointer_based_stl_iterator(XprType& xpr, Index index) EIGEN_NO_THROW : m_incr(xpr.innerStride())
0198 {
0199 m_ptr = xpr.data() + index * m_incr.value();
0200 }
0201
0202 pointer_based_stl_iterator(const non_const_iterator& other) EIGEN_NO_THROW
0203 : m_ptr(other.m_ptr), m_incr(other.m_incr)
0204 {}
0205
0206 pointer_based_stl_iterator& operator=(const non_const_iterator& other) EIGEN_NO_THROW
0207 {
0208 m_ptr = other.m_ptr;
0209 m_incr.setValue(other.m_incr);
0210 return *this;
0211 }
0212
0213 reference operator*() const { return *m_ptr; }
0214 reference operator[](Index i) const { return *(m_ptr+i*m_incr.value()); }
0215 pointer operator->() const { return m_ptr; }
0216
0217 pointer_based_stl_iterator& operator++() { m_ptr += m_incr.value(); return *this; }
0218 pointer_based_stl_iterator& operator--() { m_ptr -= m_incr.value(); return *this; }
0219
0220 pointer_based_stl_iterator operator++(int) { pointer_based_stl_iterator prev(*this); operator++(); return prev;}
0221 pointer_based_stl_iterator operator--(int) { pointer_based_stl_iterator prev(*this); operator--(); return prev;}
0222
0223 friend pointer_based_stl_iterator operator+(const pointer_based_stl_iterator& a, Index b) { pointer_based_stl_iterator ret(a); ret += b; return ret; }
0224 friend pointer_based_stl_iterator operator-(const pointer_based_stl_iterator& a, Index b) { pointer_based_stl_iterator ret(a); ret -= b; return ret; }
0225 friend pointer_based_stl_iterator operator+(Index a, const pointer_based_stl_iterator& b) { pointer_based_stl_iterator ret(b); ret += a; return ret; }
0226 friend pointer_based_stl_iterator operator-(Index a, const pointer_based_stl_iterator& b) { pointer_based_stl_iterator ret(b); ret -= a; return ret; }
0227
0228 pointer_based_stl_iterator& operator+=(Index b) { m_ptr += b*m_incr.value(); return *this; }
0229 pointer_based_stl_iterator& operator-=(Index b) { m_ptr -= b*m_incr.value(); return *this; }
0230
0231 difference_type operator-(const pointer_based_stl_iterator& other) const {
0232 return (m_ptr - other.m_ptr)/m_incr.value();
0233 }
0234
0235 difference_type operator-(const other_iterator& other) const {
0236 return (m_ptr - other.m_ptr)/m_incr.value();
0237 }
0238
0239 bool operator==(const pointer_based_stl_iterator& other) const { return m_ptr == other.m_ptr; }
0240 bool operator!=(const pointer_based_stl_iterator& other) const { return m_ptr != other.m_ptr; }
0241 bool operator< (const pointer_based_stl_iterator& other) const { return m_ptr < other.m_ptr; }
0242 bool operator<=(const pointer_based_stl_iterator& other) const { return m_ptr <= other.m_ptr; }
0243 bool operator> (const pointer_based_stl_iterator& other) const { return m_ptr > other.m_ptr; }
0244 bool operator>=(const pointer_based_stl_iterator& other) const { return m_ptr >= other.m_ptr; }
0245
0246 bool operator==(const other_iterator& other) const { return m_ptr == other.m_ptr; }
0247 bool operator!=(const other_iterator& other) const { return m_ptr != other.m_ptr; }
0248 bool operator< (const other_iterator& other) const { return m_ptr < other.m_ptr; }
0249 bool operator<=(const other_iterator& other) const { return m_ptr <= other.m_ptr; }
0250 bool operator> (const other_iterator& other) const { return m_ptr > other.m_ptr; }
0251 bool operator>=(const other_iterator& other) const { return m_ptr >= other.m_ptr; }
0252
0253 protected:
0254
0255 pointer m_ptr;
0256 internal::variable_if_dynamic<Index, XprType::InnerStrideAtCompileTime> m_incr;
0257 };
0258
0259 template<typename _XprType>
0260 struct indexed_based_stl_iterator_traits<generic_randaccess_stl_iterator<_XprType> >
0261 {
0262 typedef _XprType XprType;
0263 typedef generic_randaccess_stl_iterator<typename internal::remove_const<XprType>::type> non_const_iterator;
0264 typedef generic_randaccess_stl_iterator<typename internal::add_const<XprType>::type> const_iterator;
0265 };
0266
0267 template<typename XprType>
0268 class generic_randaccess_stl_iterator : public indexed_based_stl_iterator_base<generic_randaccess_stl_iterator<XprType> >
0269 {
0270 public:
0271 typedef typename XprType::Scalar value_type;
0272
0273 protected:
0274
0275 enum {
0276 has_direct_access = (internal::traits<XprType>::Flags & DirectAccessBit) ? 1 : 0,
0277 is_lvalue = internal::is_lvalue<XprType>::value
0278 };
0279
0280 typedef indexed_based_stl_iterator_base<generic_randaccess_stl_iterator> Base;
0281 using Base::m_index;
0282 using Base::mp_xpr;
0283
0284
0285
0286
0287 typedef const value_type read_only_ref_t;
0288
0289 public:
0290
0291 typedef typename internal::conditional<bool(is_lvalue), value_type *, const value_type *>::type pointer;
0292 typedef typename internal::conditional<bool(is_lvalue), value_type&, read_only_ref_t>::type reference;
0293
0294 generic_randaccess_stl_iterator() : Base() {}
0295 generic_randaccess_stl_iterator(XprType& xpr, Index index) : Base(xpr,index) {}
0296 generic_randaccess_stl_iterator(const typename Base::non_const_iterator& other) : Base(other) {}
0297 using Base::operator=;
0298
0299 reference operator*() const { return (*mp_xpr)(m_index); }
0300 reference operator[](Index i) const { return (*mp_xpr)(m_index+i); }
0301 pointer operator->() const { return &((*mp_xpr)(m_index)); }
0302 };
0303
0304 template<typename _XprType, DirectionType Direction>
0305 struct indexed_based_stl_iterator_traits<subvector_stl_iterator<_XprType,Direction> >
0306 {
0307 typedef _XprType XprType;
0308 typedef subvector_stl_iterator<typename internal::remove_const<XprType>::type, Direction> non_const_iterator;
0309 typedef subvector_stl_iterator<typename internal::add_const<XprType>::type, Direction> const_iterator;
0310 };
0311
0312 template<typename XprType, DirectionType Direction>
0313 class subvector_stl_iterator : public indexed_based_stl_iterator_base<subvector_stl_iterator<XprType,Direction> >
0314 {
0315 protected:
0316
0317 enum { is_lvalue = internal::is_lvalue<XprType>::value };
0318
0319 typedef indexed_based_stl_iterator_base<subvector_stl_iterator> Base;
0320 using Base::m_index;
0321 using Base::mp_xpr;
0322
0323 typedef typename internal::conditional<Direction==Vertical,typename XprType::ColXpr,typename XprType::RowXpr>::type SubVectorType;
0324 typedef typename internal::conditional<Direction==Vertical,typename XprType::ConstColXpr,typename XprType::ConstRowXpr>::type ConstSubVectorType;
0325
0326
0327 public:
0328 typedef typename internal::conditional<bool(is_lvalue), SubVectorType, ConstSubVectorType>::type reference;
0329 typedef typename reference::PlainObject value_type;
0330
0331 private:
0332 class subvector_stl_iterator_ptr
0333 {
0334 public:
0335 subvector_stl_iterator_ptr(const reference &subvector) : m_subvector(subvector) {}
0336 reference* operator->() { return &m_subvector; }
0337 private:
0338 reference m_subvector;
0339 };
0340 public:
0341
0342 typedef subvector_stl_iterator_ptr pointer;
0343
0344 subvector_stl_iterator() : Base() {}
0345 subvector_stl_iterator(XprType& xpr, Index index) : Base(xpr,index) {}
0346
0347 reference operator*() const { return (*mp_xpr).template subVector<Direction>(m_index); }
0348 reference operator[](Index i) const { return (*mp_xpr).template subVector<Direction>(m_index+i); }
0349 pointer operator->() const { return (*mp_xpr).template subVector<Direction>(m_index); }
0350 };
0351
0352 template<typename _XprType, DirectionType Direction>
0353 struct indexed_based_stl_iterator_traits<subvector_stl_reverse_iterator<_XprType,Direction> >
0354 {
0355 typedef _XprType XprType;
0356 typedef subvector_stl_reverse_iterator<typename internal::remove_const<XprType>::type, Direction> non_const_iterator;
0357 typedef subvector_stl_reverse_iterator<typename internal::add_const<XprType>::type, Direction> const_iterator;
0358 };
0359
0360 template<typename XprType, DirectionType Direction>
0361 class subvector_stl_reverse_iterator : public indexed_based_stl_reverse_iterator_base<subvector_stl_reverse_iterator<XprType,Direction> >
0362 {
0363 protected:
0364
0365 enum { is_lvalue = internal::is_lvalue<XprType>::value };
0366
0367 typedef indexed_based_stl_reverse_iterator_base<subvector_stl_reverse_iterator> Base;
0368 using Base::m_index;
0369 using Base::mp_xpr;
0370
0371 typedef typename internal::conditional<Direction==Vertical,typename XprType::ColXpr,typename XprType::RowXpr>::type SubVectorType;
0372 typedef typename internal::conditional<Direction==Vertical,typename XprType::ConstColXpr,typename XprType::ConstRowXpr>::type ConstSubVectorType;
0373
0374
0375 public:
0376 typedef typename internal::conditional<bool(is_lvalue), SubVectorType, ConstSubVectorType>::type reference;
0377 typedef typename reference::PlainObject value_type;
0378
0379 private:
0380 class subvector_stl_reverse_iterator_ptr
0381 {
0382 public:
0383 subvector_stl_reverse_iterator_ptr(const reference &subvector) : m_subvector(subvector) {}
0384 reference* operator->() { return &m_subvector; }
0385 private:
0386 reference m_subvector;
0387 };
0388 public:
0389
0390 typedef subvector_stl_reverse_iterator_ptr pointer;
0391
0392 subvector_stl_reverse_iterator() : Base() {}
0393 subvector_stl_reverse_iterator(XprType& xpr, Index index) : Base(xpr,index) {}
0394
0395 reference operator*() const { return (*mp_xpr).template subVector<Direction>(m_index); }
0396 reference operator[](Index i) const { return (*mp_xpr).template subVector<Direction>(m_index+i); }
0397 pointer operator->() const { return (*mp_xpr).template subVector<Direction>(m_index); }
0398 };
0399
0400 }
0401
0402
0403
0404
0405
0406
0407 template<typename Derived>
0408 inline typename DenseBase<Derived>::iterator DenseBase<Derived>::begin()
0409 {
0410 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
0411 return iterator(derived(), 0);
0412 }
0413
0414
0415 template<typename Derived>
0416 inline typename DenseBase<Derived>::const_iterator DenseBase<Derived>::begin() const
0417 {
0418 return cbegin();
0419 }
0420
0421
0422
0423
0424
0425 template<typename Derived>
0426 inline typename DenseBase<Derived>::const_iterator DenseBase<Derived>::cbegin() const
0427 {
0428 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
0429 return const_iterator(derived(), 0);
0430 }
0431
0432
0433
0434
0435
0436 template<typename Derived>
0437 inline typename DenseBase<Derived>::iterator DenseBase<Derived>::end()
0438 {
0439 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
0440 return iterator(derived(), size());
0441 }
0442
0443
0444 template<typename Derived>
0445 inline typename DenseBase<Derived>::const_iterator DenseBase<Derived>::end() const
0446 {
0447 return cend();
0448 }
0449
0450
0451
0452
0453
0454 template<typename Derived>
0455 inline typename DenseBase<Derived>::const_iterator DenseBase<Derived>::cend() const
0456 {
0457 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived);
0458 return const_iterator(derived(), size());
0459 }
0460
0461 }
0462
0463 #endif