Add free-function swap.
diff --git a/Eigen/src/Core/DenseBase.h b/Eigen/src/Core/DenseBase.h index 8c8ca73..e1fbb0b 100644 --- a/Eigen/src/Core/DenseBase.h +++ b/Eigen/src/Core/DenseBase.h
@@ -642,6 +642,18 @@ EIGEN_DEVICE_FUNC explicit DenseBase(const DenseBase<OtherDerived>&); }; +/** Free-function swap. + */ +template <typename DerivedA, typename DerivedB> +EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE + // Use forwarding references to capture all combinations of cv-qualified l+r-value cases. + std::enable_if_t<std::is_base_of<DenseBase<std::decay_t<DerivedA>>, std::decay_t<DerivedA>>::value && + std::is_base_of<DenseBase<std::decay_t<DerivedB>>, std::decay_t<DerivedB>>::value, + void> + swap(DerivedA&& a, DerivedB&& b) { + a.swap(b); +} + } // end namespace Eigen #endif // EIGEN_DENSEBASE_H
diff --git a/Eigen/src/SparseCore/SparseMatrix.h b/Eigen/src/SparseCore/SparseMatrix.h index 16ee8da..caa8ffa 100644 --- a/Eigen/src/SparseCore/SparseMatrix.h +++ b/Eigen/src/SparseCore/SparseMatrix.h
@@ -829,6 +829,8 @@ std::swap(m_innerNonZeros, other.m_innerNonZeros); m_data.swap(other.m_data); } + /** Free-function swap. */ + friend EIGEN_DEVICE_FUNC void swap(SparseMatrix& a, SparseMatrix& b) { a.swap(b); } /** Sets *this to the identity matrix. * This function also turns the matrix into compressed mode, and drop any reserved memory. */
diff --git a/Eigen/src/SparseCore/SparseVector.h b/Eigen/src/SparseCore/SparseVector.h index 58ebb1b..3f72a34 100644 --- a/Eigen/src/SparseCore/SparseVector.h +++ b/Eigen/src/SparseCore/SparseVector.h
@@ -278,6 +278,7 @@ std::swap(m_size, other.m_size); m_data.swap(other.m_data); } + friend EIGEN_DEVICE_FUNC void swap(SparseVector& a, SparseVector& b) { a.swap(b); } template <int OtherOptions> inline void swap(SparseMatrix<Scalar, OtherOptions, StorageIndex>& other) { @@ -285,6 +286,14 @@ std::swap(m_size, other.m_innerSize); m_data.swap(other.m_data); } + template <int OtherOptions> + friend EIGEN_DEVICE_FUNC void swap(SparseVector& a, SparseMatrix<Scalar, OtherOptions, StorageIndex>& b) { + a.swap(b); + } + template <int OtherOptions> + friend EIGEN_DEVICE_FUNC void swap(SparseMatrix<Scalar, OtherOptions, StorageIndex>& a, SparseVector& b) { + b.swap(a); + } inline SparseVector& operator=(const SparseVector& other) { if (other.isRValue()) {
diff --git a/test/swap.cpp b/test/swap.cpp index bc29704..7bfabc3 100644 --- a/test/swap.cpp +++ b/test/swap.cpp
@@ -63,6 +63,16 @@ } m1 = m1_copy; m2 = m2_copy; + d1 = m1.data(), d2 = m2.data(); + swap(m1, m2); + VERIFY_IS_APPROX(m1, m2_copy); + VERIFY_IS_APPROX(m2, m1_copy); + if (MatrixType::SizeAtCompileTime == Dynamic) { + VERIFY(m1.data() == d2); + VERIFY(m2.data() == d1); + } + m1 = m1_copy; + m2 = m2_copy; // test swapping 2 matrices of different types m1.swap(m3); @@ -70,6 +80,11 @@ VERIFY_IS_APPROX(m3, m1_copy); m1 = m1_copy; m3 = m3_copy; + swap(m1, m3); + VERIFY_IS_APPROX(m1, m3_copy); + VERIFY_IS_APPROX(m3, m1_copy); + m1 = m1_copy; + m3 = m3_copy; // test swapping matrix with expression m1.swap(m2.block(0, 0, rows, cols)); @@ -77,6 +92,11 @@ VERIFY_IS_APPROX(m2, m1_copy); m1 = m1_copy; m2 = m2_copy; + swap(m1, m2.block(0, 0, rows, cols)); + VERIFY_IS_APPROX(m1, m2_copy); + VERIFY_IS_APPROX(m2, m1_copy); + m1 = m1_copy; + m2 = m2_copy; // test swapping two expressions of different types m1.transpose().swap(m3.transpose()); @@ -84,6 +104,11 @@ VERIFY_IS_APPROX(m3, m1_copy); m1 = m1_copy; m3 = m3_copy; + swap(m1.transpose(), m3.transpose()); + VERIFY_IS_APPROX(m1, m3_copy); + VERIFY_IS_APPROX(m3, m1_copy); + m1 = m1_copy; + m3 = m3_copy; check_row_swap(m1); }