MOAB
4.9.3pre
|
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2012 Gael Guennebaud <[email protected]> 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 namespace internal { 00016 00017 template<typename _PlainObjectType, int _Options, typename _StrideType> 00018 struct traits<Ref<_PlainObjectType, _Options, _StrideType> > 00019 : public traits<Map<_PlainObjectType, _Options, _StrideType> > 00020 { 00021 typedef _PlainObjectType PlainObjectType; 00022 typedef _StrideType StrideType; 00023 enum { 00024 Options = _Options, 00025 Flags = traits<Map<_PlainObjectType, _Options, _StrideType> >::Flags | NestByRefBit, 00026 Alignment = traits<Map<_PlainObjectType, _Options, _StrideType> >::Alignment 00027 }; 00028 00029 template<typename Derived> struct match { 00030 enum { 00031 HasDirectAccess = internal::has_direct_access<Derived>::ret, 00032 StorageOrderMatch = PlainObjectType::IsVectorAtCompileTime || Derived::IsVectorAtCompileTime || ((PlainObjectType::Flags&RowMajorBit)==(Derived::Flags&RowMajorBit)), 00033 InnerStrideMatch = int(StrideType::InnerStrideAtCompileTime)==int(Dynamic) 00034 || int(StrideType::InnerStrideAtCompileTime)==int(Derived::InnerStrideAtCompileTime) 00035 || (int(StrideType::InnerStrideAtCompileTime)==0 && int(Derived::InnerStrideAtCompileTime)==1), 00036 OuterStrideMatch = Derived::IsVectorAtCompileTime 00037 || int(StrideType::OuterStrideAtCompileTime)==int(Dynamic) || int(StrideType::OuterStrideAtCompileTime)==int(Derived::OuterStrideAtCompileTime), 00038 AlignmentMatch = (int(traits<PlainObjectType>::Alignment)==int(Unaligned)) || (int(evaluator<Derived>::Alignment) >= int(Alignment)), // FIXME the first condition is not very clear, it should be replaced by the required alignment 00039 ScalarTypeMatch = internal::is_same<typename PlainObjectType::Scalar, typename Derived::Scalar>::value, 00040 MatchAtCompileTime = HasDirectAccess && StorageOrderMatch && InnerStrideMatch && OuterStrideMatch && AlignmentMatch && ScalarTypeMatch 00041 }; 00042 typedef typename internal::conditional<MatchAtCompileTime,internal::true_type,internal::false_type>::type type; 00043 }; 00044 00045 }; 00046 00047 template<typename Derived> 00048 struct traits<RefBase<Derived> > : public traits<Derived> {}; 00049 00050 } 00051 00052 template<typename Derived> class RefBase 00053 : public MapBase<Derived> 00054 { 00055 typedef typename internal::traits<Derived>::PlainObjectType PlainObjectType; 00056 typedef typename internal::traits<Derived>::StrideType StrideType; 00057 00058 public: 00059 00060 typedef MapBase<Derived> Base; 00061 EIGEN_DENSE_PUBLIC_INTERFACE(RefBase) 00062 00063 EIGEN_DEVICE_FUNC inline Index innerStride() const 00064 { 00065 return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.inner() : 1; 00066 } 00067 00068 EIGEN_DEVICE_FUNC inline Index outerStride() const 00069 { 00070 return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer() 00071 : IsVectorAtCompileTime ? this->size() 00072 : int(Flags)&RowMajorBit ? this->cols() 00073 : this->rows(); 00074 } 00075 00076 EIGEN_DEVICE_FUNC RefBase() 00077 : Base(0,RowsAtCompileTime==Dynamic?0:RowsAtCompileTime,ColsAtCompileTime==Dynamic?0:ColsAtCompileTime), 00078 // Stride<> does not allow default ctor for Dynamic strides, so let' initialize it with dummy values: 00079 m_stride(StrideType::OuterStrideAtCompileTime==Dynamic?0:StrideType::OuterStrideAtCompileTime, 00080 StrideType::InnerStrideAtCompileTime==Dynamic?0:StrideType::InnerStrideAtCompileTime) 00081 {} 00082 00083 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(RefBase) 00084 00085 protected: 00086 00087 typedef Stride<StrideType::OuterStrideAtCompileTime,StrideType::InnerStrideAtCompileTime> StrideBase; 00088 00089 template<typename Expression> 00090 EIGEN_DEVICE_FUNC void construct(Expression& expr) 00091 { 00092 if(PlainObjectType::RowsAtCompileTime==1) 00093 { 00094 eigen_assert(expr.rows()==1 || expr.cols()==1); 00095 ::new (static_cast<Base*>(this)) Base(expr.data(), 1, expr.size()); 00096 } 00097 else if(PlainObjectType::ColsAtCompileTime==1) 00098 { 00099 eigen_assert(expr.rows()==1 || expr.cols()==1); 00100 ::new (static_cast<Base*>(this)) Base(expr.data(), expr.size(), 1); 00101 } 00102 else 00103 ::new (static_cast<Base*>(this)) Base(expr.data(), expr.rows(), expr.cols()); 00104 00105 if(Expression::IsVectorAtCompileTime && (!PlainObjectType::IsVectorAtCompileTime) && ((Expression::Flags&RowMajorBit)!=(PlainObjectType::Flags&RowMajorBit))) 00106 ::new (&m_stride) StrideBase(expr.innerStride(), StrideType::InnerStrideAtCompileTime==0?0:1); 00107 else 00108 ::new (&m_stride) StrideBase(StrideType::OuterStrideAtCompileTime==0?0:expr.outerStride(), 00109 StrideType::InnerStrideAtCompileTime==0?0:expr.innerStride()); 00110 } 00111 00112 StrideBase m_stride; 00113 }; 00114 00184 template<typename PlainObjectType, int Options, typename StrideType> class Ref 00185 : public RefBase<Ref<PlainObjectType, Options, StrideType> > 00186 { 00187 private: 00188 typedef internal::traits<Ref> Traits; 00189 template<typename Derived> 00190 EIGEN_DEVICE_FUNC inline Ref(const PlainObjectBase<Derived>& expr, 00191 typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0); 00192 public: 00193 00194 typedef RefBase<Ref> Base; 00195 EIGEN_DENSE_PUBLIC_INTERFACE(Ref) 00196 00197 00198 #ifndef EIGEN_PARSED_BY_DOXYGEN 00199 template<typename Derived> 00200 EIGEN_DEVICE_FUNC inline Ref(PlainObjectBase<Derived>& expr, 00201 typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0) 00202 { 00203 EIGEN_STATIC_ASSERT(bool(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH); 00204 Base::construct(expr.derived()); 00205 } 00206 template<typename Derived> 00207 EIGEN_DEVICE_FUNC inline Ref(const DenseBase<Derived>& expr, 00208 typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0) 00209 #else 00210 00211 template<typename Derived> 00212 inline Ref(DenseBase<Derived>& expr) 00213 #endif 00214 { 00215 EIGEN_STATIC_ASSERT(bool(internal::is_lvalue<Derived>::value), THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY); 00216 EIGEN_STATIC_ASSERT(bool(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH); 00217 EIGEN_STATIC_ASSERT(!Derived::IsPlainObjectBase,THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY); 00218 Base::construct(expr.const_cast_derived()); 00219 } 00220 00221 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Ref) 00222 00223 }; 00224 00225 // this is the const ref version 00226 template<typename TPlainObjectType, int Options, typename StrideType> class Ref<const TPlainObjectType, Options, StrideType> 00227 : public RefBase<Ref<const TPlainObjectType, Options, StrideType> > 00228 { 00229 typedef internal::traits<Ref> Traits; 00230 public: 00231 00232 typedef RefBase<Ref> Base; 00233 EIGEN_DENSE_PUBLIC_INTERFACE(Ref) 00234 00235 template<typename Derived> 00236 EIGEN_DEVICE_FUNC inline Ref(const DenseBase<Derived>& expr, 00237 typename internal::enable_if<bool(Traits::template match<Derived>::ScalarTypeMatch),Derived>::type* = 0) 00238 { 00239 // std::cout << match_helper<Derived>::HasDirectAccess << "," << match_helper<Derived>::OuterStrideMatch << "," << match_helper<Derived>::InnerStrideMatch << "\n"; 00240 // std::cout << int(StrideType::OuterStrideAtCompileTime) << " - " << int(Derived::OuterStrideAtCompileTime) << "\n"; 00241 // std::cout << int(StrideType::InnerStrideAtCompileTime) << " - " << int(Derived::InnerStrideAtCompileTime) << "\n"; 00242 construct(expr.derived(), typename Traits::template match<Derived>::type()); 00243 } 00244 00245 EIGEN_DEVICE_FUNC inline Ref(const Ref& other) : Base(other) { 00246 // copy constructor shall not copy the m_object, to avoid unnecessary malloc and copy 00247 } 00248 00249 template<typename OtherRef> 00250 EIGEN_DEVICE_FUNC inline Ref(const RefBase<OtherRef>& other) { 00251 construct(other.derived(), typename Traits::template match<OtherRef>::type()); 00252 } 00253 00254 protected: 00255 00256 template<typename Expression> 00257 EIGEN_DEVICE_FUNC void construct(const Expression& expr,internal::true_type) 00258 { 00259 Base::construct(expr); 00260 } 00261 00262 template<typename Expression> 00263 EIGEN_DEVICE_FUNC void construct(const Expression& expr, internal::false_type) 00264 { 00265 internal::call_assignment_no_alias(m_object,expr,internal::assign_op<Scalar>()); 00266 Base::construct(m_object); 00267 } 00268 00269 protected: 00270 TPlainObjectType m_object; 00271 }; 00272 00273 } // end namespace Eigen 00274 00275 #endif // EIGEN_REF_H