Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:56:18

0001 // This file is part of Eigen, a lightweight C++ template library
0002 // for linear algebra.
0003 //
0004 // Copyright (C) 2018 Gael Guennebaud <gael.guennebaud@inria.fr>
0005 //
0006 // This Source Code Form is subject to the terms of the Mozilla
0007 // Public License v. 2.0. If a copy of the MPL was not distributed
0008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
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   // NOTE: in C++03 we cannot declare friend classes through typedefs because we need to write friend class:
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   // NOTE: in C++03 we cannot declare friend classes through typedefs because we need to write friend class:
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   // NOTE: in C++03 we cannot declare friend classes through typedefs because we need to write friend class:
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   // TODO currently const Transpose/Reshape expressions never returns const references,
0285   // so lets return by value too.
0286   //typedef typename internal::conditional<bool(has_direct_access), const value_type&, const value_type>::type read_only_ref_t;
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 } // namespace internal
0401 
0402 
0403 /** returns an iterator to the first element of the 1D vector or array
0404   * \only_for_vectors
0405   * \sa end(), cbegin()
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 /** const version of begin() */
0415 template<typename Derived>
0416 inline typename DenseBase<Derived>::const_iterator DenseBase<Derived>::begin() const
0417 {
0418   return cbegin();
0419 }
0420 
0421 /** returns a read-only const_iterator to the first element of the 1D vector or array
0422   * \only_for_vectors
0423   * \sa cend(), begin()
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 /** returns an iterator to the element following the last element of the 1D vector or array
0433   * \only_for_vectors
0434   * \sa begin(), cend()
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 /** const version of end() */
0444 template<typename Derived>
0445 inline typename DenseBase<Derived>::const_iterator DenseBase<Derived>::end() const
0446 {
0447   return cend();
0448 }
0449 
0450 /** returns a read-only const_iterator to the element following the last element of the 1D vector or array
0451   * \only_for_vectors
0452   * \sa begin(), cend()
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 } // namespace Eigen
0462 
0463 #endif // EIGEN_STLITERATORS_H