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