bug #872: Avoid deprecated binder1st/binder2nd usage by providing custom functors for comparison operators

This commit is contained in:
Christoph Hertzberg 2015-05-07 17:28:40 +02:00
parent 4a936974a5
commit 494fa991c3
5 changed files with 102 additions and 25 deletions

View File

@ -154,6 +154,48 @@ struct functor_traits<scalar_max_op<Scalar> > {
}; };
}; };
/** \internal
* \brief Template functors for comparison of two scalars
* \todo Implement packet-comparisons
*/
template<typename Scalar, ComparisonName cmp> struct scalar_cmp_op;
template<typename Scalar, ComparisonName cmp>
struct functor_traits<scalar_cmp_op<Scalar, cmp> > {
enum {
Cost = NumTraits<Scalar>::AddCost,
PacketAccess = false
};
};
template<ComparisonName Cmp, typename Scalar>
struct result_of<scalar_cmp_op<Scalar, Cmp>(Scalar,Scalar)> {
typedef bool type;
};
template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_EQ> {
EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a==b;}
};
template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_LT> {
EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a<b;}
};
template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_LE> {
EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a<=b;}
};
template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_UNORD> {
EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return !(a<=b || b<=a);}
};
template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_NEQ> {
EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a!=b;}
};
/** \internal /** \internal
* \brief Template functor to compute the hypot of two scalars * \brief Template functor to compute the hypot of two scalars
* *

View File

@ -492,6 +492,16 @@ struct IndexBased {};
// evaluator based on iterators to access coefficients. // evaluator based on iterators to access coefficients.
struct IteratorBased {}; struct IteratorBased {};
/** \internal
* Constants for comparison functors
*/
enum ComparisonName {
cmp_EQ = 0,
cmp_LT = 1,
cmp_LE = 2,
cmp_UNORD = 3,
cmp_NEQ = 4
};
} // end namespace internal } // end namespace internal
} // end namespace Eigen } // end namespace Eigen

View File

@ -74,6 +74,44 @@ max
return (max)(Derived::PlainObject::Constant(rows(), cols(), other)); return (max)(Derived::PlainObject::Constant(rows(), cols(), other));
} }
// TODO code generating macros could be moved to Macros.h and could include generation of documentation
#define EIGEN_MAKE_CWISE_COMP_OP(OP, COMPARATOR) \
template<typename OtherDerived> \
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_cmp_op<Scalar, internal::cmp_ ## COMPARATOR>, const Derived, const OtherDerived> \
OP(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const \
{ \
return CwiseBinaryOp<internal::scalar_cmp_op<Scalar, internal::cmp_ ## COMPARATOR>, const Derived, const OtherDerived>(derived(), other.derived()); \
}\
typedef CwiseBinaryOp<internal::scalar_cmp_op<Scalar, internal::cmp_ ## COMPARATOR>, const Derived, const CwiseNullaryOp<internal::scalar_constant_op<Scalar>, PlainObject> > Cmp ## COMPARATOR ## ReturnType; \
typedef CwiseBinaryOp<internal::scalar_cmp_op<Scalar, internal::cmp_ ## COMPARATOR>, const CwiseNullaryOp<internal::scalar_constant_op<Scalar>, PlainObject>, const Derived > RCmp ## COMPARATOR ## ReturnType; \
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Cmp ## COMPARATOR ## ReturnType \
OP(const Scalar& s) const { \
return this->OP(Derived::PlainObject::Constant(rows(), cols(), s)); \
} \
EIGEN_DEVICE_FUNC friend EIGEN_STRONG_INLINE const RCmp ## COMPARATOR ## ReturnType \
OP(const Scalar& s, const Derived& d) { \
return Derived::PlainObject::Constant(d.rows(), d.cols(), s).OP(d); \
}
#define EIGEN_MAKE_CWISE_COMP_R_OP(OP, R_OP, RCOMPARATOR) \
template<typename OtherDerived> \
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_cmp_op<Scalar, internal::cmp_##RCOMPARATOR>, const OtherDerived, const Derived> \
OP(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const \
{ \
return CwiseBinaryOp<internal::scalar_cmp_op<Scalar, internal::cmp_##RCOMPARATOR>, const OtherDerived, const Derived>(other.derived(), derived()); \
} \
EIGEN_DEVICE_FUNC \
inline const RCmp ## RCOMPARATOR ## ReturnType \
OP(const Scalar& s) const { \
return Derived::PlainObject::Constant(rows(), cols(), s).R_OP(*this); \
} \
friend inline const Cmp ## RCOMPARATOR ## ReturnType \
OP(const Scalar& s, const Derived& d) { \
return d.R_OP(Derived::PlainObject::Constant(d.rows(), d.cols(), s)); \
}
/** \returns an expression of the coefficient-wise \< operator of *this and \a other /** \returns an expression of the coefficient-wise \< operator of *this and \a other
* *
* Example: \include Cwise_less.cpp * Example: \include Cwise_less.cpp
@ -81,7 +119,7 @@ max
* *
* \sa all(), any(), operator>(), operator<=() * \sa all(), any(), operator>(), operator<=()
*/ */
EIGEN_MAKE_CWISE_BINARY_OP(operator<,std::less) EIGEN_MAKE_CWISE_COMP_OP(operator<, LT)
/** \returns an expression of the coefficient-wise \<= operator of *this and \a other /** \returns an expression of the coefficient-wise \<= operator of *this and \a other
* *
@ -90,7 +128,7 @@ EIGEN_MAKE_CWISE_BINARY_OP(operator<,std::less)
* *
* \sa all(), any(), operator>=(), operator<() * \sa all(), any(), operator>=(), operator<()
*/ */
EIGEN_MAKE_CWISE_BINARY_OP(operator<=,std::less_equal) EIGEN_MAKE_CWISE_COMP_OP(operator<=, LE)
/** \returns an expression of the coefficient-wise \> operator of *this and \a other /** \returns an expression of the coefficient-wise \> operator of *this and \a other
* *
@ -99,7 +137,7 @@ EIGEN_MAKE_CWISE_BINARY_OP(operator<=,std::less_equal)
* *
* \sa all(), any(), operator>=(), operator<() * \sa all(), any(), operator>=(), operator<()
*/ */
EIGEN_MAKE_CWISE_BINARY_OP(operator>,std::greater) EIGEN_MAKE_CWISE_COMP_R_OP(operator>, operator<, LT)
/** \returns an expression of the coefficient-wise \>= operator of *this and \a other /** \returns an expression of the coefficient-wise \>= operator of *this and \a other
* *
@ -108,7 +146,7 @@ EIGEN_MAKE_CWISE_BINARY_OP(operator>,std::greater)
* *
* \sa all(), any(), operator>(), operator<=() * \sa all(), any(), operator>(), operator<=()
*/ */
EIGEN_MAKE_CWISE_BINARY_OP(operator>=,std::greater_equal) EIGEN_MAKE_CWISE_COMP_R_OP(operator>=, operator<=, LE)
/** \returns an expression of the coefficient-wise == operator of *this and \a other /** \returns an expression of the coefficient-wise == operator of *this and \a other
* *
@ -122,7 +160,7 @@ EIGEN_MAKE_CWISE_BINARY_OP(operator>=,std::greater_equal)
* *
* \sa all(), any(), isApprox(), isMuchSmallerThan() * \sa all(), any(), isApprox(), isMuchSmallerThan()
*/ */
EIGEN_MAKE_CWISE_BINARY_OP(operator==,std::equal_to) EIGEN_MAKE_CWISE_COMP_OP(operator==, EQ)
/** \returns an expression of the coefficient-wise != operator of *this and \a other /** \returns an expression of the coefficient-wise != operator of *this and \a other
* *
@ -136,7 +174,11 @@ EIGEN_MAKE_CWISE_BINARY_OP(operator==,std::equal_to)
* *
* \sa all(), any(), isApprox(), isMuchSmallerThan() * \sa all(), any(), isApprox(), isMuchSmallerThan()
*/ */
EIGEN_MAKE_CWISE_BINARY_OP(operator!=,std::not_equal_to) EIGEN_MAKE_CWISE_COMP_OP(operator!=, NEQ)
#undef EIGEN_MAKE_CWISE_COMP_OP
#undef EIGEN_MAKE_CWISE_COMP_R_OP
// scalar addition // scalar addition

View File

@ -246,24 +246,5 @@ cube() const
return CubeReturnType(derived()); return CubeReturnType(derived());
} }
#define EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(METHOD_NAME,FUNCTOR) \
EIGEN_DEVICE_FUNC \
inline const CwiseUnaryOp<std::binder2nd<FUNCTOR<Scalar> >, const Derived> \
METHOD_NAME(const Scalar& s) const { \
return CwiseUnaryOp<std::binder2nd<FUNCTOR<Scalar> >, const Derived> \
(derived(), std::bind2nd(FUNCTOR<Scalar>(), s)); \
} \
friend inline const CwiseUnaryOp<std::binder1st<FUNCTOR<Scalar> >, const Derived> \
METHOD_NAME(const Scalar& s, const Derived& d) { \
return CwiseUnaryOp<std::binder1st<FUNCTOR<Scalar> >, const Derived> \
(d, std::bind1st(FUNCTOR<Scalar>(), s)); \
}
EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(operator==, std::equal_to)
EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(operator!=, std::not_equal_to)
EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(operator<, std::less)
EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(operator<=, std::less_equal)
EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(operator>, std::greater)
EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(operator>=, std::greater_equal)

View File

@ -136,6 +136,8 @@ template<typename ArrayType> void comparisons(const ArrayType& m)
VERIFY(! (m1 < m3).all() ); VERIFY(! (m1 < m3).all() );
VERIFY(! (m1 > m3).all() ); VERIFY(! (m1 > m3).all() );
} }
VERIFY(!(m1 > m2 && m1 < m2).any());
VERIFY((m1 <= m2 || m1 >= m2).all());
// comparisons array to scalar // comparisons array to scalar
VERIFY( (m1 != (m1(r,c)+1) ).any() ); VERIFY( (m1 != (m1(r,c)+1) ).any() );