From 74cc42b22fbe1c05dcbedefb65ceabdec20da146 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Fri, 10 Dec 2010 02:09:58 -0500 Subject: bug #54 - The big Map const-correctness changes --- Eigen/src/Core/MapBase.h | 137 +++++++++++++++++++++++++++++++---------------- 1 file changed, 91 insertions(+), 46 deletions(-) (limited to 'Eigen/src/Core/MapBase.h') diff --git a/Eigen/src/Core/MapBase.h b/Eigen/src/Core/MapBase.h index 5fab85ed7..435d9c09d 100644 --- a/Eigen/src/Core/MapBase.h +++ b/Eigen/src/Core/MapBase.h @@ -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::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 class MapBase +template class MapBase : public internal::dense_xpr_base::type { public: @@ -45,12 +50,16 @@ template class MapBase SizeAtCompileTime = Base::SizeAtCompileTime }; - typedef typename internal::traits::StorageKind StorageKind; typedef typename internal::traits::Index Index; typedef typename internal::traits::Scalar Scalar; typedef typename internal::packet_traits::type PacketScalar; typedef typename NumTraits::Real RealScalar; + typedef typename internal::conditional< + int(internal::traits::Flags) & LvalueBit, + Scalar *, + const Scalar *>::type + PointerType; using Base::derived; // using Base::RowsAtCompileTime; @@ -63,10 +72,6 @@ template 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 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 class MapBase * \sa innerStride(), outerStride() */ inline const Scalar* data() const { return m_data; } - inline Scalar* data() { return const_cast(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) + inline const Scalar& coeff(Index index) const { - return const_cast(m_data)[col * colStride() + row * rowStride()]; + EIGEN_STATIC_ASSERT_LINEAR_ACCESS(Derived) + return m_data[index * innerStride()]; } - inline const Scalar& coeff(Index index) const + inline const Scalar& coeffRef(Index row, Index col) const { - eigen_assert(Derived::IsVectorAtCompileTime || (internal::traits::Flags & LinearAccessBit)); - return m_data[index * innerStride()]; + return this->m_data[col * colStride() + row * rowStride()]; } - inline Scalar& coeffRef(Index index) + inline const Scalar& coeffRef(Index index) const { - eigen_assert(Derived::IsVectorAtCompileTime || (internal::traits::Flags & LinearAccessBit)); - return const_cast(m_data)[index * innerStride()]; + EIGEN_STATIC_ASSERT_LINEAR_ACCESS(Derived) + return this->m_data[index * innerStride()]; } template @@ -132,30 +131,17 @@ template class MapBase template inline PacketScalar packet(Index index) const { + EIGEN_STATIC_ASSERT_LINEAR_ACCESS(Derived) return internal::ploadt(m_data + index * innerStride()); } - template - inline void writePacket(Index row, Index col, const PacketScalar& x) - { - internal::pstoret - (const_cast(m_data) + (col * colStride() + row * rowStride()), x); - } - - template - inline void writePacket(Index index, const PacketScalar& x) - { - internal::pstoret - (const_cast(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 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 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 class MapBase && "data is not aligned"); } - const Scalar* EIGEN_RESTRICT m_data; + PointerType EIGEN_RESTRICT m_data; const internal::variable_if_dynamic m_rows; const internal::variable_if_dynamic m_cols; }; +template class MapBase + : public MapBase +{ + public: + + typedef MapBase 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 + inline void writePacket(Index row, Index col, const PacketScalar& x) + { + internal::pstoret + (this->m_data + (col * colStride() + row * rowStride()), x); + } + + template + inline void writePacket(Index index, const PacketScalar& x) + { + EIGEN_STATIC_ASSERT_LINEAR_ACCESS(Derived) + internal::pstoret + (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 -- cgit v1.2.3