introduce DenseCoeffsBase: this is where the coeff / coeffRef / etc... methods go.

Rationale: coeffRef() methods should only exist when we have DirectAccess. So a natural thing to do would have been to use enable_if, but since there are many methods it made more sense to do the "enable_if" for the whole group by introducing a new class. And that also that the benefit of not changing method prototypes.
This commit is contained in:
Benoit Jacob 2010-05-08 13:45:31 -04:00
parent d03779f75f
commit bfdc1c4973
7 changed files with 471 additions and 479 deletions

View File

@ -232,10 +232,10 @@ using std::size_t;
#include "src/Core/arch/Default/Settings.h"
#include "src/Core/Functors.h"
#include "src/Core/Coeffs.h"
#include "src/Core/DenseBase.h"
#include "src/Core/MatrixBase.h"
#include "src/Core/EigenBase.h"
#include "src/Core/Coeffs.h"
#ifndef EIGEN_PARSED_BY_DOXYGEN // work around Doxygen bug triggered by Assign.h r814874
// at least confirmed with Doxygen 1.5.5 and 1.5.6

View File

@ -25,8 +25,20 @@
#ifndef EIGEN_COEFFS_H
#define EIGEN_COEFFS_H
template<typename Derived>
EIGEN_STRONG_INLINE int DenseBase<Derived>::rowIndexByOuterInner(int outer, int inner)
template<typename Derived, bool EnableDirectAccessAPI>
class DenseCoeffsBase : public EigenBase<Derived>
{
public:
typedef typename ei_traits<Derived>::Scalar Scalar;
typedef typename ei_meta_if<ei_has_direct_access<Derived>::ret, const Scalar&, Scalar>::ret CoeffReturnType;
typedef EigenBase<Derived> Base;
using Base::rows;
using Base::cols;
using Base::size;
using Base::derived;
EIGEN_STRONG_INLINE int rowIndexByOuterInner(int outer, int inner) const
{
return int(Derived::RowsAtCompileTime) == 1 ? 0
: int(Derived::ColsAtCompileTime) == 1 ? inner
@ -34,8 +46,7 @@ EIGEN_STRONG_INLINE int DenseBase<Derived>::rowIndexByOuterInner(int outer, int
: inner;
}
template<typename Derived>
EIGEN_STRONG_INLINE int DenseBase<Derived>::colIndexByOuterInner(int outer, int inner)
EIGEN_STRONG_INLINE int colIndexByOuterInner(int outer, int inner) const
{
return int(Derived::ColsAtCompileTime) == 1 ? 0
: int(Derived::RowsAtCompileTime) == 1 ? inner
@ -57,18 +68,14 @@ EIGEN_STRONG_INLINE int DenseBase<Derived>::colIndexByOuterInner(int outer, int
*
* \sa operator()(int,int) const, coeffRef(int,int), coeff(int) const
*/
template<typename Derived>
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::CoeffReturnType DenseBase<Derived>
::coeff(int row, int col) const
EIGEN_STRONG_INLINE const CoeffReturnType coeff(int row, int col) const
{
ei_internal_assert(row >= 0 && row < rows()
&& col >= 0 && col < cols());
return derived().coeff(row, col);
}
template<typename Derived>
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::CoeffReturnType DenseBase<Derived>
::coeffByOuterInner(int outer, int inner) const
EIGEN_STRONG_INLINE const CoeffReturnType coeffByOuterInner(int outer, int inner) const
{
return coeff(rowIndexByOuterInner(outer, inner),
colIndexByOuterInner(outer, inner));
@ -76,61 +83,15 @@ EIGEN_STRONG_INLINE const typename DenseBase<Derived>::CoeffReturnType DenseBase
/** \returns the coefficient at given the given row and column.
*
* \sa operator()(int,int), operator[](int) const
* \sa operator()(int,int), operator[](int)
*/
template<typename Derived>
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::CoeffReturnType DenseBase<Derived>
::operator()(int row, int col) const
EIGEN_STRONG_INLINE const CoeffReturnType operator()(int row, int col) const
{
ei_assert(row >= 0 && row < rows()
&& col >= 0 && col < cols());
return derived().coeff(row, col);
}
/** Short version: don't use this function, use
* \link operator()(int,int) \endlink instead.
*
* Long version: this function is similar to
* \link operator()(int,int) \endlink, but without the assertion.
* Use this for limiting the performance cost of debugging code when doing
* repeated coefficient access. Only use this when it is guaranteed that the
* parameters \a row and \a col are in range.
*
* If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this
* function equivalent to \link operator()(int,int) \endlink.
*
* \sa operator()(int,int), coeff(int, int) const, coeffRef(int)
*/
template<typename Derived>
EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& DenseBase<Derived>
::coeffRef(int row, int col)
{
ei_internal_assert(row >= 0 && row < rows()
&& col >= 0 && col < cols());
return derived().coeffRef(row, col);
}
template<typename Derived>
EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& DenseBase<Derived>
::coeffRefByOuterInner(int outer, int inner)
{
return coeffRef(rowIndexByOuterInner(outer, inner),
colIndexByOuterInner(outer, inner));
}
/** \returns a reference to the coefficient at given the given row and column.
*
* \sa operator()(int,int) const, operator[](int)
*/
template<typename Derived>
EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& DenseBase<Derived>
::operator()(int row, int col)
{
ei_assert(row >= 0 && row < rows()
&& col >= 0 && col < cols());
return derived().coeffRef(row, col);
}
/** Short version: don't use this function, use
* \link operator[](int) const \endlink instead.
*
@ -145,14 +106,15 @@ EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& DenseBase<Derived>
*
* \sa operator[](int) const, coeffRef(int), coeff(int,int) const
*/
template<typename Derived>
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::CoeffReturnType DenseBase<Derived>
::coeff(int index) const
EIGEN_STRONG_INLINE const CoeffReturnType
coeff(int index) const
{
ei_internal_assert(index >= 0 && index < size());
return derived().coeff(index);
}
/** \returns the coefficient at given index.
*
* This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit.
@ -160,9 +122,9 @@ EIGEN_STRONG_INLINE const typename DenseBase<Derived>::CoeffReturnType DenseBase
* \sa operator[](int), operator()(int,int) const, x() const, y() const,
* z() const, w() const
*/
template<typename Derived>
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::CoeffReturnType DenseBase<Derived>
::operator[](int index) const
EIGEN_STRONG_INLINE const CoeffReturnType
operator[](int index) const
{
EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
@ -179,14 +141,146 @@ EIGEN_STRONG_INLINE const typename DenseBase<Derived>::CoeffReturnType DenseBase
* \sa operator[](int), operator()(int,int) const, x() const, y() const,
* z() const, w() const
*/
template<typename Derived>
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::CoeffReturnType DenseBase<Derived>
::operator()(int index) const
EIGEN_STRONG_INLINE const CoeffReturnType
operator()(int index) const
{
ei_assert(index >= 0 && index < size());
return derived().coeff(index);
}
/** equivalent to operator[](0). */
EIGEN_STRONG_INLINE const CoeffReturnType
x() const { return (*this)[0]; }
/** equivalent to operator[](1). */
EIGEN_STRONG_INLINE const CoeffReturnType
y() const { return (*this)[1]; }
/** equivalent to operator[](2). */
EIGEN_STRONG_INLINE const CoeffReturnType
z() const { return (*this)[2]; }
/** equivalent to operator[](3). */
EIGEN_STRONG_INLINE const CoeffReturnType
w() const { return (*this)[3]; }
/** \returns the packet of coefficients starting at the given row and column. It is your responsibility
* to ensure that a packet really starts there. This method is only available on expressions having the
* PacketAccessBit.
*
* The \a LoadMode parameter may have the value \a Aligned or \a Unaligned. Its effect is to select
* the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets
* starting at an address which is a multiple of the packet size.
*/
template<int LoadMode>
EIGEN_STRONG_INLINE typename ei_packet_traits<Scalar>::type
packet(int row, int col) const
{
ei_internal_assert(row >= 0 && row < rows()
&& col >= 0 && col < cols());
return derived().template packet<LoadMode>(row,col);
}
template<int LoadMode>
EIGEN_STRONG_INLINE typename ei_packet_traits<Scalar>::type
packetByOuterInner(int outer, int inner) const
{
return packet<LoadMode>(rowIndexByOuterInner(outer, inner),
colIndexByOuterInner(outer, inner));
}
/** \returns the packet of coefficients starting at the given index. It is your responsibility
* to ensure that a packet really starts there. This method is only available on expressions having the
* PacketAccessBit and the LinearAccessBit.
*
* The \a LoadMode parameter may have the value \a Aligned or \a Unaligned. Its effect is to select
* the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets
* starting at an address which is a multiple of the packet size.
*/
template<int LoadMode>
EIGEN_STRONG_INLINE typename ei_packet_traits<Scalar>::type
packet(int index) const
{
ei_internal_assert(index >= 0 && index < size());
return derived().template packet<LoadMode>(index);
}
void coeffRef();
void coeffRefByOuterInner();
void writePacket();
void writePacketByOuterInner();
void copyCoeff();
void copyCoeffByOuterInner();
void copyPacket();
void copyPacketByOuterInner();
};
template<typename Derived>
class DenseCoeffsBase<Derived, true> : public DenseCoeffsBase<Derived, false>
{
public:
typedef DenseCoeffsBase<Derived, false> Base;
typedef typename ei_traits<Derived>::Scalar Scalar;
using Base::CoeffReturnType;
using Base::coeff;
using Base::rows;
using Base::cols;
using Base::size;
using Base::derived;
using Base::rowIndexByOuterInner;
using Base::colIndexByOuterInner;
/** Short version: don't use this function, use
* \link operator()(int,int) \endlink instead.
*
* Long version: this function is similar to
* \link operator()(int,int) \endlink, but without the assertion.
* Use this for limiting the performance cost of debugging code when doing
* repeated coefficient access. Only use this when it is guaranteed that the
* parameters \a row and \a col are in range.
*
* If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this
* function equivalent to \link operator()(int,int) \endlink.
*
* \sa operator()(int,int), coeff(int, int) const, coeffRef(int)
*/
EIGEN_STRONG_INLINE Scalar& coeffRef(int row, int col)
{
ei_internal_assert(row >= 0 && row < rows()
&& col >= 0 && col < cols());
return derived().coeffRef(row, col);
}
EIGEN_STRONG_INLINE Scalar&
coeffRefByOuterInner(int outer, int inner)
{
return coeffRef(rowIndexByOuterInner(outer, inner),
colIndexByOuterInner(outer, inner));
}
/** \returns a reference to the coefficient at given the given row and column.
*
* \sa operator[](int)
*/
EIGEN_STRONG_INLINE Scalar&
operator()(int row, int col)
{
ei_assert(row >= 0 && row < rows()
&& col >= 0 && col < cols());
return derived().coeffRef(row, col);
}
/** Short version: don't use this function, use
* \link operator[](int) \endlink instead.
*
@ -201,9 +295,9 @@ EIGEN_STRONG_INLINE const typename DenseBase<Derived>::CoeffReturnType DenseBase
*
* \sa operator[](int), coeff(int) const, coeffRef(int,int)
*/
template<typename Derived>
EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& DenseBase<Derived>
::coeffRef(int index)
EIGEN_STRONG_INLINE Scalar&
coeffRef(int index)
{
ei_internal_assert(index >= 0 && index < size());
return derived().coeffRef(index);
@ -215,9 +309,9 @@ EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& DenseBase<Derived>
*
* \sa operator[](int) const, operator()(int,int), x(), y(), z(), w()
*/
template<typename Derived>
EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& DenseBase<Derived>
::operator[](int index)
EIGEN_STRONG_INLINE Scalar&
operator[](int index)
{
EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
@ -233,80 +327,33 @@ EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& DenseBase<Derived>
*
* \sa operator[](int) const, operator()(int,int), x(), y(), z(), w()
*/
template<typename Derived>
EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& DenseBase<Derived>
::operator()(int index)
EIGEN_STRONG_INLINE Scalar&
operator()(int index)
{
ei_assert(index >= 0 && index < size());
return derived().coeffRef(index);
}
/** equivalent to operator[](0). */
template<typename Derived>
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::CoeffReturnType DenseBase<Derived>
::x() const { return (*this)[0]; }
EIGEN_STRONG_INLINE Scalar&
x() { return (*this)[0]; }
/** equivalent to operator[](1). */
template<typename Derived>
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::CoeffReturnType DenseBase<Derived>
::y() const { return (*this)[1]; }
EIGEN_STRONG_INLINE Scalar&
y() { return (*this)[1]; }
/** equivalent to operator[](2). */
template<typename Derived>
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::CoeffReturnType DenseBase<Derived>
::z() const { return (*this)[2]; }
EIGEN_STRONG_INLINE Scalar&
z() { return (*this)[2]; }
/** equivalent to operator[](3). */
template<typename Derived>
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::CoeffReturnType DenseBase<Derived>
::w() const { return (*this)[3]; }
/** equivalent to operator[](0). */
template<typename Derived>
EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& DenseBase<Derived>
::x() { return (*this)[0]; }
/** equivalent to operator[](1). */
template<typename Derived>
EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& DenseBase<Derived>
::y() { return (*this)[1]; }
/** equivalent to operator[](2). */
template<typename Derived>
EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& DenseBase<Derived>
::z() { return (*this)[2]; }
/** equivalent to operator[](3). */
template<typename Derived>
EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& DenseBase<Derived>
::w() { return (*this)[3]; }
/** \returns the packet of coefficients starting at the given row and column. It is your responsibility
* to ensure that a packet really starts there. This method is only available on expressions having the
* PacketAccessBit.
*
* The \a LoadMode parameter may have the value \a Aligned or \a Unaligned. Its effect is to select
* the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets
* starting at an address which is a multiple of the packet size.
*/
template<typename Derived>
template<int LoadMode>
EIGEN_STRONG_INLINE typename ei_packet_traits<typename ei_traits<Derived>::Scalar>::type
DenseBase<Derived>::packet(int row, int col) const
{
ei_internal_assert(row >= 0 && row < rows()
&& col >= 0 && col < cols());
return derived().template packet<LoadMode>(row,col);
}
template<typename Derived>
template<int LoadMode>
EIGEN_STRONG_INLINE typename ei_packet_traits<typename ei_traits<Derived>::Scalar>::type
DenseBase<Derived>::packetByOuterInner(int outer, int inner) const
{
return packet<LoadMode>(rowIndexByOuterInner(outer, inner),
colIndexByOuterInner(outer, inner));
}
EIGEN_STRONG_INLINE Scalar&
w() { return (*this)[3]; }
/** 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
@ -316,43 +363,26 @@ DenseBase<Derived>::packetByOuterInner(int outer, int inner) const
* the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets
* starting at an address which is a multiple of the packet size.
*/
template<typename Derived>
template<int StoreMode>
EIGEN_STRONG_INLINE void DenseBase<Derived>::writePacket
(int row, int col, const typename ei_packet_traits<typename ei_traits<Derived>::Scalar>::type& x)
EIGEN_STRONG_INLINE void writePacket
(int row, int col, const typename ei_packet_traits<Scalar>::type& x)
{
ei_internal_assert(row >= 0 && row < rows()
&& col >= 0 && col < cols());
derived().template writePacket<StoreMode>(row,col,x);
}
template<typename Derived>
template<int StoreMode>
EIGEN_STRONG_INLINE void DenseBase<Derived>::writePacketByOuterInner
(int outer, int inner, const typename ei_packet_traits<typename ei_traits<Derived>::Scalar>::type& x)
EIGEN_STRONG_INLINE void writePacketByOuterInner
(int outer, int inner, const typename ei_packet_traits<Scalar>::type& x)
{
writePacket<StoreMode>(rowIndexByOuterInner(outer, inner),
colIndexByOuterInner(outer, inner),
x);
}
/** \returns the packet of coefficients starting at the given index. It is your responsibility
* to ensure that a packet really starts there. This method is only available on expressions having the
* PacketAccessBit and the LinearAccessBit.
*
* The \a LoadMode parameter may have the value \a Aligned or \a Unaligned. Its effect is to select
* the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets
* starting at an address which is a multiple of the packet size.
*/
template<typename Derived>
template<int LoadMode>
EIGEN_STRONG_INLINE typename ei_packet_traits<typename ei_traits<Derived>::Scalar>::type
DenseBase<Derived>::packet(int index) const
{
ei_internal_assert(index >= 0 && index < size());
return derived().template packet<LoadMode>(index);
}
/** Stores the given packet of coefficients, at the given index in this expression. It is your responsibility
* to ensure that a packet really starts there. This method is only available on expressions having the
* PacketAccessBit and the LinearAccessBit.
@ -361,10 +391,10 @@ DenseBase<Derived>::packet(int index) const
* the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets
* starting at an address which is a multiple of the packet size.
*/
template<typename Derived>
template<int StoreMode>
EIGEN_STRONG_INLINE void DenseBase<Derived>::writePacket
(int index, const typename ei_packet_traits<typename ei_traits<Derived>::Scalar>::type& x)
EIGEN_STRONG_INLINE void writePacket
(int index, const typename ei_packet_traits<Scalar>::type& x)
{
ei_internal_assert(index >= 0 && index < size());
derived().template writePacket<StoreMode>(index,x);
@ -379,9 +409,9 @@ EIGEN_STRONG_INLINE void DenseBase<Derived>::writePacket
*
* Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox.
*/
template<typename Derived>
template<typename OtherDerived>
EIGEN_STRONG_INLINE void DenseBase<Derived>::copyCoeff(int row, int col, const DenseBase<OtherDerived>& other)
EIGEN_STRONG_INLINE void copyCoeff(int row, int col, const DenseBase<OtherDerived>& other)
{
ei_internal_assert(row >= 0 && row < rows()
&& col >= 0 && col < cols());
@ -395,20 +425,20 @@ EIGEN_STRONG_INLINE void DenseBase<Derived>::copyCoeff(int row, int col, const D
*
* Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox.
*/
template<typename Derived>
template<typename OtherDerived>
EIGEN_STRONG_INLINE void DenseBase<Derived>::copyCoeff(int index, const DenseBase<OtherDerived>& other)
EIGEN_STRONG_INLINE void copyCoeff(int index, const DenseBase<OtherDerived>& other)
{
ei_internal_assert(index >= 0 && index < size());
derived().coeffRef(index) = other.derived().coeff(index);
}
template<typename Derived>
template<typename OtherDerived>
EIGEN_STRONG_INLINE void DenseBase<Derived>::copyCoeffByOuterInner(int outer, int inner, const DenseBase<OtherDerived>& other)
EIGEN_STRONG_INLINE void copyCoeffByOuterInner(int outer, int inner, const DenseBase<OtherDerived>& other)
{
const int row = Derived::rowIndexByOuterInner(outer,inner);
const int col = Derived::colIndexByOuterInner(outer,inner);
const int row = rowIndexByOuterInner(outer,inner);
const int col = colIndexByOuterInner(outer,inner);
// derived() is important here: copyCoeff() may be reimplemented in Derived!
derived().copyCoeff(row, col, other);
}
@ -420,9 +450,9 @@ EIGEN_STRONG_INLINE void DenseBase<Derived>::copyCoeffByOuterInner(int outer, in
*
* Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox.
*/
template<typename Derived>
template<typename OtherDerived, int StoreMode, int LoadMode>
EIGEN_STRONG_INLINE void DenseBase<Derived>::copyPacket(int row, int col, const DenseBase<OtherDerived>& other)
EIGEN_STRONG_INLINE void copyPacket(int row, int col, const DenseBase<OtherDerived>& other)
{
ei_internal_assert(row >= 0 && row < rows()
&& col >= 0 && col < cols());
@ -437,36 +467,37 @@ EIGEN_STRONG_INLINE void DenseBase<Derived>::copyPacket(int row, int col, const
*
* Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox.
*/
template<typename Derived>
template<typename OtherDerived, int StoreMode, int LoadMode>
EIGEN_STRONG_INLINE void DenseBase<Derived>::copyPacket(int index, const DenseBase<OtherDerived>& other)
EIGEN_STRONG_INLINE void copyPacket(int index, const DenseBase<OtherDerived>& other)
{
ei_internal_assert(index >= 0 && index < size());
derived().template writePacket<StoreMode>(index,
other.derived().template packet<LoadMode>(index));
}
template<typename Derived>
template<typename OtherDerived, int StoreMode, int LoadMode>
EIGEN_STRONG_INLINE void DenseBase<Derived>::copyPacketByOuterInner(int outer, int inner, const DenseBase<OtherDerived>& other)
EIGEN_STRONG_INLINE void copyPacketByOuterInner(int outer, int inner, const DenseBase<OtherDerived>& other)
{
const int row = Derived::rowIndexByOuterInner(outer,inner);
const int col = Derived::colIndexByOuterInner(outer,inner);
const int row = rowIndexByOuterInner(outer,inner);
const int col = colIndexByOuterInner(outer,inner);
// derived() is important here: copyCoeff() may be reimplemented in Derived!
derived().copyPacket<OtherDerived, StoreMode, LoadMode>(row, col, other);
}
#endif
};
template<typename Derived, bool JustReturnZero>
struct ei_first_aligned_impl
{
inline static int run(const DenseBase<Derived>&)
inline static int run(const Derived&)
{ return 0; }
};
template<typename Derived>
struct ei_first_aligned_impl<Derived, false>
{
inline static int run(const DenseBase<Derived>& m)
inline static int run(const Derived& m)
{
return ei_first_aligned(&m.const_cast_derived().coeffRef(0,0), m.size());
}
@ -478,13 +509,11 @@ struct ei_first_aligned_impl<Derived, false>
* documentation.
*/
template<typename Derived>
inline static int ei_first_aligned(const DenseBase<Derived>& m)
inline static int ei_first_aligned(const Derived& m)
{
return ei_first_aligned_impl
<Derived, (Derived::Flags & AlignedBit) || !(Derived::Flags & DirectAccessBit)>
::run(m);
}
#endif
#endif // EIGEN_COEFFS_H

View File

@ -64,7 +64,7 @@ template<typename Derived> class DenseBase
: public ei_special_scalar_op_base<Derived,typename ei_traits<Derived>::Scalar,
typename NumTraits<typename ei_traits<Derived>::Scalar>::Real>
#else
: public EigenBase<Derived>
: public DenseCoeffsBase<Derived>
#endif // not EIGEN_PARSED_BY_DOXYGEN
{
public:
@ -76,9 +76,33 @@ template<typename Derived> class DenseBase
typedef typename ei_traits<Derived>::Scalar Scalar;
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
typedef DenseCoeffsBase<Derived> Base;
using Base::derived;
using Base::const_cast_derived;
using Base::rows;
using Base::cols;
using Base::size;
using Base::rowIndexByOuterInner;
using Base::colIndexByOuterInner;
using Base::coeff;
using Base::coeffByOuterInner;
using Base::packet;
using Base::packetByOuterInner;
using Base::writePacket;
using Base::writePacketByOuterInner;
using Base::coeffRef;
using Base::coeffRefByOuterInner;
using Base::copyCoeff;
using Base::copyCoeffByOuterInner;
using Base::copyPacket;
using Base::copyPacketByOuterInner;
using Base::operator();
using Base::operator[];
using Base::x;
using Base::y;
using Base::z;
using Base::w;
using EigenBase<Derived>::derived;
using EigenBase<Derived>::const_cast_derived;
#endif // not EIGEN_PARSED_BY_DOXYGEN
enum {
@ -172,13 +196,6 @@ template<typename Derived> class DenseBase
typedef typename NumTraits<Scalar>::Real RealScalar;
#endif // not EIGEN_PARSED_BY_DOXYGEN
/** \returns the number of rows. \sa cols(), RowsAtCompileTime */
inline int rows() const { return derived().rows(); }
/** \returns the number of columns. \sa rows(), ColsAtCompileTime*/
inline int cols() const { return derived().cols(); }
/** \returns the number of coefficients, which is rows()*cols().
* \sa rows(), cols(), SizeAtCompileTime. */
inline int size() const { return rows() * cols(); }
/** \returns the number of nonzero coefficients which is in practice the number
* of stored coefficients. */
inline int nonZeros() const { return size(); }
@ -257,15 +274,6 @@ template<typename Derived> class DenseBase
#endif // not EIGEN_PARSED_BY_DOXYGEN
const CoeffReturnType x() const;
const CoeffReturnType y() const;
const CoeffReturnType z() const;
const CoeffReturnType w() const;
Scalar& x();
Scalar& y();
Scalar& z();
Scalar& w();
/** Copies \a other into *this. \returns a reference to *this. */
template<typename OtherDerived>
Derived& operator=(const DenseBase<OtherDerived>& other);
@ -343,56 +351,6 @@ template<typename Derived> class DenseBase
template<typename OtherDerived>
CommaInitializer<Derived> operator<< (const DenseBase<OtherDerived>& other);
const CoeffReturnType coeff(int row, int col) const;
const CoeffReturnType coeffByOuterInner(int outer, int inner) const;
const CoeffReturnType operator()(int row, int col) const;
Scalar& coeffRef(int row, int col);
Scalar& coeffRefByOuterInner(int outer, int inner);
Scalar& operator()(int row, int col);
const CoeffReturnType coeff(int index) const;
const CoeffReturnType operator[](int index) const;
const CoeffReturnType operator()(int index) const;
Scalar& coeffRef(int index);
Scalar& operator[](int index);
Scalar& operator()(int index);
#ifndef EIGEN_PARSED_BY_DOXYGEN
template<typename OtherDerived>
void copyCoeff(int row, int col, const DenseBase<OtherDerived>& other);
template<typename OtherDerived>
void copyCoeffByOuterInner(int outer, int inner, const DenseBase<OtherDerived>& other);
template<typename OtherDerived>
void copyCoeff(int index, const DenseBase<OtherDerived>& other);
template<typename OtherDerived, int StoreMode, int LoadMode>
void copyPacket(int row, int col, const DenseBase<OtherDerived>& other);
template<typename OtherDerived, int StoreMode, int LoadMode>
void copyPacketByOuterInner(int outer, int inner, const DenseBase<OtherDerived>& other);
template<typename OtherDerived, int StoreMode, int LoadMode>
void copyPacket(int index, const DenseBase<OtherDerived>& other);
private:
static int rowIndexByOuterInner(int outer, int inner);
static int colIndexByOuterInner(int outer, int inner);
public:
#endif // not EIGEN_PARSED_BY_DOXYGEN
template<int LoadMode>
PacketScalar packet(int row, int col) const;
template<int LoadMode>
PacketScalar packetByOuterInner(int outer, int inner) const;
template<int StoreMode>
void writePacket(int row, int col, const PacketScalar& x);
template<int StoreMode>
void writePacketByOuterInner(int outer, int inner, const PacketScalar& x);
template<int LoadMode>
PacketScalar packet(int index) const;
template<int StoreMode>
void writePacket(int index, const PacketScalar& x);
Eigen::Transpose<Derived> transpose();
const Eigen::Transpose<Derived> transpose() const;
void transposeInPlace();

View File

@ -51,6 +51,9 @@ template<typename Derived> struct EigenBase
inline int rows() const { return derived().rows(); }
/** \returns the number of columns. \sa rows(), ColsAtCompileTime*/
inline int cols() const { return derived().cols(); }
/** \returns the number of coefficients, which is rows()*cols().
* \sa rows(), cols(), SizeAtCompileTime. */
inline int size() const { return rows() * cols(); }
/** \internal Don't use it, but do the equivalent: \code dst = *this; \endcode */
template<typename Dest> inline void evalTo(Dest& dst) const

View File

@ -29,7 +29,15 @@
template<typename T> struct ei_traits;
template<typename T> struct NumTraits;
template<typename Derived> struct ei_has_direct_access
{
enum { ret = (ei_traits<Derived>::Flags & DirectAccessBit) ? 1 : 0 };
};
template<typename Derived> struct EigenBase;
template<typename Derived> struct DenseBase;
template<typename Derived, bool EnableDirectAccessAPI = ei_has_direct_access<Derived>::ret>
class DenseCoeffsBase;
template<typename _Scalar, int _Rows, int _Cols,
int _Options = AutoAlign |
@ -49,14 +57,6 @@ template<typename ExpressionType> class NestByValue;
template<typename ExpressionType> class ForceAlignedAccess;
template<typename ExpressionType> class SwapWrapper;
// MSVC has a big bug: when the expression ei_traits<MatrixType>::Flags&DirectAccessBit ? 1 : 0
// is used as default template parameter value here, it gets mis-evaluated as just ei_traits<MatrixType>::Flags
// Moreover, adding brackets tends to give compilation errors with MSVC.
// Solution: defer that to a helper struct.
template<typename Derived> struct ei_has_direct_access
{
enum { ret = (ei_traits<Derived>::Flags & DirectAccessBit) ? 1 : 0 };
};
template<typename XprType, int BlockRows=Dynamic, int BlockCols=Dynamic,
bool HasDirectAccess = ei_has_direct_access<XprType>::ret> class Block;

View File

@ -325,7 +325,7 @@ struct ei_dense_xpr_base<Derived, ArrayXpr>
* overloads for complex types */
template<typename Derived,typename Scalar,typename OtherScalar,
bool EnableIt = !ei_is_same_type<Scalar,OtherScalar>::ret >
struct ei_special_scalar_op_base : public EigenBase<Derived>
struct ei_special_scalar_op_base : public DenseCoeffsBase<Derived>
{
// dummy operator* so that the
// "using ei_special_scalar_op_base::operator*" compiles
@ -333,7 +333,7 @@ struct ei_special_scalar_op_base : public EigenBase<Derived>
};
template<typename Derived,typename Scalar,typename OtherScalar>
struct ei_special_scalar_op_base<Derived,Scalar,OtherScalar,true> : public EigenBase<Derived>
struct ei_special_scalar_op_base<Derived,Scalar,OtherScalar,true> : public DenseCoeffsBase<Derived>
{
const CwiseUnaryOp<ei_scalar_multiple2_op<Scalar,OtherScalar>, Derived>
operator*(const OtherScalar& scalar) const

View File

@ -152,6 +152,7 @@ template<typename MatrixType> void basicStuffComplex(const MatrixType& m)
VERIFY(!static_cast<const MatrixType&>(cm).imag().isZero());
}
#ifdef EIGEN_TEST_PART_2
void casting()
{
Matrix4f m = Matrix4f::Random(), m2;
@ -160,6 +161,7 @@ void casting()
m2 = m.cast<float>(); // check the specialization when NewType == Type
VERIFY(m.isApprox(m2));
}
#endif
void test_basicstuff()
{