$treeview $search $mathjax
Eigen
3.2.5
$projectbrief
|
$projectbrief
|
$searchbox |
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2012 Gael Guennebaud <gael.guennebaud@inria.fr> 00005 // 00006 // This Source Code Form is subject to the terms of the Mozilla 00007 // Public License v. 2.0. If a copy of the MPL was not distributed 00008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 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 // Stride<> does not allow default ctor for Dynamic strides, so let' initialize it with dummy values: 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 // this is the const ref version 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 // std::cout << match_helper<Derived>::HasDirectAccess << "," << match_helper<Derived>::OuterStrideMatch << "," << match_helper<Derived>::InnerStrideMatch << "\n"; 00243 // std::cout << int(StrideType::OuterStrideAtCompileTime) << " - " << int(Derived::OuterStrideAtCompileTime) << "\n"; 00244 // std::cout << int(StrideType::InnerStrideAtCompileTime) << " - " << int(Derived::InnerStrideAtCompileTime) << "\n"; 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 } // end namespace Eigen 00268 00269 #endif // EIGEN_REF_H