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);
}