aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Benoit Jacob <jacob.benoit.1@gmail.com>2010-05-08 13:45:31 -0400
committerGravatar Benoit Jacob <jacob.benoit.1@gmail.com>2010-05-08 13:45:31 -0400
commitbfdc1c49730c79e6058ba1506628341559670c25 (patch)
treecff450947e3fe4dabc07a382061c4664970a3a90
parentd03779f75f3a29b6cc76299f511aefc902771e4c (diff)
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.
-rw-r--r--Eigen/Core2
-rw-r--r--Eigen/src/Core/Coeffs.h889
-rw-r--r--Eigen/src/Core/DenseBase.h96
-rw-r--r--Eigen/src/Core/EigenBase.h3
-rw-r--r--Eigen/src/Core/util/ForwardDeclarations.h16
-rw-r--r--Eigen/src/Core/util/XprHelper.h4
-rw-r--r--test/basicstuff.cpp2
7 files changed, 502 insertions, 510 deletions
diff --git a/Eigen/Core b/Eigen/Core
index 0b2608036..464eb93f1 100644
--- a/Eigen/Core
+++ b/Eigen/Core
@@ -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
diff --git a/Eigen/src/Core/Coeffs.h b/Eigen/src/Core/Coeffs.h
index b26f3a4e4..661e57e74 100644
--- a/Eigen/src/Core/Coeffs.h
+++ b/Eigen/src/Core/Coeffs.h
@@ -25,448 +25,479 @@
#ifndef EIGEN_COEFFS_H
#define EIGEN_COEFFS_H
-template<typename Derived>
-EIGEN_STRONG_INLINE int DenseBase<Derived>::rowIndexByOuterInner(int outer, int inner)
-{
- return int(Derived::RowsAtCompileTime) == 1 ? 0
- : int(Derived::ColsAtCompileTime) == 1 ? inner
- : int(Derived::Flags)&RowMajorBit ? outer
- : inner;
-}
-
-template<typename Derived>
-EIGEN_STRONG_INLINE int DenseBase<Derived>::colIndexByOuterInner(int outer, int inner)
-{
- return int(Derived::ColsAtCompileTime) == 1 ? 0
- : int(Derived::RowsAtCompileTime) == 1 ? inner
- : int(Derived::Flags)&RowMajorBit ? inner
- : outer;
-}
-
-/** Short version: don't use this function, use
- * \link operator()(int,int) const \endlink instead.
- *
- * Long version: this function is similar to
- * \link operator()(int,int) const \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) const \endlink.
- *
- * \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
-{
- 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
-{
- return coeff(rowIndexByOuterInner(outer, inner),
- colIndexByOuterInner(outer, inner));
-}
-
-/** \returns the coefficient at given the given row and column.
- *
- * \sa operator()(int,int), operator[](int) const
- */
-template<typename Derived>
-EIGEN_STRONG_INLINE const typename DenseBase<Derived>::CoeffReturnType DenseBase<Derived>
- ::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.
- *
- * Long version: this function is similar to
- * \link operator[](int) const \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
- * parameter \a index is in range.
- *
- * If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this
- * function equivalent to \link operator[](int) const \endlink.
- *
- * \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
-{
- 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.
- *
- * \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_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
- THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
- ei_assert(index >= 0 && index < size());
- return derived().coeff(index);
-}
-
-/** \returns the coefficient at given index.
- *
- * This is synonymous to operator[](int) const.
- *
- * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit.
- *
- * \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
-{
- ei_assert(index >= 0 && index < size());
- return derived().coeff(index);
-}
-
-/** Short version: don't use this function, use
- * \link operator[](int) \endlink instead.
- *
- * Long version: this function is similar to
- * \link operator[](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) \endlink.
- *
- * \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)
-{
- ei_internal_assert(index >= 0 && index < size());
- return derived().coeffRef(index);
-}
-
-/** \returns a reference to the coefficient at given index.
- *
- * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit.
- *
- * \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_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
- THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
- ei_assert(index >= 0 && index < size());
- return derived().coeffRef(index);
-}
-
-/** \returns a reference to the coefficient at given index.
- *
- * This is synonymous to operator[](int).
- *
- * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit.
- *
- * \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)
+template<typename Derived, bool EnableDirectAccessAPI>
+class DenseCoeffsBase : public EigenBase<Derived>
{
- 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]; }
-
-/** equivalent to operator[](1). */
-template<typename Derived>
-EIGEN_STRONG_INLINE const typename DenseBase<Derived>::CoeffReturnType DenseBase<Derived>
- ::y() const { 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]; }
-
-/** 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));
-}
-
-/** 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
- * 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 StoreMode>
-EIGEN_STRONG_INLINE void DenseBase<Derived>::writePacket
-(int row, int col, const typename ei_packet_traits<typename ei_traits<Derived>::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)
-{
- 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);
-}
+ 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
+ : int(Derived::Flags)&RowMajorBit ? outer
+ : inner;
+ }
+
+ EIGEN_STRONG_INLINE int colIndexByOuterInner(int outer, int inner) const
+ {
+ return int(Derived::ColsAtCompileTime) == 1 ? 0
+ : int(Derived::RowsAtCompileTime) == 1 ? inner
+ : int(Derived::Flags)&RowMajorBit ? inner
+ : outer;
+ }
+
+ /** Short version: don't use this function, use
+ * \link operator()(int,int) const \endlink instead.
+ *
+ * Long version: this function is similar to
+ * \link operator()(int,int) const \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) const \endlink.
+ *
+ * \sa operator()(int,int) const, coeffRef(int,int), coeff(int) 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);
+ }
+
+ EIGEN_STRONG_INLINE const CoeffReturnType coeffByOuterInner(int outer, int inner) const
+ {
+ return coeff(rowIndexByOuterInner(outer, inner),
+ colIndexByOuterInner(outer, inner));
+ }
+
+ /** \returns the coefficient at given the given row and column.
+ *
+ * \sa operator()(int,int), operator[](int)
+ */
+ 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) const \endlink instead.
+ *
+ * Long version: this function is similar to
+ * \link operator[](int) const \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
+ * parameter \a index is in range.
+ *
+ * If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this
+ * function equivalent to \link operator[](int) const \endlink.
+ *
+ * \sa operator[](int) const, coeffRef(int), coeff(int,int) 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.
+ *
+ * \sa operator[](int), operator()(int,int) const, x() const, y() const,
+ * z() const, w() 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)
+ ei_assert(index >= 0 && index < size());
+ return derived().coeff(index);
+ }
+
+ /** \returns the coefficient at given index.
+ *
+ * This is synonymous to operator[](int) const.
+ *
+ * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit.
+ *
+ * \sa operator[](int), operator()(int,int) const, x() const, y() const,
+ * z() const, w() 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();
+};
-/** 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.
- *
- * 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 StoreMode>
-EIGEN_STRONG_INLINE void DenseBase<Derived>::writePacket
-(int index, const typename ei_packet_traits<typename ei_traits<Derived>::Scalar>::type& x)
+class DenseCoeffsBase<Derived, true> : public DenseCoeffsBase<Derived, false>
{
- ei_internal_assert(index >= 0 && index < size());
- derived().template writePacket<StoreMode>(index,x);
-}
+ 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.
+ *
+ * Long version: this function is similar to
+ * \link operator[](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) \endlink.
+ *
+ * \sa operator[](int), coeff(int) const, coeffRef(int,int)
+ */
+
+ EIGEN_STRONG_INLINE Scalar&
+ coeffRef(int index)
+ {
+ ei_internal_assert(index >= 0 && index < size());
+ return derived().coeffRef(index);
+ }
+
+ /** \returns a reference to the coefficient at given index.
+ *
+ * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit.
+ *
+ * \sa operator[](int) const, operator()(int,int), x(), y(), z(), w()
+ */
+
+ EIGEN_STRONG_INLINE Scalar&
+ operator[](int index)
+ {
+ EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
+ THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
+ ei_assert(index >= 0 && index < size());
+ return derived().coeffRef(index);
+ }
+
+ /** \returns a reference to the coefficient at given index.
+ *
+ * This is synonymous to operator[](int).
+ *
+ * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit.
+ *
+ * \sa operator[](int) const, operator()(int,int), x(), y(), z(), w()
+ */
+
+ EIGEN_STRONG_INLINE Scalar&
+ operator()(int index)
+ {
+ ei_assert(index >= 0 && index < size());
+ return derived().coeffRef(index);
+ }
+
+ /** equivalent to operator[](0). */
+
+ EIGEN_STRONG_INLINE Scalar&
+ x() { return (*this)[0]; }
+
+ /** equivalent to operator[](1). */
+
+ EIGEN_STRONG_INLINE Scalar&
+ y() { return (*this)[1]; }
+
+ /** equivalent to operator[](2). */
+
+ EIGEN_STRONG_INLINE Scalar&
+ z() { return (*this)[2]; }
+
+ /** equivalent to operator[](3). */
+
+ 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
+ * 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 StoreMode>
+ 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<int StoreMode>
+ 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);
+ }
+
+ /** 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.
+ *
+ * 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 StoreMode>
+ 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);
+ }
#ifndef EIGEN_PARSED_BY_DOXYGEN
-/** \internal Copies the coefficient at position (row,col) of other into *this.
- *
- * This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code
- * with usual assignments.
- *
- * 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)
-{
- ei_internal_assert(row >= 0 && row < rows()
- && col >= 0 && col < cols());
- derived().coeffRef(row, col) = other.derived().coeff(row, col);
-}
-
-/** \internal Copies the coefficient at the given index of other into *this.
- *
- * This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code
- * with usual assignments.
- *
- * 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)
-{
- 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)
-{
- const int row = Derived::rowIndexByOuterInner(outer,inner);
- const int col = Derived::colIndexByOuterInner(outer,inner);
- // derived() is important here: copyCoeff() may be reimplemented in Derived!
- derived().copyCoeff(row, col, other);
-}
-
-/** \internal Copies the packet at position (row,col) of other into *this.
- *
- * This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code
- * with usual assignments.
- *
- * 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)
-{
- ei_internal_assert(row >= 0 && row < rows()
- && col >= 0 && col < cols());
- derived().template writePacket<StoreMode>(row, col,
- other.derived().template packet<LoadMode>(row, col));
-}
-
-/** \internal Copies the packet at the given index of other into *this.
- *
- * This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code
- * with usual assignments.
- *
- * 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)
-{
- 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)
-{
- const int row = Derived::rowIndexByOuterInner(outer,inner);
- const int col = Derived::colIndexByOuterInner(outer,inner);
- // derived() is important here: copyCoeff() may be reimplemented in Derived!
- derived().copyPacket<OtherDerived, StoreMode, LoadMode>(row, col, other);
-}
+ /** \internal Copies the coefficient at position (row,col) of other into *this.
+ *
+ * This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code
+ * with usual assignments.
+ *
+ * Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox.
+ */
+
+ template<typename OtherDerived>
+ EIGEN_STRONG_INLINE void copyCoeff(int row, int col, const DenseBase<OtherDerived>& other)
+ {
+ ei_internal_assert(row >= 0 && row < rows()
+ && col >= 0 && col < cols());
+ derived().coeffRef(row, col) = other.derived().coeff(row, col);
+ }
+
+ /** \internal Copies the coefficient at the given index of other into *this.
+ *
+ * This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code
+ * with usual assignments.
+ *
+ * Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox.
+ */
+
+ template<typename OtherDerived>
+ 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 OtherDerived>
+ EIGEN_STRONG_INLINE void copyCoeffByOuterInner(int outer, int inner, const DenseBase<OtherDerived>& other)
+ {
+ 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);
+ }
+
+ /** \internal Copies the packet at position (row,col) of other into *this.
+ *
+ * This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code
+ * with usual assignments.
+ *
+ * Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox.
+ */
+
+ template<typename OtherDerived, int StoreMode, int LoadMode>
+ EIGEN_STRONG_INLINE void copyPacket(int row, int col, const DenseBase<OtherDerived>& other)
+ {
+ ei_internal_assert(row >= 0 && row < rows()
+ && col >= 0 && col < cols());
+ derived().template writePacket<StoreMode>(row, col,
+ other.derived().template packet<LoadMode>(row, col));
+ }
+
+ /** \internal Copies the packet at the given index of other into *this.
+ *
+ * This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code
+ * with usual assignments.
+ *
+ * Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox.
+ */
+
+ template<typename OtherDerived, int StoreMode, int LoadMode>
+ 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 OtherDerived, int StoreMode, int LoadMode>
+ EIGEN_STRONG_INLINE void copyPacketByOuterInner(int outer, int inner, const DenseBase<OtherDerived>& other)
+ {
+ 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);
+ <Derived, (Derived::Flags & AlignedBit) || !(Derived::Flags & DirectAccessBit)>
+ ::run(m);
}
-#endif
-
#endif // EIGEN_COEFFS_H
diff --git a/Eigen/src/Core/DenseBase.h b/Eigen/src/Core/DenseBase.h
index 8bdcbf52b..f686885b3 100644
--- a/Eigen/src/Core/DenseBase.h
+++ b/Eigen/src/Core/DenseBase.h
@@ -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();
diff --git a/Eigen/src/Core/EigenBase.h b/Eigen/src/Core/EigenBase.h
index cf1ce4376..e583fddc3 100644
--- a/Eigen/src/Core/EigenBase.h
+++ b/Eigen/src/Core/EigenBase.h
@@ -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
diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h
index d660078c7..9debb9409 100644
--- a/Eigen/src/Core/util/ForwardDeclarations.h
+++ b/Eigen/src/Core/util/ForwardDeclarations.h
@@ -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;
diff --git a/Eigen/src/Core/util/XprHelper.h b/Eigen/src/Core/util/XprHelper.h
index ada93bcd4..667418bb3 100644
--- a/Eigen/src/Core/util/XprHelper.h
+++ b/Eigen/src/Core/util/XprHelper.h
@@ -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
diff --git a/test/basicstuff.cpp b/test/basicstuff.cpp
index 7244dff9d..7ef127ac2 100644
--- a/test/basicstuff.cpp
+++ b/test/basicstuff.cpp
@@ -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()
{