diff --git a/Eigen/src/Core/AssignEvaluator.h b/Eigen/src/Core/AssignEvaluator.h index 99ae3f89d..2f18cbc95 100644 --- a/Eigen/src/Core/AssignEvaluator.h +++ b/Eigen/src/Core/AssignEvaluator.h @@ -646,7 +646,7 @@ struct SparseShape {}; // Based on the respective shapes of the destination and source, // the class AssignmentKind determine the kind of assignment mechanism. // AssignmentKind must define a Kind typedef. -template struct AssignmentKind; +template struct AssignmentKind; // AssignmentKind<.,.>::Kind can be one of the following: struct Dense2Dense {}; @@ -655,9 +655,11 @@ template struct AssignmentKind; struct Sparse2Dense {}; struct Sparse2Sparse {}; +template<> struct AssignmentKind { typedef Dense2Dense Kind; }; + // This is the main assignment class template< typename DstXprType, typename SrcXprType, typename Functor, - typename Kind = Dense2Dense,//AssignmentKind< evaluator::Shape , evaluator::Shape >::Kind, + typename Kind = typename AssignmentKind< typename evaluator_traits::Shape , typename evaluator_traits::Shape >::Kind, typename Scalar = typename DstXprType::Scalar> struct Assignment; diff --git a/Eigen/src/Core/CoreEvaluators.h b/Eigen/src/Core/CoreEvaluators.h index c63ff8acd..9460e675f 100644 --- a/Eigen/src/Core/CoreEvaluators.h +++ b/Eigen/src/Core/CoreEvaluators.h @@ -14,20 +14,70 @@ #define EIGEN_COREEVALUATORS_H namespace Eigen { - + namespace internal { -template struct evaluator; +struct IndexBased {}; +struct IteratorBased {}; + +// This class returns the evaluator kind from the expression storage kind. +// Default assumes index based accessors +template +struct storage_kind_to_evaluator_kind { + typedef IndexBased Kind; +}; + +// TODO to be moved to SparseCore: +/* +template<> +struct storage_kind_to_evaluator_kind { + typedef IteratorBased Kind +}; +*/ + +// This class returns the evaluator shape from the expression storage kind. +// It can be Dense, Sparse, Triangular, Diagonal, SelfAdjoint, Band, etc. +template struct storage_kind_to_shape; + + +template<> +struct storage_kind_to_shape { + typedef Dense Shape; +}; + +// TODO to be moved to SparseCore: +/* +template<> +struct storage_kind_to_shape { + typedef Sparse Shape; +}; +*/ + +template struct evaluator_traits; + +template< typename T, + typename Kind = typename evaluator_traits::Kind, + typename Scalar = typename T::Scalar> struct evaluator; + +template< typename T, + typename LhsKind = typename evaluator_traits::Kind, + typename RhsKind = typename evaluator_traits::Kind, + typename LhsScalar = typename T::Lhs::Scalar, + typename RhsScalar = typename T::Rhs::Scalar> struct binary_evaluator; // evaluator_traits contains traits for evaluator - template +template struct evaluator_traits_base { // TODO check whether these two indirections are really needed. // Basically, if nobody overwrite type and nestedType, then, they can be dropped - typedef evaluator type; - typedef evaluator nestedType; +// typedef evaluator type; +// typedef evaluator nestedType; + + // by default, get evalautor kind and shape from storage + typedef typename storage_kind_to_evaluator_kind::Kind Kind; + typedef typename storage_kind_to_shape::Shape Shape; // 1 if assignment A = B assumes aliasing when B is of type T and thus B needs to be evaluated into a // temporary; 0 if not. @@ -58,8 +108,10 @@ struct evaluator template struct evaluator_base { - typedef typename evaluator_traits::type type; - typedef typename evaluator_traits::nestedType nestedType; +// typedef typename evaluator_traits::type type; +// typedef typename evaluator_traits::nestedType nestedType; + typedef evaluator type; + typedef evaluator nestedType; typedef typename ExpressionType::Index Index; // TODO that's not very nice to have to propagate all these traits. They are currently only needed to handle outer,inner indices. diff --git a/Eigen/src/Core/Product.h b/Eigen/src/Core/Product.h index 52586e5c0..970d257a5 100644 --- a/Eigen/src/Core/Product.h +++ b/Eigen/src/Core/Product.h @@ -12,7 +12,7 @@ namespace Eigen { -template class ProductImpl; +template class ProductImpl; /** \class Product * \ingroup Core_Module @@ -26,14 +26,13 @@ template -struct traits > +template +struct traits > : traits::Type> { // We want A+B*C to be of type Product and not Product @@ -45,18 +44,23 @@ struct traits > } // end namespace internal -template -class Product : public ProductImpl::StorageKind, - typename internal::traits::StorageKind>::ret> +template +class Product : public ProductImpl<_Lhs,_Rhs,Option, + typename internal::promote_storage_type::StorageKind, + typename internal::traits<_Rhs>::StorageKind>::ret> { public: + typedef _Lhs Lhs; + typedef _Rhs Rhs; + typedef typename ProductImpl< - Lhs, Rhs, Option, ProductTag, + Lhs, Rhs, Option, typename internal::promote_storage_type::ret>::Base Base; EIGEN_GENERIC_PUBLIC_INTERFACE(Product) + + typedef typename Lhs::Nested LhsNested; typedef typename Rhs::Nested RhsNested; @@ -82,13 +86,13 @@ class Product : public ProductImpl -class ProductImpl : public internal::dense_xpr_base >::type +template +class ProductImpl : public internal::dense_xpr_base >::type { typedef Product Derived; public: - typedef typename internal::dense_xpr_base >::type Base; + typedef typename internal::dense_xpr_base >::type Base; EIGEN_DENSE_PUBLIC_INTERFACE(Derived) }; diff --git a/Eigen/src/Core/ProductEvaluators.h b/Eigen/src/Core/ProductEvaluators.h index 9f5f6eb0c..e3a893651 100644 --- a/Eigen/src/Core/ProductEvaluators.h +++ b/Eigen/src/Core/ProductEvaluators.h @@ -16,7 +16,28 @@ namespace Eigen { namespace internal { + +// Like more general binary expressions, products need they own evaluator: +template< typename T, + int ProductTag = internal::product_tag::ret, + typename LhsShape = typename evaluator_traits::Shape, + typename RhsShape = typename evaluator_traits::Shape, + typename LhsScalar = typename T::Lhs::Scalar, + typename RhsScalar = typename T::Rhs::Scalar + > struct product_evaluator; + +template +struct evaluator > + : public product_evaluator > +{ + typedef Product XprType; + typedef product_evaluator Base; + typedef evaluator type; + typedef evaluator nestedType; + + evaluator(const XprType& xpr) : Base(xpr) {} +}; // Helper class to perform a dense product with the destination at hand. // Depending on the sizes of the factors, there are different evaluation strategies @@ -27,17 +48,14 @@ struct dense_product_impl; // The evaluator for default dense products creates a temporary and call dense_product_impl template -struct evaluator > - : public evaluator::PlainObject>::type +struct product_evaluator, ProductTag, Dense, Dense, typename Lhs::Scalar, typename Rhs::Scalar> + : public evaluator::PlainObject>::type { - typedef Product XprType; + typedef Product XprType; typedef typename XprType::PlainObject PlainObject; typedef typename evaluator::type Base; - - typedef evaluator type; - typedef evaluator nestedType; - evaluator(const XprType& xpr) + product_evaluator(const XprType& xpr) : m_result(xpr.rows(), xpr.cols()) { ::new (static_cast(this)) Base(m_result); @@ -199,13 +217,13 @@ template -struct evaluator > - : evaluator_base > +struct product_evaluator, ProductTag, Dense, Dense, typename Lhs::Scalar, typename Rhs::Scalar > + : evaluator_base > { - typedef Product XprType; + typedef Product XprType; typedef CoeffBasedProduct CoeffBasedProductType; - evaluator(const XprType& xpr) + product_evaluator(const XprType& xpr) : m_lhsImpl(xpr.lhs()), m_rhsImpl(xpr.rhs()), m_innerDim(xpr.lhs().cols()) diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h index 459422524..776eac587 100644 --- a/Eigen/src/Core/util/ForwardDeclarations.h +++ b/Eigen/src/Core/util/ForwardDeclarations.h @@ -94,10 +94,7 @@ namespace internal { template struct product_tag; } -template::ret - > class Product; +template class Product; template class GeneralProduct; // TODO deprecated template class CoeffBasedProduct; // TODO deprecated