Assign.h
Go to the documentation of this file.
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 packet_traits<typename Derived1::Scalar> PacketTraits;
00443     enum {
00444       packetSize = PacketTraits::size,
00445       alignable = PacketTraits::AlignedOnScalar,
00446       dstAlignment = alignable ? Aligned : int(assign_traits<Derived1,Derived2>::DstIsAligned) ,
00447       srcAlignment = assign_traits<Derived1,Derived2>::JointAlignment
00448     };
00449     const Index packetAlignedMask = packetSize - 1;
00450     const Index innerSize = dst.innerSize();
00451     const Index outerSize = dst.outerSize();
00452     const Index alignedStep = alignable ? (packetSize - dst.outerStride() % packetSize) & packetAlignedMask : 0;
00453     Index alignedStart = ((!alignable) || assign_traits<Derived1,Derived2>::DstIsAligned) ? 0
00454                        : internal::first_aligned(&dst.coeffRef(0,0), innerSize);
00455 
00456     for(Index outer = 0; outer < outerSize; ++outer)
00457     {
00458       const Index alignedEnd = alignedStart + ((innerSize-alignedStart) & ~packetAlignedMask);
00459       // do the non-vectorizable part of the assignment
00460       for(Index inner = 0; inner<alignedStart ; ++inner)
00461         dst.copyCoeffByOuterInner(outer, inner, src);
00462 
00463       // do the vectorizable part of the assignment
00464       for(Index inner = alignedStart; inner<alignedEnd; inner+=packetSize)
00465         dst.template copyPacketByOuterInner<Derived2, dstAlignment, Unaligned>(outer, inner, src);
00466 
00467       // do the non-vectorizable part of the assignment
00468       for(Index inner = alignedEnd; inner<innerSize ; ++inner)
00469         dst.copyCoeffByOuterInner(outer, inner, src);
00470 
00471       alignedStart = std::min<Index>((alignedStart+alignedStep)%packetSize, innerSize);
00472     }
00473   }
00474 };
00475 
00476 } // end namespace internal
00477 
00478 /***************************************************************************
00479 * Part 4 : implementation of DenseBase methods
00480 ***************************************************************************/
00481 
00482 template<typename Derived>
00483 template<typename OtherDerived>
00484 EIGEN_STRONG_INLINE Derived& DenseBase<Derived>
00485   ::lazyAssign(const DenseBase<OtherDerived>& other)
00486 {
00487   enum{
00488     SameType = internal::is_same<typename Derived::Scalar,typename OtherDerived::Scalar>::value
00489   };
00490 
00491   EIGEN_STATIC_ASSERT_LVALUE(Derived)
00492   EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Derived,OtherDerived)
00493   EIGEN_STATIC_ASSERT(SameType,YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
00494 
00495 #ifdef EIGEN_DEBUG_ASSIGN
00496   internal::assign_traits<Derived, OtherDerived>::debug();
00497 #endif
00498   eigen_assert(rows() == other.rows() && cols() == other.cols());
00499   internal::assign_impl<Derived, OtherDerived, int(SameType) ? int(internal::assign_traits<Derived, OtherDerived>::Traversal)
00500                                                        : int(InvalidTraversal)>::run(derived(),other.derived());
00501 #ifndef EIGEN_NO_DEBUG
00502   checkTransposeAliasing(other.derived());
00503 #endif
00504   return derived();
00505 }
00506 
00507 namespace internal {
00508 
00509 template<typename Derived, typename OtherDerived,
00510          bool EvalBeforeAssigning = (int(internal::traits<OtherDerived>::Flags) & EvalBeforeAssigningBit) != 0,
00511          bool NeedToTranspose = ((int(Derived::RowsAtCompileTime) == 1 && int(OtherDerived::ColsAtCompileTime) == 1)
00512                               |   // FIXME | instead of || to please GCC 4.4.0 stupid warning "suggest parentheses around &&".
00513                                   // revert to || as soon as not needed anymore.
00514                                   (int(Derived::ColsAtCompileTime) == 1 && int(OtherDerived::RowsAtCompileTime) == 1))
00515                               && int(Derived::SizeAtCompileTime) != 1>
00516 struct assign_selector;
00517 
00518 template<typename Derived, typename OtherDerived>
00519 struct assign_selector<Derived,OtherDerived,false,false> {
00520   static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.derived()); }
00521   template<typename ActualDerived, typename ActualOtherDerived>
00522   static EIGEN_STRONG_INLINE Derived& evalTo(ActualDerived& dst, const ActualOtherDerived& other) { other.evalTo(dst); return dst; }
00523 };
00524 template<typename Derived, typename OtherDerived>
00525 struct assign_selector<Derived,OtherDerived,true,false> {
00526   static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.eval()); }
00527 };
00528 template<typename Derived, typename OtherDerived>
00529 struct assign_selector<Derived,OtherDerived,false,true> {
00530   static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose()); }
00531   template<typename ActualDerived, typename ActualOtherDerived>
00532   static EIGEN_STRONG_INLINE Derived& evalTo(ActualDerived& dst, const ActualOtherDerived& other) { Transpose<ActualDerived> dstTrans(dst); other.evalTo(dstTrans); return dst; }
00533 };
00534 template<typename Derived, typename OtherDerived>
00535 struct assign_selector<Derived,OtherDerived,true,true> {
00536   static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose().eval()); }
00537 };
00538 
00539 } // end namespace internal
00540 
00541 template<typename Derived>
00542 template<typename OtherDerived>
00543 EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator=(const DenseBase<OtherDerived>& other)
00544 {
00545   return internal::assign_selector<Derived,OtherDerived>::run(derived(), other.derived());
00546 }
00547 
00548 template<typename Derived>
00549 EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator=(const DenseBase& other)
00550 {
00551   return internal::assign_selector<Derived,Derived>::run(derived(), other.derived());
00552 }
00553 
00554 template<typename Derived>
00555 EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const MatrixBase& other)
00556 {
00557   return internal::assign_selector<Derived,Derived>::run(derived(), other.derived());
00558 }
00559 
00560 template<typename Derived>
00561 template <typename OtherDerived>
00562 EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const DenseBase<OtherDerived>& other)
00563 {
00564   return internal::assign_selector<Derived,OtherDerived>::run(derived(), other.derived());
00565 }
00566 
00567 template<typename Derived>
00568 template <typename OtherDerived>
00569 EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const EigenBase<OtherDerived>& other)
00570 {
00571   return internal::assign_selector<Derived,OtherDerived,false>::evalTo(derived(), other.derived());
00572 }
00573 
00574 template<typename Derived>
00575 template<typename OtherDerived>
00576 EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const ReturnByValue<OtherDerived>& other)
00577 {
00578   return internal::assign_selector<Derived,OtherDerived,false>::evalTo(derived(), other.derived());
00579 }
00580 
00581 } // end namespace Eigen
00582 
00583 #endif // EIGEN_ASSIGN_H


acado
Author(s): Milan Vukov, Rien Quirynen
autogenerated on Sat Jun 8 2019 19:36:43