Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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 Thu Nov 17 2022 22:01:27 by
1.7.2