mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-06-04 18:54:00 +08:00
bug #903: clean swap API regarding extra enable_if parameters, and add failtests for swap
This commit is contained in:
parent
c6fefe5d8e
commit
722916e19d
@ -258,13 +258,6 @@ class Array
|
|||||||
*this = other;
|
*this = other;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Override MatrixBase::swap() since for dynamic-sized matrices of same type it is enough to swap the
|
|
||||||
* data pointers.
|
|
||||||
*/
|
|
||||||
template<typename OtherDerived>
|
|
||||||
void swap(ArrayBase<OtherDerived> const & other)
|
|
||||||
{ this->_swap(other.derived()); }
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline Index innerStride() const { return 1; }
|
EIGEN_DEVICE_FUNC inline Index innerStride() const { return 1; }
|
||||||
EIGEN_DEVICE_FUNC inline Index outerStride() const { return this->innerSize(); }
|
EIGEN_DEVICE_FUNC inline Index outerStride() const { return this->innerSize(); }
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ template<typename Derived> class DenseBase
|
|||||||
OuterStrideAtCompileTime = internal::outer_stride_at_compile_time<Derived>::ret
|
OuterStrideAtCompileTime = internal::outer_stride_at_compile_time<Derived>::ret
|
||||||
};
|
};
|
||||||
|
|
||||||
enum { ThisConstantIsPrivateInPlainObjectBase };
|
enum { IsPlainObjectBase = 0 };
|
||||||
|
|
||||||
/** \returns the number of nonzero coefficients which is in practice the number
|
/** \returns the number of nonzero coefficients which is in practice the number
|
||||||
* of stored coefficients. */
|
* of stored coefficients. */
|
||||||
@ -380,9 +380,9 @@ template<typename Derived> class DenseBase
|
|||||||
*/
|
*/
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
void swap(const DenseBase<OtherDerived>& other,
|
void swap(const DenseBase<OtherDerived>& other)
|
||||||
int = OtherDerived::ThisConstantIsPrivateInPlainObjectBase)
|
|
||||||
{
|
{
|
||||||
|
EIGEN_STATIC_ASSERT(!OtherDerived::IsPlainObjectBase,THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
|
||||||
eigen_assert(rows()==other.rows() && cols()==other.cols());
|
eigen_assert(rows()==other.rows() && cols()==other.cols());
|
||||||
call_assignment(derived(), other.const_cast_derived(), internal::swap_assign_op<Scalar>());
|
call_assignment(derived(), other.const_cast_derived(), internal::swap_assign_op<Scalar>());
|
||||||
}
|
}
|
||||||
|
@ -360,15 +360,6 @@ class Matrix
|
|||||||
*this = other;
|
*this = other;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \internal
|
|
||||||
* \brief Override MatrixBase::swap() since for dynamic-sized matrices
|
|
||||||
* of same type it is enough to swap the data pointers.
|
|
||||||
*/
|
|
||||||
template<typename OtherDerived>
|
|
||||||
EIGEN_DEVICE_FUNC
|
|
||||||
void swap(MatrixBase<OtherDerived> const & other)
|
|
||||||
{ this->_swap(other.derived()); }
|
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC inline Index innerStride() const { return 1; }
|
EIGEN_DEVICE_FUNC inline Index innerStride() const { return 1; }
|
||||||
EIGEN_DEVICE_FUNC inline Index outerStride() const { return this->innerSize(); }
|
EIGEN_DEVICE_FUNC inline Index outerStride() const { return this->innerSize(); }
|
||||||
|
|
||||||
|
@ -799,19 +799,29 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
|||||||
template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
|
template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers>
|
||||||
friend struct internal::matrix_swap_impl;
|
friend struct internal::matrix_swap_impl;
|
||||||
|
|
||||||
/** \internal generic implementation of swap for dense storage since for dynamic-sized matrices of same type it is enough to swap the
|
public:
|
||||||
* data pointers.
|
|
||||||
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
|
/** \internal
|
||||||
|
* \brief Override DenseBase::swap() since for dynamic-sized matrices
|
||||||
|
* of same type it is enough to swap the data pointers.
|
||||||
*/
|
*/
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
void _swap(DenseBase<OtherDerived> const & other)
|
void swap(DenseBase<OtherDerived> & other)
|
||||||
{
|
{
|
||||||
enum { SwapPointers = internal::is_same<Derived, OtherDerived>::value && Base::SizeAtCompileTime==Dynamic };
|
enum { SwapPointers = internal::is_same<Derived, OtherDerived>::value && Base::SizeAtCompileTime==Dynamic };
|
||||||
internal::matrix_swap_impl<Derived, OtherDerived, bool(SwapPointers)>::run(this->derived(), other.const_cast_derived());
|
internal::matrix_swap_impl<Derived, OtherDerived, bool(SwapPointers)>::run(this->derived(), other.derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
/** \internal
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
* \brief const version forwarded to DenseBase::swap
|
||||||
|
*/
|
||||||
|
template<typename OtherDerived>
|
||||||
|
EIGEN_DEVICE_FUNC
|
||||||
|
void swap(DenseBase<OtherDerived> const & other)
|
||||||
|
{ Base::swap(other.derived()); }
|
||||||
|
|
||||||
EIGEN_DEVICE_FUNC
|
EIGEN_DEVICE_FUNC
|
||||||
static EIGEN_STRONG_INLINE void _check_template_params()
|
static EIGEN_STRONG_INLINE void _check_template_params()
|
||||||
{
|
{
|
||||||
@ -826,10 +836,9 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
|
|||||||
&& (Options & (DontAlign|RowMajor)) == Options),
|
&& (Options & (DontAlign|RowMajor)) == Options),
|
||||||
INVALID_MATRIX_TEMPLATE_PARAMETERS)
|
INVALID_MATRIX_TEMPLATE_PARAMETERS)
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
private:
|
enum { IsPlainObjectBase = 1 };
|
||||||
enum { ThisConstantIsPrivateInPlainObjectBase };
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
@ -208,7 +208,7 @@ template<typename PlainObjectType, int Options, typename StrideType> class Ref
|
|||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT(bool(internal::is_lvalue<Derived>::value), THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
|
EIGEN_STATIC_ASSERT(bool(internal::is_lvalue<Derived>::value), THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
|
||||||
EIGEN_STATIC_ASSERT(bool(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
|
EIGEN_STATIC_ASSERT(bool(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
|
||||||
enum { THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY = Derived::ThisConstantIsPrivateInPlainObjectBase};
|
EIGEN_STATIC_ASSERT(!Derived::IsPlainObjectBase,THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
|
||||||
Base::construct(expr.const_cast_derived());
|
Base::construct(expr.const_cast_derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,6 +38,9 @@ ei_add_failtest("ref_3")
|
|||||||
ei_add_failtest("ref_4")
|
ei_add_failtest("ref_4")
|
||||||
ei_add_failtest("ref_5")
|
ei_add_failtest("ref_5")
|
||||||
|
|
||||||
|
ei_add_failtest("swap_1")
|
||||||
|
ei_add_failtest("swap_2")
|
||||||
|
|
||||||
if (EIGEN_FAILTEST_FAILURE_COUNT)
|
if (EIGEN_FAILTEST_FAILURE_COUNT)
|
||||||
message(FATAL_ERROR
|
message(FATAL_ERROR
|
||||||
"${EIGEN_FAILTEST_FAILURE_COUNT} out of ${EIGEN_FAILTEST_COUNT} failtests FAILED. "
|
"${EIGEN_FAILTEST_FAILURE_COUNT} out of ${EIGEN_FAILTEST_COUNT} failtests FAILED. "
|
||||||
|
14
failtest/swap_1.cpp
Normal file
14
failtest/swap_1.cpp
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#include "../Eigen/Core"
|
||||||
|
|
||||||
|
using namespace Eigen;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
VectorXf a(10), b(10);
|
||||||
|
#ifdef EIGEN_SHOULD_FAIL_TO_BUILD
|
||||||
|
const DenseBase<VectorXf> &ac(a);
|
||||||
|
#else
|
||||||
|
DenseBase<VectorXf> &ac(a);
|
||||||
|
#endif
|
||||||
|
b.swap(ac);
|
||||||
|
}
|
14
failtest/swap_2.cpp
Normal file
14
failtest/swap_2.cpp
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#include "../Eigen/Core"
|
||||||
|
|
||||||
|
using namespace Eigen;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
VectorXf a(10), b(10);
|
||||||
|
VectorXf const &ac(a);
|
||||||
|
#ifdef EIGEN_SHOULD_FAIL_TO_BUILD
|
||||||
|
b.swap(ac);
|
||||||
|
#else
|
||||||
|
b.swap(ac.const_cast_derived());
|
||||||
|
#endif
|
||||||
|
}
|
@ -41,9 +41,15 @@ template<typename MatrixType> void swap(const MatrixType& m)
|
|||||||
OtherMatrixType m3_copy = m3;
|
OtherMatrixType m3_copy = m3;
|
||||||
|
|
||||||
// test swapping 2 matrices of same type
|
// test swapping 2 matrices of same type
|
||||||
|
Scalar *d1=m1.data(), *d2=m2.data();
|
||||||
m1.swap(m2);
|
m1.swap(m2);
|
||||||
VERIFY_IS_APPROX(m1,m2_copy);
|
VERIFY_IS_APPROX(m1,m2_copy);
|
||||||
VERIFY_IS_APPROX(m2,m1_copy);
|
VERIFY_IS_APPROX(m2,m1_copy);
|
||||||
|
if(MatrixType::SizeAtCompileTime==Dynamic)
|
||||||
|
{
|
||||||
|
VERIFY(m1.data()==d2);
|
||||||
|
VERIFY(m2.data()==d1);
|
||||||
|
}
|
||||||
m1 = m1_copy;
|
m1 = m1_copy;
|
||||||
m2 = m2_copy;
|
m2 = m2_copy;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user