diff --git a/Eigen/src/Core/AssignEvaluator.h b/Eigen/src/Core/AssignEvaluator.h index 6f3ea2d10..08a2c696a 100644 --- a/Eigen/src/Core/AssignEvaluator.h +++ b/Eigen/src/Core/AssignEvaluator.h @@ -38,7 +38,6 @@ namespace internal { ***************************************************************************/ // copy_using_evaluator_traits is based on assign_traits -// (actually, it's identical) template struct copy_using_evaluator_traits @@ -48,7 +47,8 @@ public: DstIsAligned = Derived::Flags & AlignedBit, DstHasDirectAccess = Derived::Flags & DirectAccessBit, SrcIsAligned = OtherDerived::Flags & AlignedBit, - JointAlignment = bool(DstIsAligned) && bool(SrcIsAligned) ? Aligned : Unaligned + JointAlignment = bool(DstIsAligned) && bool(SrcIsAligned) ? Aligned : Unaligned, + SrcEvalBeforeAssign = (evaluator_traits::HasEvalTo == 1) }; private: @@ -83,11 +83,12 @@ private: public: enum { - Traversal = int(MayInnerVectorize) ? int(InnerVectorizedTraversal) - : int(MayLinearVectorize) ? int(LinearVectorizedTraversal) - : int(MaySliceVectorize) ? int(SliceVectorizedTraversal) - : int(MayLinearize) ? int(LinearTraversal) - : int(DefaultTraversal), + Traversal = int(SrcEvalBeforeAssign) ? int(AllAtOnceTraversal) + : int(MayInnerVectorize) ? int(InnerVectorizedTraversal) + : int(MayLinearVectorize) ? int(LinearVectorizedTraversal) + : int(MaySliceVectorize) ? int(SliceVectorizedTraversal) + : int(MayLinearize) ? int(LinearTraversal) + : int(DefaultTraversal), Vectorized = int(Traversal) == InnerVectorizedTraversal || int(Traversal) == LinearVectorizedTraversal || int(Traversal) == SliceVectorizedTraversal @@ -599,6 +600,26 @@ struct copy_using_evaluator_impl +struct copy_using_evaluator_impl +{ + inline static void run(DstXprType &dst, const SrcXprType &src) + { + typedef typename evaluator::type DstEvaluatorType; + typedef typename evaluator::type SrcEvaluatorType; + typedef typename DstXprType::Index Index; + + DstEvaluatorType dstEvaluator(dst); + SrcEvaluatorType srcEvaluator(src); + + srcEvaluator.evalTo(dstEvaluator); + } +}; + /*************************************************************************** * Part 4 : Entry points ***************************************************************************/ diff --git a/Eigen/src/Core/CoreEvaluators.h b/Eigen/src/Core/CoreEvaluators.h index 015e7d698..768fa8950 100644 --- a/Eigen/src/Core/CoreEvaluators.h +++ b/Eigen/src/Core/CoreEvaluators.h @@ -31,7 +31,19 @@ namespace Eigen { namespace internal { - + +// evaluator_traits contains traits for evaluator_impl + +template +struct evaluator_traits +{ + // 1 if evaluator_impl::evalTo() exists + // 0 if evaluator_impl allows coefficient-based access + static const int HasEvalTo = 0; +}; + +// evaluator::type is type of evaluator for T + template struct evaluator_impl {}; diff --git a/Eigen/src/Core/util/Constants.h b/Eigen/src/Core/util/Constants.h index f34aac85a..e8aa9aa40 100644 --- a/Eigen/src/Core/util/Constants.h +++ b/Eigen/src/Core/util/Constants.h @@ -242,7 +242,9 @@ enum { * scalar loops to handle the unaligned boundaries */ SliceVectorizedTraversal, /** \internal Special case to properly handle incompatible scalar types or other defecting cases*/ - InvalidTraversal + InvalidTraversal, + /** \internal Evaluate all entries at once */ + AllAtOnceTraversal }; /** \internal \ingroup enums