Implement swap using evaluators.

This commit is contained in:
Jitse Niesen
2011-04-28 15:52:15 +01:00
parent 2d11041e24
commit 3b60d2dbc4
4 changed files with 107 additions and 5 deletions

View File

@@ -65,7 +65,7 @@ struct evaluator_impl_base
{
Index row = rowIndexByOuterInner(outer, inner);
Index col = colIndexByOuterInner(outer, inner);
derived().coeffRef(row, col) = other.coeff(row, col);
derived().copyCoeff(row, col, other);
}
template<typename OtherEvaluatorType>
@@ -86,8 +86,7 @@ struct evaluator_impl_base
{
Index row = rowIndexByOuterInner(outer, inner);
Index col = colIndexByOuterInner(outer, inner);
derived().template writePacket<StoreMode>(row, col,
other.template packet<LoadMode>(row, col));
derived().template copyPacket<StoreMode, LoadMode>(row, col, other);
}
template<int StoreMode, int LoadMode, typename OtherEvaluatorType>
@@ -1017,6 +1016,75 @@ private:
};
// ---------- SwapWrapper ----------
template<typename ArgType>
struct evaluator_impl<SwapWrapper<ArgType> >
: evaluator_impl_base<SwapWrapper<ArgType> >
{
typedef SwapWrapper<ArgType> XprType;
evaluator_impl(const XprType& swapWrapper)
: m_argImpl(swapWrapper.expression())
{ }
typedef typename XprType::Index Index;
typedef typename XprType::Scalar Scalar;
typedef typename XprType::Packet Packet;
Scalar& coeffRef(Index row, Index col)
{
return m_argImpl.coeffRef(row, col);
}
inline Scalar& coeffRef(Index index)
{
return m_argImpl.coeffRef(index);
}
template<typename OtherEvaluatorType>
void copyCoeff(Index row, Index col, const OtherEvaluatorType& other)
{
OtherEvaluatorType& nonconst_other = const_cast<OtherEvaluatorType&>(other);
Scalar tmp = m_argImpl.coeff(row, col);
m_argImpl.coeffRef(row, col) = nonconst_other.coeff(row, col);
nonconst_other.coeffRef(row, col) = tmp;
}
template<typename OtherEvaluatorType>
void copyCoeff(Index index, const OtherEvaluatorType& other)
{
OtherEvaluatorType& nonconst_other = const_cast<OtherEvaluatorType&>(other);
Scalar tmp = m_argImpl.coeff(index);
m_argImpl.coeffRef(index) = nonconst_other.coeff(index);
nonconst_other.coeffRef(index) = tmp;
}
template<int StoreMode, int LoadMode, typename OtherEvaluatorType>
void copyPacket(Index row, Index col, const OtherEvaluatorType& other)
{
OtherEvaluatorType& nonconst_other = const_cast<OtherEvaluatorType&>(other);
Packet tmp = m_argImpl.template packet<StoreMode>(row, col);
m_argImpl.template writePacket<StoreMode>
(row, col, nonconst_other.template packet<LoadMode>(row, col));
nonconst_other.template writePacket<LoadMode>(row, col, tmp);
}
template<int StoreMode, int LoadMode, typename OtherEvaluatorType>
void copyPacket(Index index, const OtherEvaluatorType& other)
{
OtherEvaluatorType& nonconst_other = const_cast<OtherEvaluatorType&>(other);
Packet tmp = m_argImpl.template packet<StoreMode>(index);
m_argImpl.template writePacket<StoreMode>
(index, nonconst_other.template packet<LoadMode>(index));
nonconst_other.template writePacket<LoadMode>(index, tmp);
}
protected:
typename evaluator<ArgType>::type m_argImpl;
};
} // namespace internal
#endif // EIGEN_COREEVALUATORS_H