• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@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 
rowIndexByOuterInner(Index outer,Index inner)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 
colIndexByOuterInner(Index outer,Index inner)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       */
coeff(Index row,Index col)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 
coeffByOuterInner(Index outer,Index inner)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       */
operator()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
coeff(Index index)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
operator()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
x()180     x() const { return (*this)[0]; }
181 
182     /** equivalent to operator[](1).  */
183 
184     EIGEN_STRONG_INLINE CoeffReturnType
y()185     y() const { return (*this)[1]; }
186 
187     /** equivalent to operator[](2).  */
188 
189     EIGEN_STRONG_INLINE CoeffReturnType
z()190     z() const { return (*this)[2]; }
191 
192     /** equivalent to operator[](3).  */
193 
194     EIGEN_STRONG_INLINE CoeffReturnType
w()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>
packet(Index row,Index col)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>
packetByOuterInner(Index outer,Index inner)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>
packet(Index index)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       */
coeffRef(Index row,Index col)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&
coeffRefByOuterInner(Index outer,Index inner)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&
operator()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&
coeffRef(Index index)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&
operator()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&
x()401     x() { return (*this)[0]; }
402 
403     /** equivalent to operator[](1).  */
404 
405     EIGEN_STRONG_INLINE Scalar&
y()406     y() { return (*this)[1]; }
407 
408     /** equivalent to operator[](2).  */
409 
410     EIGEN_STRONG_INLINE Scalar&
z()411     z() { return (*this)[2]; }
412 
413     /** equivalent to operator[](3).  */
414 
415     EIGEN_STRONG_INLINE Scalar&
w()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>
writePacket(Index row,Index col,const typename internal::packet_traits<Scalar>::type & x)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>
writePacketByOuterInner(Index outer,Index inner,const typename internal::packet_traits<Scalar>::type & x)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>
writePacket(Index index,const typename internal::packet_traits<Scalar>::type & x)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>
copyCoeff(Index row,Index col,const DenseBase<OtherDerived> & other)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>
copyCoeff(Index index,const DenseBase<OtherDerived> & other)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>
copyCoeffByOuterInner(Index outer,Index inner,const DenseBase<OtherDerived> & other)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>
copyPacket(Index row,Index col,const DenseBase<OtherDerived> & other)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>
copyPacket(Index index,const DenseBase<OtherDerived> & other)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>
copyPacketByOuterInner(Index outer,Index inner,const DenseBase<OtherDerived> & other)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       */
innerStride()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       */
outerStride()594     inline Index outerStride() const
595     {
596       return derived().outerStride();
597     }
598 
599     // FIXME shall we remove it ?
stride()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       */
rowStride()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       */
colStride()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       */
innerStride()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       */
outerStride()665     inline Index outerStride() const
666     {
667       return derived().outerStride();
668     }
669 
670     // FIXME shall we remove it ?
stride()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       */
rowStride()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       */
colStride()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 {
runfirst_aligned_impl700   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