Medial Code Documentation
Loading...
Searching...
No Matches
XprHelper.h
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
5// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
6//
7// This Source Code Form is subject to the terms of the Mozilla
8// Public License v. 2.0. If a copy of the MPL was not distributed
9// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10
11#ifndef EIGEN_XPRHELPER_H
12#define EIGEN_XPRHELPER_H
13
14// just a workaround because GCC seems to not really like empty structs
15// FIXME: gcc 4.3 generates bad code when strict-aliasing is enabled
16// so currently we simply disable this optimization for gcc 4.3
17#if EIGEN_COMP_GNUC && !EIGEN_GNUC_AT(4,3)
18 #define EIGEN_EMPTY_STRUCT_CTOR(X) \
19 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE X() {} \
20 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE X(const X& ) {}
21#else
22 #define EIGEN_EMPTY_STRUCT_CTOR(X)
23#endif
24
25namespace Eigen {
26
27typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE DenseIndex;
28
35typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE Index;
36
37namespace internal {
38
39template<typename IndexDest, typename IndexSrc>
40EIGEN_DEVICE_FUNC
41inline IndexDest convert_index(const IndexSrc& idx) {
42 // for sizeof(IndexDest)>=sizeof(IndexSrc) compilers should be able to optimize this away:
43 eigen_internal_assert(idx <= NumTraits<IndexDest>::highest() && "Index value to big for target type");
44 return IndexDest(idx);
45}
46
47
48//classes inheriting no_assignment_operator don't generate a default operator=.
50{
51 private:
53};
54
56template<typename I1, typename I2>
58{
59 typedef typename conditional<(sizeof(I1)<sizeof(I2)), I2, I1>::type type;
60};
61
66template<typename T, int Value> class variable_if_dynamic
67{
68 public:
69 EIGEN_EMPTY_STRUCT_CTOR(variable_if_dynamic)
70 EIGEN_DEVICE_FUNC explicit variable_if_dynamic(T v) { EIGEN_ONLY_USED_FOR_DEBUG(v); eigen_assert(v == T(Value)); }
71 EIGEN_DEVICE_FUNC static T value() { return T(Value); }
72 EIGEN_DEVICE_FUNC void setValue(T) {}
73};
74
75template<typename T> class variable_if_dynamic<T, Dynamic>
76{
77 T m_value;
78 EIGEN_DEVICE_FUNC variable_if_dynamic() { eigen_assert(false); }
79 public:
80 EIGEN_DEVICE_FUNC explicit variable_if_dynamic(T value) : m_value(value) {}
81 EIGEN_DEVICE_FUNC T value() const { return m_value; }
82 EIGEN_DEVICE_FUNC void setValue(T value) { m_value = value; }
83};
84
87template<typename T, int Value> class variable_if_dynamicindex
88{
89 public:
90 EIGEN_EMPTY_STRUCT_CTOR(variable_if_dynamicindex)
91 EIGEN_DEVICE_FUNC explicit variable_if_dynamicindex(T v) { EIGEN_ONLY_USED_FOR_DEBUG(v); eigen_assert(v == T(Value)); }
92 EIGEN_DEVICE_FUNC static T value() { return T(Value); }
93 EIGEN_DEVICE_FUNC void setValue(T) {}
94};
95
96template<typename T> class variable_if_dynamicindex<T, DynamicIndex>
97{
98 T m_value;
99 EIGEN_DEVICE_FUNC variable_if_dynamicindex() { eigen_assert(false); }
100 public:
101 EIGEN_DEVICE_FUNC explicit variable_if_dynamicindex(T value) : m_value(value) {}
102 EIGEN_DEVICE_FUNC T value() const { return m_value; }
103 EIGEN_DEVICE_FUNC void setValue(T value) { m_value = value; }
104};
105
106template<typename T> struct functor_traits
107{
108 enum
109 {
110 Cost = 10,
111 PacketAccess = false,
112 IsRepeatable = false
113 };
114};
115
116template<typename T> struct packet_traits;
117
118template<typename T> struct unpacket_traits
119{
120 typedef T type;
121 typedef T half;
122 enum
123 {
124 size = 1,
125 alignment = 1
126 };
127};
128
129template<int Size, typename PacketType,
130 bool Stop = Size==Dynamic || (Size%unpacket_traits<PacketType>::size)==0 || is_same<PacketType,typename unpacket_traits<PacketType>::half>::value>
132
133template< int Size, typename PacketType>
135{
136 typedef PacketType type;
137};
138
139template<int Size, typename PacketType>
144
145template<typename T, int Size>
147{
149};
150
151#if EIGEN_MAX_STATIC_ALIGN_BYTES>0
152template<int ArrayBytes, int AlignmentBytes,
153 bool Match = bool((ArrayBytes%AlignmentBytes)==0),
154 bool TryHalf = bool(AlignmentBytes>EIGEN_MIN_ALIGN_BYTES) >
156{
157 enum { value = 0 };
158};
159
160template<int ArrayBytes, int AlignmentBytes, bool TryHalf>
161struct compute_default_alignment_helper<ArrayBytes, AlignmentBytes, true, TryHalf> // Match
162{
163 enum { value = AlignmentBytes };
164};
165
166template<int ArrayBytes, int AlignmentBytes>
167struct compute_default_alignment_helper<ArrayBytes, AlignmentBytes, false, true> // Try-half
168{
169 // current packet too large, try with an half-packet
170 enum { value = compute_default_alignment_helper<ArrayBytes, AlignmentBytes/2>::value };
171};
172#else
173// If static alignment is disabled, no need to bother.
174// This also avoids a division by zero in "bool Match = bool((ArrayBytes%AlignmentBytes)==0)"
175template<int ArrayBytes, int AlignmentBytes>
177{
178 enum { value = 0 };
179};
180#endif
181
182template<typename T, int Size> struct compute_default_alignment {
183 enum { value = compute_default_alignment_helper<Size*sizeof(T),EIGEN_MAX_STATIC_ALIGN_BYTES>::value };
184};
185
186template<typename T> struct compute_default_alignment<T,Dynamic> {
187 enum { value = EIGEN_MAX_ALIGN_BYTES };
188};
189
190template<typename _Scalar, int _Rows, int _Cols,
191 int _Options = AutoAlign |
192 ( (_Rows==1 && _Cols!=1) ? RowMajor
193 : (_Cols==1 && _Rows!=1) ? ColMajor
194 : EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION ),
195 int _MaxRows = _Rows,
196 int _MaxCols = _Cols
198{
199 enum {
200 IsColVector = _Cols==1 && _Rows!=1,
201 IsRowVector = _Rows==1 && _Cols!=1,
202 Options = IsColVector ? (_Options | ColMajor) & ~RowMajor
203 : IsRowVector ? (_Options | RowMajor) & ~ColMajor
204 : _Options
205 };
206 public:
208};
209
210template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
212{
213 enum { row_major_bit = Options&RowMajor ? RowMajorBit : 0 };
214 public:
215 // FIXME currently we still have to handle DirectAccessBit at the expression level to handle DenseCoeffsBase<>
216 // and then propagate this information to the evaluator's flags.
217 // However, I (Gael) think that DirectAccessBit should only matter at the evaluation stage.
218 enum { ret = DirectAccessBit | LvalueBit | NestByRefBit | row_major_bit };
219};
220
221template<int _Rows, int _Cols> struct size_at_compile_time
222{
223 enum { ret = (_Rows==Dynamic || _Cols==Dynamic) ? Dynamic : _Rows * _Cols };
224};
225
230
231/* plain_matrix_type : the difference from eval is that plain_matrix_type is always a plain matrix type,
232 * whereas eval is a const reference in the case of a matrix
233 */
234
236template<typename T, typename BaseClassType, int Flags> struct plain_matrix_type_dense;
237template<typename T> struct plain_matrix_type<T,Dense>
238{
240};
241template<typename T> struct plain_matrix_type<T,DiagonalShape>
242{
243 typedef typename T::PlainObject type;
244};
245
256
267
268/* eval : the return type of eval(). For matrices, this is just a const reference
269 * in order to avoid a useless copy
270 */
271
273
274template<typename T> struct eval<T,Dense>
275{
276 typedef typename plain_matrix_type<T>::type type;
277// typedef typename T::PlainObject type;
278// typedef T::Matrix<typename traits<T>::Scalar,
279// traits<T>::RowsAtCompileTime,
280// traits<T>::ColsAtCompileTime,
281// AutoAlign | (traits<T>::Flags&RowMajorBit ? RowMajor : ColMajor),
282// traits<T>::MaxRowsAtCompileTime,
283// traits<T>::MaxColsAtCompileTime
284// > type;
285};
286
287template<typename T> struct eval<T,DiagonalShape>
288{
289 typedef typename plain_matrix_type<T>::type type;
290};
291
292// for matrices, no need to evaluate, just use a const reference to avoid a useless copy
293template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
294struct eval<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, Dense>
295{
297};
298
299template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
300struct eval<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, Dense>
301{
303};
304
305
306/* similar to plain_matrix_type, but using the evaluator's Flags */
308
309template<typename T>
314
315
316/* plain_matrix_type_column_major : same as plain_matrix_type but guaranteed to be column-major
317 */
318template<typename T> struct plain_matrix_type_column_major
319{
320 enum { Rows = traits<T>::RowsAtCompileTime,
324 };
326 Rows,
327 Cols,
328 (MaxRows==1&&MaxCols!=1) ? RowMajor : ColMajor,
329 MaxRows,
330 MaxCols
331 > type;
332};
333
334/* plain_matrix_type_row_major : same as plain_matrix_type but guaranteed to be row-major
335 */
336template<typename T> struct plain_matrix_type_row_major
337{
338 enum { Rows = traits<T>::RowsAtCompileTime,
342 };
344 Rows,
345 Cols,
346 (MaxCols==1&&MaxRows!=1) ? RowMajor : ColMajor,
347 MaxRows,
348 MaxCols
349 > type;
350};
351
355template <typename T>
357{
358 typedef typename conditional<
359 bool(traits<T>::Flags & NestByRefBit),
360 T const&,
361 const T
362 >::type type;
363
364 typedef typename conditional<
365 bool(traits<T>::Flags & NestByRefBit),
366 T &,
367 T
368 >::type non_const_type;
369};
370
372template<typename T1, typename T2>
374{
375 typedef typename conditional<
378 T2
379 >::type type;
380};
381
382
383// However, we still need a mechanism to detect whether an expression which is evaluated multiple time
384// has to be evaluated into a temporary.
385// That's the purpose of this new nested_eval helper:
398{
399 enum {
400 ScalarReadCost = NumTraits<typename traits<T>::Scalar>::ReadCost,
401 CoeffReadCost = evaluator<T>::CoeffReadCost, // NOTE What if an evaluator evaluate itself into a tempory?
402 // Then CoeffReadCost will be small (e.g., 1) but we still have to evaluate, especially if n>1.
403 // This situation is already taken care by the EvalBeforeNestingBit flag, which is turned ON
404 // for all evaluator creating a temporary. This flag is then propagated by the parent evaluators.
405 // Another solution could be to count the number of temps?
406 NAsInteger = n == Dynamic ? HugeCost : n,
407 CostEval = (NAsInteger+1) * ScalarReadCost + CoeffReadCost,
408 CostNoEval = NAsInteger * CoeffReadCost
409 };
410
411 typedef typename conditional<
413 (int(CostEval) < int(CostNoEval)) ),
414 PlainObject,
415 typename ref_selector<T>::type
416 >::type type;
417};
418
419template<typename T>
421inline T* const_cast_ptr(const T* ptr)
422{
423 return const_cast<T*>(ptr);
424}
425
428{
429 /* dense_xpr_base should only ever be used on dense expressions, thus falling either into the MatrixXpr or into the ArrayXpr cases */
430};
431
432template<typename Derived>
433struct dense_xpr_base<Derived, MatrixXpr>
434{
436};
437
438template<typename Derived>
439struct dense_xpr_base<Derived, ArrayXpr>
440{
441 typedef ArrayBase<Derived> type;
442};
443
446
447template<typename Derived, typename XprKind>
448struct generic_xpr_base<Derived, XprKind, Dense>
449{
450 typedef typename dense_xpr_base<Derived,XprKind>::type type;
451};
452
455template<typename Derived, typename Scalar, typename OtherScalar, typename BaseType,
457struct special_scalar_op_base : public BaseType
458{
459 // dummy operator* so that the
460 // "using special_scalar_op_base::operator*" compiles
461 struct dummy {};
462 void operator*(dummy) const;
463 void operator/(dummy) const;
464};
465
466template<typename Derived,typename Scalar,typename OtherScalar, typename BaseType>
467struct special_scalar_op_base<Derived,Scalar,OtherScalar,BaseType,true> : public BaseType
468{
470 operator*(const OtherScalar& scalar) const
471 {
472#ifdef EIGEN_SPECIAL_SCALAR_MULTIPLE_PLUGIN
474#endif
476 (*static_cast<const Derived*>(this), scalar_multiple2_op<Scalar,OtherScalar>(scalar));
477 }
478
479 inline friend const CwiseUnaryOp<scalar_multiple2_op<Scalar,OtherScalar>, Derived>
480 operator*(const OtherScalar& scalar, const Derived& matrix)
481 {
482#ifdef EIGEN_SPECIAL_SCALAR_MULTIPLE_PLUGIN
484#endif
485 return static_cast<const special_scalar_op_base&>(matrix).operator*(scalar);
486 }
487
489 operator/(const OtherScalar& scalar) const
490 {
491#ifdef EIGEN_SPECIAL_SCALAR_MULTIPLE_PLUGIN
493#endif
495 (*static_cast<const Derived*>(this), scalar_quotient2_op<Scalar,OtherScalar>(scalar));
496 }
497};
498
499template<typename XprType, typename CastType> struct cast_return_type
500{
501 typedef typename XprType::Scalar CurrentScalarType;
502 typedef typename remove_all<CastType>::type _CastType;
503 typedef typename _CastType::Scalar NewScalarType;
505 const XprType&,CastType>::type type;
506};
507
508template <typename A, typename B> struct promote_storage_type;
509
510template <typename A> struct promote_storage_type<A,A>
511{
512 typedef A ret;
513};
514template <typename A> struct promote_storage_type<A, const A>
515{
516 typedef A ret;
517};
518template <typename A> struct promote_storage_type<const A, A>
519{
520 typedef A ret;
521};
522
536template <typename A, typename B, typename Functor> struct cwise_promote_storage_type;
537
538template <typename A, typename Functor> struct cwise_promote_storage_type<A,A,Functor> { typedef A ret; };
539template <typename Functor> struct cwise_promote_storage_type<Dense,Dense,Functor> { typedef Dense ret; };
540template <typename ScalarA, typename ScalarB> struct cwise_promote_storage_type<Dense,Dense,scalar_product_op<ScalarA,ScalarB> > { typedef Dense ret; };
541template <typename A, typename Functor> struct cwise_promote_storage_type<A,Dense,Functor> { typedef Dense ret; };
542template <typename B, typename Functor> struct cwise_promote_storage_type<Dense,B,Functor> { typedef Dense ret; };
543template <typename A, typename ScalarA, typename ScalarB> struct cwise_promote_storage_type<A,Dense,scalar_product_op<ScalarA,ScalarB> > { typedef A ret; };
544template <typename B, typename ScalarA, typename ScalarB> struct cwise_promote_storage_type<Dense,B,scalar_product_op<ScalarA,ScalarB> > { typedef B ret; };
545
560template <typename A, typename B, int ProductTag> struct product_promote_storage_type;
561
562template <typename A, int ProductTag> struct product_promote_storage_type<A, A, ProductTag> { typedef A ret;};
563template <int ProductTag> struct product_promote_storage_type<Dense, Dense, ProductTag> { typedef Dense ret;};
564template <typename A, int ProductTag> struct product_promote_storage_type<A, Dense, ProductTag> { typedef Dense ret; };
565template <typename B, int ProductTag> struct product_promote_storage_type<Dense, B, ProductTag> { typedef Dense ret; };
566
567template <typename A, int ProductTag> struct product_promote_storage_type<A, DiagonalShape, ProductTag> { typedef A ret; };
568template <typename B, int ProductTag> struct product_promote_storage_type<DiagonalShape, B, ProductTag> { typedef B ret; };
569template <int ProductTag> struct product_promote_storage_type<Dense, DiagonalShape, ProductTag> { typedef Dense ret; };
570template <int ProductTag> struct product_promote_storage_type<DiagonalShape, Dense, ProductTag> { typedef Dense ret; };
571
572template <typename A, int ProductTag> struct product_promote_storage_type<A, PermutationStorage, ProductTag> { typedef A ret; };
573template <typename B, int ProductTag> struct product_promote_storage_type<PermutationStorage, B, ProductTag> { typedef B ret; };
574template <int ProductTag> struct product_promote_storage_type<Dense, PermutationStorage, ProductTag> { typedef Dense ret; };
575template <int ProductTag> struct product_promote_storage_type<PermutationStorage, Dense, ProductTag> { typedef Dense ret; };
576
580template<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar>
582{
583 typedef Matrix<Scalar, 1, ExpressionType::ColsAtCompileTime,
584 ExpressionType::PlainObject::Options | RowMajor, 1, ExpressionType::MaxColsAtCompileTime> MatrixRowType;
585 typedef Array<Scalar, 1, ExpressionType::ColsAtCompileTime,
586 ExpressionType::PlainObject::Options | RowMajor, 1, ExpressionType::MaxColsAtCompileTime> ArrayRowType;
587
588 typedef typename conditional<
592 >::type type;
593};
594
595template<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar>
597{
598 typedef Matrix<Scalar, ExpressionType::RowsAtCompileTime, 1,
599 ExpressionType::PlainObject::Options & ~RowMajor, ExpressionType::MaxRowsAtCompileTime, 1> MatrixColType;
600 typedef Array<Scalar, ExpressionType::RowsAtCompileTime, 1,
601 ExpressionType::PlainObject::Options & ~RowMajor, ExpressionType::MaxRowsAtCompileTime, 1> ArrayColType;
602
603 typedef typename conditional<
607 >::type type;
608};
609
610template<typename ExpressionType, typename Scalar = typename ExpressionType::Scalar>
612{
613 enum { diag_size = EIGEN_SIZE_MIN_PREFER_DYNAMIC(ExpressionType::RowsAtCompileTime, ExpressionType::ColsAtCompileTime),
614 max_diag_size = EIGEN_SIZE_MIN_PREFER_FIXED(ExpressionType::MaxRowsAtCompileTime, ExpressionType::MaxColsAtCompileTime)
615 };
618
619 typedef typename conditional<
623 >::type type;
624};
625
626template<typename ExpressionType>
628{
629 enum { value = !bool(is_const<ExpressionType>::value) &&
631};
632
633template<typename T> struct is_diagonal
634{ enum { ret = false }; };
635
636template<typename T> struct is_diagonal<DiagonalBase<T> >
637{ enum { ret = true }; };
638
639template<typename T> struct is_diagonal<DiagonalWrapper<T> >
640{ enum { ret = true }; };
641
642template<typename T, int S> struct is_diagonal<DiagonalMatrix<T,S> >
643{ enum { ret = true }; };
644
645template<typename S1, typename S2> struct glue_shapes;
647
648template<typename T1, typename T2>
649bool is_same_dense(const T1 &mat1, const T2 &mat2, typename enable_if<has_direct_access<T1>::ret&&has_direct_access<T2>::ret, T1>::type * = 0)
650{
651 return (mat1.data()==mat2.data()) && (mat1.innerStride()==mat2.innerStride()) && (mat1.outerStride()==mat2.outerStride());
652}
653
654template<typename T1, typename T2>
655bool is_same_dense(const T1 &, const T2 &, typename enable_if<!(has_direct_access<T1>::ret&&has_direct_access<T2>::ret), T1>::type * = 0)
656{
657 return false;
658}
659
660template<typename T, typename U> struct is_same_or_void { enum { value = is_same<T,U>::value }; };
661template<typename T> struct is_same_or_void<void,T> { enum { value = 1 }; };
662template<typename T> struct is_same_or_void<T,void> { enum { value = 1 }; };
663template<> struct is_same_or_void<void,void> { enum { value = 1 }; };
664
665#ifdef EIGEN_DEBUG_ASSIGN
666std::string demangle_traversal(int t)
667{
668 if(t==DefaultTraversal) return "DefaultTraversal";
669 if(t==LinearTraversal) return "LinearTraversal";
670 if(t==InnerVectorizedTraversal) return "InnerVectorizedTraversal";
671 if(t==LinearVectorizedTraversal) return "LinearVectorizedTraversal";
672 if(t==SliceVectorizedTraversal) return "SliceVectorizedTraversal";
673 return "?";
674}
675std::string demangle_unrolling(int t)
676{
677 if(t==NoUnrolling) return "NoUnrolling";
678 if(t==InnerUnrolling) return "InnerUnrolling";
679 if(t==CompleteUnrolling) return "CompleteUnrolling";
680 return "?";
681}
682std::string demangle_flags(int f)
683{
684 std::string res;
685 if(f&RowMajorBit) res += " | RowMajor";
686 if(f&PacketAccessBit) res += " | Packet";
687 if(f&LinearAccessBit) res += " | Linear";
688 if(f&LvalueBit) res += " | Lvalue";
689 if(f&DirectAccessBit) res += " | Direct";
690 if(f&NestByRefBit) res += " | NestByRef";
691 if(f&NoPreferredStorageOrderBit) res += " | NoPreferredStorageOrderBit";
692
693 return res;
694}
695#endif
696
697} // end namespace internal
698
699// we require Lhs and Rhs to have the same scalar type. Currently there is no example of a binary functor
700// that would take two operands of different types. If there were such an example, then this check should be
701// moved to the BinaryOp functors, on a per-case basis. This would however require a change in the BinaryOp functors, as
702// currently they take only one typename Scalar template parameter.
703// It is tempting to always allow mixing different types but remember that this is often impossible in the vectorized paths.
704// So allowing mixing different types gives very unexpected errors when enabling vectorization, when the user tries to
705// add together a float matrix and a double matrix.
706#define EIGEN_CHECK_BINARY_COMPATIBILIY(BINOP,LHS,RHS) \
707 EIGEN_STATIC_ASSERT((internal::functor_is_product_like<BINOP>::ret \
708 ? int(internal::scalar_product_traits<LHS, RHS>::Defined) \
709 : int(internal::is_same_or_void<LHS, RHS>::value)), \
710 YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
711
712} // end namespace Eigen
713
714#endif // EIGEN_XPRHELPER_H
General-purpose arrays with easy API for coefficient-wise operations.
Definition Array.h:47
Definition DiagonalMatrix.h:19
Represents a diagonal matrix with its storage.
Definition DiagonalMatrix.h:119
Expression of a diagonal matrix.
Definition DiagonalMatrix.h:248
The matrix class, also used for vectors and row-vectors.
Definition Matrix.h:180
Pseudo expression representing a solving operation.
Definition Solve.h:63
Definition XprHelper.h:212
Definition XprHelper.h:67
@ ColMajor
Storage order is column major (see TopicStorageOrders).
Definition Constants.h:320
@ RowMajor
Storage order is row major (see TopicStorageOrders).
Definition Constants.h:322
@ AutoAlign
Align the matrix itself if it is vectorizable fixed-size.
Definition Constants.h:324
const unsigned int PacketAccessBit
Short version: means the expression might be vectorized.
Definition Constants.h:88
const unsigned int NoPreferredStorageOrderBit
for an expression, this means that the storage order can be either row-major or column-major.
Definition Constants.h:172
const unsigned int LinearAccessBit
Short version: means the expression can be seen as 1D vector.
Definition Constants.h:124
const unsigned int EvalBeforeNestingBit
means the expression should be evaluated by the calling expression
Definition Constants.h:65
const unsigned int DirectAccessBit
Means that the underlying array of coefficients can be directly accessed as a plain strided array.
Definition Constants.h:149
const unsigned int LvalueBit
Means the expression has a coeffRef() method, i.e.
Definition Constants.h:138
const unsigned int RowMajorBit
for a matrix, this means that the storage order is row-major.
Definition Constants.h:61
The type used to identify an array expression.
Definition Constants.h:508
Definition Constants.h:511
The type used to identify a dense storage.
Definition Constants.h:490
Definition Constants.h:514
The type used to identify a matrix expression.
Definition Constants.h:505
The type used to identify a permutation storage.
Definition Constants.h:499
Definition Constants.h:516
Definition XprHelper.h:500
Definition Meta.h:34
Definition XprHelper.h:428
Definition Meta.h:131
Definition XprHelper.h:272
Definition CoreEvaluators.h:82
Definition XprHelper.h:147
Definition XprHelper.h:107
Definition XprHelper.h:445
Definition XprHelper.h:645
Definition ForwardDeclarations.h:26
Definition Meta.h:91
Definition XprHelper.h:634
Definition XprHelper.h:628
Definition XprHelper.h:660
Definition Meta.h:39
Definition XprHelper.h:398
Definition GenericPacketMath.h:90
Definition XprHelper.h:597
Definition XprHelper.h:612
Definition XprHelper.h:235
Definition XprHelper.h:307
Definition XprHelper.h:582
Definition XprHelper.h:58
Definition XprHelper.h:508
Definition XprHelper.h:357
Definition BinaryFunctors.h:59
Definition XprHelper.h:222
Definition XprHelper.h:458
Definition ForwardDeclarations.h:17
Definition XprHelper.h:374
Definition Meta.h:30
Definition XprHelper.h:119