Home | History | Annotate | Download | only in Core
      1 // This file is part of Eigen, a lightweight C++ template library
      2 // for linear algebra.
      3 //
      4 // Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1 (at) gmail.com>
      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_DENSECOEFFSBASE_H
     11 #define EIGEN_DENSECOEFFSBASE_H
     12 
     13 namespace Eigen {
     14 
     15 namespace internal {
     16 template<typename T> struct add_const_on_value_type_if_arithmetic
     17 {
     18   typedef typename conditional<is_arithmetic<T>::value, T, typename add_const_on_value_type<T>::type>::type type;
     19 };
     20 }
     21 
     22 /** \brief Base class providing read-only coefficient access to matrices and arrays.
     23   * \ingroup Core_Module
     24   * \tparam Derived Type of the derived class
     25   * \tparam #ReadOnlyAccessors Constant indicating read-only access
     26   *
     27   * This class defines the \c operator() \c const function and friends, which can be used to read specific
     28   * entries of a matrix or array.
     29   *
     30   * \sa DenseCoeffsBase<Derived, WriteAccessors>, DenseCoeffsBase<Derived, DirectAccessors>,
     31   *     \ref TopicClassHierarchy
     32   */
     33 template<typename Derived>
     34 class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
     35 {
     36   public:
     37     typedef typename internal::traits<Derived>::StorageKind StorageKind;
     38     typedef typename internal::traits<Derived>::Index Index;
     39     typedef typename internal::traits<Derived>::Scalar Scalar;
     40     typedef typename internal::packet_traits<Scalar>::type PacketScalar;
     41 
     42     // Explanation for this CoeffReturnType typedef.
     43     // - This is the return type of the coeff() method.
     44     // - The LvalueBit means exactly that we can offer a coeffRef() method, which means exactly that we can get references
     45     // to coeffs, which means exactly that we can have coeff() return a const reference (as opposed to returning a value).
     46     // - The is_artihmetic check is required since "const int", "const double", etc. will cause warnings on some systems
     47     // while the declaration of "const T", where T is a non arithmetic type does not. Always returning "const Scalar&" is
     48     // not possible, since the underlying expressions might not offer a valid address the reference could be referring to.
     49     typedef typename internal::conditional<bool(internal::traits<Derived>::Flags&LvalueBit),
     50                          const Scalar&,
     51                          typename internal::conditional<internal::is_arithmetic<Scalar>::value, Scalar, const Scalar>::type
     52                      >::type CoeffReturnType;
     53 
     54     typedef typename internal::add_const_on_value_type_if_arithmetic<
     55                          typename internal::packet_traits<Scalar>::type
     56                      >::type PacketReturnType;
     57 
     58     typedef EigenBase<Derived> Base;
     59     using Base::rows;
     60     using Base::cols;
     61     using Base::size;
     62     using Base::derived;
     63 
     64     EIGEN_STRONG_INLINE Index rowIndexByOuterInner(Index outer, Index inner) const
     65     {
     66       return int(Derived::RowsAtCompileTime) == 1 ? 0
     67           : int(Derived::ColsAtCompileTime) == 1 ? inner
     68           : int(Derived::Flags)&RowMajorBit ? outer
     69           : inner;
     70     }
     71 
     72     EIGEN_STRONG_INLINE Index colIndexByOuterInner(Index outer, Index inner) const
     73     {
     74       return int(Derived::ColsAtCompileTime) == 1 ? 0
     75           : int(Derived::RowsAtCompileTime) == 1 ? inner
     76           : int(Derived::Flags)&RowMajorBit ? inner
     77           : outer;
     78     }
     79 
     80     /** Short version: don't use this function, use
     81       * \link operator()(Index,Index) const \endlink instead.
     82       *
     83       * Long version: this function is similar to
     84       * \link operator()(Index,Index) const \endlink, but without the assertion.
     85       * Use this for limiting the performance cost of debugging code when doing
     86       * repeated coefficient access. Only use this when it is guaranteed that the
     87       * parameters \a row and \a col are in range.
     88       *
     89       * If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this
     90       * function equivalent to \link operator()(Index,Index) const \endlink.
     91       *
     92       * \sa operator()(Index,Index) const, coeffRef(Index,Index), coeff(Index) const
     93       */
     94     EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const
     95     {
     96       eigen_internal_assert(row >= 0 && row < rows()
     97                         && col >= 0 && col < cols());
     98       return derived().coeff(row, col);
     99     }
    100 
    101     EIGEN_STRONG_INLINE CoeffReturnType coeffByOuterInner(Index outer, Index inner) const
    102     {
    103       return coeff(rowIndexByOuterInner(outer, inner),
    104                    colIndexByOuterInner(outer, inner));
    105     }
    106 
    107     /** \returns the coefficient at given the given row and column.
    108       *
    109       * \sa operator()(Index,Index), operator[](Index)
    110       */
    111     EIGEN_STRONG_INLINE CoeffReturnType operator()(Index row, Index col) const
    112     {
    113       eigen_assert(row >= 0 && row < rows()
    114           && col >= 0 && col < cols());
    115       return derived().coeff(row, col);
    116     }
    117 
    118     /** Short version: don't use this function, use
    119       * \link operator[](Index) const \endlink instead.
    120       *
    121       * Long version: this function is similar to
    122       * \link operator[](Index) const \endlink, but without the assertion.
    123       * Use this for limiting the performance cost of debugging code when doing
    124       * repeated coefficient access. Only use this when it is guaranteed that the
    125       * parameter \a index is in range.
    126       *
    127       * If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this
    128       * function equivalent to \link operator[](Index) const \endlink.
    129       *
    130       * \sa operator[](Index) const, coeffRef(Index), coeff(Index,Index) const
    131       */
    132 
    133     EIGEN_STRONG_INLINE CoeffReturnType
    134     coeff(Index index) const
    135     {
    136       eigen_internal_assert(index >= 0 && index < size());
    137       return derived().coeff(index);
    138     }
    139 
    140 
    141     /** \returns the coefficient at given index.
    142       *
    143       * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit.
    144       *
    145       * \sa operator[](Index), operator()(Index,Index) const, x() const, y() const,
    146       * z() const, w() const
    147       */
    148 
    149     EIGEN_STRONG_INLINE CoeffReturnType
    150     operator[](Index index) const
    151     {
    152       #ifndef EIGEN2_SUPPORT
    153       EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
    154                           THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
    155       #endif
    156       eigen_assert(index >= 0 && index < size());
    157       return derived().coeff(index);
    158     }
    159 
    160     /** \returns the coefficient at given index.
    161       *
    162       * This is synonymous to operator[](Index) const.
    163       *
    164       * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit.
    165       *
    166       * \sa operator[](Index), operator()(Index,Index) const, x() const, y() const,
    167       * z() const, w() const
    168       */
    169 
    170     EIGEN_STRONG_INLINE CoeffReturnType
    171     operator()(Index index) const
    172     {
    173       eigen_assert(index >= 0 && index < size());
    174       return derived().coeff(index);
    175     }
    176 
    177     /** equivalent to operator[](0).  */
    178 
    179     EIGEN_STRONG_INLINE CoeffReturnType
    180     x() const { return (*this)[0]; }
    181 
    182     /** equivalent to operator[](1).  */
    183 
    184     EIGEN_STRONG_INLINE CoeffReturnType
    185     y() const { return (*this)[1]; }
    186 
    187     /** equivalent to operator[](2).  */
    188 
    189     EIGEN_STRONG_INLINE CoeffReturnType
    190     z() const { return (*this)[2]; }
    191 
    192     /** equivalent to operator[](3).  */
    193 
    194     EIGEN_STRONG_INLINE CoeffReturnType
    195     w() const { return (*this)[3]; }
    196 
    197     /** \internal
    198       * \returns the packet of coefficients starting at the given row and column. It is your responsibility
    199       * to ensure that a packet really starts there. This method is only available on expressions having the
    200       * PacketAccessBit.
    201       *
    202       * The \a LoadMode parameter may have the value \a #Aligned or \a #Unaligned. Its effect is to select
    203       * the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets
    204       * starting at an address which is a multiple of the packet size.
    205       */
    206 
    207     template<int LoadMode>
    208     EIGEN_STRONG_INLINE PacketReturnType packet(Index row, Index col) const
    209     {
    210       eigen_internal_assert(row >= 0 && row < rows()
    211                       && col >= 0 && col < cols());
    212       return derived().template packet<LoadMode>(row,col);
    213     }
    214 
    215 
    216     /** \internal */
    217     template<int LoadMode>
    218     EIGEN_STRONG_INLINE PacketReturnType packetByOuterInner(Index outer, Index inner) const
    219     {
    220       return packet<LoadMode>(rowIndexByOuterInner(outer, inner),
    221                               colIndexByOuterInner(outer, inner));
    222     }
    223 
    224     /** \internal
    225       * \returns the packet of coefficients starting at the given index. It is your responsibility
    226       * to ensure that a packet really starts there. This method is only available on expressions having the
    227       * PacketAccessBit and the LinearAccessBit.
    228       *
    229       * The \a LoadMode parameter may have the value \a #Aligned or \a #Unaligned. Its effect is to select
    230       * the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets
    231       * starting at an address which is a multiple of the packet size.
    232       */
    233 
    234     template<int LoadMode>
    235     EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const
    236     {
    237       eigen_internal_assert(index >= 0 && index < size());
    238       return derived().template packet<LoadMode>(index);
    239     }
    240 
    241   protected:
    242     // explanation: DenseBase is doing "using ..." on the methods from DenseCoeffsBase.
    243     // But some methods are only available in the DirectAccess case.
    244     // So we add dummy methods here with these names, so that "using... " doesn't fail.
    245     // It's not private so that the child class DenseBase can access them, and it's not public
    246     // either since it's an implementation detail, so has to be protected.
    247     void coeffRef();
    248     void coeffRefByOuterInner();
    249     void writePacket();
    250     void writePacketByOuterInner();
    251     void copyCoeff();
    252     void copyCoeffByOuterInner();
    253     void copyPacket();
    254     void copyPacketByOuterInner();
    255     void stride();
    256     void innerStride();
    257     void outerStride();
    258     void rowStride();
    259     void colStride();
    260 };
    261 
    262 /** \brief Base class providing read/write coefficient access to matrices and arrays.
    263   * \ingroup Core_Module
    264   * \tparam Derived Type of the derived class
    265   * \tparam #WriteAccessors Constant indicating read/write access
    266   *
    267   * This class defines the non-const \c operator() function and friends, which can be used to write specific
    268   * entries of a matrix or array. This class inherits DenseCoeffsBase<Derived, ReadOnlyAccessors> which
    269   * defines the const variant for reading specific entries.
    270   *
    271   * \sa DenseCoeffsBase<Derived, DirectAccessors>, \ref TopicClassHierarchy
    272   */
    273 template<typename Derived>
    274 class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived, ReadOnlyAccessors>
    275 {
    276   public:
    277 
    278     typedef DenseCoeffsBase<Derived, ReadOnlyAccessors> Base;
    279 
    280     typedef typename internal::traits<Derived>::StorageKind StorageKind;
    281     typedef typename internal::traits<Derived>::Index Index;
    282     typedef typename internal::traits<Derived>::Scalar Scalar;
    283     typedef typename internal::packet_traits<Scalar>::type PacketScalar;
    284     typedef typename NumTraits<Scalar>::Real RealScalar;
    285 
    286     using Base::coeff;
    287     using Base::rows;
    288     using Base::cols;
    289     using Base::size;
    290     using Base::derived;
    291     using Base::rowIndexByOuterInner;
    292     using Base::colIndexByOuterInner;
    293     using Base::operator[];
    294     using Base::operator();
    295     using Base::x;
    296     using Base::y;
    297     using Base::z;
    298     using Base::w;
    299 
    300     /** Short version: don't use this function, use
    301       * \link operator()(Index,Index) \endlink instead.
    302       *
    303       * Long version: this function is similar to
    304       * \link operator()(Index,Index) \endlink, but without the assertion.
    305       * Use this for limiting the performance cost of debugging code when doing
    306       * repeated coefficient access. Only use this when it is guaranteed that the
    307       * parameters \a row and \a col are in range.
    308       *
    309       * If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this
    310       * function equivalent to \link operator()(Index,Index) \endlink.
    311       *
    312       * \sa operator()(Index,Index), coeff(Index, Index) const, coeffRef(Index)
    313       */
    314     EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col)
    315     {
    316       eigen_internal_assert(row >= 0 && row < rows()
    317                         && col >= 0 && col < cols());
    318       return derived().coeffRef(row, col);
    319     }
    320 
    321     EIGEN_STRONG_INLINE Scalar&
    322     coeffRefByOuterInner(Index outer, Index inner)
    323     {
    324       return coeffRef(rowIndexByOuterInner(outer, inner),
    325                       colIndexByOuterInner(outer, inner));
    326     }
    327 
    328     /** \returns a reference to the coefficient at given the given row and column.
    329       *
    330       * \sa operator[](Index)
    331       */
    332 
    333     EIGEN_STRONG_INLINE Scalar&
    334     operator()(Index row, Index col)
    335     {
    336       eigen_assert(row >= 0 && row < rows()
    337           && col >= 0 && col < cols());
    338       return derived().coeffRef(row, col);
    339     }
    340 
    341 
    342     /** Short version: don't use this function, use
    343       * \link operator[](Index) \endlink instead.
    344       *
    345       * Long version: this function is similar to
    346       * \link operator[](Index) \endlink, but without the assertion.
    347       * Use this for limiting the performance cost of debugging code when doing
    348       * repeated coefficient access. Only use this when it is guaranteed that the
    349       * parameters \a row and \a col are in range.
    350       *
    351       * If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this
    352       * function equivalent to \link operator[](Index) \endlink.
    353       *
    354       * \sa operator[](Index), coeff(Index) const, coeffRef(Index,Index)
    355       */
    356 
    357     EIGEN_STRONG_INLINE Scalar&
    358     coeffRef(Index index)
    359     {
    360       eigen_internal_assert(index >= 0 && index < size());
    361       return derived().coeffRef(index);
    362     }
    363 
    364     /** \returns a reference to the coefficient at given index.
    365       *
    366       * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit.
    367       *
    368       * \sa operator[](Index) const, operator()(Index,Index), x(), y(), z(), w()
    369       */
    370 
    371     EIGEN_STRONG_INLINE Scalar&
    372     operator[](Index index)
    373     {
    374       #ifndef EIGEN2_SUPPORT
    375       EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
    376                           THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
    377       #endif
    378       eigen_assert(index >= 0 && index < size());
    379       return derived().coeffRef(index);
    380     }
    381 
    382     /** \returns a reference to the coefficient at given index.
    383       *
    384       * This is synonymous to operator[](Index).
    385       *
    386       * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit.
    387       *
    388       * \sa operator[](Index) const, operator()(Index,Index), x(), y(), z(), w()
    389       */
    390 
    391     EIGEN_STRONG_INLINE Scalar&
    392     operator()(Index index)
    393     {
    394       eigen_assert(index >= 0 && index < size());
    395       return derived().coeffRef(index);
    396     }
    397 
    398     /** equivalent to operator[](0).  */
    399 
    400     EIGEN_STRONG_INLINE Scalar&
    401     x() { return (*this)[0]; }
    402 
    403     /** equivalent to operator[](1).  */
    404 
    405     EIGEN_STRONG_INLINE Scalar&
    406     y() { return (*this)[1]; }
    407 
    408     /** equivalent to operator[](2).  */
    409 
    410     EIGEN_STRONG_INLINE Scalar&
    411     z() { return (*this)[2]; }
    412 
    413     /** equivalent to operator[](3).  */
    414 
    415     EIGEN_STRONG_INLINE Scalar&
    416     w() { return (*this)[3]; }
    417 
    418     /** \internal
    419       * Stores the given packet of coefficients, at the given row and column of this expression. It is your responsibility
    420       * to ensure that a packet really starts there. This method is only available on expressions having the
    421       * PacketAccessBit.
    422       *
    423       * The \a LoadMode parameter may have the value \a #Aligned or \a #Unaligned. Its effect is to select
    424       * the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets
    425       * starting at an address which is a multiple of the packet size.
    426       */
    427 
    428     template<int StoreMode>
    429     EIGEN_STRONG_INLINE void writePacket
    430     (Index row, Index col, const typename internal::packet_traits<Scalar>::type& x)
    431     {
    432       eigen_internal_assert(row >= 0 && row < rows()
    433                         && col >= 0 && col < cols());
    434       derived().template writePacket<StoreMode>(row,col,x);
    435     }
    436 
    437 
    438     /** \internal */
    439     template<int StoreMode>
    440     EIGEN_STRONG_INLINE void writePacketByOuterInner
    441     (Index outer, Index inner, const typename internal::packet_traits<Scalar>::type& x)
    442     {
    443       writePacket<StoreMode>(rowIndexByOuterInner(outer, inner),
    444                             colIndexByOuterInner(outer, inner),
    445                             x);
    446     }
    447 
    448     /** \internal
    449       * Stores the given packet of coefficients, at the given index in this expression. It is your responsibility
    450       * to ensure that a packet really starts there. This method is only available on expressions having the
    451       * PacketAccessBit and the LinearAccessBit.
    452       *
    453       * The \a LoadMode parameter may have the value \a Aligned or \a Unaligned. Its effect is to select
    454       * the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets
    455       * starting at an address which is a multiple of the packet size.
    456       */
    457     template<int StoreMode>
    458     EIGEN_STRONG_INLINE void writePacket
    459     (Index index, const typename internal::packet_traits<Scalar>::type& x)
    460     {
    461       eigen_internal_assert(index >= 0 && index < size());
    462       derived().template writePacket<StoreMode>(index,x);
    463     }
    464 
    465 #ifndef EIGEN_PARSED_BY_DOXYGEN
    466 
    467     /** \internal Copies the coefficient at position (row,col) of other into *this.
    468       *
    469       * This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code
    470       * with usual assignments.
    471       *
    472       * Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox.
    473       */
    474 
    475     template<typename OtherDerived>
    476     EIGEN_STRONG_INLINE void copyCoeff(Index row, Index col, const DenseBase<OtherDerived>& other)
    477     {
    478       eigen_internal_assert(row >= 0 && row < rows()
    479                         && col >= 0 && col < cols());
    480       derived().coeffRef(row, col) = other.derived().coeff(row, col);
    481     }
    482 
    483     /** \internal Copies the coefficient at the given index of other into *this.
    484       *
    485       * This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code
    486       * with usual assignments.
    487       *
    488       * Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox.
    489       */
    490 
    491     template<typename OtherDerived>
    492     EIGEN_STRONG_INLINE void copyCoeff(Index index, const DenseBase<OtherDerived>& other)
    493     {
    494       eigen_internal_assert(index >= 0 && index < size());
    495       derived().coeffRef(index) = other.derived().coeff(index);
    496     }
    497 
    498 
    499     template<typename OtherDerived>
    500     EIGEN_STRONG_INLINE void copyCoeffByOuterInner(Index outer, Index inner, const DenseBase<OtherDerived>& other)
    501     {
    502       const Index row = rowIndexByOuterInner(outer,inner);
    503       const Index col = colIndexByOuterInner(outer,inner);
    504       // derived() is important here: copyCoeff() may be reimplemented in Derived!
    505       derived().copyCoeff(row, col, other);
    506     }
    507 
    508     /** \internal Copies the packet at position (row,col) of other into *this.
    509       *
    510       * This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code
    511       * with usual assignments.
    512       *
    513       * Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox.
    514       */
    515 
    516     template<typename OtherDerived, int StoreMode, int LoadMode>
    517     EIGEN_STRONG_INLINE void copyPacket(Index row, Index col, const DenseBase<OtherDerived>& other)
    518     {
    519       eigen_internal_assert(row >= 0 && row < rows()
    520                         && col >= 0 && col < cols());
    521       derived().template writePacket<StoreMode>(row, col,
    522         other.derived().template packet<LoadMode>(row, col));
    523     }
    524 
    525     /** \internal Copies the packet at the given index of other into *this.
    526       *
    527       * This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code
    528       * with usual assignments.
    529       *
    530       * Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox.
    531       */
    532 
    533     template<typename OtherDerived, int StoreMode, int LoadMode>
    534     EIGEN_STRONG_INLINE void copyPacket(Index index, const DenseBase<OtherDerived>& other)
    535     {
    536       eigen_internal_assert(index >= 0 && index < size());
    537       derived().template writePacket<StoreMode>(index,
    538         other.derived().template packet<LoadMode>(index));
    539     }
    540 
    541     /** \internal */
    542     template<typename OtherDerived, int StoreMode, int LoadMode>
    543     EIGEN_STRONG_INLINE void copyPacketByOuterInner(Index outer, Index inner, const DenseBase<OtherDerived>& other)
    544     {
    545       const Index row = rowIndexByOuterInner(outer,inner);
    546       const Index col = colIndexByOuterInner(outer,inner);
    547       // derived() is important here: copyCoeff() may be reimplemented in Derived!
    548       derived().template copyPacket< OtherDerived, StoreMode, LoadMode>(row, col, other);
    549     }
    550 #endif
    551 
    552 };
    553 
    554 /** \brief Base class providing direct read-only coefficient access to matrices and arrays.
    555   * \ingroup Core_Module
    556   * \tparam Derived Type of the derived class
    557   * \tparam #DirectAccessors Constant indicating direct access
    558   *
    559   * This class defines functions to work with strides which can be used to access entries directly. This class
    560   * inherits DenseCoeffsBase<Derived, ReadOnlyAccessors> which defines functions to access entries read-only using
    561   * \c operator() .
    562   *
    563   * \sa \ref TopicClassHierarchy
    564   */
    565 template<typename Derived>
    566 class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived, ReadOnlyAccessors>
    567 {
    568   public:
    569 
    570     typedef DenseCoeffsBase<Derived, ReadOnlyAccessors> Base;
    571     typedef typename internal::traits<Derived>::Index Index;
    572     typedef typename internal::traits<Derived>::Scalar Scalar;
    573     typedef typename NumTraits<Scalar>::Real RealScalar;
    574 
    575     using Base::rows;
    576     using Base::cols;
    577     using Base::size;
    578     using Base::derived;
    579 
    580     /** \returns the pointer increment between two consecutive elements within a slice in the inner direction.
    581       *
    582       * \sa outerStride(), rowStride(), colStride()
    583       */
    584     inline Index innerStride() const
    585     {
    586       return derived().innerStride();
    587     }
    588 
    589     /** \returns the pointer increment between two consecutive inner slices (for example, between two consecutive columns
    590       *          in a column-major matrix).
    591       *
    592       * \sa innerStride(), rowStride(), colStride()
    593       */
    594     inline Index outerStride() const
    595     {
    596       return derived().outerStride();
    597     }
    598 
    599     // FIXME shall we remove it ?
    600     inline Index stride() const
    601     {
    602       return Derived::IsVectorAtCompileTime ? innerStride() : outerStride();
    603     }
    604 
    605     /** \returns the pointer increment between two consecutive rows.
    606       *
    607       * \sa innerStride(), outerStride(), colStride()
    608       */
    609     inline Index rowStride() const
    610     {
    611       return Derived::IsRowMajor ? outerStride() : innerStride();
    612     }
    613 
    614     /** \returns the pointer increment between two consecutive columns.
    615       *
    616       * \sa innerStride(), outerStride(), rowStride()
    617       */
    618     inline Index colStride() const
    619     {
    620       return Derived::IsRowMajor ? innerStride() : outerStride();
    621     }
    622 };
    623 
    624 /** \brief Base class providing direct read/write coefficient access to matrices and arrays.
    625   * \ingroup Core_Module
    626   * \tparam Derived Type of the derived class
    627   * \tparam #DirectWriteAccessors Constant indicating direct access
    628   *
    629   * This class defines functions to work with strides which can be used to access entries directly. This class
    630   * inherits DenseCoeffsBase<Derived, WriteAccessors> which defines functions to access entries read/write using
    631   * \c operator().
    632   *
    633   * \sa \ref TopicClassHierarchy
    634   */
    635 template<typename Derived>
    636 class DenseCoeffsBase<Derived, DirectWriteAccessors>
    637   : public DenseCoeffsBase<Derived, WriteAccessors>
    638 {
    639   public:
    640 
    641     typedef DenseCoeffsBase<Derived, WriteAccessors> Base;
    642     typedef typename internal::traits<Derived>::Index Index;
    643     typedef typename internal::traits<Derived>::Scalar Scalar;
    644     typedef typename NumTraits<Scalar>::Real RealScalar;
    645 
    646     using Base::rows;
    647     using Base::cols;
    648     using Base::size;
    649     using Base::derived;
    650 
    651     /** \returns the pointer increment between two consecutive elements within a slice in the inner direction.
    652       *
    653       * \sa outerStride(), rowStride(), colStride()
    654       */
    655     inline Index innerStride() const
    656     {
    657       return derived().innerStride();
    658     }
    659 
    660     /** \returns the pointer increment between two consecutive inner slices (for example, between two consecutive columns
    661       *          in a column-major matrix).
    662       *
    663       * \sa innerStride(), rowStride(), colStride()
    664       */
    665     inline Index outerStride() const
    666     {
    667       return derived().outerStride();
    668     }
    669 
    670     // FIXME shall we remove it ?
    671     inline Index stride() const
    672     {
    673       return Derived::IsVectorAtCompileTime ? innerStride() : outerStride();
    674     }
    675 
    676     /** \returns the pointer increment between two consecutive rows.
    677       *
    678       * \sa innerStride(), outerStride(), colStride()
    679       */
    680     inline Index rowStride() const
    681     {
    682       return Derived::IsRowMajor ? outerStride() : innerStride();
    683     }
    684 
    685     /** \returns the pointer increment between two consecutive columns.
    686       *
    687       * \sa innerStride(), outerStride(), rowStride()
    688       */
    689     inline Index colStride() const
    690     {
    691       return Derived::IsRowMajor ? innerStride() : outerStride();
    692     }
    693 };
    694 
    695 namespace internal {
    696 
    697 template<typename Derived, bool JustReturnZero>
    698 struct first_aligned_impl
    699 {
    700   static inline typename Derived::Index run(const Derived&)
    701   { return 0; }
    702 };
    703 
    704 template<typename Derived>
    705 struct first_aligned_impl<Derived, false>
    706 {
    707   static inline typename Derived::Index run(const Derived& m)
    708   {
    709     return internal::first_aligned(&m.const_cast_derived().coeffRef(0,0), m.size());
    710   }
    711 };
    712 
    713 /** \internal \returns the index of the first element of the array that is well aligned for vectorization.
    714   *
    715   * There is also the variant first_aligned(const Scalar*, Integer) defined in Memory.h. See it for more
    716   * documentation.
    717   */
    718 template<typename Derived>
    719 static inline typename Derived::Index first_aligned(const Derived& m)
    720 {
    721   return first_aligned_impl
    722           <Derived, (Derived::Flags & AlignedBit) || !(Derived::Flags & DirectAccessBit)>
    723           ::run(m);
    724 }
    725 
    726 template<typename Derived, bool HasDirectAccess = has_direct_access<Derived>::ret>
    727 struct inner_stride_at_compile_time
    728 {
    729   enum { ret = traits<Derived>::InnerStrideAtCompileTime };
    730 };
    731 
    732 template<typename Derived>
    733 struct inner_stride_at_compile_time<Derived, false>
    734 {
    735   enum { ret = 0 };
    736 };
    737 
    738 template<typename Derived, bool HasDirectAccess = has_direct_access<Derived>::ret>
    739 struct outer_stride_at_compile_time
    740 {
    741   enum { ret = traits<Derived>::OuterStrideAtCompileTime };
    742 };
    743 
    744 template<typename Derived>
    745 struct outer_stride_at_compile_time<Derived, false>
    746 {
    747   enum { ret = 0 };
    748 };
    749 
    750 } // end namespace internal
    751 
    752 } // end namespace Eigen
    753 
    754 #endif // EIGEN_DENSECOEFFSBASE_H
    755