File indexing completed on 2025-01-18 09:56:17
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef EIGEN_REF_H
0011 #define EIGEN_REF_H
0012
0013 namespace Eigen {
0014
0015 namespace internal {
0016
0017 template<typename _PlainObjectType, int _Options, typename _StrideType>
0018 struct traits<Ref<_PlainObjectType, _Options, _StrideType> >
0019 : public traits<Map<_PlainObjectType, _Options, _StrideType> >
0020 {
0021 typedef _PlainObjectType PlainObjectType;
0022 typedef _StrideType StrideType;
0023 enum {
0024 Options = _Options,
0025 Flags = traits<Map<_PlainObjectType, _Options, _StrideType> >::Flags | NestByRefBit,
0026 Alignment = traits<Map<_PlainObjectType, _Options, _StrideType> >::Alignment
0027 };
0028
0029 template<typename Derived> struct match {
0030 enum {
0031 IsVectorAtCompileTime = PlainObjectType::IsVectorAtCompileTime || Derived::IsVectorAtCompileTime,
0032 HasDirectAccess = internal::has_direct_access<Derived>::ret,
0033 StorageOrderMatch = IsVectorAtCompileTime || ((PlainObjectType::Flags&RowMajorBit)==(Derived::Flags&RowMajorBit)),
0034 InnerStrideMatch = int(StrideType::InnerStrideAtCompileTime)==int(Dynamic)
0035 || int(StrideType::InnerStrideAtCompileTime)==int(Derived::InnerStrideAtCompileTime)
0036 || (int(StrideType::InnerStrideAtCompileTime)==0 && int(Derived::InnerStrideAtCompileTime)==1),
0037 OuterStrideMatch = IsVectorAtCompileTime
0038 || int(StrideType::OuterStrideAtCompileTime)==int(Dynamic) || int(StrideType::OuterStrideAtCompileTime)==int(Derived::OuterStrideAtCompileTime),
0039
0040
0041
0042
0043
0044 DerivedAlignment = int(evaluator<Derived>::Alignment),
0045 AlignmentMatch = (int(traits<PlainObjectType>::Alignment)==int(Unaligned)) || (DerivedAlignment >= int(Alignment)),
0046 ScalarTypeMatch = internal::is_same<typename PlainObjectType::Scalar, typename Derived::Scalar>::value,
0047 MatchAtCompileTime = HasDirectAccess && StorageOrderMatch && InnerStrideMatch && OuterStrideMatch && AlignmentMatch && ScalarTypeMatch
0048 };
0049 typedef typename internal::conditional<MatchAtCompileTime,internal::true_type,internal::false_type>::type type;
0050 };
0051
0052 };
0053
0054 template<typename Derived>
0055 struct traits<RefBase<Derived> > : public traits<Derived> {};
0056
0057 }
0058
0059 template<typename Derived> class RefBase
0060 : public MapBase<Derived>
0061 {
0062 typedef typename internal::traits<Derived>::PlainObjectType PlainObjectType;
0063 typedef typename internal::traits<Derived>::StrideType StrideType;
0064
0065 public:
0066
0067 typedef MapBase<Derived> Base;
0068 EIGEN_DENSE_PUBLIC_INTERFACE(RefBase)
0069
0070 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Index innerStride() const
0071 {
0072 return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.inner() : 1;
0073 }
0074
0075 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR inline Index outerStride() const
0076 {
0077 return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer()
0078 : IsVectorAtCompileTime ? this->size()
0079 : int(Flags)&RowMajorBit ? this->cols()
0080 : this->rows();
0081 }
0082
0083 EIGEN_DEVICE_FUNC RefBase()
0084 : Base(0,RowsAtCompileTime==Dynamic?0:RowsAtCompileTime,ColsAtCompileTime==Dynamic?0:ColsAtCompileTime),
0085
0086 m_stride(StrideType::OuterStrideAtCompileTime==Dynamic?0:StrideType::OuterStrideAtCompileTime,
0087 StrideType::InnerStrideAtCompileTime==Dynamic?0:StrideType::InnerStrideAtCompileTime)
0088 {}
0089
0090 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(RefBase)
0091
0092 protected:
0093
0094 typedef Stride<StrideType::OuterStrideAtCompileTime,StrideType::InnerStrideAtCompileTime> StrideBase;
0095
0096
0097 static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index resolveInnerStride(Index inner) {
0098 return inner == 0 ? 1 : inner;
0099 }
0100
0101
0102 static EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index resolveOuterStride(Index inner, Index outer, Index rows, Index cols, bool isVectorAtCompileTime, bool isRowMajor) {
0103 return outer == 0 ? isVectorAtCompileTime ? inner * rows * cols : isRowMajor ? inner * cols : inner * rows : outer;
0104 }
0105
0106
0107
0108 template<typename Expression>
0109 EIGEN_DEVICE_FUNC bool construct(Expression& expr)
0110 {
0111
0112
0113 EIGEN_STATIC_ASSERT(
0114 EIGEN_PREDICATE_SAME_MATRIX_SIZE(PlainObjectType, Expression)
0115
0116 || ( PlainObjectType::IsVectorAtCompileTime
0117 && ((int(PlainObjectType::RowsAtCompileTime)==Eigen::Dynamic
0118 || int(Expression::ColsAtCompileTime)==Eigen::Dynamic
0119 || int(PlainObjectType::RowsAtCompileTime)==int(Expression::ColsAtCompileTime))
0120 && (int(PlainObjectType::ColsAtCompileTime)==Eigen::Dynamic
0121 || int(Expression::RowsAtCompileTime)==Eigen::Dynamic
0122 || int(PlainObjectType::ColsAtCompileTime)==int(Expression::RowsAtCompileTime)))),
0123 YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES
0124 )
0125
0126
0127 Index rows = expr.rows();
0128 Index cols = expr.cols();
0129 if(PlainObjectType::RowsAtCompileTime==1)
0130 {
0131 eigen_assert(expr.rows()==1 || expr.cols()==1);
0132 rows = 1;
0133 cols = expr.size();
0134 }
0135 else if(PlainObjectType::ColsAtCompileTime==1)
0136 {
0137 eigen_assert(expr.rows()==1 || expr.cols()==1);
0138 rows = expr.size();
0139 cols = 1;
0140 }
0141
0142 eigen_assert(
0143 (PlainObjectType::RowsAtCompileTime == Dynamic) || (PlainObjectType::RowsAtCompileTime == rows));
0144 eigen_assert(
0145 (PlainObjectType::ColsAtCompileTime == Dynamic) || (PlainObjectType::ColsAtCompileTime == cols));
0146
0147
0148
0149 const bool transpose = PlainObjectType::IsVectorAtCompileTime && (rows != expr.rows());
0150
0151 const bool row_major = ((PlainObjectType::Flags)&RowMajorBit) != 0;
0152 const bool expr_row_major = (Expression::Flags&RowMajorBit) != 0;
0153 const bool storage_differs = (row_major != expr_row_major);
0154
0155 const bool swap_stride = (transpose != storage_differs);
0156
0157
0158 const Index expr_inner_actual = resolveInnerStride(expr.innerStride());
0159 const Index expr_outer_actual = resolveOuterStride(expr_inner_actual,
0160 expr.outerStride(),
0161 expr.rows(),
0162 expr.cols(),
0163 Expression::IsVectorAtCompileTime != 0,
0164 expr_row_major);
0165
0166
0167
0168 const bool row_vector = (rows == 1);
0169 const bool col_vector = (cols == 1);
0170 const Index inner_stride =
0171 ( (!row_major && row_vector) || (row_major && col_vector) ) ?
0172 ( StrideType::InnerStrideAtCompileTime > 0 ? Index(StrideType::InnerStrideAtCompileTime) : 1)
0173 : swap_stride ? expr_outer_actual : expr_inner_actual;
0174
0175
0176
0177 const Index outer_stride =
0178 ( (!row_major && col_vector) || (row_major && row_vector) ) ?
0179 ( StrideType::OuterStrideAtCompileTime > 0 ? Index(StrideType::OuterStrideAtCompileTime) : rows * cols * inner_stride)
0180 : swap_stride ? expr_inner_actual : expr_outer_actual;
0181
0182
0183 const bool inner_valid = (StrideType::InnerStrideAtCompileTime == Dynamic)
0184 || (resolveInnerStride(Index(StrideType::InnerStrideAtCompileTime)) == inner_stride);
0185 if (!inner_valid) {
0186 return false;
0187 }
0188
0189 const bool outer_valid = (StrideType::OuterStrideAtCompileTime == Dynamic)
0190 || (resolveOuterStride(
0191 inner_stride,
0192 Index(StrideType::OuterStrideAtCompileTime),
0193 rows, cols, PlainObjectType::IsVectorAtCompileTime != 0,
0194 row_major)
0195 == outer_stride);
0196 if (!outer_valid) {
0197 return false;
0198 }
0199
0200 ::new (static_cast<Base*>(this)) Base(expr.data(), rows, cols);
0201 ::new (&m_stride) StrideBase(
0202 (StrideType::OuterStrideAtCompileTime == 0) ? 0 : outer_stride,
0203 (StrideType::InnerStrideAtCompileTime == 0) ? 0 : inner_stride );
0204 return true;
0205 }
0206
0207 StrideBase m_stride;
0208 };
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281 template<typename PlainObjectType, int Options, typename StrideType> class Ref
0282 : public RefBase<Ref<PlainObjectType, Options, StrideType> >
0283 {
0284 private:
0285 typedef internal::traits<Ref> Traits;
0286 template<typename Derived>
0287 EIGEN_DEVICE_FUNC inline Ref(const PlainObjectBase<Derived>& expr,
0288 typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0);
0289 public:
0290
0291 typedef RefBase<Ref> Base;
0292 EIGEN_DENSE_PUBLIC_INTERFACE(Ref)
0293
0294
0295 #ifndef EIGEN_PARSED_BY_DOXYGEN
0296 template<typename Derived>
0297 EIGEN_DEVICE_FUNC inline Ref(PlainObjectBase<Derived>& expr,
0298 typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0)
0299 {
0300 EIGEN_STATIC_ASSERT(bool(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
0301
0302 const bool success = Base::construct(expr.derived());
0303 EIGEN_UNUSED_VARIABLE(success)
0304 eigen_assert(success);
0305 }
0306 template<typename Derived>
0307 EIGEN_DEVICE_FUNC inline Ref(const DenseBase<Derived>& expr,
0308 typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0)
0309 #else
0310
0311 template<typename Derived>
0312 inline Ref(DenseBase<Derived>& expr)
0313 #endif
0314 {
0315 EIGEN_STATIC_ASSERT(bool(internal::is_lvalue<Derived>::value), THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
0316 EIGEN_STATIC_ASSERT(bool(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
0317 EIGEN_STATIC_ASSERT(!Derived::IsPlainObjectBase,THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
0318
0319 const bool success = Base::construct(expr.const_cast_derived());
0320 EIGEN_UNUSED_VARIABLE(success)
0321 eigen_assert(success);
0322 }
0323
0324 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Ref)
0325
0326 };
0327
0328
0329 template<typename TPlainObjectType, int Options, typename StrideType> class Ref<const TPlainObjectType, Options, StrideType>
0330 : public RefBase<Ref<const TPlainObjectType, Options, StrideType> >
0331 {
0332 typedef internal::traits<Ref> Traits;
0333 public:
0334
0335 typedef RefBase<Ref> Base;
0336 EIGEN_DENSE_PUBLIC_INTERFACE(Ref)
0337
0338 template<typename Derived>
0339 EIGEN_DEVICE_FUNC inline Ref(const DenseBase<Derived>& expr,
0340 typename internal::enable_if<bool(Traits::template match<Derived>::ScalarTypeMatch),Derived>::type* = 0)
0341 {
0342
0343
0344
0345 construct(expr.derived(), typename Traits::template match<Derived>::type());
0346 }
0347
0348 EIGEN_DEVICE_FUNC inline Ref(const Ref& other) : Base(other) {
0349
0350 }
0351
0352 template<typename OtherRef>
0353 EIGEN_DEVICE_FUNC inline Ref(const RefBase<OtherRef>& other) {
0354 construct(other.derived(), typename Traits::template match<OtherRef>::type());
0355 }
0356
0357 protected:
0358
0359 template<typename Expression>
0360 EIGEN_DEVICE_FUNC void construct(const Expression& expr,internal::true_type)
0361 {
0362
0363 if (!Base::construct(expr)) {
0364 construct(expr, internal::false_type());
0365 }
0366 }
0367
0368 template<typename Expression>
0369 EIGEN_DEVICE_FUNC void construct(const Expression& expr, internal::false_type)
0370 {
0371 internal::call_assignment_no_alias(m_object,expr,internal::assign_op<Scalar,Scalar>());
0372 Base::construct(m_object);
0373 }
0374
0375 protected:
0376 TPlainObjectType m_object;
0377 };
0378
0379 }
0380
0381 #endif