diff --git a/Eigen/src/SparseCore/SparseMatrix.h b/Eigen/src/SparseCore/SparseMatrix.h index ecf406fef..849970a9b 100644 --- a/Eigen/src/SparseCore/SparseMatrix.h +++ b/Eigen/src/SparseCore/SparseMatrix.h @@ -788,8 +788,11 @@ class SparseMatrix : public SparseCompressedBaseswap(other); } + + template + inline SparseMatrix(SparseCompressedBase&& other) : SparseMatrix() { *this = other.derived().markAsRValue(); } @@ -857,7 +860,10 @@ class SparseMatrix : public SparseCompressedBaseswap(other); + return *this; + } #ifndef EIGEN_PARSED_BY_DOXYGEN template @@ -872,6 +878,12 @@ class SparseMatrix : public SparseCompressedBase EIGEN_DONT_INLINE SparseMatrix& operator=(const SparseMatrixBase& other); + template + inline SparseMatrix& operator=(SparseCompressedBase&& other) { + *this = other.derived().markAsRValue(); + return *this; + } + #ifndef EIGEN_NO_IO friend std::ostream& operator<<(std::ostream& s, const SparseMatrix& m) { EIGEN_DBG_SPARSE( diff --git a/Eigen/src/SparseCore/SparseVector.h b/Eigen/src/SparseCore/SparseVector.h index 07337188b..fac162e93 100644 --- a/Eigen/src/SparseCore/SparseVector.h +++ b/Eigen/src/SparseCore/SparseVector.h @@ -304,6 +304,24 @@ class SparseVector : public SparseCompressedBaseswap(other); } + + template + inline SparseVector(SparseCompressedBase&& other) : SparseVector() { + *this = other.derived().markAsRValue(); + } + + inline SparseVector& operator=(SparseVector&& other) { + this->swap(other); + return *this; + } + + template + inline SparseVector& operator=(SparseCompressedBase&& other) { + *this = other.derived().markAsRValue(); + return *this; + } + #ifndef EIGEN_PARSED_BY_DOXYGEN template inline SparseVector& operator=(const SparseSparseProduct& product) { diff --git a/test/sparse_basic.cpp b/test/sparse_basic.cpp index 364aac0b2..a9c6f4c07 100644 --- a/test/sparse_basic.cpp +++ b/test/sparse_basic.cpp @@ -39,7 +39,7 @@ void sparse_basic(const SparseMatrixType& ref) { typedef Matrix DenseMatrix; typedef Matrix DenseVector; typedef Matrix CompatibleDenseMatrix; - Scalar eps = 1e-6; + Scalar eps = Scalar(1e-6); Scalar s1 = internal::random(); { @@ -948,6 +948,27 @@ void sparse_basic(const SparseMatrixType& ref) { SparseMatrixType m2(rows, 0); m2.reserve(ArrayXi::Constant(m2.outerSize(), 1)); } + + // test move + { + using TransposedType = SparseMatrix; + DenseMatrix refMat1 = DenseMatrix::Random(rows, cols); + SparseMatrixType m1(rows, cols); + initSparse(density, refMat1, m1); + // test move ctor + SparseMatrixType m2(std::move(m1)); + VERIFY_IS_APPROX(m2, refMat1); + // test move assignment + m1 = std::move(m2); + VERIFY_IS_APPROX(m1, refMat1); + // test move ctor (SparseMatrixBase) + TransposedType m3(std::move(m1.transpose())); + VERIFY_IS_APPROX(m3, refMat1.transpose()); + // test move assignment (SparseMatrixBase) + m2 = std::move(m3.transpose()); + VERIFY_IS_APPROX(m2, refMat1); + } } template @@ -994,7 +1015,7 @@ EIGEN_DECLARE_TEST(sparse_basic) { g_dense_op_sparse_count = 0; // Suppresses compiler warning. for (int i = 0; i < g_repeat; i++) { int r = Eigen::internal::random(1, 200), c = Eigen::internal::random(1, 200); - if (Eigen::internal::random(0, 4) == 0) { + if (Eigen::internal::random(0, 3) == 0) { r = c; // check square matrices in 25% of tries } EIGEN_UNUSED_VARIABLE(r + c); @@ -1011,7 +1032,7 @@ EIGEN_DECLARE_TEST(sparse_basic) { r = Eigen::internal::random(1, 100); c = Eigen::internal::random(1, 100); - if (Eigen::internal::random(0, 4) == 0) { + if (Eigen::internal::random(0, 3) == 0) { r = c; // check square matrices in 25% of tries } diff --git a/test/sparse_vector.cpp b/test/sparse_vector.cpp index 83ad3241a..8d47fb00d 100644 --- a/test/sparse_vector.cpp +++ b/test/sparse_vector.cpp @@ -108,6 +108,33 @@ void sparse_vector(int rows, int cols) { VERIFY_IS_APPROX(refV3 = v1.transpose(), v1.toDense()); VERIFY_IS_APPROX(DenseVector(v1), v1.toDense()); + // test move + { + SparseVectorType v3(std::move(v1)); + VERIFY_IS_APPROX(v3, refV1); + v1 = v3; + } + + { + SparseVectorType v3; + v3 = std::move(v1); + VERIFY_IS_APPROX(v3, refV1); + v1 = v3; + } + + { + SparseVectorType v3(std::move(mv1)); + VERIFY_IS_APPROX(v3, refV1); + mv1 = v3; + } + + { + SparseVectorType v3; + v3 = std::move(mv1); + VERIFY_IS_APPROX(v3, refV1); + mv1 = v3; + } + // test conservative resize { std::vector inc;