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