00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef EIGEN_REF_H
00011 #define EIGEN_REF_H
00012
00013 namespace Eigen {
00014
00015 template<typename Derived> class RefBase;
00016 template<typename PlainObjectType, int Options = 0,
00017 typename StrideType = typename internal::conditional<PlainObjectType::IsVectorAtCompileTime,InnerStride<1>,OuterStride<> >::type > class Ref;
00018
00088 namespace internal {
00089
00090 template<typename _PlainObjectType, int _Options, typename _StrideType>
00091 struct traits<Ref<_PlainObjectType, _Options, _StrideType> >
00092 : public traits<Map<_PlainObjectType, _Options, _StrideType> >
00093 {
00094 typedef _PlainObjectType PlainObjectType;
00095 typedef _StrideType StrideType;
00096 enum {
00097 Options = _Options,
00098 Flags = traits<Map<_PlainObjectType, _Options, _StrideType> >::Flags | NestByRefBit
00099 };
00100
00101 template<typename Derived> struct match {
00102 enum {
00103 HasDirectAccess = internal::has_direct_access<Derived>::ret,
00104 StorageOrderMatch = PlainObjectType::IsVectorAtCompileTime || Derived::IsVectorAtCompileTime || ((PlainObjectType::Flags&RowMajorBit)==(Derived::Flags&RowMajorBit)),
00105 InnerStrideMatch = int(StrideType::InnerStrideAtCompileTime)==int(Dynamic)
00106 || int(StrideType::InnerStrideAtCompileTime)==int(Derived::InnerStrideAtCompileTime)
00107 || (int(StrideType::InnerStrideAtCompileTime)==0 && int(Derived::InnerStrideAtCompileTime)==1),
00108 OuterStrideMatch = Derived::IsVectorAtCompileTime
00109 || int(StrideType::OuterStrideAtCompileTime)==int(Dynamic) || int(StrideType::OuterStrideAtCompileTime)==int(Derived::OuterStrideAtCompileTime),
00110 AlignmentMatch = (_Options!=Aligned) || ((PlainObjectType::Flags&AlignedBit)==0) || ((traits<Derived>::Flags&AlignedBit)==AlignedBit),
00111 ScalarTypeMatch = internal::is_same<typename PlainObjectType::Scalar, typename Derived::Scalar>::value,
00112 MatchAtCompileTime = HasDirectAccess && StorageOrderMatch && InnerStrideMatch && OuterStrideMatch && AlignmentMatch && ScalarTypeMatch
00113 };
00114 typedef typename internal::conditional<MatchAtCompileTime,internal::true_type,internal::false_type>::type type;
00115 };
00116
00117 };
00118
00119 template<typename Derived>
00120 struct traits<RefBase<Derived> > : public traits<Derived> {};
00121
00122 }
00123
00124 template<typename Derived> class RefBase
00125 : public MapBase<Derived>
00126 {
00127 typedef typename internal::traits<Derived>::PlainObjectType PlainObjectType;
00128 typedef typename internal::traits<Derived>::StrideType StrideType;
00129
00130 public:
00131
00132 typedef MapBase<Derived> Base;
00133 EIGEN_DENSE_PUBLIC_INTERFACE(RefBase)
00134
00135 inline Index innerStride() const
00136 {
00137 return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.inner() : 1;
00138 }
00139
00140 inline Index outerStride() const
00141 {
00142 return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer()
00143 : IsVectorAtCompileTime ? this->size()
00144 : int(Flags)&RowMajorBit ? this->cols()
00145 : this->rows();
00146 }
00147
00148 RefBase()
00149 : Base(0,RowsAtCompileTime==Dynamic?0:RowsAtCompileTime,ColsAtCompileTime==Dynamic?0:ColsAtCompileTime),
00150
00151 m_stride(StrideType::OuterStrideAtCompileTime==Dynamic?0:StrideType::OuterStrideAtCompileTime,
00152 StrideType::InnerStrideAtCompileTime==Dynamic?0:StrideType::InnerStrideAtCompileTime)
00153 {}
00154
00155 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(RefBase)
00156
00157 protected:
00158
00159 typedef Stride<StrideType::OuterStrideAtCompileTime,StrideType::InnerStrideAtCompileTime> StrideBase;
00160
00161 template<typename Expression>
00162 void construct(Expression& expr)
00163 {
00164 if(PlainObjectType::RowsAtCompileTime==1)
00165 {
00166 eigen_assert(expr.rows()==1 || expr.cols()==1);
00167 ::new (static_cast<Base*>(this)) Base(expr.data(), 1, expr.size());
00168 }
00169 else if(PlainObjectType::ColsAtCompileTime==1)
00170 {
00171 eigen_assert(expr.rows()==1 || expr.cols()==1);
00172 ::new (static_cast<Base*>(this)) Base(expr.data(), expr.size(), 1);
00173 }
00174 else
00175 ::new (static_cast<Base*>(this)) Base(expr.data(), expr.rows(), expr.cols());
00176
00177 if(Expression::IsVectorAtCompileTime && (!PlainObjectType::IsVectorAtCompileTime) && ((Expression::Flags&RowMajorBit)!=(PlainObjectType::Flags&RowMajorBit)))
00178 ::new (&m_stride) StrideBase(expr.innerStride(), StrideType::InnerStrideAtCompileTime==0?0:1);
00179 else
00180 ::new (&m_stride) StrideBase(StrideType::OuterStrideAtCompileTime==0?0:expr.outerStride(),
00181 StrideType::InnerStrideAtCompileTime==0?0:expr.innerStride());
00182 }
00183
00184 StrideBase m_stride;
00185 };
00186
00187
00188 template<typename PlainObjectType, int Options, typename StrideType> class Ref
00189 : public RefBase<Ref<PlainObjectType, Options, StrideType> >
00190 {
00191 private:
00192 typedef internal::traits<Ref> Traits;
00193 template<typename Derived>
00194 inline Ref(const PlainObjectBase<Derived>& expr,
00195 typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0);
00196 public:
00197
00198 typedef RefBase<Ref> Base;
00199 EIGEN_DENSE_PUBLIC_INTERFACE(Ref)
00200
00201
00202 #ifndef EIGEN_PARSED_BY_DOXYGEN
00203 template<typename Derived>
00204 inline Ref(PlainObjectBase<Derived>& expr,
00205 typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0)
00206 {
00207 EIGEN_STATIC_ASSERT(static_cast<bool>(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
00208 Base::construct(expr.derived());
00209 }
00210 template<typename Derived>
00211 inline Ref(const DenseBase<Derived>& expr,
00212 typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0)
00213 #else
00214 template<typename Derived>
00215 inline Ref(DenseBase<Derived>& expr)
00216 #endif
00217 {
00218 EIGEN_STATIC_ASSERT(static_cast<bool>(internal::is_lvalue<Derived>::value), THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
00219 EIGEN_STATIC_ASSERT(static_cast<bool>(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
00220 enum { THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY = Derived::ThisConstantIsPrivateInPlainObjectBase};
00221 Base::construct(expr.const_cast_derived());
00222 }
00223
00224 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Ref)
00225
00226 };
00227
00228
00229 template<typename TPlainObjectType, int Options, typename StrideType> class Ref<const TPlainObjectType, Options, StrideType>
00230 : public RefBase<Ref<const TPlainObjectType, Options, StrideType> >
00231 {
00232 typedef internal::traits<Ref> Traits;
00233 public:
00234
00235 typedef RefBase<Ref> Base;
00236 EIGEN_DENSE_PUBLIC_INTERFACE(Ref)
00237
00238 template<typename Derived>
00239 inline Ref(const DenseBase<Derived>& expr,
00240 typename internal::enable_if<bool(Traits::template match<Derived>::ScalarTypeMatch),Derived>::type* = 0)
00241 {
00242
00243
00244
00245 construct(expr.derived(), typename Traits::template match<Derived>::type());
00246 }
00247
00248 protected:
00249
00250 template<typename Expression>
00251 void construct(const Expression& expr,internal::true_type)
00252 {
00253 Base::construct(expr);
00254 }
00255
00256 template<typename Expression>
00257 void construct(const Expression& expr, internal::false_type)
00258 {
00259 m_object.lazyAssign(expr);
00260 Base::construct(m_object);
00261 }
00262
00263 protected:
00264 TPlainObjectType m_object;
00265 };
00266
00267 }
00268
00269 #endif // EIGEN_REF_H