mirror of
https://gitlab.com/libeigen/eigen.git
synced 2024-11-27 06:30:28 +08:00
bug #54 - The big Map const-correctness changes
This commit is contained in:
parent
e736df3edd
commit
74cc42b22f
@ -500,6 +500,7 @@ EIGEN_STRONG_INLINE Derived& DenseBase<Derived>
|
||||
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)
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
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); }
|
||||
//@}
|
||||
|
@ -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(); }
|
||||
|
@ -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(); }
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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>,
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
23
test/map.cpp
23
test/map.cpp
@ -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()) );
|
||||
|
Loading…
Reference in New Issue
Block a user