1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is part of Eigen, a lightweight C++ template library
2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// for linear algebra.
3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2007 Michael Olbrich <michael.olbrich@gmx.net>
5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This Source Code Form is subject to the terms of the Mozilla
9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Public License v. 2.0. If a copy of the MPL was not distributed
10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef EIGEN_ASSIGN_H
13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define EIGEN_ASSIGN_H
14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace Eigen {
16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace internal {
18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/***************************************************************************
20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath* Part 1 : the logic deciding a strategy for traversal and unrolling       *
21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath***************************************************************************/
22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate <typename Derived, typename OtherDerived>
24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct assign_traits
25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathpublic:
27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum {
28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    DstIsAligned = Derived::Flags & AlignedBit,
29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    DstHasDirectAccess = Derived::Flags & DirectAccessBit,
30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    SrcIsAligned = OtherDerived::Flags & AlignedBit,
31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    JointAlignment = bool(DstIsAligned) && bool(SrcIsAligned) ? Aligned : Unaligned
32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  };
33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
34c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathprivate:
35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum {
36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    InnerSize = int(Derived::IsVectorAtCompileTime) ? int(Derived::SizeAtCompileTime)
37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath              : int(Derived::Flags)&RowMajorBit ? int(Derived::ColsAtCompileTime)
38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath              : int(Derived::RowsAtCompileTime),
39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    InnerMaxSize = int(Derived::IsVectorAtCompileTime) ? int(Derived::MaxSizeAtCompileTime)
40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath              : int(Derived::Flags)&RowMajorBit ? int(Derived::MaxColsAtCompileTime)
41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath              : int(Derived::MaxRowsAtCompileTime),
42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    MaxSizeAtCompileTime = Derived::SizeAtCompileTime,
43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    PacketSize = packet_traits<typename Derived::Scalar>::size
44c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  };
45c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum {
47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    StorageOrdersAgree = (int(Derived::IsRowMajor) == int(OtherDerived::IsRowMajor)),
48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    MightVectorize = StorageOrdersAgree
49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                  && (int(Derived::Flags) & int(OtherDerived::Flags) & ActualPacketAccessBit),
50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    MayInnerVectorize  = MightVectorize && int(InnerSize)!=Dynamic && int(InnerSize)%int(PacketSize)==0
51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                       && int(DstIsAligned) && int(SrcIsAligned),
52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    MayLinearize = StorageOrdersAgree && (int(Derived::Flags) & int(OtherDerived::Flags) & LinearAccessBit),
53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    MayLinearVectorize = MightVectorize && MayLinearize && DstHasDirectAccess
54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                       && (DstIsAligned || MaxSizeAtCompileTime == Dynamic),
55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      /* If the destination isn't aligned, we have to do runtime checks and we don't unroll,
56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath         so it's only good for large enough sizes. */
57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    MaySliceVectorize  = MightVectorize && DstHasDirectAccess
58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                       && (int(InnerMaxSize)==Dynamic || int(InnerMaxSize)>=3*PacketSize)
59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      /* slice vectorization can be slow, so we only want it if the slices are big, which is
60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath         indicated by InnerMaxSize rather than InnerSize, think of the case of a dynamic block
61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath         in a fixed-size matrix */
62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  };
63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathpublic:
65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum {
66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Traversal = int(MayInnerVectorize)  ? int(InnerVectorizedTraversal)
67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath              : int(MayLinearVectorize) ? int(LinearVectorizedTraversal)
68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath              : int(MaySliceVectorize)  ? int(SliceVectorizedTraversal)
69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath              : int(MayLinearize)       ? int(LinearTraversal)
70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                                        : int(DefaultTraversal),
71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Vectorized = int(Traversal) == InnerVectorizedTraversal
72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath              || int(Traversal) == LinearVectorizedTraversal
73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath              || int(Traversal) == SliceVectorizedTraversal
74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  };
75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathprivate:
77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum {
78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    UnrollingLimit      = EIGEN_UNROLLING_LIMIT * (Vectorized ? int(PacketSize) : 1),
79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    MayUnrollCompletely = int(Derived::SizeAtCompileTime) != Dynamic
80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                       && int(OtherDerived::CoeffReadCost) != Dynamic
81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                       && int(Derived::SizeAtCompileTime) * int(OtherDerived::CoeffReadCost) <= int(UnrollingLimit),
82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    MayUnrollInner      = int(InnerSize) != Dynamic
83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                       && int(OtherDerived::CoeffReadCost) != Dynamic
84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                       && int(InnerSize) * int(OtherDerived::CoeffReadCost) <= int(UnrollingLimit)
85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  };
86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathpublic:
88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum {
89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Unrolling = (int(Traversal) == int(InnerVectorizedTraversal) || int(Traversal) == int(DefaultTraversal))
90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                ? (
91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                    int(MayUnrollCompletely) ? int(CompleteUnrolling)
92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                  : int(MayUnrollInner)      ? int(InnerUnrolling)
93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                                             : int(NoUnrolling)
94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                  )
95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath              : int(Traversal) == int(LinearVectorizedTraversal)
96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                ? ( bool(MayUnrollCompletely) && bool(DstIsAligned) ? int(CompleteUnrolling) : int(NoUnrolling) )
97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath              : int(Traversal) == int(LinearTraversal)
98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                ? ( bool(MayUnrollCompletely) ? int(CompleteUnrolling) : int(NoUnrolling) )
99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath              : int(NoUnrolling)
100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  };
101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifdef EIGEN_DEBUG_ASSIGN
103c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static void debug()
104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_DEBUG_VAR(DstIsAligned)
106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_DEBUG_VAR(SrcIsAligned)
107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_DEBUG_VAR(JointAlignment)
108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_DEBUG_VAR(InnerSize)
109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_DEBUG_VAR(InnerMaxSize)
110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_DEBUG_VAR(PacketSize)
111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_DEBUG_VAR(StorageOrdersAgree)
112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_DEBUG_VAR(MightVectorize)
113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_DEBUG_VAR(MayLinearize)
114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_DEBUG_VAR(MayInnerVectorize)
115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_DEBUG_VAR(MayLinearVectorize)
116c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_DEBUG_VAR(MaySliceVectorize)
117c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_DEBUG_VAR(Traversal)
118c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_DEBUG_VAR(UnrollingLimit)
119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_DEBUG_VAR(MayUnrollCompletely)
120c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_DEBUG_VAR(MayUnrollInner)
121c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_DEBUG_VAR(Unrolling)
122c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
123c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif
124c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
125c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
126c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/***************************************************************************
127c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath* Part 2 : meta-unrollers
128c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath***************************************************************************/
129c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
130c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/************************
131c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath*** Default traversal ***
132c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath************************/
133c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
134c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived1, typename Derived2, int Index, int Stop>
135c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct assign_DefaultTraversal_CompleteUnrolling
136c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
137c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum {
138c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    outer = Index / Derived1::InnerSizeAtCompileTime,
139c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inner = Index % Derived1::InnerSizeAtCompileTime
140c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  };
141c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
142c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
143c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
144c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    dst.copyCoeffByOuterInner(outer, inner, src);
145c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src);
146c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
147c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
148c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
149c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived1, typename Derived2, int Stop>
150c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, Stop, Stop>
151c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
152c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &) {}
153c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
154c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
155c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived1, typename Derived2, int Index, int Stop>
156c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct assign_DefaultTraversal_InnerUnrolling
157c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
1587faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src, typename Derived1::Index outer)
159c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
160c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    dst.copyCoeffByOuterInner(outer, Index, src);
161c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src, outer);
162c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
163c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
164c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
165c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived1, typename Derived2, int Stop>
166c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, Stop, Stop>
167c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
1687faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &, typename Derived1::Index) {}
169c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
170c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
171c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/***********************
172c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath*** Linear traversal ***
173c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath***********************/
174c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
175c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived1, typename Derived2, int Index, int Stop>
176c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct assign_LinearTraversal_CompleteUnrolling
177c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
178c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
179c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
180c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    dst.copyCoeff(Index, src);
181c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src);
182c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
183c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
184c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
185c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived1, typename Derived2, int Stop>
186c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, Stop, Stop>
187c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
188c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &) {}
189c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
190c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
191c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/**************************
192c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath*** Inner vectorization ***
193c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath**************************/
194c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
195c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived1, typename Derived2, int Index, int Stop>
196c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct assign_innervec_CompleteUnrolling
197c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
198c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum {
199c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    outer = Index / Derived1::InnerSizeAtCompileTime,
200c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inner = Index % Derived1::InnerSizeAtCompileTime,
201c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    JointAlignment = assign_traits<Derived1,Derived2>::JointAlignment
202c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  };
203c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
204c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
205c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
206c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    dst.template copyPacketByOuterInner<Derived2, Aligned, JointAlignment>(outer, inner, src);
207c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    assign_innervec_CompleteUnrolling<Derived1, Derived2,
208c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      Index+packet_traits<typename Derived1::Scalar>::size, Stop>::run(dst, src);
209c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
210c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
211c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
212c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived1, typename Derived2, int Stop>
213c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct assign_innervec_CompleteUnrolling<Derived1, Derived2, Stop, Stop>
214c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
215c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &) {}
216c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
217c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
218c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived1, typename Derived2, int Index, int Stop>
219c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct assign_innervec_InnerUnrolling
220c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
2217faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src, typename Derived1::Index outer)
222c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
223c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    dst.template copyPacketByOuterInner<Derived2, Aligned, Aligned>(outer, Index, src);
224c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    assign_innervec_InnerUnrolling<Derived1, Derived2,
225c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      Index+packet_traits<typename Derived1::Scalar>::size, Stop>::run(dst, src, outer);
226c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
227c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
228c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
229c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived1, typename Derived2, int Stop>
230c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct assign_innervec_InnerUnrolling<Derived1, Derived2, Stop, Stop>
231c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
2327faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  static EIGEN_STRONG_INLINE void run(Derived1 &, const Derived2 &, typename Derived1::Index) {}
233c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
234c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
235c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/***************************************************************************
236c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath* Part 3 : implementation of all cases
237c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath***************************************************************************/
238c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
239c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived1, typename Derived2,
240c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath         int Traversal = assign_traits<Derived1, Derived2>::Traversal,
241c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath         int Unrolling = assign_traits<Derived1, Derived2>::Unrolling,
242c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath         int Version = Specialized>
243c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct assign_impl;
244c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
245c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/************************
246c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath*** Default traversal ***
247c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath************************/
248c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
249c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived1, typename Derived2, int Unrolling, int Version>
250c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct assign_impl<Derived1, Derived2, InvalidTraversal, Unrolling, Version>
251c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
252c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline void run(Derived1 &, const Derived2 &) { }
253c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
254c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
255c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived1, typename Derived2, int Version>
256c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct assign_impl<Derived1, Derived2, DefaultTraversal, NoUnrolling, Version>
257c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
258c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename Derived1::Index Index;
259c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline void run(Derived1 &dst, const Derived2 &src)
260c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
261c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const Index innerSize = dst.innerSize();
262c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const Index outerSize = dst.outerSize();
263c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for(Index outer = 0; outer < outerSize; ++outer)
264c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      for(Index inner = 0; inner < innerSize; ++inner)
265c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        dst.copyCoeffByOuterInner(outer, inner, src);
266c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
267c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
268c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
269c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived1, typename Derived2, int Version>
270c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct assign_impl<Derived1, Derived2, DefaultTraversal, CompleteUnrolling, Version>
271c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
272c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
273c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
274c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
275c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      ::run(dst, src);
276c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
277c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
278c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
279c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived1, typename Derived2, int Version>
280c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct assign_impl<Derived1, Derived2, DefaultTraversal, InnerUnrolling, Version>
281c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
282c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename Derived1::Index Index;
283c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
284c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
285c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const Index outerSize = dst.outerSize();
286c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for(Index outer = 0; outer < outerSize; ++outer)
287c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, 0, Derived1::InnerSizeAtCompileTime>
288c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        ::run(dst, src, outer);
289c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
290c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
291c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
292c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/***********************
293c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath*** Linear traversal ***
294c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath***********************/
295c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
296c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived1, typename Derived2, int Version>
297c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct assign_impl<Derived1, Derived2, LinearTraversal, NoUnrolling, Version>
298c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
299c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename Derived1::Index Index;
300c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline void run(Derived1 &dst, const Derived2 &src)
301c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
302c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const Index size = dst.size();
303c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for(Index i = 0; i < size; ++i)
304c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      dst.copyCoeff(i, src);
305c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
306c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
307c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
308c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived1, typename Derived2, int Version>
309c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct assign_impl<Derived1, Derived2, LinearTraversal, CompleteUnrolling, Version>
310c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
311c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
312c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
313c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
314c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      ::run(dst, src);
315c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
316c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
317c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
318c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/**************************
319c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath*** Inner vectorization ***
320c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath**************************/
321c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
322c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived1, typename Derived2, int Version>
323c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct assign_impl<Derived1, Derived2, InnerVectorizedTraversal, NoUnrolling, Version>
324c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
325c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename Derived1::Index Index;
326c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline void run(Derived1 &dst, const Derived2 &src)
327c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
328c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const Index innerSize = dst.innerSize();
329c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const Index outerSize = dst.outerSize();
330c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const Index packetSize = packet_traits<typename Derived1::Scalar>::size;
331c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for(Index outer = 0; outer < outerSize; ++outer)
332c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      for(Index inner = 0; inner < innerSize; inner+=packetSize)
333c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        dst.template copyPacketByOuterInner<Derived2, Aligned, Aligned>(outer, inner, src);
334c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
335c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
336c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
337c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived1, typename Derived2, int Version>
338c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct assign_impl<Derived1, Derived2, InnerVectorizedTraversal, CompleteUnrolling, Version>
339c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
340c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
341c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
342c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    assign_innervec_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime>
343c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      ::run(dst, src);
344c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
345c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
346c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
347c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived1, typename Derived2, int Version>
348c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct assign_impl<Derived1, Derived2, InnerVectorizedTraversal, InnerUnrolling, Version>
349c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
350c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename Derived1::Index Index;
351c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
352c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
353c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const Index outerSize = dst.outerSize();
354c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for(Index outer = 0; outer < outerSize; ++outer)
355c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      assign_innervec_InnerUnrolling<Derived1, Derived2, 0, Derived1::InnerSizeAtCompileTime>
356c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        ::run(dst, src, outer);
357c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
358c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
359c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
360c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/***************************
361c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath*** Linear vectorization ***
362c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath***************************/
363c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
364c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate <bool IsAligned = false>
365c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct unaligned_assign_impl
366c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
367c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  template <typename Derived, typename OtherDerived>
368c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static EIGEN_STRONG_INLINE void run(const Derived&, OtherDerived&, typename Derived::Index, typename Derived::Index) {}
369c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
370c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
371c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate <>
372c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct unaligned_assign_impl<false>
373c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
374c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // MSVC must not inline this functions. If it does, it fails to optimize the
375c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  // packet access path.
376c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifdef _MSC_VER
377c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  template <typename Derived, typename OtherDerived>
378c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static EIGEN_DONT_INLINE void run(const Derived& src, OtherDerived& dst, typename Derived::Index start, typename Derived::Index end)
379c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#else
380c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  template <typename Derived, typename OtherDerived>
381c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static EIGEN_STRONG_INLINE void run(const Derived& src, OtherDerived& dst, typename Derived::Index start, typename Derived::Index end)
382c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif
383c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
384c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for (typename Derived::Index index = start; index < end; ++index)
385c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      dst.copyCoeff(index, src);
386c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
387c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
388c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
389c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived1, typename Derived2, int Version>
390c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct assign_impl<Derived1, Derived2, LinearVectorizedTraversal, NoUnrolling, Version>
391c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
392c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename Derived1::Index Index;
393c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
394c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
395c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const Index size = dst.size();
396c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef packet_traits<typename Derived1::Scalar> PacketTraits;
397c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    enum {
398c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      packetSize = PacketTraits::size,
399c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      dstAlignment = PacketTraits::AlignedOnScalar ? Aligned : int(assign_traits<Derived1,Derived2>::DstIsAligned) ,
400c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      srcAlignment = assign_traits<Derived1,Derived2>::JointAlignment
401c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    };
402c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const Index alignedStart = assign_traits<Derived1,Derived2>::DstIsAligned ? 0
403c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                             : internal::first_aligned(&dst.coeffRef(0), size);
404c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const Index alignedEnd = alignedStart + ((size-alignedStart)/packetSize)*packetSize;
405c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
406c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    unaligned_assign_impl<assign_traits<Derived1,Derived2>::DstIsAligned!=0>::run(src,dst,0,alignedStart);
407c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
408c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for(Index index = alignedStart; index < alignedEnd; index += packetSize)
409c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
410c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      dst.template copyPacket<Derived2, dstAlignment, srcAlignment>(index, src);
411c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
412c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
413c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    unaligned_assign_impl<>::run(src,dst,alignedEnd,size);
414c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
415c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
416c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
417c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived1, typename Derived2, int Version>
418c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct assign_impl<Derived1, Derived2, LinearVectorizedTraversal, CompleteUnrolling, Version>
419c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
420c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename Derived1::Index Index;
421c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static EIGEN_STRONG_INLINE void run(Derived1 &dst, const Derived2 &src)
422c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
423c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    enum { size = Derived1::SizeAtCompileTime,
424c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath           packetSize = packet_traits<typename Derived1::Scalar>::size,
425c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath           alignedSize = (size/packetSize)*packetSize };
426c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
427c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    assign_innervec_CompleteUnrolling<Derived1, Derived2, 0, alignedSize>::run(dst, src);
428c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, alignedSize, size>::run(dst, src);
429c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
430c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
431c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
432c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/**************************
433c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath*** Slice vectorization ***
434c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath***************************/
435c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
436c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived1, typename Derived2, int Version>
437c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct assign_impl<Derived1, Derived2, SliceVectorizedTraversal, NoUnrolling, Version>
438c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
439c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename Derived1::Index Index;
440c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline void run(Derived1 &dst, const Derived2 &src)
441c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
442c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef packet_traits<typename Derived1::Scalar> PacketTraits;
443c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    enum {
444c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      packetSize = PacketTraits::size,
445c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      alignable = PacketTraits::AlignedOnScalar,
446c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      dstAlignment = alignable ? Aligned : int(assign_traits<Derived1,Derived2>::DstIsAligned) ,
447c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      srcAlignment = assign_traits<Derived1,Derived2>::JointAlignment
448c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    };
449c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const Index packetAlignedMask = packetSize - 1;
450c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const Index innerSize = dst.innerSize();
451c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const Index outerSize = dst.outerSize();
452c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const Index alignedStep = alignable ? (packetSize - dst.outerStride() % packetSize) & packetAlignedMask : 0;
453c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Index alignedStart = ((!alignable) || assign_traits<Derived1,Derived2>::DstIsAligned) ? 0
454c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                       : internal::first_aligned(&dst.coeffRef(0,0), innerSize);
455c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
456c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for(Index outer = 0; outer < outerSize; ++outer)
457c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
458c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      const Index alignedEnd = alignedStart + ((innerSize-alignedStart) & ~packetAlignedMask);
459c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      // do the non-vectorizable part of the assignment
460c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      for(Index inner = 0; inner<alignedStart ; ++inner)
461c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        dst.copyCoeffByOuterInner(outer, inner, src);
462c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
463c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      // do the vectorizable part of the assignment
464c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      for(Index inner = alignedStart; inner<alignedEnd; inner+=packetSize)
465c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        dst.template copyPacketByOuterInner<Derived2, dstAlignment, Unaligned>(outer, inner, src);
466c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
467c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      // do the non-vectorizable part of the assignment
468c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      for(Index inner = alignedEnd; inner<innerSize ; ++inner)
469c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        dst.copyCoeffByOuterInner(outer, inner, src);
470c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
471c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      alignedStart = std::min<Index>((alignedStart+alignedStep)%packetSize, innerSize);
472c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
473c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
474c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
475c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
476c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace internal
477c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
478c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/***************************************************************************
479c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath* Part 4 : implementation of DenseBase methods
480c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath***************************************************************************/
481c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
482c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived>
483c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename OtherDerived>
484c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathEIGEN_STRONG_INLINE Derived& DenseBase<Derived>
485c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  ::lazyAssign(const DenseBase<OtherDerived>& other)
486c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
487c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum{
488c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    SameType = internal::is_same<typename Derived::Scalar,typename OtherDerived::Scalar>::value
489c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  };
490c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
491c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  EIGEN_STATIC_ASSERT_LVALUE(Derived)
492c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Derived,OtherDerived)
493c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  EIGEN_STATIC_ASSERT(SameType,YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
494c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
495c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifdef EIGEN_DEBUG_ASSIGN
496c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  internal::assign_traits<Derived, OtherDerived>::debug();
497c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif
498c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  eigen_assert(rows() == other.rows() && cols() == other.cols());
499c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  internal::assign_impl<Derived, OtherDerived, int(SameType) ? int(internal::assign_traits<Derived, OtherDerived>::Traversal)
500c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                                                       : int(InvalidTraversal)>::run(derived(),other.derived());
501c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef EIGEN_NO_DEBUG
502c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  checkTransposeAliasing(other.derived());
503c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif
504c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return derived();
505c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
506c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
507c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace internal {
508c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
509c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived, typename OtherDerived,
5107faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez         bool EvalBeforeAssigning = (int(internal::traits<OtherDerived>::Flags) & EvalBeforeAssigningBit) != 0,
5117faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez         bool NeedToTranspose = ((int(Derived::RowsAtCompileTime) == 1 && int(OtherDerived::ColsAtCompileTime) == 1)
5127faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                              |   // FIXME | instead of || to please GCC 4.4.0 stupid warning "suggest parentheses around &&".
5137faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                                  // revert to || as soon as not needed anymore.
5147faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                                  (int(Derived::ColsAtCompileTime) == 1 && int(OtherDerived::RowsAtCompileTime) == 1))
5157faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                              && int(Derived::SizeAtCompileTime) != 1>
516c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct assign_selector;
517c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
518c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived, typename OtherDerived>
519c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct assign_selector<Derived,OtherDerived,false,false> {
520c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.derived()); }
5217faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  template<typename ActualDerived, typename ActualOtherDerived>
5227faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  static EIGEN_STRONG_INLINE Derived& evalTo(ActualDerived& dst, const ActualOtherDerived& other) { other.evalTo(dst); return dst; }
523c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
524c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived, typename OtherDerived>
525c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct assign_selector<Derived,OtherDerived,true,false> {
526c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.eval()); }
527c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
528c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived, typename OtherDerived>
529c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct assign_selector<Derived,OtherDerived,false,true> {
530c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose()); }
5317faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  template<typename ActualDerived, typename ActualOtherDerived>
5327faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  static EIGEN_STRONG_INLINE Derived& evalTo(ActualDerived& dst, const ActualOtherDerived& other) { Transpose<ActualDerived> dstTrans(dst); other.evalTo(dstTrans); return dst; }
533c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
534c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived, typename OtherDerived>
535c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct assign_selector<Derived,OtherDerived,true,true> {
536c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static EIGEN_STRONG_INLINE Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.transpose().eval()); }
537c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
538c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
539c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace internal
540c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
541c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived>
542c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename OtherDerived>
543c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathEIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator=(const DenseBase<OtherDerived>& other)
544c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
545c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return internal::assign_selector<Derived,OtherDerived>::run(derived(), other.derived());
546c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
547c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
548c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived>
549c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathEIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator=(const DenseBase& other)
550c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
551c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return internal::assign_selector<Derived,Derived>::run(derived(), other.derived());
552c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
553c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
554c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived>
555c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathEIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const MatrixBase& other)
556c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
557c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return internal::assign_selector<Derived,Derived>::run(derived(), other.derived());
558c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
559c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
560c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived>
561c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate <typename OtherDerived>
562c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathEIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const DenseBase<OtherDerived>& other)
563c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
564c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return internal::assign_selector<Derived,OtherDerived>::run(derived(), other.derived());
565c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
566c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
567c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived>
568c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate <typename OtherDerived>
569c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathEIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const EigenBase<OtherDerived>& other)
570c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
5717faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  return internal::assign_selector<Derived,OtherDerived,false>::evalTo(derived(), other.derived());
572c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
573c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
574c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived>
575c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename OtherDerived>
576c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathEIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const ReturnByValue<OtherDerived>& other)
577c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
5787faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  return internal::assign_selector<Derived,OtherDerived,false>::evalTo(derived(), other.derived());
579c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
580c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
581c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace Eigen
582c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
583c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif // EIGEN_ASSIGN_H
584