Eigne Matrix Class Library
Dependents: Eigen_test Odometry_test AttitudeEstimation_usingTicker MPU9250_Quaternion_Binary_Serial ... more
Assign.h
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2007 Michael Olbrich <michael.olbrich@gmx.net> 00005 // Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com> 00006 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> 00007 // 00008 // This Source Code Form is subject to the terms of the Mozilla 00009 // Public License v. 2.0. If a copy of the MPL was not distributed 00010 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 00011 00012 #ifndef EIGEN_ASSIGN_H 00013 #define EIGEN_ASSIGN_H 00014 00015 namespace Eigen { 00016 00017 namespace internal { 00018 00019 /*************************************************************************** 00020 * Part 1 : the logic deciding a strategy for traversal and unrolling * 00021 ***************************************************************************/ 00022 00023 template <typename Derived, typename OtherDerived> 00024 struct assign_traits 00025 { 00026 public: 00027 enum { 00028 DstIsAligned = Derived::Flags & AlignedBit, 00029 DstHasDirectAccess = Derived::Flags & DirectAccessBit, 00030 SrcIsAligned = OtherDerived::Flags & AlignedBit, 00031 JointAlignment = bool(DstIsAligned) && bool(SrcIsAligned) ? Aligned : Unaligned 00032 }; 00033 00034 private: 00035 enum { 00036 InnerSize = int(Derived::IsVectorAtCompileTime) ? int(Derived::SizeAtCompileTime) 00037 : int(Derived::Flags)&RowMajorBit ? int(Derived::ColsAtCompileTime) 00038 : int(Derived::RowsAtCompileTime), 00039 InnerMaxSize = int(Derived::IsVectorAtCompileTime) ? int(Derived::MaxSizeAtCompileTime) 00040 : int(Derived::Flags)&RowMajorBit ? int(Derived::MaxColsAtCompileTime) 00041 : int(Derived::MaxRowsAtCompileTime), 00042 MaxSizeAtCompileTime = Derived::SizeAtCompileTime, 00043 PacketSize = packet_traits<typename Derived::Scalar>::size 00044 }; 00045 00046 enum { 00047 StorageOrdersAgree = (int(Derived::IsRowMajor) == int(OtherDerived::IsRowMajor)), 00048 MightVectorize = StorageOrdersAgree 00049 && (int(Derived::Flags) & int(OtherDerived::Flags) & ActualPacketAccessBit), 00050 MayInnerVectorize = MightVectorize && int(InnerSize)!=Dynamic && int(InnerSize)%int(PacketSize)==0 00051 && int(DstIsAligned) && int(SrcIsAligned), 00052 MayLinearize = StorageOrdersAgree && (int(Derived::Flags) & int(OtherDerived::Flags) & LinearAccessBit), 00053 MayLinearVectorize = MightVectorize && MayLinearize && DstHasDirectAccess 00054 && (DstIsAligned || MaxSizeAtCompileTime == Dynamic), 00055 /* If the destination isn't aligned, we have to do runtime checks and we don't unroll, 00056 so it's only good for large enough sizes. */ 00057 MaySliceVectorize = MightVectorize && DstHasDirectAccess 00058 && (int(InnerMaxSize)==Dynamic || int(InnerMaxSize)>=3*PacketSize) 00059 /* slice vectorization can be slow, so we only want it if the slices are big, which is 00060 indicated by InnerMaxSize rather than InnerSize, think of the case of a dynamic block 00061 in a fixed-size matrix */ 00062 }; 00063 00064 public: 00065 enum { 00066 Traversal = int(MayInnerVectorize) ? int(InnerVectorizedTraversal) 00067 : int(MayLinearVectorize) ? int(LinearVectorizedTraversal) 00068 : int(MaySliceVectorize) ? int(SliceVectorizedTraversal) 00069 : int(MayLinearize) ? int(LinearTraversal) 00070 : int(DefaultTraversal), 00071 Vectorized = int(Traversal) == InnerVectorizedTraversal 00072 || int(Traversal) == LinearVectorizedTraversal 00073 || int(Traversal) == SliceVectorizedTraversal 00074 }; 00075 00076 private: 00077 enum { 00078 UnrollingLimit = EIGEN_UNROLLING_LIMIT * (Vectorized ? int(PacketSize) : 1), 00079 MayUnrollCompletely = int(Derived::SizeAtCompileTime) != Dynamic 00080 && int(OtherDerived::CoeffReadCost) != Dynamic 00081 && int(Derived::SizeAtCompileTime) * int(OtherDerived::CoeffReadCost) <= int(UnrollingLimit), 00082 MayUnrollInner = int(InnerSize) != Dynamic 00083 && int(OtherDerived::CoeffReadCost) != Dynamic 00084 && int(InnerSize) * int(OtherDerived::CoeffReadCost) <= int(UnrollingLimit) 00085 }; 00086 00087 public: 00088 enum { 00089 Unrolling = (int(Traversal) == int(InnerVectorizedTraversal) || int(Traversal) == int(DefaultTraversal)) 00090 ? ( 00091 int(MayUnrollCompletely) ? int(CompleteUnrolling) 00092 : int(MayUnrollInner) ? int(InnerUnrolling) 00093 : int(NoUnrolling) 00094 ) 00095 : int(Traversal) == int(LinearVectorizedTraversal) 00096 ? ( bool(MayUnrollCompletely) && bool(DstIsAligned) ? int(CompleteUnrolling) : int(NoUnrolling) ) 00097 : int(Traversal) == int(LinearTraversal) 00098 ? ( bool(MayUnrollCompletely) ? int(CompleteUnrolling) : int(NoUnrolling) ) 00099 : int(NoUnrolling) 00100 }; 00101 00102 #ifdef EIGEN_DEBUG_ASSIGN 00103 static void debug() 00104 { 00105 EIGEN_DEBUG_VAR(DstIsAligned) 00106 EIGEN_DEBUG_VAR(SrcIsAligned) 00107 EIGEN_DEBUG_VAR(JointAlignment) 00108 EIGEN_DEBUG_VAR(InnerSize) 00109 EIGEN_DEBUG_VAR(InnerMaxSize) 00110 EIGEN_DEBUG_VAR(PacketSize) 00111 EIGEN_DEBUG_VAR(StorageOrdersAgree) 00112 EIGEN_DEBUG_VAR(MightVectorize) 00113 EIGEN_DEBUG_VAR(MayLinearize) 00114 EIGEN_DEBUG_VAR(MayInnerVectorize) 00115 EIGEN_DEBUG_VAR(MayLinearVectorize) 00116 EIGEN_DEBUG_VAR(MaySliceVectorize) 00117 EIGEN_DEBUG_VAR(Traversal) 00118 EIGEN_DEBUG_VAR(UnrollingLimit) 00119 EIGEN_DEBUG_VAR(MayUnrollCompletely) 00120 EIGEN_DEBUG_VAR(MayUnrollInner) 00121 EIGEN_DEBUG_VAR(Unrolling) 00122 } 00123 #endif 00124 }; 00125 00126 /*************************************************************************** 00127 * Part 2 : meta-unrollers 00128 ***************************************************************************/ 00129 00130 /************************ 00131 *** Default traversal *** 00132 ************************/ 00133 00134 template<typename Derived1, typename Derived2, int Index, int Stop> 00135 struct assign_DefaultTraversal_CompleteUnrolling 00136 { 00137 enum { 00138 outer = Index / Derived1::InnerSizeAtCompileTime, 00139 inner = Index % Derived1::InnerSizeAtCompileTime 00140 }; 00141 00142 static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) 00143 { 00144 dst.copyCoeffByOuterInner(outer, inner, src); 00145 assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src); 00146 } 00147 }; 00148 00149 template<typename Derived1, typename Derived2, int Stop> 00150 struct assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, Stop, Stop> 00151 { 00152 static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &) {} 00153 }; 00154 00155 template<typename Derived1, typename Derived2, int Index, int Stop> 00156 struct assign_DefaultTraversal_InnerUnrolling 00157 { 00158 static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src, typename Derived1::Index outer) 00159 { 00160 dst.copyCoeffByOuterInner(outer, Index, src); 00161 assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src, outer); 00162 } 00163 }; 00164 00165 template<typename Derived1, typename Derived2, int Stop> 00166 struct assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, Stop, Stop> 00167 { 00168 static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &, typename Derived1::Index) {} 00169 }; 00170 00171 /*********************** 00172 *** Linear traversal *** 00173 ***********************/ 00174 00175 template<typename Derived1, typename Derived2, int Index, int Stop> 00176 struct assign_LinearTraversal_CompleteUnrolling 00177 { 00178 static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) 00179 { 00180 dst.copyCoeff(Index, src); 00181 assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src); 00182 } 00183 }; 00184 00185 template<typename Derived1, typename Derived2, int Stop> 00186 struct assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, Stop, Stop> 00187 { 00188 static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &) {} 00189 }; 00190 00191 /************************** 00192 *** Inner vectorization *** 00193 **************************/ 00194 00195 template<typename Derived1, typename Derived2, int Index, int Stop> 00196 struct assign_innervec_CompleteUnrolling 00197 { 00198 enum { 00199 outer = Index / Derived1::InnerSizeAtCompileTime, 00200 inner = Index % Derived1::InnerSizeAtCompileTime, 00201 JointAlignment = assign_traits<Derived1,Derived2>::JointAlignment 00202 }; 00203 00204 static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) 00205 { 00206 dst.template copyPacketByOuterInner<Derived2, Aligned, JointAlignment>(outer, inner, src); 00207 assign_innervec_CompleteUnrolling<Derived1, Derived2, 00208 Index+packet_traits<typename Derived1::Scalar>::size, Stop>::run(dst, src); 00209 } 00210 }; 00211 00212 template<typename Derived1, typename Derived2, int Stop> 00213 struct assign_innervec_CompleteUnrolling<Derived1, Derived2, Stop, Stop> 00214 { 00215 static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &) {} 00216 }; 00217 00218 template<typename Derived1, typename Derived2, int Index, int Stop> 00219 struct assign_innervec_InnerUnrolling 00220 { 00221 static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src, typename Derived1::Index outer) 00222 { 00223 dst.template copyPacketByOuterInner<Derived2, Aligned, Aligned>(outer, Index, src); 00224 assign_innervec_InnerUnrolling<Derived1, Derived2, 00225 Index+packet_traits<typename Derived1::Scalar>::size, Stop>::run(dst, src, outer); 00226 } 00227 }; 00228 00229 template<typename Derived1, typename Derived2, int Stop> 00230 struct assign_innervec_InnerUnrolling<Derived1, Derived2, Stop, Stop> 00231 { 00232 static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &, typename Derived1::Index) {} 00233 }; 00234 00235 /*************************************************************************** 00236 * Part 3 : implementation of all cases 00237 ***************************************************************************/ 00238 00239 template<typename Derived1, typename Derived2, 00240 int Traversal = assign_traits<Derived1, Derived2>::Traversal, 00241 int Unrolling = assign_traits<Derived1, Derived2>::Unrolling, 00242 int Version = Specialized> 00243 struct assign_impl; 00244 00245 /************************ 00246 *** Default traversal *** 00247 ************************/ 00248 00249 template<typename Derived1, typename Derived2, int Unrolling, int Version> 00250 struct assign_impl<Derived1, Derived2, InvalidTraversal, Unrolling, Version> 00251 { 00252 static inline void run(Derived1 &, const Derived2 &) { } 00253 }; 00254 00255 template<typename Derived1, typename Derived2, int Version> 00256 struct assign_impl<Derived1, Derived2, DefaultTraversal, NoUnrolling, Version> 00257 { 00258 typedef typename Derived1::Index Index; 00259 static inline void run(Derived1 &dst, const Derived2 &src) 00260 { 00261 const Index innerSize = dst.innerSize(); 00262 const Index outerSize = dst.outerSize(); 00263 for(Index outer = 0; outer < outerSize; ++outer) 00264 for(Index inner = 0; inner < innerSize; ++inner) 00265 dst.copyCoeffByOuterInner(outer, inner, src); 00266 } 00267 }; 00268 00269 template<typename Derived1, typename Derived2, int Version> 00270 struct assign_impl<Derived1, Derived2, DefaultTraversal, CompleteUnrolling, Version> 00271 { 00272 static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) 00273 { 00274 assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime> 00275 ::run(dst, src); 00276 } 00277 }; 00278 00279 template<typename Derived1, typename Derived2, int Version> 00280 struct assign_impl<Derived1, Derived2, DefaultTraversal, InnerUnrolling, Version> 00281 { 00282 typedef typename Derived1::Index Index; 00283 static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) 00284 { 00285 const Index outerSize = dst.outerSize(); 00286 for(Index outer = 0; outer < outerSize; ++outer) 00287 assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, 0, Derived1::InnerSizeAtCompileTime> 00288 ::run(dst, src, outer); 00289 } 00290 }; 00291 00292 /*********************** 00293 *** Linear traversal *** 00294 ***********************/ 00295 00296 template<typename Derived1, typename Derived2, int Version> 00297 struct assign_impl<Derived1, Derived2, LinearTraversal, NoUnrolling, Version> 00298 { 00299 typedef typename Derived1::Index Index; 00300 static inline void run(Derived1 &dst, const Derived2 &src) 00301 { 00302 const Index size = dst.size(); 00303 for(Index i = 0; i < size; ++i) 00304 dst.copyCoeff(i, src); 00305 } 00306 }; 00307 00308 template<typename Derived1, typename Derived2, int Version> 00309 struct assign_impl<Derived1, Derived2, LinearTraversal, CompleteUnrolling, Version> 00310 { 00311 static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) 00312 { 00313 assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime> 00314 ::run(dst, src); 00315 } 00316 }; 00317 00318 /************************** 00319 *** Inner vectorization *** 00320 **************************/ 00321 00322 template<typename Derived1, typename Derived2, int Version> 00323 struct assign_impl<Derived1, Derived2, InnerVectorizedTraversal, NoUnrolling, Version> 00324 { 00325 typedef typename Derived1::Index Index; 00326 static inline void run(Derived1 &dst, const Derived2 &src) 00327 { 00328 const Index innerSize = dst.innerSize(); 00329 const Index outerSize = dst.outerSize(); 00330 const Index packetSize = packet_traits<typename Derived1::Scalar>::size; 00331 for(Index outer = 0; outer < outerSize; ++outer) 00332 for(Index inner = 0; inner < innerSize; inner+=packetSize) 00333 dst.template copyPacketByOuterInner<Derived2, Aligned, Aligned>(outer, inner, src); 00334 } 00335 }; 00336 00337 template<typename Derived1, typename Derived2, int Version> 00338 struct assign_impl<Derived1, Derived2, InnerVectorizedTraversal, CompleteUnrolling, Version> 00339 { 00340 static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) 00341 { 00342 assign_innervec_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime> 00343 ::run(dst, src); 00344 } 00345 }; 00346 00347 template<typename Derived1, typename Derived2, int Version> 00348 struct assign_impl<Derived1, Derived2, InnerVectorizedTraversal, InnerUnrolling, Version> 00349 { 00350 typedef typename Derived1::Index Index; 00351 static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) 00352 { 00353 const Index outerSize = dst.outerSize(); 00354 for(Index outer = 0; outer < outerSize; ++outer) 00355 assign_innervec_InnerUnrolling<Derived1, Derived2, 0, Derived1::InnerSizeAtCompileTime> 00356 ::run(dst, src, outer); 00357 } 00358 }; 00359 00360 /*************************** 00361 *** Linear vectorization *** 00362 ***************************/ 00363 00364 template <bool IsAligned = false> 00365 struct unaligned_assign_impl 00366 { 00367 template <typename Derived, typename OtherDerived> 00368 static EIGEN_STRONG_INLINE void run(const Derived&, OtherDerived&, typename Derived::Index, typename Derived::Index) {} 00369 }; 00370 00371 template <> 00372 struct unaligned_assign_impl<false> 00373 { 00374 // MSVC must not inline this functions. If it does, it fails to optimize the 00375 // packet access path. 00376 #ifdef _MSC_VER 00377 template <typename Derived, typename OtherDerived> 00378 static EIGEN_DONT_INLINE void run(const Derived& src, OtherDerived& dst, typename Derived::Index start, typename Derived::Index end) 00379 #else 00380 template <typename Derived, typename OtherDerived> 00381 static EIGEN_STRONG_INLINE void run(const Derived& src, OtherDerived& dst, typename Derived::Index start, typename Derived::Index end) 00382 #endif 00383 { 00384 for (typename Derived::Index index = start; index < end; ++index) 00385 dst.copyCoeff(index, src); 00386 } 00387 }; 00388 00389 template<typename Derived1, typename Derived2, int Version> 00390 struct assign_impl<Derived1, Derived2, LinearVectorizedTraversal, NoUnrolling, Version> 00391 { 00392 typedef typename Derived1::Index Index; 00393 static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) 00394 { 00395 const Index size = dst.size(); 00396 typedef packet_traits<typename Derived1::Scalar> PacketTraits; 00397 enum { 00398 packetSize = PacketTraits::size, 00399 dstAlignment = PacketTraits::AlignedOnScalar ? Aligned : int(assign_traits<Derived1,Derived2>::DstIsAligned) , 00400 srcAlignment = assign_traits<Derived1,Derived2>::JointAlignment 00401 }; 00402 const Index alignedStart = assign_traits<Derived1,Derived2>::DstIsAligned ? 0 00403 : internal::first_aligned(&dst.coeffRef(0), size); 00404 const Index alignedEnd = alignedStart + ((size-alignedStart)/packetSize)*packetSize; 00405 00406 unaligned_assign_impl<assign_traits<Derived1,Derived2>::DstIsAligned!=0>::run(src,dst,0,alignedStart); 00407 00408 for(Index index = alignedStart; index < alignedEnd; index += packetSize) 00409 { 00410 dst.template copyPacket<Derived2, dstAlignment, srcAlignment>(index, src); 00411 } 00412 00413 unaligned_assign_impl<>::run(src,dst,alignedEnd,size); 00414 } 00415 }; 00416 00417 template<typename Derived1, typename Derived2, int Version> 00418 struct assign_impl<Derived1, Derived2, LinearVectorizedTraversal, CompleteUnrolling, Version> 00419 { 00420 typedef typename Derived1::Index Index; 00421 static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src) 00422 { 00423 enum { size = Derived1::SizeAtCompileTime, 00424 packetSize = packet_traits<typename Derived1::Scalar>::size, 00425 alignedSize = (size/packetSize)*packetSize }; 00426 00427 assign_innervec_CompleteUnrolling<Derived1, Derived2, 0, alignedSize>::run(dst, src); 00428 assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, alignedSize, size>::run(dst, src); 00429 } 00430 }; 00431 00432 /************************** 00433 *** Slice vectorization *** 00434 ***************************/ 00435 00436 template<typename Derived1, typename Derived2, int Version> 00437 struct assign_impl<Derived1, Derived2, SliceVectorizedTraversal, NoUnrolling, Version> 00438 { 00439 typedef typename Derived1::Index Index; 00440 static inline void run(Derived1 &dst, const Derived2 &src) 00441 { 00442 typedef typename Derived1::Scalar Scalar; 00443 typedef packet_traits<Scalar> PacketTraits; 00444 enum { 00445 packetSize = PacketTraits::size, 00446 alignable = PacketTraits::AlignedOnScalar, 00447 dstIsAligned = assign_traits<Derived1,Derived2>::DstIsAligned, 00448 dstAlignment = alignable ? Aligned : int(dstIsAligned), 00449 srcAlignment = assign_traits<Derived1,Derived2>::JointAlignment 00450 }; 00451 const Scalar *dst_ptr = &dst.coeffRef(0,0); 00452 if((!bool(dstIsAligned)) && (size_t(dst_ptr) % sizeof(Scalar))>0) 00453 { 00454 // the pointer is not aligend-on scalar, so alignment is not possible 00455 return assign_impl<Derived1,Derived2,DefaultTraversal,NoUnrolling>::run(dst, src); 00456 } 00457 const Index packetAlignedMask = packetSize - 1; 00458 const Index innerSize = dst.innerSize(); 00459 const Index outerSize = dst.outerSize(); 00460 const Index alignedStep = alignable ? (packetSize - dst.outerStride() % packetSize) & packetAlignedMask : 0; 00461 Index alignedStart = ((!alignable) || bool(dstIsAligned)) ? 0 : internal::first_aligned(dst_ptr, innerSize); 00462 00463 for(Index outer = 0; outer < outerSize; ++outer) 00464 { 00465 const Index alignedEnd = alignedStart + ((innerSize-alignedStart) & ~packetAlignedMask); 00466 // do the non-vectorizable part of the assignment 00467 for(Index inner = 0; inner<alignedStart ; ++inner) 00468 dst.copyCoeffByOuterInner(outer, inner, src); 00469 00470 // do the vectorizable part of the assignment 00471 for(Index inner = alignedStart; inner<alignedEnd; inner+=packetSize) 00472 dst.template copyPacketByOuterInner<Derived2, dstAlignment, Unaligned>(outer, inner, src); 00473 00474 // do the non-vectorizable part of the assignment 00475 for(Index inner = alignedEnd; inner<innerSize ; ++inner) 00476 dst.copyCoeffByOuterInner(outer, inner, src); 00477 00478 alignedStart = std::min<Index>((alignedStart+alignedStep)%packetSize, innerSize); 00479 } 00480 } 00481 }; 00482 00483 } // end namespace internal 00484 00485 /*************************************************************************** 00486 * Part 4 : implementation of DenseBase methods 00487 ***************************************************************************/ 00488 00489 template<typename Derived> 00490 template<typename OtherDerived> 00491 EIGEN_STRONG_INLINE Derived& DenseBase<Derived> 00492 ::lazyAssign(const DenseBase<OtherDerived>& other) 00493 { 00494 enum{ 00495 SameType = internal::is_same<typename Derived::Scalar,typename OtherDerived::Scalar>::value 00496 }; 00497 00498 EIGEN_STATIC_ASSERT_LVALUE(Derived) 00499 EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Derived,OtherDerived) 00500 EIGEN_STATIC_ASSERT(SameType,YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) 00501 00502 #ifdef EIGEN_DEBUG_ASSIGN 00503 internal::assign_traits<Derived, OtherDerived>::debug(); 00504 #endif 00505 eigen_assert(rows() == other.rows() && cols() == other.cols()); 00506 internal::assign_impl<Derived, OtherDerived, int(SameType) ? int(internal::assign_traits<Derived, OtherDerived>::Traversal) 00507 : int(InvalidTraversal)>::run(derived(),other.derived()); 00508 #ifndef EIGEN_NO_DEBUG 00509 checkTransposeAliasing(other.derived()); 00510 #endif 00511 return derived(); 00512 } 00513 00514 namespace internal { 00515 00516 template<typename Derived, typename OtherDerived, 00517 bool EvalBeforeAssigning = (int(internal::traits<OtherDerived>::Flags) & EvalBeforeAssigningBit) != 0, 00518 bool NeedToTranspose = ((int(Derived::RowsAtCompileTime) == 1 && int(OtherDerived::ColsAtCompileTime) == 1) 00519 | // FIXME | instead of || to please GCC 4.4.0 stupid warning "suggest parentheses around &&". 00520 // revert to || as soon as not needed anymore. 00521 (int(Derived::ColsAtCompileTime) == 1 && int(OtherDerived::RowsAtCompileTime) == 1)) 00522 && int(Derived::SizeAtCompileTime) != 1> 00523 struct assign_selector; 00524 00525 template<typename Derived, typename OtherDerived> 00526 struct assign_selector<Derived,OtherDerived,false,false> { 00527 static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.derived()); } 00528 template<typename ActualDerived, typename ActualOtherDerived> 00529 static EIGEN_STRONG_INLINE Derived& evalTo(ActualDerived& dst, const ActualOtherDerived& other) { other.evalTo(dst); return dst; } 00530 }; 00531 template<typename Derived, typename OtherDerived> 00532 struct assign_selector<Derived,OtherDerived,true,false> { 00533 static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.eval()); } 00534 }; 00535 template<typename Derived, typename OtherDerived> 00536 struct assign_selector<Derived,OtherDerived,false,true> { 00537 static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose()); } 00538 template<typename ActualDerived, typename ActualOtherDerived> 00539 static EIGEN_STRONG_INLINE Derived& evalTo(ActualDerived& dst, const ActualOtherDerived& other) { Transpose<ActualDerived> dstTrans(dst); other.evalTo(dstTrans); return dst; } 00540 }; 00541 template<typename Derived, typename OtherDerived> 00542 struct assign_selector<Derived,OtherDerived,true,true> { 00543 static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose().eval()); } 00544 }; 00545 00546 } // end namespace internal 00547 00548 template<typename Derived> 00549 template<typename OtherDerived> 00550 EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator=(const DenseBase<OtherDerived>& other) 00551 { 00552 return internal::assign_selector<Derived,OtherDerived>::run(derived(), other.derived()); 00553 } 00554 00555 template<typename Derived> 00556 EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator=(const DenseBase& other) 00557 { 00558 return internal::assign_selector<Derived,Derived>::run(derived(), other.derived()); 00559 } 00560 00561 template<typename Derived> 00562 EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const MatrixBase& other) 00563 { 00564 return internal::assign_selector<Derived,Derived>::run(derived(), other.derived()); 00565 } 00566 00567 template<typename Derived> 00568 template <typename OtherDerived> 00569 EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const DenseBase<OtherDerived>& other) 00570 { 00571 return internal::assign_selector<Derived,OtherDerived>::run(derived(), other.derived()); 00572 } 00573 00574 template<typename Derived> 00575 template <typename OtherDerived> 00576 EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const EigenBase<OtherDerived>& other) 00577 { 00578 return internal::assign_selector<Derived,OtherDerived,false>::evalTo(derived(), other.derived()); 00579 } 00580 00581 template<typename Derived> 00582 template<typename OtherDerived> 00583 EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const ReturnByValue<OtherDerived>& other) 00584 { 00585 return internal::assign_selector<Derived,OtherDerived,false>::evalTo(derived(), other.derived()); 00586 } 00587 00588 } // end namespace Eigen 00589 00590 #endif // EIGEN_ASSIGN_H
Generated on Tue Jul 12 2022 17:46:49 by 1.7.2