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