bug #626: add compiletime check of the Options template parameter of SparseMatrix and SparseVector. Fix eval and plain_object for sparse objects.

This commit is contained in:
Gael Guennebaud 2013-06-28 15:56:43 +02:00
parent 487d94f495
commit 4cf742525f
3 changed files with 21 additions and 13 deletions

View File

@ -31,7 +31,7 @@ namespace Eigen {
* *
* \tparam _Scalar the scalar type, i.e. the type of the coefficients * \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 * \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. * \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 * 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() static void check_template_parameters()
{ {
EIGEN_STATIC_ASSERT(NumTraits<Index>::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE); EIGEN_STATIC_ASSERT(NumTraits<Index>::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE);
EIGEN_STATIC_ASSERT((Options&(ColMajor|RowMajor))==Options,INVALID_MATRIX_TEMPLATE_PARAMETERS);
} }
struct default_prunning_func { struct default_prunning_func {

View File

@ -98,16 +98,16 @@ template<typename T> struct eval<T,Sparse>
template<typename T,int Cols> struct sparse_eval<T,1,Cols> { template<typename T,int Cols> struct sparse_eval<T,1,Cols> {
typedef typename traits<T>::Scalar _Scalar; typedef typename traits<T>::Scalar _Scalar;
enum { _Flags = traits<T>::Flags| RowMajorBit }; typedef typename traits<T>::Index _Index;
public: public:
typedef SparseVector<_Scalar, _Flags> type; typedef SparseVector<_Scalar, RowMajor, _Index> type;
}; };
template<typename T,int Rows> struct sparse_eval<T,Rows,1> { template<typename T,int Rows> struct sparse_eval<T,Rows,1> {
typedef typename traits<T>::Scalar _Scalar; typedef typename traits<T>::Scalar _Scalar;
enum { _Flags = traits<T>::Flags & (~RowMajorBit) }; typedef typename traits<T>::Index _Index;
public: public:
typedef SparseVector<_Scalar, _Flags> type; typedef SparseVector<_Scalar, ColMajor, _Index> type;
}; };
template<typename T,int Rows,int Cols> struct sparse_eval { template<typename T,int Rows,int Cols> struct sparse_eval {
@ -127,12 +127,10 @@ template<typename T> struct sparse_eval<T,1,1> {
template<typename T> struct plain_matrix_type<T,Sparse> template<typename T> struct plain_matrix_type<T,Sparse>
{ {
typedef typename traits<T>::Scalar _Scalar; typedef typename traits<T>::Scalar _Scalar;
enum { typedef typename traits<T>::Index _Index;
_Flags = traits<T>::Flags enum { _Options = ((traits<T>::Flags&RowMajorBit)==RowMajorBit) ? RowMajor : ColMajor };
};
public: public:
typedef SparseMatrix<_Scalar, _Flags> type; typedef SparseMatrix<_Scalar, _Options, _Index> type;
}; };
} // end namespace internal } // end namespace internal

View File

@ -184,22 +184,24 @@ class SparseVector
void resizeNonZeros(Index size) { m_data.resize(size); } 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<typename OtherDerived> template<typename OtherDerived>
inline SparseVector(const SparseMatrixBase<OtherDerived>& other) inline SparseVector(const SparseMatrixBase<OtherDerived>& other)
: m_size(0) : m_size(0)
{ {
check_template_parameters();
*this = other.derived(); *this = other.derived();
} }
inline SparseVector(const SparseVector& other) inline SparseVector(const SparseVector& other)
: SparseBase(other), m_size(0) : SparseBase(other), m_size(0)
{ {
check_template_parameters();
*this = other.derived(); *this = other.derived();
} }
@ -309,6 +311,13 @@ class SparseVector
# endif # endif
protected: protected:
static void check_template_parameters()
{
EIGEN_STATIC_ASSERT(NumTraits<Index>::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE);
EIGEN_STATIC_ASSERT((_Options&(ColMajor|RowMajor))==Options,INVALID_MATRIX_TEMPLATE_PARAMETERS);
}
template<typename OtherDerived> template<typename OtherDerived>
EIGEN_DONT_INLINE SparseVector& assign(const SparseMatrixBase<OtherDerived>& _other); EIGEN_DONT_INLINE SparseVector& assign(const SparseMatrixBase<OtherDerived>& _other);