bug #54 - The big Map const-correctness changes

This commit is contained in:
Benoit Jacob 2010-12-10 02:09:58 -05:00
parent e736df3edd
commit 74cc42b22f
19 changed files with 311 additions and 113 deletions

View File

@ -499,7 +499,8 @@ EIGEN_STRONG_INLINE Derived& DenseBase<Derived>
enum{
SameType = internal::is_same<typename Derived::Scalar,typename OtherDerived::Scalar>::value
};
EIGEN_STATIC_ASSERT_LVALUE(Derived)
EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Derived,OtherDerived)
EIGEN_STATIC_ASSERT(SameType,YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)

View File

@ -501,8 +501,6 @@ template<typename Derived> class DenseBase
* Only do it when debugging Eigen, as this borders on paranoiac and could slow compilation down
*/
#ifdef EIGEN_INTERNAL_DEBUGGING
EIGEN_STATIC_ASSERT(internal::are_flags_consistent<Flags>::ret,
INVALID_MATRIXBASE_TEMPLATE_PARAMETERS)
EIGEN_STATIC_ASSERT((EIGEN_IMPLIES(MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1, int(IsRowMajor))
&& EIGEN_IMPLIES(MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1, int(!IsRowMajor))),
INVALID_STORAGE_ORDER_FOR_THIS_VECTOR_EXPRESSION)

View File

@ -554,19 +554,90 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
};
/** \brief Base class providing direct coefficient access to matrices and arrays.
/** \brief Base class providing direct read-only coefficient access to matrices and arrays.
* \ingroup Core_Module
* \tparam Derived Type of the derived class
* \tparam DirectAccessors Constant indicating direct access
*
* This class defines functions to work with strides which can be used to access entries directly. This class
* inherits DenseCoeffsBase<Derived, WriteAccessors> which defines functions to access entries using
* inherits DenseCoeffsBase<Derived, ReadOnlyAccessors> which defines functions to access entries read-only using
* \c operator() .
*
* \sa \ref TopicClassHierarchy
*/
template<typename Derived>
class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived, WriteAccessors>
class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived, ReadOnlyAccessors>
{
public:
typedef DenseCoeffsBase<Derived, ReadOnlyAccessors> Base;
typedef typename internal::traits<Derived>::Index Index;
typedef typename internal::traits<Derived>::Scalar Scalar;
typedef typename NumTraits<Scalar>::Real RealScalar;
using Base::rows;
using Base::cols;
using Base::size;
using Base::derived;
/** \returns the pointer increment between two consecutive elements within a slice in the inner direction.
*
* \sa outerStride(), rowStride(), colStride()
*/
inline Index innerStride() const
{
return derived().innerStride();
}
/** \returns the pointer increment between two consecutive inner slices (for example, between two consecutive columns
* in a column-major matrix).
*
* \sa innerStride(), rowStride(), colStride()
*/
inline Index outerStride() const
{
return derived().outerStride();
}
// FIXME shall we remove it ?
inline Index stride() const
{
return Derived::IsVectorAtCompileTime ? innerStride() : outerStride();
}
/** \returns the pointer increment between two consecutive rows.
*
* \sa innerStride(), outerStride(), colStride()
*/
inline Index rowStride() const
{
return Derived::IsRowMajor ? outerStride() : innerStride();
}
/** \returns the pointer increment between two consecutive columns.
*
* \sa innerStride(), outerStride(), rowStride()
*/
inline Index colStride() const
{
return Derived::IsRowMajor ? innerStride() : outerStride();
}
};
/** \brief Base class providing direct read/write coefficient access to matrices and arrays.
* \ingroup Core_Module
* \tparam Derived Type of the derived class
* \tparam DirectAccessors Constant indicating direct access
*
* This class defines functions to work with strides which can be used to access entries directly. This class
* inherits DenseCoeffsBase<Derived, WriteAccessors> which defines functions to access entries read/write using
* \c operator().
*
* \sa \ref TopicClassHierarchy
*/
template<typename Derived>
class DenseCoeffsBase<Derived, DirectWriteAccessors>
: public DenseCoeffsBase<Derived, WriteAccessors>
{
public:

View File

@ -80,8 +80,9 @@
namespace internal {
template<typename PlainObjectType, int MapOptions, typename StrideType>
struct traits<Map<PlainObjectType, MapOptions, StrideType> >
: public traits<PlainObjectType>
: public traits<typename internal::remove_const<PlainObjectType>::type>
{
typedef traits<typename internal::remove_const<PlainObjectType>::type> TraitsBase;
typedef typename PlainObjectType::Index Index;
typedef typename PlainObjectType::Scalar Scalar;
enum {
@ -101,13 +102,15 @@ struct traits<Map<PlainObjectType, MapOptions, StrideType> >
|| HasNoOuterStride
|| ( OuterStrideAtCompileTime!=Dynamic
&& ((static_cast<int>(sizeof(Scalar))*OuterStrideAtCompileTime)%16)==0 ) ),
Flags0 = traits<PlainObjectType>::Flags,
Flags0 = TraitsBase::Flags,
Flags1 = IsAligned ? (int(Flags0) | AlignedBit) : (int(Flags0) & ~AlignedBit),
Flags2 = HasNoStride ? int(Flags1) : int(Flags1 & ~LinearAccessBit),
Flags = KeepsPacketAccess ? int(Flags2) : (int(Flags2) & ~PacketAccessBit)
Flags2 = (bool(HasNoStride) || bool(PlainObjectType::IsVectorAtCompileTime))
? int(Flags1) : int(Flags1 & ~LinearAccessBit),
Flags3 = internal::is_const<PlainObjectType>::value ? (int(Flags2) & ~LvalueBit) : int(Flags2),
Flags = KeepsPacketAccess ? int(Flags3) : (int(Flags3) & ~PacketAccessBit)
};
private:
enum { Options }; // Expressions don't support Options
enum { Options }; // Expressions don't have Options
};
}
@ -120,6 +123,9 @@ template<typename PlainObjectType, int MapOptions, typename StrideType> class Ma
EIGEN_DENSE_PUBLIC_INTERFACE(Map)
typedef typename Base::PointerType PointerType;
inline Index innerStride() const
{
return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.inner() : 1;
@ -138,7 +144,7 @@ template<typename PlainObjectType, int MapOptions, typename StrideType> class Ma
* \param data pointer to the array to map
* \param stride optional Stride object, passing the strides.
*/
inline Map(const Scalar* data, const StrideType& stride = StrideType())
inline Map(PointerType data, const StrideType& stride = StrideType())
: Base(data), m_stride(stride)
{
PlainObjectType::Base::_check_template_params();
@ -150,7 +156,7 @@ template<typename PlainObjectType, int MapOptions, typename StrideType> class Ma
* \param size the size of the vector expression
* \param stride optional Stride object, passing the strides.
*/
inline Map(const Scalar* data, Index size, const StrideType& stride = StrideType())
inline Map(PointerType data, Index size, const StrideType& stride = StrideType())
: Base(data, size), m_stride(stride)
{
PlainObjectType::Base::_check_template_params();
@ -163,7 +169,7 @@ template<typename PlainObjectType, int MapOptions, typename StrideType> class Ma
* \param cols the number of columns of the matrix expression
* \param stride optional Stride object, passing the strides.
*/
inline Map(const Scalar* data, Index rows, Index cols, const StrideType& stride = StrideType())
inline Map(PointerType data, Index rows, Index cols, const StrideType& stride = StrideType())
: Base(data, rows, cols), m_stride(stride)
{
PlainObjectType::Base::_check_template_params();

View File

@ -26,6 +26,11 @@
#ifndef EIGEN_MAPBASE_H
#define EIGEN_MAPBASE_H
#define EIGEN_STATIC_ASSERT_LINEAR_ACCESS(Derived) \
EIGEN_STATIC_ASSERT(int(internal::traits<Derived>::Flags) & LinearAccessBit, \
YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT)
/** \class MapBase
* \ingroup Core_Module
*
@ -33,7 +38,7 @@
*
* \sa class Map, class Block
*/
template<typename Derived> class MapBase
template<typename Derived> class MapBase<Derived, ReadOnlyAccessors>
: public internal::dense_xpr_base<Derived>::type
{
public:
@ -45,12 +50,16 @@ template<typename Derived> class MapBase
SizeAtCompileTime = Base::SizeAtCompileTime
};
typedef typename internal::traits<Derived>::StorageKind StorageKind;
typedef typename internal::traits<Derived>::Index Index;
typedef typename internal::traits<Derived>::Scalar Scalar;
typedef typename internal::packet_traits<Scalar>::type PacketScalar;
typedef typename NumTraits<Scalar>::Real RealScalar;
typedef typename internal::conditional<
int(internal::traits<Derived>::Flags) & LvalueBit,
Scalar *,
const Scalar *>::type
PointerType;
using Base::derived;
// using Base::RowsAtCompileTime;
@ -63,10 +72,6 @@ template<typename Derived> class MapBase
using Base::Flags;
using Base::IsRowMajor;
using Base::CoeffReadCost;
// using Base::derived;
using Base::const_cast_derived;
using Base::rows;
using Base::cols;
using Base::size;
@ -74,11 +79,6 @@ template<typename Derived> class MapBase
using Base::coeffRef;
using Base::lazyAssign;
using Base::eval;
// using Base::operator=;
using Base::operator+=;
using Base::operator-=;
using Base::operator*=;
using Base::operator/=;
using Base::innerStride;
using Base::outerStride;
@ -98,28 +98,27 @@ template<typename Derived> class MapBase
* \sa innerStride(), outerStride()
*/
inline const Scalar* data() const { return m_data; }
inline Scalar* data() { return const_cast<Scalar*>(m_data); }
inline const Scalar& coeff(Index row, Index col) const
{
return m_data[col * colStride() + row * rowStride()];
}
inline Scalar& coeffRef(Index row, Index col)
{
return const_cast<Scalar*>(m_data)[col * colStride() + row * rowStride()];
}
inline const Scalar& coeff(Index index) const
{
eigen_assert(Derived::IsVectorAtCompileTime || (internal::traits<Derived>::Flags & LinearAccessBit));
EIGEN_STATIC_ASSERT_LINEAR_ACCESS(Derived)
return m_data[index * innerStride()];
}
inline Scalar& coeffRef(Index index)
inline const Scalar& coeffRef(Index row, Index col) const
{
eigen_assert(Derived::IsVectorAtCompileTime || (internal::traits<Derived>::Flags & LinearAccessBit));
return const_cast<Scalar*>(m_data)[index * innerStride()];
return this->m_data[col * colStride() + row * rowStride()];
}
inline const Scalar& coeffRef(Index index) const
{
EIGEN_STATIC_ASSERT_LINEAR_ACCESS(Derived)
return this->m_data[index * innerStride()];
}
template<int LoadMode>
@ -132,30 +131,17 @@ template<typename Derived> class MapBase
template<int LoadMode>
inline PacketScalar packet(Index index) const
{
EIGEN_STATIC_ASSERT_LINEAR_ACCESS(Derived)
return internal::ploadt<PacketScalar, LoadMode>(m_data + index * innerStride());
}
template<int StoreMode>
inline void writePacket(Index row, Index col, const PacketScalar& x)
{
internal::pstoret<Scalar, PacketScalar, StoreMode>
(const_cast<Scalar*>(m_data) + (col * colStride() + row * rowStride()), x);
}
template<int StoreMode>
inline void writePacket(Index index, const PacketScalar& x)
{
internal::pstoret<Scalar, PacketScalar, StoreMode>
(const_cast<Scalar*>(m_data) + index * innerStride(), x);
}
inline MapBase(const Scalar* data) : m_data(data), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime)
inline MapBase(PointerType data) : m_data(data), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime)
{
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
checkSanity();
}
inline MapBase(const Scalar* data, Index size)
inline MapBase(PointerType data, Index size)
: m_data(data),
m_rows(RowsAtCompileTime == Dynamic ? size : Index(RowsAtCompileTime)),
m_cols(ColsAtCompileTime == Dynamic ? size : Index(ColsAtCompileTime))
@ -166,7 +152,7 @@ template<typename Derived> class MapBase
checkSanity();
}
inline MapBase(const Scalar* data, Index rows, Index cols)
inline MapBase(PointerType data, Index rows, Index cols)
: m_data(data), m_rows(rows), m_cols(cols)
{
eigen_assert( (data == 0)
@ -175,14 +161,6 @@ template<typename Derived> class MapBase
checkSanity();
}
Derived& operator=(const MapBase& other)
{
Base::operator=(other);
return derived();
}
using Base::operator=;
protected:
void checkSanity() const
@ -194,9 +172,76 @@ template<typename Derived> class MapBase
&& "data is not aligned");
}
const Scalar* EIGEN_RESTRICT m_data;
PointerType EIGEN_RESTRICT m_data;
const internal::variable_if_dynamic<Index, RowsAtCompileTime> m_rows;
const internal::variable_if_dynamic<Index, ColsAtCompileTime> m_cols;
};
template<typename Derived> class MapBase<Derived, WriteAccessors>
: public MapBase<Derived, ReadOnlyAccessors>
{
public:
typedef MapBase<Derived, ReadOnlyAccessors> Base;
typedef typename Base::Scalar Scalar;
typedef typename Base::PacketScalar PacketScalar;
typedef typename Base::Index Index;
typedef typename Base::PointerType PointerType;
using Base::derived;
using Base::rows;
using Base::cols;
using Base::size;
using Base::coeff;
using Base::coeffRef;
using Base::innerStride;
using Base::outerStride;
using Base::rowStride;
using Base::colStride;
inline const Scalar* data() const { return this->m_data; }
inline Scalar* data() { return this->m_data; } // no const-cast here so non-const-correct code will give a compile error
inline Scalar& coeffRef(Index row, Index col)
{
return this->m_data[col * colStride() + row * rowStride()];
}
inline Scalar& coeffRef(Index index)
{
EIGEN_STATIC_ASSERT_LINEAR_ACCESS(Derived)
return this->m_data[index * innerStride()];
}
template<int StoreMode>
inline void writePacket(Index row, Index col, const PacketScalar& x)
{
internal::pstoret<Scalar, PacketScalar, StoreMode>
(this->m_data + (col * colStride() + row * rowStride()), x);
}
template<int StoreMode>
inline void writePacket(Index index, const PacketScalar& x)
{
EIGEN_STATIC_ASSERT_LINEAR_ACCESS(Derived)
internal::pstoret<Scalar, PacketScalar, StoreMode>
(this->m_data + index * innerStride(), x);
}
inline MapBase(PointerType data) : Base(data) {}
inline MapBase(PointerType data, Index size) : Base(data, size) {}
inline MapBase(PointerType data, Index rows, Index cols) : Base(data, rows, cols) {}
Derived& operator=(const MapBase& other)
{
Base::Base::operator=(other);
return derived();
}
using Base::Base::operator=;
};
#endif // EIGEN_MAPBASE_H

View File

@ -66,10 +66,15 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
using Base::IsVectorAtCompileTime;
using Base::Flags;
typedef typename internal::add_const<Derived>::type ConstDerived;
friend class Eigen::Map<Derived, Unaligned>;
typedef class Eigen::Map<Derived, Unaligned> UnalignedMapType;
typedef class Eigen::Map<Derived, Unaligned> MapType;
friend class Eigen::Map<ConstDerived, Unaligned>;
typedef class Eigen::Map<ConstDerived, Unaligned> ConstMapType;
friend class Eigen::Map<Derived, Aligned>;
typedef class Eigen::Map<Derived, Aligned> AlignedMapType;
typedef class Eigen::Map<Derived, Aligned> AlignedMapType;
friend class Eigen::Map<ConstDerived, Aligned>;
typedef class Eigen::Map<ConstDerived, Aligned> ConstAlignedMapType;
protected:
DenseStorage<Scalar, Base::MaxSizeAtCompileTime, Base::RowsAtCompileTime, Base::ColsAtCompileTime, Options> m_storage;
@ -376,29 +381,29 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
* \see class Map
*/
//@{
inline static const UnalignedMapType Map(const Scalar* data)
{ return UnalignedMapType(data); }
inline static UnalignedMapType Map(Scalar* data)
{ return UnalignedMapType(data); }
inline static const UnalignedMapType Map(const Scalar* data, Index size)
{ return UnalignedMapType(data, size); }
inline static UnalignedMapType Map(Scalar* data, Index size)
{ return UnalignedMapType(data, size); }
inline static const UnalignedMapType Map(const Scalar* data, Index rows, Index cols)
{ return UnalignedMapType(data, rows, cols); }
inline static UnalignedMapType Map(Scalar* data, Index rows, Index cols)
{ return UnalignedMapType(data, rows, cols); }
inline static const ConstMapType Map(const Scalar* data)
{ return ConstMapType(data); }
inline static MapType Map(Scalar* data)
{ return MapType(data); }
inline static const ConstMapType Map(const Scalar* data, Index size)
{ return ConstMapType(data, size); }
inline static MapType Map(Scalar* data, Index size)
{ return MapType(data, size); }
inline static const ConstMapType Map(const Scalar* data, Index rows, Index cols)
{ return ConstMapType(data, rows, cols); }
inline static MapType Map(Scalar* data, Index rows, Index cols)
{ return MapType(data, rows, cols); }
inline static const AlignedMapType MapAligned(const Scalar* data)
{ return AlignedMapType(data); }
inline static const ConstAlignedMapType MapAligned(const Scalar* data)
{ return ConstAlignedMapType(data); }
inline static AlignedMapType MapAligned(Scalar* data)
{ return AlignedMapType(data); }
inline static const AlignedMapType MapAligned(const Scalar* data, Index size)
{ return AlignedMapType(data, size); }
inline static const ConstAlignedMapType MapAligned(const Scalar* data, Index size)
{ return ConstAlignedMapType(data, size); }
inline static AlignedMapType MapAligned(Scalar* data, Index size)
{ return AlignedMapType(data, size); }
inline static const AlignedMapType MapAligned(const Scalar* data, Index rows, Index cols)
{ return AlignedMapType(data, rows, cols); }
inline static const ConstAlignedMapType MapAligned(const Scalar* data, Index rows, Index cols)
{ return ConstAlignedMapType(data, rows, cols); }
inline static AlignedMapType MapAligned(Scalar* data, Index rows, Index cols)
{ return AlignedMapType(data, rows, cols); }
//@}

View File

@ -80,7 +80,7 @@ template<typename MatrixType, unsigned int UpLo> class SelfAdjointView
typedef typename MatrixType::PlainObject PlainObject;
inline SelfAdjointView(const MatrixType& matrix) : m_matrix(matrix)
{ eigen_assert(internal::are_flags_consistent<Mode>::ret); }
{}
inline Index rows() const { return m_matrix.rows(); }
inline Index cols() const { return m_matrix.cols(); }

View File

@ -181,7 +181,7 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularView
};
inline TriangularView(const MatrixType& matrix) : m_matrix(matrix)
{ eigen_assert(internal::are_flags_consistent<Mode>::ret); }
{}
inline Index rows() const { return m_matrix.rows(); }
inline Index cols() const { return m_matrix.cols(); }

View File

@ -53,7 +53,7 @@ SelfAdjointView<MatrixType,UpLo>& SelfAdjointView<MatrixType,UpLo>
MatrixType::Flags&RowMajorBit ? RowMajor : ColMajor, UpLo>
::run(_expression().cols(), actualU.cols(),
&actualU.coeff(0,0), actualU.outerStride(), &actualU.coeff(0,0), actualU.outerStride(),
const_cast<Scalar*>(_expression().data()), _expression().outerStride(), actualAlpha);
_expression().const_cast_derived().data(), _expression().outerStride(), actualAlpha);
return *this;
}

View File

@ -91,7 +91,7 @@ SelfAdjointView<MatrixType,UpLo>& SelfAdjointView<MatrixType,UpLo>
typename internal::remove_all<typename internal::conj_expr_if<IsRowMajor ^ UBlasTraits::NeedToConjugate,_ActualUType>::type>::type,
typename internal::remove_all<typename internal::conj_expr_if<IsRowMajor ^ VBlasTraits::NeedToConjugate,_ActualVType>::type>::type,
(IsRowMajor ? int(UpLo==Upper ? Lower : Upper) : UpLo)>
::run(const_cast<Scalar*>(_expression().data()),_expression().outerStride(),actualU,actualV,actualAlpha);
::run(_expression().const_cast_derived().data(),_expression().outerStride(),actualU,actualV,actualAlpha);
return *this;
}

View File

@ -46,11 +46,11 @@ struct product_triangular_matrix_vector<Index,Mode,LhsScalar,ConjLhs,RhsScalar,C
static const Index PanelWidth = EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH;
typedef Map<Matrix<LhsScalar,Dynamic,Dynamic,ColMajor>, 0, OuterStride<> > LhsMap;
typedef Map<const Matrix<LhsScalar,Dynamic,Dynamic,ColMajor>, 0, OuterStride<> > LhsMap;
const LhsMap lhs(_lhs,rows,cols,OuterStride<>(lhsStride));
typename conj_expr_if<ConjLhs,LhsMap>::type cjLhs(lhs);
typedef Map<Matrix<RhsScalar,Dynamic,1>, 0, InnerStride<> > RhsMap;
typedef Map<const Matrix<RhsScalar,Dynamic,1>, 0, InnerStride<> > RhsMap;
const RhsMap rhs(_rhs,cols,InnerStride<>(rhsIncr));
typename conj_expr_if<ConjRhs,RhsMap>::type cjRhs(rhs);
@ -100,11 +100,11 @@ struct product_triangular_matrix_vector<Index,Mode,LhsScalar,ConjLhs,RhsScalar,C
static const Index PanelWidth = EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH;
typedef Map<Matrix<LhsScalar,Dynamic,Dynamic,RowMajor>, 0, OuterStride<> > LhsMap;
typedef Map<const Matrix<LhsScalar,Dynamic,Dynamic,RowMajor>, 0, OuterStride<> > LhsMap;
const LhsMap lhs(_lhs,rows,cols,OuterStride<>(lhsStride));
typename conj_expr_if<ConjLhs,LhsMap>::type cjLhs(lhs);
typedef Map<Matrix<RhsScalar,Dynamic,1> > RhsMap;
typedef Map<const Matrix<RhsScalar,Dynamic,1> > RhsMap;
const RhsMap rhs(_rhs,cols);
typename conj_expr_if<ConjRhs,RhsMap>::type cjRhs(rhs);

View File

@ -48,7 +48,7 @@ struct triangular_solve_vector<LhsScalar, RhsScalar, Index, OnTheLeft, Mode, Con
};
static void run(Index size, const LhsScalar* _lhs, Index lhsStride, RhsScalar* rhs)
{
typedef Map<Matrix<LhsScalar,Dynamic,Dynamic,RowMajor>, 0, OuterStride<> > LhsMap;
typedef Map<const Matrix<LhsScalar,Dynamic,Dynamic,RowMajor>, 0, OuterStride<> > LhsMap;
const LhsMap lhs(_lhs,size,size,OuterStride<>(lhsStride));
typename internal::conditional<
Conjugate,
@ -84,7 +84,7 @@ struct triangular_solve_vector<LhsScalar, RhsScalar, Index, OnTheLeft, Mode, Con
Index i = IsLower ? pi+k : pi-k-1;
Index s = IsLower ? pi : i+1;
if (k>0)
rhs[i] -= (cjLhs.row(i).segment(s,k).transpose().cwiseProduct(Map<Matrix<RhsScalar,Dynamic,1> >(rhs+s,k))).sum();
rhs[i] -= (cjLhs.row(i).segment(s,k).transpose().cwiseProduct(Map<const Matrix<RhsScalar,Dynamic,1> >(rhs+s,k))).sum();
if(!(Mode & UnitDiag))
rhs[i] /= cjLhs(i,i);
@ -102,7 +102,7 @@ struct triangular_solve_vector<LhsScalar, RhsScalar, Index, OnTheLeft, Mode, Con
};
static void run(Index size, const LhsScalar* _lhs, Index lhsStride, RhsScalar* rhs)
{
typedef Map<Matrix<LhsScalar,Dynamic,Dynamic,ColMajor>, 0, OuterStride<> > LhsMap;
typedef Map<const Matrix<LhsScalar,Dynamic,Dynamic,ColMajor>, 0, OuterStride<> > LhsMap;
const LhsMap lhs(_lhs,size,size,OuterStride<>(lhsStride));
typename internal::conditional<Conjugate,
const CwiseUnaryOp<typename internal::scalar_conjugate_op<LhsScalar>,LhsMap>,

View File

@ -128,8 +128,10 @@ const unsigned int LinearAccessBit = 0x10;
* Means the expression has a coeffRef() method, i.e. is writable as its individual coefficients are directly addressable.
* This rules out read-only expressions.
*
* Note that DirectAccessBit implies LvalueBit, but the converse is false: LvalueBit doesn't imply DirectAccessBit because
* DirectAccessBit means that the whole memory layout is a plain strided array.
* Note that DirectAccessBit and LvalueBit are mutually orthogonal, as there are examples of expression having one but note
* the other:
* \li writable expressions that don't have a very simple memory layout as a strided array, have LvalueBit but not DirectAccessBit
* \li Map-to-const expressions, for example Map<const Matrix>, have DirectAccessBit but not LvalueBit
*
* Expressions having LvalueBit also have their coeff() method returning a const reference instead of returning a new value.
*/
@ -137,14 +139,12 @@ const unsigned int LvalueBit = 0x20;
/** \ingroup flags
*
* Means that the underlying array of coefficients can be directly accessed. This means two things.
*
* First, this means LvalueBit, i.e. this means that the expression has a coeffRef() method, i.e. is writable as its
* individual coefficients are directly addressable. This rules out read-only expressions.
*
* Second, the memory layout of the array of coefficients must be exactly the natural one suggested by rows(), cols(),
* Means that the underlying array of coefficients can be directly accessed as a plain strided array. The memory layout
* of the array of coefficients must be exactly the natural one suggested by rows(), cols(),
* outerStride(), innerStride(), and the RowMajorBit. This rules out expressions such as Diagonal, whose coefficients,
* though referencable, do not have such a regular memory layout.
*
* See the comment on LvalueBit for an explanation of how LvalueBit and DirectAccessBit are mutually orthogonal.
*/
const unsigned int DirectAccessBit = 0x40;
@ -242,7 +242,7 @@ enum {
};
enum AccessorLevels {
ReadOnlyAccessors, WriteAccessors, DirectAccessors
ReadOnlyAccessors, WriteAccessors, DirectAccessors, DirectWriteAccessors
};
enum DecompositionOptions {

View File

@ -33,16 +33,26 @@ template<typename Derived> struct has_direct_access
{
enum { ret = (traits<Derived>::Flags & DirectAccessBit) ? 1 : 0 };
};
template<typename Derived> struct accessors_level
{
enum { has_direct_access = (traits<Derived>::Flags & DirectAccessBit) ? 1 : 0,
has_write_access = (traits<Derived>::Flags & LvalueBit) ? 1 : 0,
value = has_direct_access ? (has_write_access ? DirectWriteAccessors : DirectAccessors)
: (has_write_access ? WriteAccessors : ReadOnlyAccessors)
};
};
} // end namespace internal
template<typename T> struct NumTraits;
template<typename Derived> struct EigenBase;
template<typename Derived> class DenseBase;
template<typename Derived,
AccessorLevels Level = (internal::traits<Derived>::Flags & DirectAccessBit) ? DirectAccessors
: (internal::traits<Derived>::Flags & LvalueBit) ? WriteAccessors
: ReadOnlyAccessors>
int Level = internal::accessors_level<Derived>::value >
class DenseCoeffsBase;
template<typename _Scalar, int _Rows, int _Cols,
@ -86,6 +96,9 @@ template<typename MatrixType, int Index> class Diagonal;
template<int SizeAtCompileTime, int MaxSizeAtCompileTime = SizeAtCompileTime> class PermutationMatrix;
template<int SizeAtCompileTime, int MaxSizeAtCompileTime = SizeAtCompileTime> class Transpositions;
template<typename Derived,
int Level = internal::accessors_level<Derived>::has_write_access ? WriteAccessors : ReadOnlyAccessors
> class MapBase;
template<int InnerStrideAtCompileTime, int OuterStrideAtCompileTime> class Stride;
template<typename MatrixType, int MapOptions=Unaligned, typename StrideType = Stride<0,0> > class Map;

View File

@ -93,6 +93,8 @@
THIS_METHOD_IS_ONLY_FOR_SPECIFIC_TRANSFORMATIONS,
YOU_CANNOT_MIX_ARRAYS_AND_MATRICES,
YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION,
YOU_ARE_TRYING_TO_WRITE_INTO_A_READ_ONLY_EXPRESSION,
YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT,
THIS_METHOD_IS_ONLY_FOR_1x1_EXPRESSIONS
};
};
@ -183,4 +185,8 @@
(TYPE::ColsAtCompileTime == 1 || TYPE::ColsAtCompileTime == Dynamic), \
THIS_METHOD_IS_ONLY_FOR_1x1_EXPRESSIONS)
#define EIGEN_STATIC_ASSERT_LVALUE(Derived) \
EIGEN_STATIC_ASSERT(int(internal::traits<Derived>::Flags) & LvalueBit, \
YOU_ARE_TRYING_TO_WRITE_INTO_A_READ_ONLY_EXPRESSION)
#endif // EIGEN_STATIC_ASSERT_H

View File

@ -333,11 +333,6 @@ template<typename T, int n=1, typename PlainObject = typename eval<T>::type> str
>::type type;
};
template<unsigned int Flags> struct are_flags_consistent
{
enum { ret = EIGEN_IMPLIES(bool(Flags&DirectAccessBit), bool(Flags&LvalueBit)) };
};
template<typename Derived, typename XprKind = typename traits<Derived>::XprKind>
struct dense_xpr_base
{

View File

@ -298,6 +298,42 @@ traits<Quaternion<_Scalar> >
};
}
/** \brief Quaternion expression mapping a constant memory buffer
*
* \param _Scalar the type of the Quaternion coefficients
* \param PacketAccess see class Map
*
* This is a specialization of class Map for Quaternion. This class allows to view
* a 4 scalar memory buffer as an Eigen's Quaternion object.
*
* \sa class Map, class Quaternion, class QuaternionBase
*/
template<typename _Scalar, int PacketAccess>
class Map<const Quaternion<_Scalar>, PacketAccess >
: public QuaternionBase<Map<const Quaternion<_Scalar>, PacketAccess> >
{
typedef QuaternionBase<Map<Quaternion<_Scalar>, PacketAccess> > Base;
public:
typedef _Scalar Scalar;
typedef typename internal::traits<Map>::Coefficients Coefficients;
EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Map)
using Base::operator*=;
/** Constructs a Mapped Quaternion object from the pointer \a coeffs
*
* The pointer \a coeffs must reference the four coeffecients of Quaternion in the following order:
* \code *coeffs == {x, y, z, w} \endcode
*
* If the template parameter PacketAccess is set to Aligned, then the pointer coeffs must be aligned. */
EIGEN_STRONG_INLINE Map(const Scalar* coeffs) : m_coeffs(coeffs) {}
inline const Coefficients& coeffs() const { return m_coeffs;}
protected:
const Coefficients m_coeffs;
};
/** \brief Expression of a quaternion from a memory buffer
*
* \param _Scalar the type of the Quaternion coefficients
@ -326,10 +362,10 @@ class Map<Quaternion<_Scalar>, PacketAccess >
* \code *coeffs == {x, y, z, w} \endcode
*
* If the template parameter PacketAccess is set to Aligned, then the pointer coeffs must be aligned. */
EIGEN_STRONG_INLINE Map(const Scalar* coeffs) : m_coeffs(coeffs) {}
EIGEN_STRONG_INLINE Map(Scalar* coeffs) : m_coeffs(coeffs) {}
inline Coefficients& coeffs() { return m_coeffs;}
inline const Coefficients& coeffs() const { return m_coeffs;}
inline Coefficients& coeffs() { return m_coeffs; }
inline const Coefficients& coeffs() const { return m_coeffs; }
protected:
Coefficients m_coeffs;

View File

@ -75,7 +75,6 @@ template<typename MatrixType, unsigned int UpLo> class SparseSelfAdjointView
inline SparseSelfAdjointView(const MatrixType& matrix) : m_matrix(matrix)
{
eigen_assert(internal::are_flags_consistent<UpLo>::ret);
eigen_assert(rows()==cols() && "SelfAdjointView is only for squared matrices");
}

View File

@ -22,6 +22,10 @@
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_NO_STATIC_ASSERT
#define EIGEN_NO_STATIC_ASSERT // turn static asserts into runtime asserts in order to check them
#endif
#include "main.h"
template<typename VectorType> void map_class_vector(const VectorType& m)
@ -110,15 +114,34 @@ template<typename VectorType> void map_static_methods(const VectorType& m)
delete[] array3;
}
template<typename PlainObjectType> void check_const_correctness(const PlainObjectType&)
{
typedef typename PlainObjectType::Index Index;
typedef typename PlainObjectType::Scalar Scalar;
// there's a lot that we can't test here while still having this test compile!
// the only possible approach would be to run a script trying to compile stuff and checking that it fails.
// CMake can help with that.
// verify that map-to-const don't have LvalueBit
typedef typename internal::add_const<PlainObjectType>::type ConstPlainObjectType;
VERIFY( !(internal::traits<Map<ConstPlainObjectType> >::Flags & LvalueBit) );
VERIFY( !(internal::traits<Map<ConstPlainObjectType, Aligned> >::Flags & LvalueBit) );
VERIFY( !(Map<ConstPlainObjectType>::Flags & LvalueBit) );
VERIFY( !(Map<ConstPlainObjectType, Aligned>::Flags & LvalueBit) );
}
void test_map()
{
for(int i = 0; i < g_repeat; i++) {
CALL_SUBTEST_1( map_class_vector(Matrix<float, 1, 1>()) );
CALL_SUBTEST_1( check_const_correctness(Matrix<float, 1, 1>()) );
CALL_SUBTEST_2( map_class_vector(Vector4d()) );
CALL_SUBTEST_2( check_const_correctness(Matrix4d()) );
CALL_SUBTEST_3( map_class_vector(RowVector4f()) );
CALL_SUBTEST_4( map_class_vector(VectorXcf(8)) );
CALL_SUBTEST_5( map_class_vector(VectorXi(12)) );
CALL_SUBTEST_5( check_const_correctness(VectorXi(12)) );
CALL_SUBTEST_1( map_class_matrix(Matrix<float, 1, 1>()) );
CALL_SUBTEST_2( map_class_matrix(Matrix4d()) );