From 4cf742525f47129878fe561f56be9bd6ec83feb1 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Fri, 28 Jun 2013 15:56:43 +0200 Subject: [PATCH] bug #626: add compiletime check of the Options template parameter of SparseMatrix and SparseVector. Fix eval and plain_object for sparse objects. --- Eigen/src/SparseCore/SparseMatrix.h | 3 ++- Eigen/src/SparseCore/SparseUtil.h | 16 +++++++--------- Eigen/src/SparseCore/SparseVector.h | 15 ++++++++++++--- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/Eigen/src/SparseCore/SparseMatrix.h b/Eigen/src/SparseCore/SparseMatrix.h index 072578132..fc6933a60 100644 --- a/Eigen/src/SparseCore/SparseMatrix.h +++ b/Eigen/src/SparseCore/SparseMatrix.h @@ -31,7 +31,7 @@ namespace Eigen { * * \tparam _Scalar the scalar type, i.e. the type of the coefficients * \tparam _Options Union of bit flags controlling the storage scheme. Currently the only possibility - * is RowMajor. The default is 0 which means column-major. + * is ColMajor or RowMajor. The default is 0 which means column-major. * \tparam _Index the type of the indices. It has to be a \b signed type (e.g., short, int, std::ptrdiff_t). Default is \c int. * * This class can be extended with the help of the plugin mechanism described on the page @@ -833,6 +833,7 @@ private: static void check_template_parameters() { EIGEN_STATIC_ASSERT(NumTraits::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE); + EIGEN_STATIC_ASSERT((Options&(ColMajor|RowMajor))==Options,INVALID_MATRIX_TEMPLATE_PARAMETERS); } struct default_prunning_func { diff --git a/Eigen/src/SparseCore/SparseUtil.h b/Eigen/src/SparseCore/SparseUtil.h index d58b51356..064a40707 100644 --- a/Eigen/src/SparseCore/SparseUtil.h +++ b/Eigen/src/SparseCore/SparseUtil.h @@ -98,16 +98,16 @@ template struct eval template struct sparse_eval { typedef typename traits::Scalar _Scalar; - enum { _Flags = traits::Flags| RowMajorBit }; + typedef typename traits::Index _Index; public: - typedef SparseVector<_Scalar, _Flags> type; + typedef SparseVector<_Scalar, RowMajor, _Index> type; }; template struct sparse_eval { typedef typename traits::Scalar _Scalar; - enum { _Flags = traits::Flags & (~RowMajorBit) }; + typedef typename traits::Index _Index; public: - typedef SparseVector<_Scalar, _Flags> type; + typedef SparseVector<_Scalar, ColMajor, _Index> type; }; template struct sparse_eval { @@ -127,12 +127,10 @@ template struct sparse_eval { template struct plain_matrix_type { typedef typename traits::Scalar _Scalar; - enum { - _Flags = traits::Flags - }; - + typedef typename traits::Index _Index; + enum { _Options = ((traits::Flags&RowMajorBit)==RowMajorBit) ? RowMajor : ColMajor }; public: - typedef SparseMatrix<_Scalar, _Flags> type; + typedef SparseMatrix<_Scalar, _Options, _Index> type; }; } // end namespace internal diff --git a/Eigen/src/SparseCore/SparseVector.h b/Eigen/src/SparseCore/SparseVector.h index cd1e76070..d29a0977c 100644 --- a/Eigen/src/SparseCore/SparseVector.h +++ b/Eigen/src/SparseCore/SparseVector.h @@ -184,22 +184,24 @@ class SparseVector void resizeNonZeros(Index size) { m_data.resize(size); } - inline SparseVector() : m_size(0) { resize(0); } + inline SparseVector() : m_size(0) { check_template_parameters(); resize(0); } - inline SparseVector(Index size) : m_size(0) { resize(size); } + inline SparseVector(Index size) : m_size(0) { check_template_parameters(); resize(size); } - inline SparseVector(Index rows, Index cols) : m_size(0) { resize(rows,cols); } + inline SparseVector(Index rows, Index cols) : m_size(0) { check_template_parameters(); resize(rows,cols); } template inline SparseVector(const SparseMatrixBase& other) : m_size(0) { + check_template_parameters(); *this = other.derived(); } inline SparseVector(const SparseVector& other) : SparseBase(other), m_size(0) { + check_template_parameters(); *this = other.derived(); } @@ -309,6 +311,13 @@ class SparseVector # endif protected: + + static void check_template_parameters() + { + EIGEN_STATIC_ASSERT(NumTraits::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE); + EIGEN_STATIC_ASSERT((_Options&(ColMajor|RowMajor))==Options,INVALID_MATRIX_TEMPLATE_PARAMETERS); + } + template EIGEN_DONT_INLINE SparseVector& assign(const SparseMatrixBase& _other);