Apply clang-format

This commit is contained in:
Tobias Wood
2023-11-29 11:12:48 +00:00
parent 9ea520fc45
commit f38e16c193
534 changed files with 103368 additions and 116934 deletions

View File

@@ -16,159 +16,166 @@
namespace Eigen {
namespace internal {
/** \internal
* \brief Template functor for scalar/packet assignment
*
*/
template<typename DstScalar,typename SrcScalar> struct assign_op {
/** \internal
* \brief Template functor for scalar/packet assignment
*
*/
template <typename DstScalar, typename SrcScalar>
struct assign_op {
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(DstScalar& a, const SrcScalar& b) const { a = b; }
template<int Alignment, typename Packet>
EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const
{ internal::pstoret<DstScalar,Packet,Alignment>(a,b); }
template <int Alignment, typename Packet>
EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const {
internal::pstoret<DstScalar, Packet, Alignment>(a, b);
}
};
// Empty overload for void type (used by PermutationMatrix)
template<typename DstScalar> struct assign_op<DstScalar,void> {};
template <typename DstScalar>
struct assign_op<DstScalar, void> {};
template<typename DstScalar,typename SrcScalar>
struct functor_traits<assign_op<DstScalar,SrcScalar> > {
template <typename DstScalar, typename SrcScalar>
struct functor_traits<assign_op<DstScalar, SrcScalar> > {
enum {
Cost = NumTraits<DstScalar>::ReadCost,
PacketAccess = is_same<DstScalar,SrcScalar>::value && packet_traits<DstScalar>::Vectorizable && packet_traits<SrcScalar>::Vectorizable
PacketAccess = is_same<DstScalar, SrcScalar>::value && packet_traits<DstScalar>::Vectorizable &&
packet_traits<SrcScalar>::Vectorizable
};
};
/** \internal
* \brief Template functor for scalar/packet assignment with addition
*
*/
template<typename DstScalar,typename SrcScalar> struct add_assign_op {
* \brief Template functor for scalar/packet assignment with addition
*
*/
template <typename DstScalar, typename SrcScalar>
struct add_assign_op {
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(DstScalar& a, const SrcScalar& b) const { a += b; }
template<int Alignment, typename Packet>
EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const
{ internal::pstoret<DstScalar,Packet,Alignment>(a,internal::padd(internal::ploadt<Packet,Alignment>(a),b)); }
template <int Alignment, typename Packet>
EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const {
internal::pstoret<DstScalar, Packet, Alignment>(a, internal::padd(internal::ploadt<Packet, Alignment>(a), b));
}
};
template<typename DstScalar,typename SrcScalar>
struct functor_traits<add_assign_op<DstScalar,SrcScalar> > {
template <typename DstScalar, typename SrcScalar>
struct functor_traits<add_assign_op<DstScalar, SrcScalar> > {
enum {
Cost = NumTraits<DstScalar>::ReadCost + NumTraits<DstScalar>::AddCost,
PacketAccess = is_same<DstScalar,SrcScalar>::value && packet_traits<DstScalar>::HasAdd
PacketAccess = is_same<DstScalar, SrcScalar>::value && packet_traits<DstScalar>::HasAdd
};
};
/** \internal
* \brief Template functor for scalar/packet assignment with subtraction
*
*/
template<typename DstScalar,typename SrcScalar> struct sub_assign_op {
* \brief Template functor for scalar/packet assignment with subtraction
*
*/
template <typename DstScalar, typename SrcScalar>
struct sub_assign_op {
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(DstScalar& a, const SrcScalar& b) const { a -= b; }
template<int Alignment, typename Packet>
EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const
{ internal::pstoret<DstScalar,Packet,Alignment>(a,internal::psub(internal::ploadt<Packet,Alignment>(a),b)); }
template <int Alignment, typename Packet>
EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const {
internal::pstoret<DstScalar, Packet, Alignment>(a, internal::psub(internal::ploadt<Packet, Alignment>(a), b));
}
};
template<typename DstScalar,typename SrcScalar>
struct functor_traits<sub_assign_op<DstScalar,SrcScalar> > {
template <typename DstScalar, typename SrcScalar>
struct functor_traits<sub_assign_op<DstScalar, SrcScalar> > {
enum {
Cost = NumTraits<DstScalar>::ReadCost + NumTraits<DstScalar>::AddCost,
PacketAccess = is_same<DstScalar,SrcScalar>::value && packet_traits<DstScalar>::HasSub
PacketAccess = is_same<DstScalar, SrcScalar>::value && packet_traits<DstScalar>::HasSub
};
};
/** \internal
* \brief Template functor for scalar/packet assignment with multiplication
*
*/
template<typename DstScalar, typename SrcScalar=DstScalar>
* \brief Template functor for scalar/packet assignment with multiplication
*
*/
template <typename DstScalar, typename SrcScalar = DstScalar>
struct mul_assign_op {
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(DstScalar& a, const SrcScalar& b) const { a *= b; }
template<int Alignment, typename Packet>
EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const
{ internal::pstoret<DstScalar,Packet,Alignment>(a,internal::pmul(internal::ploadt<Packet,Alignment>(a),b)); }
template <int Alignment, typename Packet>
EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const {
internal::pstoret<DstScalar, Packet, Alignment>(a, internal::pmul(internal::ploadt<Packet, Alignment>(a), b));
}
};
template<typename DstScalar, typename SrcScalar>
struct functor_traits<mul_assign_op<DstScalar,SrcScalar> > {
template <typename DstScalar, typename SrcScalar>
struct functor_traits<mul_assign_op<DstScalar, SrcScalar> > {
enum {
Cost = NumTraits<DstScalar>::ReadCost + NumTraits<DstScalar>::MulCost,
PacketAccess = is_same<DstScalar,SrcScalar>::value && packet_traits<DstScalar>::HasMul
PacketAccess = is_same<DstScalar, SrcScalar>::value && packet_traits<DstScalar>::HasMul
};
};
/** \internal
* \brief Template functor for scalar/packet assignment with diviving
*
*/
template<typename DstScalar, typename SrcScalar=DstScalar> struct div_assign_op {
* \brief Template functor for scalar/packet assignment with diviving
*
*/
template <typename DstScalar, typename SrcScalar = DstScalar>
struct div_assign_op {
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(DstScalar& a, const SrcScalar& b) const { a /= b; }
template<int Alignment, typename Packet>
EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const
{ internal::pstoret<DstScalar,Packet,Alignment>(a,internal::pdiv(internal::ploadt<Packet,Alignment>(a),b)); }
template <int Alignment, typename Packet>
EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const {
internal::pstoret<DstScalar, Packet, Alignment>(a, internal::pdiv(internal::ploadt<Packet, Alignment>(a), b));
}
};
template<typename DstScalar, typename SrcScalar>
struct functor_traits<div_assign_op<DstScalar,SrcScalar> > {
template <typename DstScalar, typename SrcScalar>
struct functor_traits<div_assign_op<DstScalar, SrcScalar> > {
enum {
Cost = NumTraits<DstScalar>::ReadCost + NumTraits<DstScalar>::MulCost,
PacketAccess = is_same<DstScalar,SrcScalar>::value && packet_traits<DstScalar>::HasDiv
PacketAccess = is_same<DstScalar, SrcScalar>::value && packet_traits<DstScalar>::HasDiv
};
};
/** \internal
* \brief Template functor for scalar/packet assignment with swapping
*
* It works as follow. For a non-vectorized evaluation loop, we have:
* for(i) func(A.coeffRef(i), B.coeff(i));
* where B is a SwapWrapper expression. The trick is to make SwapWrapper::coeff behaves like a non-const coeffRef.
* Actually, SwapWrapper might not even be needed since even if B is a plain expression, since it has to be writable
* B.coeff already returns a const reference to the underlying scalar value.
*
* The case of a vectorized loop is more tricky:
* for(i,j) func.assignPacket<A_Align>(&A.coeffRef(i,j), B.packet<B_Align>(i,j));
* Here, B must be a SwapWrapper whose packet function actually returns a proxy object holding a Scalar*,
* the actual alignment and Packet type.
*
*/
template<typename Scalar> struct swap_assign_op {
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(Scalar& a, const Scalar& b) const
{
* \brief Template functor for scalar/packet assignment with swapping
*
* It works as follow. For a non-vectorized evaluation loop, we have:
* for(i) func(A.coeffRef(i), B.coeff(i));
* where B is a SwapWrapper expression. The trick is to make SwapWrapper::coeff behaves like a non-const coeffRef.
* Actually, SwapWrapper might not even be needed since even if B is a plain expression, since it has to be writable
* B.coeff already returns a const reference to the underlying scalar value.
*
* The case of a vectorized loop is more tricky:
* for(i,j) func.assignPacket<A_Align>(&A.coeffRef(i,j), B.packet<B_Align>(i,j));
* Here, B must be a SwapWrapper whose packet function actually returns a proxy object holding a Scalar*,
* the actual alignment and Packet type.
*
*/
template <typename Scalar>
struct swap_assign_op {
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(Scalar& a, const Scalar& b) const {
#ifdef EIGEN_GPUCC
// FIXME is there some kind of cuda::swap?
Scalar t=b; const_cast<Scalar&>(b)=a; a=t;
Scalar t = b;
const_cast<Scalar&>(b) = a;
a = t;
#else
using std::swap;
swap(a,const_cast<Scalar&>(b));
swap(a, const_cast<Scalar&>(b));
#endif
}
};
template<typename Scalar>
template <typename Scalar>
struct functor_traits<swap_assign_op<Scalar> > {
enum {
Cost = 3 * NumTraits<Scalar>::ReadCost,
PacketAccess =
#if defined(EIGEN_VECTORIZE_AVX) && (EIGEN_CLANG_STRICT_LESS_THAN(8,0,0) || EIGEN_COMP_CLANGAPPLE)
// This is a partial workaround for a bug in clang generating bad code
// when mixing 256/512 bits loads and 128 bits moves.
// See http://eigen.tuxfamily.org/bz/show_bug.cgi?id=1684
// https://bugs.llvm.org/show_bug.cgi?id=40815
PacketAccess =
#if defined(EIGEN_VECTORIZE_AVX) && (EIGEN_CLANG_STRICT_LESS_THAN(8, 0, 0) || EIGEN_COMP_CLANGAPPLE)
// This is a partial workaround for a bug in clang generating bad code
// when mixing 256/512 bits loads and 128 bits moves.
// See http://eigen.tuxfamily.org/bz/show_bug.cgi?id=1684
// https://bugs.llvm.org/show_bug.cgi?id=40815
0
#else
packet_traits<Scalar>::Vectorizable
#endif
#else
packet_traits<Scalar>::Vectorizable
#endif
};
};
} // namespace internal
} // namespace internal
} // namespace Eigen
} // namespace Eigen
#endif // EIGEN_ASSIGNMENT_FUNCTORS_H
#endif // EIGEN_ASSIGNMENT_FUNCTORS_H

View File

@@ -19,108 +19,114 @@ namespace internal {
//---------- associative binary functors ----------
template<typename Arg1, typename Arg2>
struct binary_op_base
{
template <typename Arg1, typename Arg2>
struct binary_op_base {
typedef Arg1 first_argument_type;
typedef Arg2 second_argument_type;
};
/** \internal
* \brief Template functor to compute the sum of two scalars
*
* \sa class CwiseBinaryOp, MatrixBase::operator+, class VectorwiseOp, DenseBase::sum()
*/
template<typename LhsScalar,typename RhsScalar>
struct scalar_sum_op : binary_op_base<LhsScalar,RhsScalar>
{
typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_sum_op>::ReturnType result_type;
* \brief Template functor to compute the sum of two scalars
*
* \sa class CwiseBinaryOp, MatrixBase::operator+, class VectorwiseOp, DenseBase::sum()
*/
template <typename LhsScalar, typename RhsScalar>
struct scalar_sum_op : binary_op_base<LhsScalar, RhsScalar> {
typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar, scalar_sum_op>::ReturnType result_type;
#ifdef EIGEN_SCALAR_BINARY_OP_PLUGIN
scalar_sum_op() {
EIGEN_SCALAR_BINARY_OP_PLUGIN
}
scalar_sum_op(){EIGEN_SCALAR_BINARY_OP_PLUGIN}
#endif
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a + b; }
template<typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const
{ return internal::padd(a,b); }
template<typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type predux(const Packet& a) const
{ return internal::predux(a); }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type
operator()(const LhsScalar& a, const RhsScalar& b) const {
return a + b;
}
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const {
return internal::padd(a, b);
}
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type predux(const Packet& a) const {
return internal::predux(a);
}
};
template<typename LhsScalar,typename RhsScalar>
struct functor_traits<scalar_sum_op<LhsScalar,RhsScalar> > {
template <typename LhsScalar, typename RhsScalar>
struct functor_traits<scalar_sum_op<LhsScalar, RhsScalar>> {
enum {
Cost = (int(NumTraits<LhsScalar>::AddCost) + int(NumTraits<RhsScalar>::AddCost)) / 2, // rough estimate!
PacketAccess = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasAdd && packet_traits<RhsScalar>::HasAdd
Cost = (int(NumTraits<LhsScalar>::AddCost) + int(NumTraits<RhsScalar>::AddCost)) / 2, // rough estimate!
PacketAccess =
is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasAdd && packet_traits<RhsScalar>::HasAdd
// TODO vectorize mixed sum
};
};
template<>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool scalar_sum_op<bool,bool>::operator() (const bool& a, const bool& b) const { return a || b; }
template <>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool scalar_sum_op<bool, bool>::operator()(const bool& a, const bool& b) const {
return a || b;
}
/** \internal
* \brief Template functor to compute the product of two scalars
*
* \sa class CwiseBinaryOp, Cwise::operator*(), class VectorwiseOp, MatrixBase::redux()
*/
template<typename LhsScalar,typename RhsScalar>
struct scalar_product_op : binary_op_base<LhsScalar,RhsScalar>
{
typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_product_op>::ReturnType result_type;
* \brief Template functor to compute the product of two scalars
*
* \sa class CwiseBinaryOp, Cwise::operator*(), class VectorwiseOp, MatrixBase::redux()
*/
template <typename LhsScalar, typename RhsScalar>
struct scalar_product_op : binary_op_base<LhsScalar, RhsScalar> {
typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar, scalar_product_op>::ReturnType result_type;
#ifdef EIGEN_SCALAR_BINARY_OP_PLUGIN
scalar_product_op() {
EIGEN_SCALAR_BINARY_OP_PLUGIN
}
scalar_product_op(){EIGEN_SCALAR_BINARY_OP_PLUGIN}
#endif
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a * b; }
template<typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const
{ return internal::pmul(a,b); }
template<typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type predux(const Packet& a) const
{ return internal::predux_mul(a); }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type
operator()(const LhsScalar& a, const RhsScalar& b) const {
return a * b;
}
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const {
return internal::pmul(a, b);
}
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type predux(const Packet& a) const {
return internal::predux_mul(a);
}
};
template<typename LhsScalar,typename RhsScalar>
struct functor_traits<scalar_product_op<LhsScalar,RhsScalar> > {
template <typename LhsScalar, typename RhsScalar>
struct functor_traits<scalar_product_op<LhsScalar, RhsScalar>> {
enum {
Cost = (int(NumTraits<LhsScalar>::MulCost) + int(NumTraits<RhsScalar>::MulCost))/2, // rough estimate!
PacketAccess = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasMul && packet_traits<RhsScalar>::HasMul
Cost = (int(NumTraits<LhsScalar>::MulCost) + int(NumTraits<RhsScalar>::MulCost)) / 2, // rough estimate!
PacketAccess =
is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasMul && packet_traits<RhsScalar>::HasMul
// TODO vectorize mixed product
};
};
template<>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool scalar_product_op<bool,bool>::operator() (const bool& a, const bool& b) const { return a && b; }
template <>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool scalar_product_op<bool, bool>::operator()(const bool& a,
const bool& b) const {
return a && b;
}
/** \internal
* \brief Template functor to compute the conjugate product of two scalars
*
* This is a short cut for conj(x) * y which is needed for optimization purpose; in Eigen2 support mode, this becomes x * conj(y)
*/
template<typename LhsScalar,typename RhsScalar>
struct scalar_conj_product_op : binary_op_base<LhsScalar,RhsScalar>
{
* \brief Template functor to compute the conjugate product of two scalars
*
* This is a short cut for conj(x) * y which is needed for optimization purpose; in Eigen2 support mode, this becomes x
* * conj(y)
*/
template <typename LhsScalar, typename RhsScalar>
struct scalar_conj_product_op : binary_op_base<LhsScalar, RhsScalar> {
enum { Conj = NumTraits<LhsScalar>::IsComplex };
enum {
Conj = NumTraits<LhsScalar>::IsComplex
};
typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar, scalar_conj_product_op>::ReturnType result_type;
typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_conj_product_op>::ReturnType result_type;
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(const LhsScalar& a, const RhsScalar& b) const {
return conj_helper<LhsScalar, RhsScalar, Conj, false>().pmul(a, b);
}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const LhsScalar& a, const RhsScalar& b) const
{ return conj_helper<LhsScalar,RhsScalar,Conj,false>().pmul(a,b); }
template<typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const
{ return conj_helper<Packet,Packet,Conj,false>().pmul(a,b); }
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const {
return conj_helper<Packet, Packet, Conj, false>().pmul(a, b);
}
};
template<typename LhsScalar,typename RhsScalar>
struct functor_traits<scalar_conj_product_op<LhsScalar,RhsScalar> > {
template <typename LhsScalar, typename RhsScalar>
struct functor_traits<scalar_conj_product_op<LhsScalar, RhsScalar>> {
enum {
Cost = NumTraits<LhsScalar>::MulCost,
PacketAccess = internal::is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasMul
@@ -128,65 +134,59 @@ struct functor_traits<scalar_conj_product_op<LhsScalar,RhsScalar> > {
};
/** \internal
* \brief Template functor to compute the min of two scalars
*
* \sa class CwiseBinaryOp, MatrixBase::cwiseMin, class VectorwiseOp, MatrixBase::minCoeff()
*/
template<typename LhsScalar,typename RhsScalar, int NaNPropagation>
struct scalar_min_op : binary_op_base<LhsScalar,RhsScalar>
{
typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_min_op>::ReturnType result_type;
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const LhsScalar& a, const RhsScalar& b) const {
* \brief Template functor to compute the min of two scalars
*
* \sa class CwiseBinaryOp, MatrixBase::cwiseMin, class VectorwiseOp, MatrixBase::minCoeff()
*/
template <typename LhsScalar, typename RhsScalar, int NaNPropagation>
struct scalar_min_op : binary_op_base<LhsScalar, RhsScalar> {
typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar, scalar_min_op>::ReturnType result_type;
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(const LhsScalar& a, const RhsScalar& b) const {
return internal::pmin<NaNPropagation>(a, b);
}
template<typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const
{
return internal::pmin<NaNPropagation>(a,b);
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const {
return internal::pmin<NaNPropagation>(a, b);
}
template<typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type predux(const Packet& a) const
{
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type predux(const Packet& a) const {
return internal::predux_min<NaNPropagation>(a);
}
};
template<typename LhsScalar,typename RhsScalar, int NaNPropagation>
struct functor_traits<scalar_min_op<LhsScalar,RhsScalar, NaNPropagation> > {
template <typename LhsScalar, typename RhsScalar, int NaNPropagation>
struct functor_traits<scalar_min_op<LhsScalar, RhsScalar, NaNPropagation>> {
enum {
Cost = (NumTraits<LhsScalar>::AddCost+NumTraits<RhsScalar>::AddCost)/2,
Cost = (NumTraits<LhsScalar>::AddCost + NumTraits<RhsScalar>::AddCost) / 2,
PacketAccess = internal::is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasMin
};
};
/** \internal
* \brief Template functor to compute the max of two scalars
*
* \sa class CwiseBinaryOp, MatrixBase::cwiseMax, class VectorwiseOp, MatrixBase::maxCoeff()
*/
template<typename LhsScalar,typename RhsScalar, int NaNPropagation>
struct scalar_max_op : binary_op_base<LhsScalar,RhsScalar>
{
typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_max_op>::ReturnType result_type;
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const LhsScalar& a, const RhsScalar& b) const {
return internal::pmax<NaNPropagation>(a,b);
* \brief Template functor to compute the max of two scalars
*
* \sa class CwiseBinaryOp, MatrixBase::cwiseMax, class VectorwiseOp, MatrixBase::maxCoeff()
*/
template <typename LhsScalar, typename RhsScalar, int NaNPropagation>
struct scalar_max_op : binary_op_base<LhsScalar, RhsScalar> {
typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar, scalar_max_op>::ReturnType result_type;
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(const LhsScalar& a, const RhsScalar& b) const {
return internal::pmax<NaNPropagation>(a, b);
}
template<typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const
{
return internal::pmax<NaNPropagation>(a,b);
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const {
return internal::pmax<NaNPropagation>(a, b);
}
template<typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type predux(const Packet& a) const
{
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type predux(const Packet& a) const {
return internal::predux_max<NaNPropagation>(a);
}
};
template<typename LhsScalar,typename RhsScalar, int NaNPropagation>
struct functor_traits<scalar_max_op<LhsScalar,RhsScalar, NaNPropagation> > {
template <typename LhsScalar, typename RhsScalar, int NaNPropagation>
struct functor_traits<scalar_max_op<LhsScalar, RhsScalar, NaNPropagation>> {
enum {
Cost = (NumTraits<LhsScalar>::AddCost+NumTraits<RhsScalar>::AddCost)/2,
Cost = (NumTraits<LhsScalar>::AddCost + NumTraits<RhsScalar>::AddCost) / 2,
PacketAccess = internal::is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasMax
};
};
@@ -195,8 +195,7 @@ struct functor_traits<scalar_max_op<LhsScalar,RhsScalar, NaNPropagation> > {
* \brief Template functors for comparison of two scalars
* \todo Implement packet-comparisons
*/
template <typename LhsScalar, typename RhsScalar, ComparisonName cmp,
bool UseTypedComparators = false>
template <typename LhsScalar, typename RhsScalar, ComparisonName cmp, bool UseTypedComparators = false>
struct scalar_cmp_op;
template <typename LhsScalar, typename RhsScalar, ComparisonName cmp, bool UseTypedComparators>
@@ -311,42 +310,36 @@ struct scalar_cmp_op<LhsScalar, RhsScalar, cmp_NEQ, UseTypedComparators> : binar
};
/** \internal
* \brief Template functor to compute the hypot of two \b positive \b and \b real scalars
*
* \sa MatrixBase::stableNorm(), class Redux
*/
template<typename Scalar>
struct scalar_hypot_op<Scalar,Scalar> : binary_op_base<Scalar,Scalar>
{
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar &x, const Scalar &y) const
{
* \brief Template functor to compute the hypot of two \b positive \b and \b real scalars
*
* \sa MatrixBase::stableNorm(), class Redux
*/
template <typename Scalar>
struct scalar_hypot_op<Scalar, Scalar> : binary_op_base<Scalar, Scalar> {
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator()(const Scalar& x, const Scalar& y) const {
// This functor is used by hypotNorm only for which it is faster to first apply abs
// on all coefficients prior to reduction through hypot.
// This way we avoid calling abs on positive and real entries, and this also permits
// to seamlessly handle complexes. Otherwise we would have to handle both real and complexes
// through the same functor...
return internal::positive_real_hypot(x,y);
return internal::positive_real_hypot(x, y);
}
};
template<typename Scalar>
struct functor_traits<scalar_hypot_op<Scalar,Scalar> > {
enum
{
Cost = 3 * NumTraits<Scalar>::AddCost +
2 * NumTraits<Scalar>::MulCost +
2 * scalar_div_cost<Scalar,false>::value,
template <typename Scalar>
struct functor_traits<scalar_hypot_op<Scalar, Scalar>> {
enum {
Cost = 3 * NumTraits<Scalar>::AddCost + 2 * NumTraits<Scalar>::MulCost + 2 * scalar_div_cost<Scalar, false>::value,
PacketAccess = false
};
};
/** \internal
* \brief Template functor to compute the pow of two scalars
* See the specification of pow in https://en.cppreference.com/w/cpp/numeric/math/pow
*/
template<typename Scalar, typename Exponent>
struct scalar_pow_op : binary_op_base<Scalar,Exponent>
{
typedef typename ScalarBinaryOpTraits<Scalar,Exponent,scalar_pow_op>::ReturnType result_type;
* \brief Template functor to compute the pow of two scalars
* See the specification of pow in https://en.cppreference.com/w/cpp/numeric/math/pow
*/
template <typename Scalar, typename Exponent>
struct scalar_pow_op : binary_op_base<Scalar, Exponent> {
typedef typename ScalarBinaryOpTraits<Scalar, Exponent, scalar_pow_op>::ReturnType result_type;
#ifdef EIGEN_SCALAR_BINARY_OP_PLUGIN
scalar_pow_op() {
typedef Scalar LhsScalar;
@@ -355,64 +348,62 @@ struct scalar_pow_op : binary_op_base<Scalar,Exponent>
}
#endif
EIGEN_DEVICE_FUNC
inline result_type operator() (const Scalar& a, const Exponent& b) const { return numext::pow(a, b); }
EIGEN_DEVICE_FUNC inline result_type operator()(const Scalar& a, const Exponent& b) const {
return numext::pow(a, b);
}
template<typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
{
return generic_pow(a,b);
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const {
return generic_pow(a, b);
}
};
template<typename Scalar, typename Exponent>
struct functor_traits<scalar_pow_op<Scalar,Exponent> > {
template <typename Scalar, typename Exponent>
struct functor_traits<scalar_pow_op<Scalar, Exponent>> {
enum {
Cost = 5 * NumTraits<Scalar>::MulCost,
PacketAccess = (!NumTraits<Scalar>::IsComplex && !NumTraits<Scalar>::IsInteger &&
packet_traits<Scalar>::HasExp && packet_traits<Scalar>::HasLog &&
packet_traits<Scalar>::HasRound && packet_traits<Scalar>::HasCmp &&
PacketAccess = (!NumTraits<Scalar>::IsComplex && !NumTraits<Scalar>::IsInteger && packet_traits<Scalar>::HasExp &&
packet_traits<Scalar>::HasLog && packet_traits<Scalar>::HasRound && packet_traits<Scalar>::HasCmp &&
// Temporarily disable packet access for half/bfloat16 until
// accuracy is improved.
!is_same<Scalar, half>::value && !is_same<Scalar, bfloat16>::value
)
!is_same<Scalar, half>::value && !is_same<Scalar, bfloat16>::value)
};
};
//---------- non associative binary functors ----------
/** \internal
* \brief Template functor to compute the difference of two scalars
*
* \sa class CwiseBinaryOp, MatrixBase::operator-
*/
template<typename LhsScalar,typename RhsScalar>
struct scalar_difference_op : binary_op_base<LhsScalar,RhsScalar>
{
typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_difference_op>::ReturnType result_type;
* \brief Template functor to compute the difference of two scalars
*
* \sa class CwiseBinaryOp, MatrixBase::operator-
*/
template <typename LhsScalar, typename RhsScalar>
struct scalar_difference_op : binary_op_base<LhsScalar, RhsScalar> {
typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar, scalar_difference_op>::ReturnType result_type;
#ifdef EIGEN_SCALAR_BINARY_OP_PLUGIN
scalar_difference_op() {
EIGEN_SCALAR_BINARY_OP_PLUGIN
}
scalar_difference_op(){EIGEN_SCALAR_BINARY_OP_PLUGIN}
#endif
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a - b; }
template<typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
{ return internal::psub(a,b); }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type
operator()(const LhsScalar& a, const RhsScalar& b) const {
return a - b;
}
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const {
return internal::psub(a, b);
}
};
template<typename LhsScalar,typename RhsScalar>
struct functor_traits<scalar_difference_op<LhsScalar,RhsScalar> > {
template <typename LhsScalar, typename RhsScalar>
struct functor_traits<scalar_difference_op<LhsScalar, RhsScalar>> {
enum {
Cost = (int(NumTraits<LhsScalar>::AddCost) + int(NumTraits<RhsScalar>::AddCost)) / 2,
PacketAccess = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasSub && packet_traits<RhsScalar>::HasSub
PacketAccess =
is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasSub && packet_traits<RhsScalar>::HasSub
};
};
template <typename Packet, bool IsInteger = NumTraits<typename unpacket_traits<Packet>::type>::IsInteger>
struct maybe_raise_div_by_zero {
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Packet x) {
EIGEN_UNUSED_VARIABLE(x);
}
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Packet x) { EIGEN_UNUSED_VARIABLE(x); }
};
#ifndef EIGEN_GPU_COMPILE_PHASE
@@ -431,40 +422,41 @@ struct maybe_raise_div_by_zero<Packet, true> {
#endif
/** \internal
* \brief Template functor to compute the quotient of two scalars
*
* \sa class CwiseBinaryOp, Cwise::operator/()
*/
template<typename LhsScalar,typename RhsScalar>
struct scalar_quotient_op : binary_op_base<LhsScalar,RhsScalar>
{
typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_quotient_op>::ReturnType result_type;
* \brief Template functor to compute the quotient of two scalars
*
* \sa class CwiseBinaryOp, Cwise::operator/()
*/
template <typename LhsScalar, typename RhsScalar>
struct scalar_quotient_op : binary_op_base<LhsScalar, RhsScalar> {
typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar, scalar_quotient_op>::ReturnType result_type;
#ifdef EIGEN_SCALAR_BINARY_OP_PLUGIN
scalar_quotient_op() {
EIGEN_SCALAR_BINARY_OP_PLUGIN
}
scalar_quotient_op(){EIGEN_SCALAR_BINARY_OP_PLUGIN}
#endif
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a / b; }
template<typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type
operator()(const LhsScalar& a, const RhsScalar& b) const {
return a / b;
}
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const {
maybe_raise_div_by_zero<Packet>::run(b);
return internal::pdiv(a,b);
return internal::pdiv(a, b);
}
};
template<typename LhsScalar,typename RhsScalar>
struct functor_traits<scalar_quotient_op<LhsScalar,RhsScalar> > {
typedef typename scalar_quotient_op<LhsScalar,RhsScalar>::result_type result_type;
template <typename LhsScalar, typename RhsScalar>
struct functor_traits<scalar_quotient_op<LhsScalar, RhsScalar>> {
typedef typename scalar_quotient_op<LhsScalar, RhsScalar>::result_type result_type;
enum {
PacketAccess = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasDiv && packet_traits<RhsScalar>::HasDiv,
Cost = scalar_div_cost<result_type,PacketAccess>::value
PacketAccess =
is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasDiv && packet_traits<RhsScalar>::HasDiv,
Cost = scalar_div_cost<result_type, PacketAccess>::value
};
};
/** \internal
* \brief Template functor to compute the and of two scalars as if they were booleans
*
* \sa class CwiseBinaryOp, ArrayBase::operator&&
*/
* \brief Template functor to compute the and of two scalars as if they were booleans
*
* \sa class CwiseBinaryOp, ArrayBase::operator&&
*/
template <typename Scalar>
struct scalar_boolean_and_op {
using result_type = Scalar;
@@ -489,10 +481,10 @@ struct functor_traits<scalar_boolean_and_op<Scalar>> {
};
/** \internal
* \brief Template functor to compute the or of two scalars as if they were booleans
*
* \sa class CwiseBinaryOp, ArrayBase::operator||
*/
* \brief Template functor to compute the or of two scalars as if they were booleans
*
* \sa class CwiseBinaryOp, ArrayBase::operator||
*/
template <typename Scalar>
struct scalar_boolean_or_op {
using result_type = Scalar;
@@ -588,10 +580,10 @@ struct bitwise_binary_impl<Scalar, true> {
};
/** \internal
* \brief Template functor to compute the bitwise and of two scalars
*
* \sa class CwiseBinaryOp, ArrayBase::operator&
*/
* \brief Template functor to compute the bitwise and of two scalars
*
* \sa class CwiseBinaryOp, ArrayBase::operator&
*/
template <typename Scalar>
struct scalar_bitwise_and_op {
EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::RequireInitialization,
@@ -612,10 +604,10 @@ struct functor_traits<scalar_bitwise_and_op<Scalar>> {
};
/** \internal
* \brief Template functor to compute the bitwise or of two scalars
*
* \sa class CwiseBinaryOp, ArrayBase::operator|
*/
* \brief Template functor to compute the bitwise or of two scalars
*
* \sa class CwiseBinaryOp, ArrayBase::operator|
*/
template <typename Scalar>
struct scalar_bitwise_or_op {
EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::RequireInitialization,
@@ -636,10 +628,10 @@ struct functor_traits<scalar_bitwise_or_op<Scalar>> {
};
/** \internal
* \brief Template functor to compute the bitwise xor of two scalars
*
* \sa class CwiseBinaryOp, ArrayBase::operator^
*/
* \brief Template functor to compute the bitwise xor of two scalars
*
* \sa class CwiseBinaryOp, ArrayBase::operator^
*/
template <typename Scalar>
struct scalar_bitwise_xor_op {
EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::RequireInitialization,
@@ -660,39 +652,39 @@ struct functor_traits<scalar_bitwise_xor_op<Scalar>> {
};
/** \internal
* \brief Template functor to compute the absolute difference of two scalars
*
* \sa class CwiseBinaryOp, MatrixBase::absolute_difference
*/
template<typename LhsScalar,typename RhsScalar>
struct scalar_absolute_difference_op : binary_op_base<LhsScalar,RhsScalar>
{
typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_absolute_difference_op>::ReturnType result_type;
* \brief Template functor to compute the absolute difference of two scalars
*
* \sa class CwiseBinaryOp, MatrixBase::absolute_difference
*/
template <typename LhsScalar, typename RhsScalar>
struct scalar_absolute_difference_op : binary_op_base<LhsScalar, RhsScalar> {
typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar, scalar_absolute_difference_op>::ReturnType result_type;
#ifdef EIGEN_SCALAR_BINARY_OP_PLUGIN
scalar_absolute_difference_op() {
EIGEN_SCALAR_BINARY_OP_PLUGIN
}
scalar_absolute_difference_op(){EIGEN_SCALAR_BINARY_OP_PLUGIN}
#endif
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const
{ return numext::absdiff(a,b); }
template<typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
{ return internal::pabsdiff(a,b); }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type
operator()(const LhsScalar& a, const RhsScalar& b) const {
return numext::absdiff(a, b);
}
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const {
return internal::pabsdiff(a, b);
}
};
template<typename LhsScalar,typename RhsScalar>
struct functor_traits<scalar_absolute_difference_op<LhsScalar,RhsScalar> > {
template <typename LhsScalar, typename RhsScalar>
struct functor_traits<scalar_absolute_difference_op<LhsScalar, RhsScalar>> {
enum {
Cost = (NumTraits<LhsScalar>::AddCost+NumTraits<RhsScalar>::AddCost)/2,
PacketAccess = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasAbsDiff
Cost = (NumTraits<LhsScalar>::AddCost + NumTraits<RhsScalar>::AddCost) / 2,
PacketAccess = is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasAbsDiff
};
};
template <typename LhsScalar, typename RhsScalar>
struct scalar_atan2_op {
using Scalar = LhsScalar;
static constexpr bool Enable = is_same<LhsScalar, RhsScalar>::value && !NumTraits<Scalar>::IsInteger && !NumTraits<Scalar>::IsComplex;
static constexpr bool Enable =
is_same<LhsScalar, RhsScalar>::value && !NumTraits<Scalar>::IsInteger && !NumTraits<Scalar>::IsComplex;
EIGEN_STATIC_ASSERT(Enable, "LhsScalar and RhsScalar must be the same non-integer, non-complex type")
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(const Scalar& y, const Scalar& x) const {
@@ -704,61 +696,68 @@ struct scalar_atan2_op {
}
};
template<typename LhsScalar,typename RhsScalar>
struct functor_traits<scalar_atan2_op<LhsScalar, RhsScalar>> {
template <typename LhsScalar, typename RhsScalar>
struct functor_traits<scalar_atan2_op<LhsScalar, RhsScalar>> {
using Scalar = LhsScalar;
enum {
PacketAccess = is_same<LhsScalar,RhsScalar>::value && packet_traits<Scalar>::HasATan && packet_traits<Scalar>::HasDiv && !NumTraits<Scalar>::IsInteger && !NumTraits<Scalar>::IsComplex,
PacketAccess = is_same<LhsScalar, RhsScalar>::value && packet_traits<Scalar>::HasATan &&
packet_traits<Scalar>::HasDiv && !NumTraits<Scalar>::IsInteger && !NumTraits<Scalar>::IsComplex,
Cost = int(scalar_div_cost<Scalar, PacketAccess>::value) + int(functor_traits<scalar_atan_op<Scalar>>::Cost)
};
};
//---------- binary functors bound to a constant, thus appearing as a unary functor ----------
// The following two classes permits to turn any binary functor into a unary one with one argument bound to a constant value.
// They are analogues to std::binder1st/binder2nd but with the following differences:
// The following two classes permits to turn any binary functor into a unary one with one argument bound to a constant
// value. They are analogues to std::binder1st/binder2nd but with the following differences:
// - they are compatible with packetOp
// - they are portable across C++ versions (the std::binder* are deprecated in C++11)
template<typename BinaryOp> struct bind1st_op : BinaryOp {
typedef typename BinaryOp::first_argument_type first_argument_type;
template <typename BinaryOp>
struct bind1st_op : BinaryOp {
typedef typename BinaryOp::first_argument_type first_argument_type;
typedef typename BinaryOp::second_argument_type second_argument_type;
typedef typename BinaryOp::result_type result_type;
typedef typename BinaryOp::result_type result_type;
EIGEN_DEVICE_FUNC explicit bind1st_op(const first_argument_type &val) : m_value(val) {}
EIGEN_DEVICE_FUNC explicit bind1st_op(const first_argument_type& val) : m_value(val) {}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const second_argument_type& b) const { return BinaryOp::operator()(m_value,b); }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator()(const second_argument_type& b) const {
return BinaryOp::operator()(m_value, b);
}
template<typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& b) const
{ return BinaryOp::packetOp(internal::pset1<Packet>(m_value), b); }
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& b) const {
return BinaryOp::packetOp(internal::pset1<Packet>(m_value), b);
}
first_argument_type m_value;
};
template<typename BinaryOp> struct functor_traits<bind1st_op<BinaryOp> > : functor_traits<BinaryOp> {};
template <typename BinaryOp>
struct functor_traits<bind1st_op<BinaryOp>> : functor_traits<BinaryOp> {};
template<typename BinaryOp> struct bind2nd_op : BinaryOp {
typedef typename BinaryOp::first_argument_type first_argument_type;
template <typename BinaryOp>
struct bind2nd_op : BinaryOp {
typedef typename BinaryOp::first_argument_type first_argument_type;
typedef typename BinaryOp::second_argument_type second_argument_type;
typedef typename BinaryOp::result_type result_type;
typedef typename BinaryOp::result_type result_type;
EIGEN_DEVICE_FUNC explicit bind2nd_op(const second_argument_type &val) : m_value(val) {}
EIGEN_DEVICE_FUNC explicit bind2nd_op(const second_argument_type& val) : m_value(val) {}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const first_argument_type& a) const { return BinaryOp::operator()(a,m_value); }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator()(const first_argument_type& a) const {
return BinaryOp::operator()(a, m_value);
}
template<typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
{ return BinaryOp::packetOp(a,internal::pset1<Packet>(m_value)); }
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const {
return BinaryOp::packetOp(a, internal::pset1<Packet>(m_value));
}
second_argument_type m_value;
};
template<typename BinaryOp> struct functor_traits<bind2nd_op<BinaryOp> > : functor_traits<BinaryOp> {};
template <typename BinaryOp>
struct functor_traits<bind2nd_op<BinaryOp>> : functor_traits<BinaryOp> {};
} // end namespace internal
} // end namespace internal
} // end namespace Eigen
} // end namespace Eigen
#endif // EIGEN_BINARY_FUNCTORS_H
#endif // EIGEN_BINARY_FUNCTORS_H

View File

@@ -17,67 +17,75 @@ namespace Eigen {
namespace internal {
template<typename Scalar>
template <typename Scalar>
struct scalar_constant_op {
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE scalar_constant_op(const scalar_constant_op& other) : m_other(other.m_other) { }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE scalar_constant_op(const Scalar& other) : m_other(other) { }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() () const { return m_other; }
template<typename PacketType>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const PacketType packetOp() const { return internal::pset1<PacketType>(m_other); }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE scalar_constant_op(const scalar_constant_op& other) : m_other(other.m_other) {}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE scalar_constant_op(const Scalar& other) : m_other(other) {}
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator()() const { return m_other; }
template <typename PacketType>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const PacketType packetOp() const {
return internal::pset1<PacketType>(m_other);
}
const Scalar m_other;
};
template<typename Scalar>
struct functor_traits<scalar_constant_op<Scalar> >
{ enum { Cost = 0 /* as the constant value should be loaded in register only once for the whole expression */,
PacketAccess = packet_traits<Scalar>::Vectorizable, IsRepeatable = true }; };
template<typename Scalar> struct scalar_identity_op {
template<typename IndexType>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (IndexType row, IndexType col) const { return row==col ? Scalar(1) : Scalar(0); }
template <typename Scalar>
struct functor_traits<scalar_constant_op<Scalar> > {
enum {
Cost = 0 /* as the constant value should be loaded in register only once for the whole expression */,
PacketAccess = packet_traits<Scalar>::Vectorizable,
IsRepeatable = true
};
};
template<typename Scalar>
struct functor_traits<scalar_identity_op<Scalar> >
{ enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = false, IsRepeatable = true }; };
template <typename Scalar, bool IsInteger> struct linspaced_op_impl;
template <typename Scalar>
struct linspaced_op_impl<Scalar,/*IsInteger*/false>
{
struct scalar_identity_op {
template <typename IndexType>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator()(IndexType row, IndexType col) const {
return row == col ? Scalar(1) : Scalar(0);
}
};
template <typename Scalar>
struct functor_traits<scalar_identity_op<Scalar> > {
enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = false, IsRepeatable = true };
};
template <typename Scalar, bool IsInteger>
struct linspaced_op_impl;
template <typename Scalar>
struct linspaced_op_impl<Scalar, /*IsInteger*/ false> {
typedef typename NumTraits<Scalar>::Real RealScalar;
EIGEN_DEVICE_FUNC linspaced_op_impl(const Scalar& low, const Scalar& high, Index num_steps) :
m_low(low), m_high(high), m_size1(num_steps==1 ? 1 : num_steps-1), m_step(num_steps==1 ? Scalar() : Scalar((high-low)/RealScalar(num_steps-1))),
m_flip(numext::abs(high)<numext::abs(low))
{}
EIGEN_DEVICE_FUNC linspaced_op_impl(const Scalar& low, const Scalar& high, Index num_steps)
: m_low(low),
m_high(high),
m_size1(num_steps == 1 ? 1 : num_steps - 1),
m_step(num_steps == 1 ? Scalar() : Scalar((high - low) / RealScalar(num_steps - 1))),
m_flip(numext::abs(high) < numext::abs(low)) {}
template<typename IndexType>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (IndexType i) const {
if(m_flip)
return (i==0)? m_low : Scalar(m_high - RealScalar(m_size1-i)*m_step);
template <typename IndexType>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator()(IndexType i) const {
if (m_flip)
return (i == 0) ? m_low : Scalar(m_high - RealScalar(m_size1 - i) * m_step);
else
return (i==m_size1)? m_high : Scalar(m_low + RealScalar(i)*m_step);
return (i == m_size1) ? m_high : Scalar(m_low + RealScalar(i) * m_step);
}
template<typename Packet, typename IndexType>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(IndexType i) const
{
template <typename Packet, typename IndexType>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(IndexType i) const {
// Principle:
// [low, ..., low] + ( [step, ..., step] * ( [i, ..., i] + [0, ..., size] ) )
if(m_flip)
{
Packet pi = plset<Packet>(Scalar(i-m_size1));
if (m_flip) {
Packet pi = plset<Packet>(Scalar(i - m_size1));
Packet res = padd(pset1<Packet>(m_high), pmul(pset1<Packet>(m_step), pi));
if (EIGEN_PREDICT_TRUE(i != 0)) return res;
Packet mask = pcmp_lt(pset1<Packet>(0), plset<Packet>(0));
return pselect<Packet>(mask, res, pset1<Packet>(m_low));
}
else
{
} else {
Packet pi = plset<Packet>(Scalar(i));
Packet res = padd(pset1<Packet>(m_low), pmul(pset1<Packet>(m_step), pi));
if(EIGEN_PREDICT_TRUE(i != m_size1-unpacket_traits<Packet>::size+1)) return res;
Packet mask = pcmp_lt(plset<Packet>(0), pset1<Packet>(unpacket_traits<Packet>::size-1));
if (EIGEN_PREDICT_TRUE(i != m_size1 - unpacket_traits<Packet>::size + 1)) return res;
Packet mask = pcmp_lt(plset<Packet>(0), pset1<Packet>(unpacket_traits<Packet>::size - 1));
return pselect<Packet>(mask, res, pset1<Packet>(m_high));
}
}
@@ -90,21 +98,20 @@ struct linspaced_op_impl<Scalar,/*IsInteger*/false>
};
template <typename Scalar>
struct linspaced_op_impl<Scalar,/*IsInteger*/true>
{
EIGEN_DEVICE_FUNC linspaced_op_impl(const Scalar& low, const Scalar& high, Index num_steps) :
m_low(low),
m_multiplier((high-low)/convert_index<Scalar>(num_steps<=1 ? 1 : num_steps-1)),
m_divisor(convert_index<Scalar>((high>=low?num_steps:-num_steps)+(high-low))/((numext::abs(high-low)+1)==0?1:(numext::abs(high-low)+1))),
m_use_divisor(num_steps>1 && (numext::abs(high-low)+1)<num_steps)
{}
struct linspaced_op_impl<Scalar, /*IsInteger*/ true> {
EIGEN_DEVICE_FUNC linspaced_op_impl(const Scalar& low, const Scalar& high, Index num_steps)
: m_low(low),
m_multiplier((high - low) / convert_index<Scalar>(num_steps <= 1 ? 1 : num_steps - 1)),
m_divisor(convert_index<Scalar>((high >= low ? num_steps : -num_steps) + (high - low)) /
((numext::abs(high - low) + 1) == 0 ? 1 : (numext::abs(high - low) + 1))),
m_use_divisor(num_steps > 1 && (numext::abs(high - low) + 1) < num_steps) {}
template<typename IndexType>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Scalar operator() (IndexType i) const
{
if(m_use_divisor) return m_low + convert_index<Scalar>(i)/m_divisor;
else return m_low + convert_index<Scalar>(i)*m_multiplier;
template <typename IndexType>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator()(IndexType i) const {
if (m_use_divisor)
return m_low + convert_index<Scalar>(i) / m_divisor;
else
return m_low + convert_index<Scalar>(i) * m_multiplier;
}
const Scalar m_low;
@@ -118,32 +125,37 @@ struct linspaced_op_impl<Scalar,/*IsInteger*/true>
// Forward declaration (we default to random access which does not really give
// us a speed gain when using packet access but it allows to use the functor in
// nested expressions).
template <typename Scalar> struct linspaced_op;
template <typename Scalar> struct functor_traits< linspaced_op<Scalar> >
{
enum
{
template <typename Scalar>
struct linspaced_op;
template <typename Scalar>
struct functor_traits<linspaced_op<Scalar> > {
enum {
Cost = 1,
PacketAccess = (!NumTraits<Scalar>::IsInteger) && packet_traits<Scalar>::HasSetLinear && packet_traits<Scalar>::HasBlend,
/*&& ((!NumTraits<Scalar>::IsInteger) || packet_traits<Scalar>::HasDiv),*/ // <- vectorization for integer is currently disabled
PacketAccess =
(!NumTraits<Scalar>::IsInteger) && packet_traits<Scalar>::HasSetLinear && packet_traits<Scalar>::HasBlend,
/*&& ((!NumTraits<Scalar>::IsInteger) || packet_traits<Scalar>::HasDiv),*/ // <- vectorization for integer is
// currently disabled
IsRepeatable = true
};
};
template <typename Scalar> struct linspaced_op
{
template <typename Scalar>
struct linspaced_op {
EIGEN_DEVICE_FUNC linspaced_op(const Scalar& low, const Scalar& high, Index num_steps)
: impl((num_steps==1 ? high : low),high,num_steps)
{}
: impl((num_steps == 1 ? high : low), high, num_steps) {}
template<typename IndexType>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (IndexType i) const { return impl(i); }
template <typename IndexType>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator()(IndexType i) const {
return impl(i);
}
template<typename Packet,typename IndexType>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(IndexType i) const { return impl.template packetOp<Packet>(i); }
template <typename Packet, typename IndexType>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(IndexType i) const {
return impl.template packetOp<Packet>(i);
}
// This proxy object handles the actual required temporaries and the different
// implementations (integer vs. floating point).
const linspaced_op_impl<Scalar,NumTraits<Scalar>::IsInteger> impl;
const linspaced_op_impl<Scalar, NumTraits<Scalar>::IsInteger> impl;
};
template <typename Scalar>
@@ -183,42 +195,69 @@ struct functor_traits<equalspaced_op<Scalar> > {
// If it exposes an operator()(i,j), then we assume the i and j coefficients are required independently
// and linear access is not possible. In all other cases, linear access is enabled.
// Users should not have to deal with this structure.
template<typename Functor> struct functor_has_linear_access { enum { ret = !has_binary_operator<Functor>::value }; };
template <typename Functor>
struct functor_has_linear_access {
enum { ret = !has_binary_operator<Functor>::value };
};
// For unreliable compilers, let's specialize the has_*ary_operator
// helpers so that at least built-in nullary functors work fine.
#if !( EIGEN_COMP_MSVC || EIGEN_COMP_GNUC || (EIGEN_COMP_ICC>=1600))
template<typename Scalar,typename IndexType>
struct has_nullary_operator<scalar_constant_op<Scalar>,IndexType> { enum { value = 1}; };
template<typename Scalar,typename IndexType>
struct has_unary_operator<scalar_constant_op<Scalar>,IndexType> { enum { value = 0}; };
template<typename Scalar,typename IndexType>
struct has_binary_operator<scalar_constant_op<Scalar>,IndexType> { enum { value = 0}; };
#if !(EIGEN_COMP_MSVC || EIGEN_COMP_GNUC || (EIGEN_COMP_ICC >= 1600))
template <typename Scalar, typename IndexType>
struct has_nullary_operator<scalar_constant_op<Scalar>, IndexType> {
enum { value = 1 };
};
template <typename Scalar, typename IndexType>
struct has_unary_operator<scalar_constant_op<Scalar>, IndexType> {
enum { value = 0 };
};
template <typename Scalar, typename IndexType>
struct has_binary_operator<scalar_constant_op<Scalar>, IndexType> {
enum { value = 0 };
};
template<typename Scalar,typename IndexType>
struct has_nullary_operator<scalar_identity_op<Scalar>,IndexType> { enum { value = 0}; };
template<typename Scalar,typename IndexType>
struct has_unary_operator<scalar_identity_op<Scalar>,IndexType> { enum { value = 0}; };
template<typename Scalar,typename IndexType>
struct has_binary_operator<scalar_identity_op<Scalar>,IndexType> { enum { value = 1}; };
template <typename Scalar, typename IndexType>
struct has_nullary_operator<scalar_identity_op<Scalar>, IndexType> {
enum { value = 0 };
};
template <typename Scalar, typename IndexType>
struct has_unary_operator<scalar_identity_op<Scalar>, IndexType> {
enum { value = 0 };
};
template <typename Scalar, typename IndexType>
struct has_binary_operator<scalar_identity_op<Scalar>, IndexType> {
enum { value = 1 };
};
template<typename Scalar,typename IndexType>
struct has_nullary_operator<linspaced_op<Scalar>,IndexType> { enum { value = 0}; };
template<typename Scalar,typename IndexType>
struct has_unary_operator<linspaced_op<Scalar>,IndexType> { enum { value = 1}; };
template<typename Scalar,typename IndexType>
struct has_binary_operator<linspaced_op<Scalar>,IndexType> { enum { value = 0}; };
template <typename Scalar, typename IndexType>
struct has_nullary_operator<linspaced_op<Scalar>, IndexType> {
enum { value = 0 };
};
template <typename Scalar, typename IndexType>
struct has_unary_operator<linspaced_op<Scalar>, IndexType> {
enum { value = 1 };
};
template <typename Scalar, typename IndexType>
struct has_binary_operator<linspaced_op<Scalar>, IndexType> {
enum { value = 0 };
};
template<typename Scalar,typename IndexType>
struct has_nullary_operator<scalar_random_op<Scalar>,IndexType> { enum { value = 1}; };
template<typename Scalar,typename IndexType>
struct has_unary_operator<scalar_random_op<Scalar>,IndexType> { enum { value = 0}; };
template<typename Scalar,typename IndexType>
struct has_binary_operator<scalar_random_op<Scalar>,IndexType> { enum { value = 0}; };
template <typename Scalar, typename IndexType>
struct has_nullary_operator<scalar_random_op<Scalar>, IndexType> {
enum { value = 1 };
};
template <typename Scalar, typename IndexType>
struct has_unary_operator<scalar_random_op<Scalar>, IndexType> {
enum { value = 0 };
};
template <typename Scalar, typename IndexType>
struct has_binary_operator<scalar_random_op<Scalar>, IndexType> {
enum { value = 0 };
};
#endif
} // end namespace internal
} // end namespace internal
} // end namespace Eigen
} // end namespace Eigen
#endif // EIGEN_NULLARY_FUNCTORS_H
#endif // EIGEN_NULLARY_FUNCTORS_H

View File

@@ -18,101 +18,123 @@ namespace internal {
// default functor traits for STL functors:
template<typename T>
struct functor_traits<std::multiplies<T> >
{ enum { Cost = NumTraits<T>::MulCost, PacketAccess = false }; };
template <typename T>
struct functor_traits<std::multiplies<T> > {
enum { Cost = NumTraits<T>::MulCost, PacketAccess = false };
};
template<typename T>
struct functor_traits<std::divides<T> >
{ enum { Cost = NumTraits<T>::MulCost, PacketAccess = false }; };
template <typename T>
struct functor_traits<std::divides<T> > {
enum { Cost = NumTraits<T>::MulCost, PacketAccess = false };
};
template<typename T>
struct functor_traits<std::plus<T> >
{ enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; };
template <typename T>
struct functor_traits<std::plus<T> > {
enum { Cost = NumTraits<T>::AddCost, PacketAccess = false };
};
template<typename T>
struct functor_traits<std::minus<T> >
{ enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; };
template <typename T>
struct functor_traits<std::minus<T> > {
enum { Cost = NumTraits<T>::AddCost, PacketAccess = false };
};
template<typename T>
struct functor_traits<std::negate<T> >
{ enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; };
template <typename T>
struct functor_traits<std::negate<T> > {
enum { Cost = NumTraits<T>::AddCost, PacketAccess = false };
};
template<typename T>
struct functor_traits<std::logical_or<T> >
{ enum { Cost = 1, PacketAccess = false }; };
template <typename T>
struct functor_traits<std::logical_or<T> > {
enum { Cost = 1, PacketAccess = false };
};
template<typename T>
struct functor_traits<std::logical_and<T> >
{ enum { Cost = 1, PacketAccess = false }; };
template <typename T>
struct functor_traits<std::logical_and<T> > {
enum { Cost = 1, PacketAccess = false };
};
template<typename T>
struct functor_traits<std::logical_not<T> >
{ enum { Cost = 1, PacketAccess = false }; };
template <typename T>
struct functor_traits<std::logical_not<T> > {
enum { Cost = 1, PacketAccess = false };
};
template<typename T>
struct functor_traits<std::greater<T> >
{ enum { Cost = 1, PacketAccess = false }; };
template <typename T>
struct functor_traits<std::greater<T> > {
enum { Cost = 1, PacketAccess = false };
};
template<typename T>
struct functor_traits<std::less<T> >
{ enum { Cost = 1, PacketAccess = false }; };
template <typename T>
struct functor_traits<std::less<T> > {
enum { Cost = 1, PacketAccess = false };
};
template<typename T>
struct functor_traits<std::greater_equal<T> >
{ enum { Cost = 1, PacketAccess = false }; };
template <typename T>
struct functor_traits<std::greater_equal<T> > {
enum { Cost = 1, PacketAccess = false };
};
template<typename T>
struct functor_traits<std::less_equal<T> >
{ enum { Cost = 1, PacketAccess = false }; };
template <typename T>
struct functor_traits<std::less_equal<T> > {
enum { Cost = 1, PacketAccess = false };
};
template<typename T>
struct functor_traits<std::equal_to<T> >
{ enum { Cost = 1, PacketAccess = false }; };
template <typename T>
struct functor_traits<std::equal_to<T> > {
enum { Cost = 1, PacketAccess = false };
};
template<typename T>
struct functor_traits<std::not_equal_to<T> >
{ enum { Cost = 1, PacketAccess = false }; };
template <typename T>
struct functor_traits<std::not_equal_to<T> > {
enum { Cost = 1, PacketAccess = false };
};
#if (EIGEN_COMP_CXXVER < 17)
// std::unary_negate is deprecated since c++17 and will be removed in c++20
template<typename T>
struct functor_traits<std::unary_negate<T> >
{ enum { Cost = 1 + functor_traits<T>::Cost, PacketAccess = false }; };
template <typename T>
struct functor_traits<std::unary_negate<T> > {
enum { Cost = 1 + functor_traits<T>::Cost, PacketAccess = false };
};
// std::binary_negate is deprecated since c++17 and will be removed in c++20
template<typename T>
struct functor_traits<std::binary_negate<T> >
{ enum { Cost = 1 + functor_traits<T>::Cost, PacketAccess = false }; };
template <typename T>
struct functor_traits<std::binary_negate<T> > {
enum { Cost = 1 + functor_traits<T>::Cost, PacketAccess = false };
};
#endif
#ifdef EIGEN_STDEXT_SUPPORT
template<typename T0,typename T1>
struct functor_traits<std::project1st<T0,T1> >
{ enum { Cost = 0, PacketAccess = false }; };
template <typename T0, typename T1>
struct functor_traits<std::project1st<T0, T1> > {
enum { Cost = 0, PacketAccess = false };
};
template<typename T0,typename T1>
struct functor_traits<std::project2nd<T0,T1> >
{ enum { Cost = 0, PacketAccess = false }; };
template <typename T0, typename T1>
struct functor_traits<std::project2nd<T0, T1> > {
enum { Cost = 0, PacketAccess = false };
};
template<typename T0,typename T1>
struct functor_traits<std::select2nd<std::pair<T0,T1> > >
{ enum { Cost = 0, PacketAccess = false }; };
template <typename T0, typename T1>
struct functor_traits<std::select2nd<std::pair<T0, T1> > > {
enum { Cost = 0, PacketAccess = false };
};
template<typename T0,typename T1>
struct functor_traits<std::select1st<std::pair<T0,T1> > >
{ enum { Cost = 0, PacketAccess = false }; };
template <typename T0, typename T1>
struct functor_traits<std::select1st<std::pair<T0, T1> > > {
enum { Cost = 0, PacketAccess = false };
};
template<typename T0,typename T1>
struct functor_traits<std::unary_compose<T0,T1> >
{ enum { Cost = functor_traits<T0>::Cost + functor_traits<T1>::Cost, PacketAccess = false }; };
template <typename T0, typename T1>
struct functor_traits<std::unary_compose<T0, T1> > {
enum { Cost = functor_traits<T0>::Cost + functor_traits<T1>::Cost, PacketAccess = false };
};
template<typename T0,typename T1,typename T2>
struct functor_traits<std::binary_compose<T0,T1,T2> >
{ enum { Cost = functor_traits<T0>::Cost + functor_traits<T1>::Cost + functor_traits<T2>::Cost, PacketAccess = false }; };
template <typename T0, typename T1, typename T2>
struct functor_traits<std::binary_compose<T0, T1, T2> > {
enum { Cost = functor_traits<T0>::Cost + functor_traits<T1>::Cost + functor_traits<T2>::Cost, PacketAccess = false };
};
#endif // EIGEN_STDEXT_SUPPORT
#endif // EIGEN_STDEXT_SUPPORT
// allow to add new functors and specializations of functor_traits from outside Eigen.
// this macro is really needed because functor_traits must be specialized after it is declared but before it is used...
@@ -120,8 +142,8 @@ struct functor_traits<std::binary_compose<T0,T1,T2> >
#include EIGEN_FUNCTORS_PLUGIN
#endif
} // end namespace internal
} // end namespace internal
} // end namespace Eigen
} // end namespace Eigen
#endif // EIGEN_STL_FUNCTORS_H
#endif // EIGEN_STL_FUNCTORS_H

View File

@@ -25,26 +25,28 @@ struct scalar_boolean_select_op {
EIGEN_STATIC_ASSERT(ThenElseAreSame, THEN AND ELSE MUST BE SAME TYPE)
using Scalar = ThenScalar;
using result_type = Scalar;
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(const ThenScalar& a, const ElseScalar& b, const ConditionScalar& cond) const {
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(const ThenScalar& a, const ElseScalar& b,
const ConditionScalar& cond) const {
return cond == ConditionScalar(0) ? b : a;
}
template <typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b, const Packet& cond) const {
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b, const Packet& cond) const {
return pselect(pcmp_eq(cond, pzero(cond)), b, a);
}
};
template <typename ThenScalar, typename ElseScalar, typename ConditionScalar>
struct functor_traits<scalar_boolean_select_op<ThenScalar, ElseScalar, ConditionScalar>> {
struct functor_traits<scalar_boolean_select_op<ThenScalar, ElseScalar, ConditionScalar>> {
using Scalar = ThenScalar;
enum {
Cost = 1,
PacketAccess = is_same<ThenScalar, ElseScalar>::value && is_same<ConditionScalar, Scalar>::value && packet_traits<Scalar>::HasCmp
PacketAccess = is_same<ThenScalar, ElseScalar>::value && is_same<ConditionScalar, Scalar>::value &&
packet_traits<Scalar>::HasCmp
};
};
} // end namespace internal
} // end namespace internal
} // end namespace Eigen
} // end namespace Eigen
#endif // EIGEN_TERNARY_FUNCTORS_H
#endif // EIGEN_TERNARY_FUNCTORS_H

File diff suppressed because it is too large Load Diff