aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2014-06-20 15:39:38 +0200
committerGravatar Gael Guennebaud <g.gael@free.fr>2014-06-20 15:39:38 +0200
commit78bb80833708615c330659d9b64870b19185df37 (patch)
tree15976a9b6efcf2e9a63b8ed9136737a2006fc527
parent0a6c472335b593a227c3adbcf1d770187449a30f (diff)
1- Introduce sub-evaluator types for unary, binary, product, and map expressions to ease specializing them.
2- Remove a lot of code which should not be there with evaluators, in particular coeff/packet methods implemented in the expressions.
-rw-r--r--Eigen/src/Core/ArrayBase.h4
-rw-r--r--Eigen/src/Core/ArrayWrapper.h2
-rw-r--r--Eigen/src/Core/Block.h13
-rw-r--r--Eigen/src/Core/CoreEvaluators.h247
-rw-r--r--Eigen/src/Core/CwiseBinaryOp.h30
-rw-r--r--Eigen/src/Core/CwiseUnaryOp.h14
-rw-r--r--Eigen/src/Core/CwiseUnaryView.h9
-rw-r--r--Eigen/src/Core/DenseBase.h5
-rw-r--r--Eigen/src/Core/DenseCoeffsBase.h45
-rw-r--r--Eigen/src/Core/Inverse.h9
-rw-r--r--Eigen/src/Core/Replicate.h1
-rw-r--r--Eigen/src/Core/ReturnByValue.h28
-rw-r--r--Eigen/src/Core/Reverse.h1
-rw-r--r--Eigen/src/Core/Transpose.h30
-rw-r--r--Eigen/src/Core/TriangularMatrix.h4
-rw-r--r--Eigen/src/Core/products/GeneralMatrixMatrix.h4
-rw-r--r--Eigen/src/Core/util/ForwardDeclarations.h4
-rw-r--r--Eigen/src/Core/util/XprHelper.h9
18 files changed, 300 insertions, 159 deletions
diff --git a/Eigen/src/Core/ArrayBase.h b/Eigen/src/Core/ArrayBase.h
index d1c422836..f5bae6357 100644
--- a/Eigen/src/Core/ArrayBase.h
+++ b/Eigen/src/Core/ArrayBase.h
@@ -123,7 +123,11 @@ template<typename Derived> class ArrayBase
EIGEN_DEVICE_FUNC
Derived& operator=(const ArrayBase& other)
{
+#ifndef EIGEN_TEST_EVALUATORS
return internal::assign_selector<Derived,Derived>::run(derived(), other.derived());
+#else
+ internal::call_assignment(derived(), other.derived());
+#endif
}
EIGEN_DEVICE_FUNC
diff --git a/Eigen/src/Core/ArrayWrapper.h b/Eigen/src/Core/ArrayWrapper.h
index 4bb648024..599d87f64 100644
--- a/Eigen/src/Core/ArrayWrapper.h
+++ b/Eigen/src/Core/ArrayWrapper.h
@@ -39,6 +39,7 @@ class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> >
typedef ArrayBase<ArrayWrapper> Base;
EIGEN_DENSE_PUBLIC_INTERFACE(ArrayWrapper)
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ArrayWrapper)
+ typedef typename internal::remove_all<ExpressionType>::type NestedExpression;
typedef typename internal::conditional<
internal::is_lvalue<ExpressionType>::value,
@@ -176,6 +177,7 @@ class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> >
typedef MatrixBase<MatrixWrapper<ExpressionType> > Base;
EIGEN_DENSE_PUBLIC_INTERFACE(MatrixWrapper)
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(MatrixWrapper)
+ typedef typename internal::remove_all<ExpressionType>::type NestedExpression;
typedef typename internal::conditional<
internal::is_lvalue<ExpressionType>::value,
diff --git a/Eigen/src/Core/Block.h b/Eigen/src/Core/Block.h
index e0b24e199..ef6c143d3 100644
--- a/Eigen/src/Core/Block.h
+++ b/Eigen/src/Core/Block.h
@@ -344,6 +344,9 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
: public MapBase<Block<XprType, BlockRows, BlockCols, InnerPanel> >
{
typedef Block<XprType, BlockRows, BlockCols, InnerPanel> BlockType;
+ enum {
+ XprTypeIsRowMajor = (int(traits<XprType>::Flags)&RowMajorBit) != 0
+ };
public:
typedef MapBase<BlockType> Base;
@@ -354,9 +357,8 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
*/
EIGEN_DEVICE_FUNC
inline BlockImpl_dense(XprType& xpr, Index i)
- : Base(internal::const_cast_ptr(&xpr.coeffRef(
- (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0,
- (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0)),
+ : Base(xpr.data() + i * ( ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && (!XprTypeIsRowMajor))
+ || ((BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) && ( XprTypeIsRowMajor)) ? xpr.innerStride() : xpr.outerStride()),
BlockRows==1 ? 1 : xpr.rows(),
BlockCols==1 ? 1 : xpr.cols()),
m_xpr(xpr)
@@ -368,7 +370,8 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
*/
EIGEN_DEVICE_FUNC
inline BlockImpl_dense(XprType& xpr, Index startRow, Index startCol)
- : Base(internal::const_cast_ptr(&xpr.coeffRef(startRow,startCol))), m_xpr(xpr)
+ : Base(xpr.data()+xpr.innerStride()*(XprTypeIsRowMajor?startCol:startRow) + xpr.outerStride()*(XprTypeIsRowMajor?startRow:startCol)),
+ m_xpr(xpr)
{
init();
}
@@ -379,7 +382,7 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
inline BlockImpl_dense(XprType& xpr,
Index startRow, Index startCol,
Index blockRows, Index blockCols)
- : Base(internal::const_cast_ptr(&xpr.coeffRef(startRow,startCol)), blockRows, blockCols),
+ : Base(xpr.data()+xpr.innerStride()*(XprTypeIsRowMajor?startCol:startRow) + xpr.outerStride()*(XprTypeIsRowMajor?startRow:startCol), blockRows, blockCols),
m_xpr(xpr)
{
init();
diff --git a/Eigen/src/Core/CoreEvaluators.h b/Eigen/src/Core/CoreEvaluators.h
index 47f50d548..f872b41e1 100644
--- a/Eigen/src/Core/CoreEvaluators.h
+++ b/Eigen/src/Core/CoreEvaluators.h
@@ -27,14 +27,6 @@ struct storage_kind_to_evaluator_kind {
typedef IndexBased Kind;
};
-// TODO to be moved to SparseCore:
-/*
-template<>
-struct storage_kind_to_evaluator_kind<Sparse> {
- 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<typename StorageKind> struct storage_kind_to_shape;
@@ -45,22 +37,28 @@ struct storage_kind_to_shape<Dense> {
typedef DenseShape Shape;
};
-// TODO to be moved to SparseCore:
-/*
-template<>
-struct storage_kind_to_shape<Sparse> {
- typedef SparseSpape Shape;
-};
-*/
-
+// Evaluators have to be specialized with respect to various criteria such as:
+// - storage/structure/shape
+// - scalar type
+// - etc.
+// Therefore, we need specialization of evaluator providing additional template arguments for each kind of evaluators.
+// We currently distinguish the following kind of evaluators:
+// - unary_evaluator for expressions taking only one arguments (CwiseUnaryOp, CwiseUnaryView, Transpose, MatrixWrapper, ArrayWrapper, Reverse, Replicate)
+// - binary_evaluator for expression taking two arguments (CwiseBinaryOp)
+// - product_evaluator for linear algebra products (Product); special case of binary_evaluator because it requires additional tags for dispatching.
+// - mapbase_evaluator for Map, Block, Ref
+// - block_evaluator for Block (special dispatching to a mapbase_evaluator or unary_evaluator)
-
template< typename T,
- typename LhsKind = typename evaluator_traits<typename T::Lhs>::Kind,
- typename RhsKind = typename evaluator_traits<typename T::Rhs>::Kind,
+ typename LhsKind = typename evaluator_traits<typename T::Lhs>::Kind,
+ typename RhsKind = typename evaluator_traits<typename T::Rhs>::Kind,
typename LhsScalar = typename T::Lhs::Scalar,
typename RhsScalar = typename T::Rhs::Scalar> struct binary_evaluator;
+template< typename T,
+ typename Kind = typename evaluator_traits<typename T::NestedExpression>::Kind,
+ typename Scalar = typename T::Scalar> struct unary_evaluator;
+
// evaluator_traits<T> contains traits for evaluator<T>
template<typename T>
@@ -80,15 +78,20 @@ struct evaluator_traits_base
static const int AssumeAliasing = 0;
};
+// Default evaluator traits
template<typename T>
struct evaluator_traits : public evaluator_traits_base<T>
{
};
-// expression class for evaluating nested expression to a temporary
-
-template<typename ArgType>
-class EvalToTemp;
+
+// By default, we assume a unary expression:
+template<typename T>
+struct evaluator : public unary_evaluator<T>
+{
+ typedef unary_evaluator<T> Base;
+ evaluator(const T& xpr) : Base(xpr) {}
+};
// TODO: Think about const-correctness
@@ -118,6 +121,8 @@ struct evaluator_base
//
// evaluator<PlainObjectBase> is a common base class for the
// Matrix and Array evaluators.
+// Here we directly specialize evaluator. This is not really a unary expression, and it is, by definition, dense,
+// so no need for more sophisticated dispatching.
template<typename Derived>
struct evaluator<PlainObjectBase<Derived> >
@@ -245,81 +250,10 @@ struct evaluator<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> >
{ }
};
-// -------------------- EvalToTemp --------------------
-
-template<typename ArgType>
-struct traits<EvalToTemp<ArgType> >
- : public traits<ArgType>
-{ };
-
-template<typename ArgType>
-class EvalToTemp
- : public dense_xpr_base<EvalToTemp<ArgType> >::type
-{
- public:
-
- typedef typename dense_xpr_base<EvalToTemp>::type Base;
- EIGEN_GENERIC_PUBLIC_INTERFACE(EvalToTemp)
-
- EvalToTemp(const ArgType& arg)
- : m_arg(arg)
- { }
-
- const ArgType& arg() const
- {
- return m_arg;
- }
-
- Index rows() const
- {
- return m_arg.rows();
- }
-
- Index cols() const
- {
- return m_arg.cols();
- }
-
- private:
- const ArgType& m_arg;
-};
-
-template<typename ArgType>
-struct evaluator<EvalToTemp<ArgType> >
- : public evaluator<typename ArgType::PlainObject>::type
-{
- typedef EvalToTemp<ArgType> XprType;
- typedef typename ArgType::PlainObject PlainObject;
- typedef typename evaluator<PlainObject>::type Base;
-
- typedef evaluator type;
- typedef evaluator nestedType;
-
- evaluator(const XprType& xpr)
- : m_result(xpr.rows(), xpr.cols())
- {
- ::new (static_cast<Base*>(this)) Base(m_result);
- // TODO we should simply do m_result(xpr.arg());
- call_dense_assignment_loop(m_result, xpr.arg());
- }
-
- // This constructor is used when nesting an EvalTo evaluator in another evaluator
- evaluator(const ArgType& arg)
- : m_result(arg.rows(), arg.cols())
- {
- ::new (static_cast<Base*>(this)) Base(m_result);
- // TODO we should simply do m_result(xpr.arg());
- call_dense_assignment_loop(m_result, arg);
- }
-
-protected:
- PlainObject m_result;
-};
-
// -------------------- Transpose --------------------
template<typename ArgType>
-struct evaluator<Transpose<ArgType> >
+struct unary_evaluator<Transpose<ArgType> >
: evaluator_base<Transpose<ArgType> >
{
typedef Transpose<ArgType> XprType;
@@ -329,7 +263,7 @@ struct evaluator<Transpose<ArgType> >
Flags = evaluator<ArgType>::Flags ^ RowMajorBit
};
- evaluator(const XprType& t) : m_argImpl(t.nestedExpression()) {}
+ unary_evaluator(const XprType& t) : m_argImpl(t.nestedExpression()) {}
typedef typename XprType::Index Index;
typedef typename XprType::Scalar Scalar;
@@ -386,6 +320,8 @@ protected:
};
// -------------------- CwiseNullaryOp --------------------
+// Like Matrix and Array, this is not really a unary expression, so we directly specialize evaluator.
+// Likewise, there is not need to more sophisticated dispatching here.
template<typename NullaryOp, typename PlainObjectType>
struct evaluator<CwiseNullaryOp<NullaryOp,PlainObjectType> >
@@ -441,7 +377,7 @@ protected:
// -------------------- CwiseUnaryOp --------------------
template<typename UnaryOp, typename ArgType>
-struct evaluator<CwiseUnaryOp<UnaryOp, ArgType> >
+struct unary_evaluator<CwiseUnaryOp<UnaryOp, ArgType>, IndexBased >
: evaluator_base<CwiseUnaryOp<UnaryOp, ArgType> >
{
typedef CwiseUnaryOp<UnaryOp, ArgType> XprType;
@@ -454,7 +390,7 @@ struct evaluator<CwiseUnaryOp<UnaryOp, ArgType> >
| (functor_traits<UnaryOp>::PacketAccess ? PacketAccessBit : 0))
};
- evaluator(const XprType& op)
+ unary_evaluator(const XprType& op)
: m_functor(op.functor()),
m_argImpl(op.nestedExpression())
{ }
@@ -492,8 +428,19 @@ protected:
// -------------------- CwiseBinaryOp --------------------
+// this is a binary expression
template<typename BinaryOp, typename Lhs, typename Rhs>
struct evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
+ : public binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
+{
+ typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType;
+ typedef binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > Base;
+
+ evaluator(const XprType& xpr) : Base(xpr) {}
+};
+
+template<typename BinaryOp, typename Lhs, typename Rhs>
+struct binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
: evaluator_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
{
typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType;
@@ -517,7 +464,7 @@ struct evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
Flags = (Flags0 & ~RowMajorBit) | (LhsFlags & RowMajorBit)
};
- evaluator(const XprType& xpr)
+ binary_evaluator(const XprType& xpr)
: m_functor(xpr.functor()),
m_lhsImpl(xpr.lhs()),
m_rhsImpl(xpr.rhs())
@@ -560,7 +507,7 @@ protected:
// -------------------- CwiseUnaryView --------------------
template<typename UnaryOp, typename ArgType>
-struct evaluator<CwiseUnaryView<UnaryOp, ArgType> >
+struct unary_evaluator<CwiseUnaryView<UnaryOp, ArgType> >
: evaluator_base<CwiseUnaryView<UnaryOp, ArgType> >
{
typedef CwiseUnaryView<UnaryOp, ArgType> XprType;
@@ -571,7 +518,7 @@ struct evaluator<CwiseUnaryView<UnaryOp, ArgType> >
Flags = (evaluator<ArgType>::Flags & (HereditaryBits | LinearAccessBit | DirectAccessBit))
};
- evaluator(const XprType& op)
+ unary_evaluator(const XprType& op)
: m_unaryOp(op.functor()),
m_argImpl(op.nestedExpression())
{ }
@@ -884,6 +831,7 @@ struct block_evaluator<ArgType, BlockRows, BlockCols, InnerPanel, /* HasDirectAc
// -------------------- Select --------------------
+// TODO shall we introduce a ternary_evaluator?
// TODO enable vectorization for Select
template<typename ConditionMatrixType, typename ThenMatrixType, typename ElseMatrixType>
@@ -934,7 +882,7 @@ protected:
// -------------------- Replicate --------------------
template<typename ArgType, int RowFactor, int ColFactor>
-struct evaluator<Replicate<ArgType, RowFactor, ColFactor> >
+struct unary_evaluator<Replicate<ArgType, RowFactor, ColFactor> >
: evaluator_base<Replicate<ArgType, RowFactor, ColFactor> >
{
typedef Replicate<ArgType, RowFactor, ColFactor> XprType;
@@ -953,7 +901,7 @@ struct evaluator<Replicate<ArgType, RowFactor, ColFactor> >
Flags = (evaluator<ArgTypeNestedCleaned>::Flags & HereditaryBits & ~RowMajorBit) | (traits<XprType>::Flags & RowMajorBit)
};
- evaluator(const XprType& replicate)
+ unary_evaluator(const XprType& replicate)
: m_arg(replicate.nestedExpression()),
m_argImpl(m_arg),
m_rows(replicate.nestedExpression().rows()),
@@ -1111,23 +1059,23 @@ protected:
};
template<typename TArgType>
-struct evaluator<MatrixWrapper<TArgType> >
+struct unary_evaluator<MatrixWrapper<TArgType> >
: evaluator_wrapper_base<MatrixWrapper<TArgType> >
{
typedef MatrixWrapper<TArgType> XprType;
- evaluator(const XprType& wrapper)
+ unary_evaluator(const XprType& wrapper)
: evaluator_wrapper_base<MatrixWrapper<TArgType> >(wrapper.nestedExpression())
{ }
};
template<typename TArgType>
-struct evaluator<ArrayWrapper<TArgType> >
+struct unary_evaluator<ArrayWrapper<TArgType> >
: evaluator_wrapper_base<ArrayWrapper<TArgType> >
{
typedef ArrayWrapper<TArgType> XprType;
- evaluator(const XprType& wrapper)
+ unary_evaluator(const XprType& wrapper)
: evaluator_wrapper_base<ArrayWrapper<TArgType> >(wrapper.nestedExpression())
{ }
};
@@ -1139,7 +1087,7 @@ struct evaluator<ArrayWrapper<TArgType> >
template<typename PacketScalar, bool ReversePacket> struct reverse_packet_cond;
template<typename ArgType, int Direction>
-struct evaluator<Reverse<ArgType, Direction> >
+struct unary_evaluator<Reverse<ArgType, Direction> >
: evaluator_base<Reverse<ArgType, Direction> >
{
typedef Reverse<ArgType, Direction> XprType;
@@ -1173,7 +1121,7 @@ struct evaluator<Reverse<ArgType, Direction> >
};
typedef internal::reverse_packet_cond<PacketScalar,ReversePacket> reverse_packet;
- evaluator(const XprType& reverse)
+ unary_evaluator(const XprType& reverse)
: m_argImpl(reverse.nestedExpression()),
m_rows(ReverseRow ? reverse.nestedExpression().rows() : 0),
m_cols(ReverseCol ? reverse.nestedExpression().cols() : 0)
@@ -1292,6 +1240,87 @@ private:
EIGEN_STRONG_INLINE Index colOffset() const { return m_index.value() > 0 ? m_index.value() : 0; }
};
+
+
+//----------------------------------------------------------------------
+// deprecated code
+//----------------------------------------------------------------------
+
+// -------------------- EvalToTemp --------------------
+
+// expression class for evaluating nested expression to a temporary
+
+template<typename ArgType> class EvalToTemp;
+
+template<typename ArgType>
+struct traits<EvalToTemp<ArgType> >
+ : public traits<ArgType>
+{ };
+
+template<typename ArgType>
+class EvalToTemp
+ : public dense_xpr_base<EvalToTemp<ArgType> >::type
+{
+ public:
+
+ typedef typename dense_xpr_base<EvalToTemp>::type Base;
+ EIGEN_GENERIC_PUBLIC_INTERFACE(EvalToTemp)
+
+ EvalToTemp(const ArgType& arg)
+ : m_arg(arg)
+ { }
+
+ const ArgType& arg() const
+ {
+ return m_arg;
+ }
+
+ Index rows() const
+ {
+ return m_arg.rows();
+ }
+
+ Index cols() const
+ {
+ return m_arg.cols();
+ }
+
+ private:
+ const ArgType& m_arg;
+};
+
+template<typename ArgType>
+struct evaluator<EvalToTemp<ArgType> >
+ : public evaluator<typename ArgType::PlainObject>::type
+{
+ typedef EvalToTemp<ArgType> XprType;
+ typedef typename ArgType::PlainObject PlainObject;
+ typedef typename evaluator<PlainObject>::type Base;
+
+ typedef evaluator type;
+ typedef evaluator nestedType;
+
+ evaluator(const XprType& xpr)
+ : m_result(xpr.rows(), xpr.cols())
+ {
+ ::new (static_cast<Base*>(this)) Base(m_result);
+ // TODO we should simply do m_result(xpr.arg());
+ call_dense_assignment_loop(m_result, xpr.arg());
+ }
+
+ // This constructor is used when nesting an EvalTo evaluator in another evaluator
+ evaluator(const ArgType& arg)
+ : m_result(arg.rows(), arg.cols())
+ {
+ ::new (static_cast<Base*>(this)) Base(m_result);
+ // TODO we should simply do m_result(xpr.arg());
+ call_dense_assignment_loop(m_result, arg);
+ }
+
+protected:
+ PlainObject m_result;
+};
+
} // namespace internal
} // end namespace Eigen
diff --git a/Eigen/src/Core/CwiseBinaryOp.h b/Eigen/src/Core/CwiseBinaryOp.h
index 07861dbc9..5e4fb147b 100644
--- a/Eigen/src/Core/CwiseBinaryOp.h
+++ b/Eigen/src/Core/CwiseBinaryOp.h
@@ -94,23 +94,26 @@ struct traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
template<typename BinaryOp, typename Lhs, typename Rhs, typename StorageKind>
class CwiseBinaryOpImpl;
-template<typename BinaryOp, typename Lhs, typename Rhs>
+template<typename BinaryOp, typename LhsType, typename RhsType>
class CwiseBinaryOp : internal::no_assignment_operator,
public CwiseBinaryOpImpl<
- BinaryOp, Lhs, Rhs,
- typename internal::promote_storage_type<typename internal::traits<Lhs>::StorageKind,
- typename internal::traits<Rhs>::StorageKind>::ret>
+ BinaryOp, LhsType, RhsType,
+ typename internal::promote_storage_type<typename internal::traits<LhsType>::StorageKind,
+ typename internal::traits<RhsType>::StorageKind>::ret>
{
public:
+
+ typedef typename internal::remove_all<LhsType>::type Lhs;
+ typedef typename internal::remove_all<RhsType>::type Rhs;
typedef typename CwiseBinaryOpImpl<
- BinaryOp, Lhs, Rhs,
- typename internal::promote_storage_type<typename internal::traits<Lhs>::StorageKind,
+ BinaryOp, LhsType, RhsType,
+ typename internal::promote_storage_type<typename internal::traits<LhsType>::StorageKind,
typename internal::traits<Rhs>::StorageKind>::ret>::Base Base;
EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseBinaryOp)
- typedef typename internal::nested<Lhs>::type LhsNested;
- typedef typename internal::nested<Rhs>::type RhsNested;
+ typedef typename internal::nested<LhsType>::type LhsNested;
+ typedef typename internal::nested<RhsType>::type RhsNested;
typedef typename internal::remove_reference<LhsNested>::type _LhsNested;
typedef typename internal::remove_reference<RhsNested>::type _RhsNested;
@@ -157,6 +160,7 @@ class CwiseBinaryOp : internal::no_assignment_operator,
const BinaryOp m_functor;
};
+#ifndef EIGEN_TEST_EVALUATORS
template<typename BinaryOp, typename Lhs, typename Rhs>
class CwiseBinaryOpImpl<BinaryOp, Lhs, Rhs, Dense>
: public internal::dense_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type
@@ -195,6 +199,16 @@ class CwiseBinaryOpImpl<BinaryOp, Lhs, Rhs, Dense>
derived().rhs().template packet<LoadMode>(index));
}
};
+#else
+// Generic API dispatcher
+template<typename BinaryOp, typename Lhs, typename Rhs, typename StorageKind>
+class CwiseBinaryOpImpl
+ : public internal::generic_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type
+{
+public:
+ typedef typename internal::generic_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type Base;
+};
+#endif
/** replaces \c *this by \c *this - \a other.
*
diff --git a/Eigen/src/Core/CwiseUnaryOp.h b/Eigen/src/Core/CwiseUnaryOp.h
index af05a9108..098034a1e 100644
--- a/Eigen/src/Core/CwiseUnaryOp.h
+++ b/Eigen/src/Core/CwiseUnaryOp.h
@@ -67,6 +67,7 @@ class CwiseUnaryOp : internal::no_assignment_operator,
typedef typename CwiseUnaryOpImpl<UnaryOp, XprType,typename internal::traits<XprType>::StorageKind>::Base Base;
EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseUnaryOp)
+ typedef typename internal::remove_all<XprType>::type NestedExpression;
EIGEN_DEVICE_FUNC
inline CwiseUnaryOp(const XprType& xpr, const UnaryOp& func = UnaryOp())
@@ -96,6 +97,7 @@ class CwiseUnaryOp : internal::no_assignment_operator,
const UnaryOp m_functor;
};
+#ifndef EIGEN_TEST_EVALUATORS
// This is the generic implementation for dense storage.
// It can be used for any expression types implementing the dense concept.
template<typename UnaryOp, typename XprType>
@@ -107,7 +109,7 @@ class CwiseUnaryOpImpl<UnaryOp,XprType,Dense>
typedef CwiseUnaryOp<UnaryOp, XprType> Derived;
typedef typename internal::dense_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type Base;
EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
-
+
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE const Scalar coeff(Index rowId, Index colId) const
{
@@ -133,6 +135,16 @@ class CwiseUnaryOpImpl<UnaryOp,XprType,Dense>
return derived().functor().packetOp(derived().nestedExpression().template packet<LoadMode>(index));
}
};
+#else
+// Generic API dispatcher
+template<typename UnaryOp, typename XprType, typename StorageKind>
+class CwiseUnaryOpImpl
+ : public internal::generic_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type
+{
+public:
+ typedef typename internal::generic_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type Base;
+};
+#endif
} // end namespace Eigen
diff --git a/Eigen/src/Core/CwiseUnaryView.h b/Eigen/src/Core/CwiseUnaryView.h
index 9cdebb8e7..92b031e19 100644
--- a/Eigen/src/Core/CwiseUnaryView.h
+++ b/Eigen/src/Core/CwiseUnaryView.h
@@ -66,6 +66,7 @@ class CwiseUnaryView : public CwiseUnaryViewImpl<ViewOp, MatrixType, typename in
typedef typename CwiseUnaryViewImpl<ViewOp, MatrixType,typename internal::traits<MatrixType>::StorageKind>::Base Base;
EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseUnaryView)
+ typedef typename internal::remove_all<MatrixType>::type NestedExpression;
inline CwiseUnaryView(const MatrixType& mat, const ViewOp& func = ViewOp())
: m_matrix(mat), m_functor(func) {}
@@ -104,8 +105,8 @@ class CwiseUnaryViewImpl<ViewOp,MatrixType,Dense>
EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(CwiseUnaryViewImpl)
- inline Scalar* data() { return &coeffRef(0); }
- inline const Scalar* data() const { return &coeff(0); }
+ inline Scalar* data() { return &(this->coeffRef(0)); }
+ inline const Scalar* data() const { return &(this->coeff(0)); }
inline Index innerStride() const
{
@@ -116,6 +117,8 @@ class CwiseUnaryViewImpl<ViewOp,MatrixType,Dense>
{
return derived().nestedExpression().outerStride() * sizeof(typename internal::traits<MatrixType>::Scalar) / sizeof(Scalar);
}
+
+#ifndef EIGEN_TEST_EVALUATORS
EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const
{
@@ -136,6 +139,8 @@ class CwiseUnaryViewImpl<ViewOp,MatrixType,Dense>
{
return derived().functor()(const_cast_derived().nestedExpression().coeffRef(index));
}
+
+#endif
};
} // end namespace Eigen
diff --git a/Eigen/src/Core/DenseBase.h b/Eigen/src/Core/DenseBase.h
index f3c79aa31..624276240 100644
--- a/Eigen/src/Core/DenseBase.h
+++ b/Eigen/src/Core/DenseBase.h
@@ -74,6 +74,7 @@ template<typename Derived> class DenseBase
using Base::colIndexByOuterInner;
using Base::coeff;
using Base::coeffByOuterInner;
+#ifndef EIGEN_TEST_EVALUATORS
using Base::packet;
using Base::packetByOuterInner;
using Base::writePacket;
@@ -84,6 +85,7 @@ template<typename Derived> class DenseBase
using Base::copyCoeffByOuterInner;
using Base::copyPacket;
using Base::copyPacketByOuterInner;
+#endif
using Base::operator();
using Base::operator[];
using Base::x;
@@ -280,7 +282,8 @@ template<typename Derived> class DenseBase
Derived& operator=(const ReturnByValue<OtherDerived>& func);
#ifndef EIGEN_PARSED_BY_DOXYGEN
- /** Copies \a other into *this without evaluating other. \returns a reference to *this. */
+ /** Copies \a other into *this without evaluating other. \returns a reference to *this.
+ * \deprecated */
template<typename OtherDerived>
EIGEN_DEVICE_FUNC
Derived& lazyAssign(const DenseBase<OtherDerived>& other);
diff --git a/Eigen/src/Core/DenseCoeffsBase.h b/Eigen/src/Core/DenseCoeffsBase.h
index efabb5e67..6f35a67ca 100644
--- a/Eigen/src/Core/DenseCoeffsBase.h
+++ b/Eigen/src/Core/DenseCoeffsBase.h
@@ -97,8 +97,12 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const
{
eigen_internal_assert(row >= 0 && row < rows()
- && col >= 0 && col < cols());
+ && col >= 0 && col < cols());
+#ifndef EIGEN_TEST_EVALUATORS
return derived().coeff(row, col);
+#else
+ return typename internal::evaluator<Derived>::type(derived()).coeff(row,col);
+#endif
}
EIGEN_DEVICE_FUNC
@@ -117,7 +121,7 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
{
eigen_assert(row >= 0 && row < rows()
&& col >= 0 && col < cols());
- return derived().coeff(row, col);
+ return coeff(row, col);
}
/** Short version: don't use this function, use
@@ -140,7 +144,11 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
coeff(Index index) const
{
eigen_internal_assert(index >= 0 && index < size());
+#ifndef EIGEN_TEST_EVALUATORS
return derived().coeff(index);
+#else
+ return typename internal::evaluator<Derived>::type(derived()).coeff(index);
+#endif
}
@@ -161,7 +169,7 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
#endif
eigen_assert(index >= 0 && index < size());
- return derived().coeff(index);
+ return coeff(index);
}
/** \returns the coefficient at given index.
@@ -179,7 +187,7 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
operator()(Index index) const
{
eigen_assert(index >= 0 && index < size());
- return derived().coeff(index);
+ return coeff(index);
}
/** equivalent to operator[](0). */
@@ -219,9 +227,12 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
template<int LoadMode>
EIGEN_STRONG_INLINE PacketReturnType packet(Index row, Index col) const
{
- eigen_internal_assert(row >= 0 && row < rows()
- && col >= 0 && col < cols());
+ eigen_internal_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
+#ifndef EIGEN_TEST_EVALUATORS
return derived().template packet<LoadMode>(row,col);
+#else
+ return typename internal::evaluator<Derived>::type(derived()).template packet<LoadMode>(row,col);
+#endif
}
@@ -247,7 +258,11 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const
{
eigen_internal_assert(index >= 0 && index < size());
+#ifndef EIGEN_TEST_EVALUATORS
return derived().template packet<LoadMode>(index);
+#else
+ return typename internal::evaluator<Derived>::type(derived()).template packet<LoadMode>(index);
+#endif
}
protected:
@@ -327,8 +342,12 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col)
{
eigen_internal_assert(row >= 0 && row < rows()
- && col >= 0 && col < cols());
+ && col >= 0 && col < cols());
+#ifndef EIGEN_TEST_EVALUATORS
return derived().coeffRef(row, col);
+#else
+ return typename internal::evaluator<Derived>::type(derived()).coeffRef(row,col);
+#endif
}
EIGEN_DEVICE_FUNC
@@ -350,7 +369,7 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
{
eigen_assert(row >= 0 && row < rows()
&& col >= 0 && col < cols());
- return derived().coeffRef(row, col);
+ return coeffRef(row, col);
}
@@ -374,7 +393,11 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
coeffRef(Index index)
{
eigen_internal_assert(index >= 0 && index < size());
+#ifndef EIGEN_TEST_EVALUATORS
return derived().coeffRef(index);
+#else
+ return typename internal::evaluator<Derived>::type(derived()).coeffRef(index);
+#endif
}
/** \returns a reference to the coefficient at given index.
@@ -393,7 +416,7 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
#endif
eigen_assert(index >= 0 && index < size());
- return derived().coeffRef(index);
+ return coeffRef(index);
}
/** \returns a reference to the coefficient at given index.
@@ -410,7 +433,7 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
operator()(Index index)
{
eigen_assert(index >= 0 && index < size());
- return derived().coeffRef(index);
+ return coeffRef(index);
}
/** equivalent to operator[](0). */
@@ -437,6 +460,7 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
EIGEN_STRONG_INLINE Scalar&
w() { return (*this)[3]; }
+#ifndef EIGEN_TEST_EVALUATORS
/** \internal
* Stores the given packet of coefficients, at the given row and column of this expression. It is your responsibility
* to ensure that a packet really starts there. This method is only available on expressions having the
@@ -573,6 +597,7 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
derived().template copyPacket< OtherDerived, StoreMode, LoadMode>(row, col, other);
}
#endif
+#endif // EIGEN_TEST_EVALUATORS
};
diff --git a/Eigen/src/Core/Inverse.h b/Eigen/src/Core/Inverse.h
index 57eaf99f1..788d0664d 100644
--- a/Eigen/src/Core/Inverse.h
+++ b/Eigen/src/Core/Inverse.h
@@ -81,6 +81,7 @@ public:
typedef MatrixBase<Derived> Base;
EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
+ typedef typename internal::remove_all<XprType>::type NestedExpression;
private:
@@ -101,19 +102,19 @@ namespace internal {
* \sa class Inverse
*/
template<typename XprType>
-struct evaluator<Inverse<XprType> >
+struct unary_evaluator<Inverse<XprType> >
: public evaluator<typename Inverse<XprType>::PlainObject>::type
{
typedef Inverse<XprType> InverseType;
typedef typename InverseType::PlainObject PlainObject;
typedef typename evaluator<PlainObject>::type Base;
- typedef evaluator type;
- typedef evaluator nestedType;
+ typedef evaluator<XprType> type;
+ typedef evaluator<XprType> nestedType;
enum { Flags = Base::Flags | EvalBeforeNestingBit };
- evaluator(const InverseType& inv_xpr)
+ unary_evaluator(const InverseType& inv_xpr)
: m_result(inv_xpr.rows(), inv_xpr.cols())
{
::new (static_cast<Base*>(this)) Base(m_result);
diff --git a/Eigen/src/Core/Replicate.h b/Eigen/src/Core/Replicate.h
index 2dff03ea3..e63f0d421 100644
--- a/Eigen/src/Core/Replicate.h
+++ b/Eigen/src/Core/Replicate.h
@@ -74,6 +74,7 @@ template<typename MatrixType,int RowFactor,int ColFactor> class Replicate
typedef typename internal::dense_xpr_base<Replicate>::type Base;
EIGEN_DENSE_PUBLIC_INTERFACE(Replicate)
+ typedef typename internal::remove_all<MatrixType>::type NestedExpression;
template<typename OriginalMatrixType>
inline explicit Replicate(const OriginalMatrixType& a_matrix)
diff --git a/Eigen/src/Core/ReturnByValue.h b/Eigen/src/Core/ReturnByValue.h
index d63b96138..30ade1b75 100644
--- a/Eigen/src/Core/ReturnByValue.h
+++ b/Eigen/src/Core/ReturnByValue.h
@@ -92,6 +92,34 @@ Derived& DenseBase<Derived>::operator=(const ReturnByValue<OtherDerived>& other)
return derived();
}
+#ifdef EIGEN_TEST_EVALUATORS
+namespace internal {
+
+template<typename Derived>
+struct evaluator<ReturnByValue<Derived> >
+ : public evaluator<typename internal::traits<Derived>::ReturnType>::type
+{
+ typedef ReturnByValue<Derived> XprType;
+ typedef typename internal::traits<Derived>::ReturnType PlainObject;
+ typedef typename evaluator<PlainObject>::type Base;
+
+ typedef evaluator type;
+ typedef evaluator nestedType;
+
+ evaluator(const XprType& xpr)
+ : m_result(xpr.rows(), xpr.cols())
+ {
+ ::new (static_cast<Base*>(this)) Base(m_result);
+ xpr.evalTo(m_result);
+ }
+
+protected:
+ PlainObject m_result;
+};
+
+} // end namespace internal
+#endif
+
} // end namespace Eigen
#endif // EIGEN_RETURNBYVALUE_H
diff --git a/Eigen/src/Core/Reverse.h b/Eigen/src/Core/Reverse.h
index 4969bb4fc..ceb6e4701 100644
--- a/Eigen/src/Core/Reverse.h
+++ b/Eigen/src/Core/Reverse.h
@@ -77,6 +77,7 @@ template<typename MatrixType, int Direction> class Reverse
typedef typename internal::dense_xpr_base<Reverse>::type Base;
EIGEN_DENSE_PUBLIC_INTERFACE(Reverse)
+ typedef typename internal::remove_all<MatrixType>::type NestedExpression;
using Base::IsRowMajor;
// next line is necessary because otherwise const version of operator()
diff --git a/Eigen/src/Core/Transpose.h b/Eigen/src/Core/Transpose.h
index 079f21fd9..4b605dfd6 100644
--- a/Eigen/src/Core/Transpose.h
+++ b/Eigen/src/Core/Transpose.h
@@ -68,6 +68,7 @@ template<typename MatrixType> class Transpose
typedef typename TransposeImpl<MatrixType,typename internal::traits<MatrixType>::StorageKind>::Base Base;
EIGEN_GENERIC_PUBLIC_INTERFACE(Transpose)
+ typedef typename internal::remove_all<MatrixType>::type NestedExpression;
EIGEN_DEVICE_FUNC
inline Transpose(MatrixType& a_matrix) : m_matrix(a_matrix) {}
@@ -113,6 +114,7 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Dense>
public:
typedef typename internal::TransposeImpl_base<MatrixType>::type Base;
+ using Base::coeffRef;
EIGEN_DENSE_PUBLIC_INTERFACE(Transpose<MatrixType>)
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(TransposeImpl)
@@ -127,6 +129,8 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Dense>
inline ScalarWithConstIfNotLvalue* data() { return derived().nestedExpression().data(); }
inline const Scalar* data() const { return derived().nestedExpression().data(); }
+
+#ifndef EIGEN_TEST_EVALUATORS
EIGEN_DEVICE_FUNC
inline ScalarWithConstIfNotLvalue& coeffRef(Index rowId, Index colId)
@@ -143,18 +147,6 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Dense>
}
EIGEN_DEVICE_FUNC
- inline const Scalar& coeffRef(Index rowId, Index colId) const
- {
- return derived().nestedExpression().coeffRef(colId, rowId);
- }
-
- EIGEN_DEVICE_FUNC
- inline const Scalar& coeffRef(Index index) const
- {
- return derived().nestedExpression().coeffRef(index);
- }
-
- EIGEN_DEVICE_FUNC
inline CoeffReturnType coeff(Index rowId, Index colId) const
{
return derived().nestedExpression().coeff(colId, rowId);
@@ -189,6 +181,20 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Dense>
{
derived().nestedExpression().const_cast_derived().template writePacket<LoadMode>(index, x);
}
+#endif
+
+ // FIXME: shall we keep the const version of coeffRef?
+ EIGEN_DEVICE_FUNC
+ inline const Scalar& coeffRef(Index rowId, Index colId) const
+ {
+ return derived().nestedExpression().coeffRef(colId, rowId);
+ }
+
+ EIGEN_DEVICE_FUNC
+ inline const Scalar& coeffRef(Index index) const
+ {
+ return derived().nestedExpression().coeffRef(index);
+ }
};
/** \returns an expression of the transpose of *this.
diff --git a/Eigen/src/Core/TriangularMatrix.h b/Eigen/src/Core/TriangularMatrix.h
index 064e0e10d..180efdd62 100644
--- a/Eigen/src/Core/TriangularMatrix.h
+++ b/Eigen/src/Core/TriangularMatrix.h
@@ -1071,8 +1071,8 @@ struct evaluator_traits<TriangularView<MatrixType,Mode> >
static const int AssumeAliasing = 0;
};
-template<typename MatrixType, unsigned int Mode, typename Kind>
-struct evaluator<TriangularView<MatrixType,Mode>, Kind, typename MatrixType::Scalar>
+template<typename MatrixType, unsigned int Mode>
+struct evaluator<TriangularView<MatrixType,Mode> >
: evaluator<typename internal::remove_all<MatrixType>::type>
{
typedef TriangularView<MatrixType,Mode> XprType;
diff --git a/Eigen/src/Core/products/GeneralMatrixMatrix.h b/Eigen/src/Core/products/GeneralMatrixMatrix.h
index 1726f98ed..b0a09216d 100644
--- a/Eigen/src/Core/products/GeneralMatrixMatrix.h
+++ b/Eigen/src/Core/products/GeneralMatrixMatrix.h
@@ -219,8 +219,8 @@ struct gemm_functor
cols = m_rhs.cols();
Gemm::run(rows, cols, m_lhs.cols(),
- /*(const Scalar*)*/&m_lhs.coeffRef(row,0), m_lhs.outerStride(),
- /*(const Scalar*)*/&m_rhs.coeffRef(0,col), m_rhs.outerStride(),
+ &m_lhs.coeffRef(row,0), m_lhs.outerStride(),
+ &m_rhs.coeffRef(0,col), m_rhs.outerStride(),
(Scalar*)&(m_dest.coeffRef(row,col)), m_dest.outerStride(),
m_actualAlpha, m_blocking, info);
}
diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h
index 092ba758e..ead5de650 100644
--- a/Eigen/src/Core/util/ForwardDeclarations.h
+++ b/Eigen/src/Core/util/ForwardDeclarations.h
@@ -38,9 +38,7 @@ template<typename Derived> struct accessors_level
template<typename T> struct evaluator_traits;
-template< typename T,
- typename Kind = typename evaluator_traits<T>::Kind,
- typename Scalar = typename T::Scalar> struct evaluator;
+template< typename T> struct evaluator;
} // end namespace internal
diff --git a/Eigen/src/Core/util/XprHelper.h b/Eigen/src/Core/util/XprHelper.h
index 0be5029c9..5407645c9 100644
--- a/Eigen/src/Core/util/XprHelper.h
+++ b/Eigen/src/Core/util/XprHelper.h
@@ -465,6 +465,15 @@ struct dense_xpr_base<Derived, ArrayXpr>
typedef ArrayBase<Derived> type;
};
+template<typename Derived, typename XprKind = typename traits<Derived>::XprKind, typename StorageKind = typename traits<Derived>::StorageKind>
+struct generic_xpr_base;
+
+template<typename Derived, typename XprKind>
+struct generic_xpr_base<Derived, XprKind, Dense>
+{
+ typedef typename dense_xpr_base<Derived,XprKind>::type type;
+};
+
/** \internal Helper base class to add a scalar multiple operator
* overloads for complex types */
template<typename Derived,typename Scalar,typename OtherScalar,