00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef EIGEN_XPRHELPER_H
00027 #define EIGEN_XPRHELPER_H
00028
00029
00030 #ifdef __GNUG__
00031 struct ei_empty_struct{char _ei_dummy_;};
00032 #define EIGEN_EMPTY_STRUCT : Eigen::ei_empty_struct
00033 #else
00034 #define EIGEN_EMPTY_STRUCT
00035 #endif
00036
00037
00038 class ei_no_assignment_operator
00039 {
00040 #if EIGEN_GCC3_OR_OLDER
00041 protected:
00042 void nevermind_this_is_just_to_work_around_a_stupid_gcc3_warning();
00043 #endif
00044 private:
00045 ei_no_assignment_operator& operator=(const ei_no_assignment_operator&);
00046 };
00047
00052 template<int Value> class ei_int_if_dynamic EIGEN_EMPTY_STRUCT
00053 {
00054 public:
00055 ei_int_if_dynamic() {}
00056 explicit ei_int_if_dynamic(int) {}
00057 static int value() { return Value; }
00058 void setValue(int) {}
00059 };
00060
00061 template<> class ei_int_if_dynamic<Dynamic>
00062 {
00063 int m_value;
00064 ei_int_if_dynamic() {}
00065 public:
00066 explicit ei_int_if_dynamic(int value) : m_value(value) {}
00067 int value() const { return m_value; }
00068 void setValue(int value) { m_value = value; }
00069 };
00070
00071 template<typename T> struct ei_functor_traits
00072 {
00073 enum
00074 {
00075 Cost = 10,
00076 PacketAccess = false
00077 };
00078 };
00079
00080 template<typename T> struct ei_packet_traits
00081 {
00082 typedef T type;
00083 enum {size=1};
00084 };
00085
00086 template<typename T> struct ei_unpacket_traits
00087 {
00088 typedef T type;
00089 enum {size=1};
00090 };
00091
00092 template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
00093 class ei_compute_matrix_flags
00094 {
00095 enum {
00096 row_major_bit = Options&RowMajor ? RowMajorBit : 0,
00097 inner_max_size = int(MaxRows==1) ? int(MaxCols)
00098 : int(MaxCols==1) ? int(MaxRows)
00099 : int(row_major_bit) ? int(MaxCols) : int(MaxRows),
00100 is_big = inner_max_size == Dynamic,
00101 storage_has_fixed_size = MaxRows != Dynamic && MaxCols != Dynamic,
00102 storage_has_aligned_fixed_size = storage_has_fixed_size
00103 && ( (MaxCols*MaxRows) % ei_packet_traits<Scalar>::size == 0 ),
00104 aligned_bit = ( (Options&AutoAlign)
00105 && (is_big || storage_has_aligned_fixed_size)
00106 ) ? AlignedBit : 0,
00107 packet_access_bit = ei_packet_traits<Scalar>::size > 1 && aligned_bit ? PacketAccessBit : 0
00108 };
00109
00110 public:
00111 enum { ret = LinearAccessBit | DirectAccessBit | packet_access_bit | row_major_bit | aligned_bit };
00112 };
00113
00114 template<int _Rows, int _Cols> struct ei_size_at_compile_time
00115 {
00116 enum { ret = (_Rows==Dynamic || _Cols==Dynamic) ? Dynamic : _Rows * _Cols };
00117 };
00118
00119
00120
00121
00122
00123 template<typename T, int Sparseness = ei_traits<T>::Flags&SparseBit> struct ei_eval;
00124
00125 template<typename T> struct ei_eval<T,IsDense>
00126 {
00127 typedef Matrix<typename ei_traits<T>::Scalar,
00128 ei_traits<T>::RowsAtCompileTime,
00129 ei_traits<T>::ColsAtCompileTime,
00130 AutoAlign | (ei_traits<T>::Flags&RowMajorBit ? RowMajor : ColMajor),
00131 ei_traits<T>::MaxRowsAtCompileTime,
00132 ei_traits<T>::MaxColsAtCompileTime
00133 > type;
00134 };
00135
00136
00137 template<typename _Scalar, int _Rows, int _Cols, int _StorageOrder, int _MaxRows, int _MaxCols>
00138 struct ei_eval<Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols>, IsDense>
00139 {
00140 typedef const Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols>& type;
00141 };
00142
00143
00144
00145
00146 template<typename T> struct ei_plain_matrix_type
00147 {
00148 typedef Matrix<typename ei_traits<T>::Scalar,
00149 ei_traits<T>::RowsAtCompileTime,
00150 ei_traits<T>::ColsAtCompileTime,
00151 AutoAlign | (ei_traits<T>::Flags&RowMajorBit ? RowMajor : ColMajor),
00152 ei_traits<T>::MaxRowsAtCompileTime,
00153 ei_traits<T>::MaxColsAtCompileTime
00154 > type;
00155 };
00156
00157
00158
00159 template<typename T> struct ei_plain_matrix_type_column_major
00160 {
00161 typedef Matrix<typename ei_traits<T>::Scalar,
00162 ei_traits<T>::RowsAtCompileTime,
00163 ei_traits<T>::ColsAtCompileTime,
00164 AutoAlign | ColMajor,
00165 ei_traits<T>::MaxRowsAtCompileTime,
00166 ei_traits<T>::MaxColsAtCompileTime
00167 > type;
00168 };
00169
00170
00171
00172 template<typename T> struct ei_plain_matrix_type_row_major
00173 {
00174 typedef Matrix<typename ei_traits<T>::Scalar,
00175 ei_traits<T>::RowsAtCompileTime,
00176 ei_traits<T>::ColsAtCompileTime,
00177 AutoAlign | RowMajor,
00178 ei_traits<T>::MaxRowsAtCompileTime,
00179 ei_traits<T>::MaxColsAtCompileTime
00180 > type;
00181 };
00182
00183 template<typename T> struct ei_must_nest_by_value { enum { ret = false }; };
00184 template<typename T> struct ei_must_nest_by_value<NestByValue<T> > { enum { ret = true }; };
00185
00204 template<typename T, int n=1, typename PlainMatrixType = typename ei_eval<T>::type> struct ei_nested
00205 {
00206 enum {
00207 CostEval = (n+1) * int(NumTraits<typename ei_traits<T>::Scalar>::ReadCost),
00208 CostNoEval = (n-1) * int(ei_traits<T>::CoeffReadCost)
00209 };
00210 typedef typename ei_meta_if<
00211 ei_must_nest_by_value<T>::ret,
00212 T,
00213 typename ei_meta_if<
00214 (int(ei_traits<T>::Flags) & EvalBeforeNestingBit)
00215 || ( int(CostEval) <= int(CostNoEval) ),
00216 PlainMatrixType,
00217 const T&
00218 >::ret
00219 >::ret type;
00220 };
00221
00222 template<unsigned int Flags> struct ei_are_flags_consistent
00223 {
00224 enum { ret = !( (Flags&UnitDiagBit && Flags&ZeroDiagBit) )
00225 };
00226 };
00227
00231 template<typename ExpressionType, int RowsOrSize=Dynamic, int Cols=Dynamic> struct BlockReturnType {
00232 typedef Block<ExpressionType, (ei_traits<ExpressionType>::RowsAtCompileTime == 1 ? 1 : RowsOrSize),
00233 (ei_traits<ExpressionType>::ColsAtCompileTime == 1 ? 1 : RowsOrSize)> SubVectorType;
00234 typedef Block<ExpressionType, RowsOrSize, Cols> Type;
00235 };
00236
00237 template<typename CurrentType, typename NewType> struct ei_cast_return_type
00238 {
00239 typedef typename ei_meta_if<ei_is_same_type<CurrentType,NewType>::ret,const CurrentType&,NewType>::ret type;
00240 };
00241
00242 #endif // EIGEN_XPRHELPER_H