From 9d5478303667bd97f3e20696f8a8c82cb5b2d65f Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Fri, 18 Dec 2009 17:08:59 +0100 Subject: [PATCH] much better workaround for empty struct (the previous one caused GCC 4.3 to generate wrong code leading to segfaults) --- Eigen/src/Array/Functors.h | 12 ++++++-- Eigen/src/Array/Random.h | 4 +-- Eigen/src/Array/VectorwiseOp.h | 3 +- Eigen/src/Core/Functors.h | 51 ++++++++++++++++++++++----------- Eigen/src/Core/util/XprHelper.h | 17 ++++------- 5 files changed, 53 insertions(+), 34 deletions(-) diff --git a/Eigen/src/Array/Functors.h b/Eigen/src/Array/Functors.h index 120c56cc1..975fd9c7f 100644 --- a/Eigen/src/Array/Functors.h +++ b/Eigen/src/Array/Functors.h @@ -56,7 +56,8 @@ struct ei_functor_traits > * * \sa class CwiseUnaryOp, Cwise::sqrt() */ -template struct ei_scalar_sqrt_op EIGEN_EMPTY_STRUCT { +template struct ei_scalar_sqrt_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_sqrt_op) inline const Scalar operator() (const Scalar& a) const { return ei_sqrt(a); } typedef typename ei_packet_traits::type Packet; inline Packet packetOp(const Packet& a) const { return ei_psqrt(a); } @@ -77,7 +78,8 @@ struct ei_functor_traits > * * \sa class CwiseUnaryOp, Cwise::cos() */ -template struct ei_scalar_cos_op EIGEN_EMPTY_STRUCT { +template struct ei_scalar_cos_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_cos_op) inline Scalar operator() (const Scalar& a) const { return ei_cos(a); } typedef typename ei_packet_traits::type Packet; inline Packet packetOp(const Packet& a) const { return ei_pcos(a); } @@ -99,7 +101,8 @@ struct ei_functor_traits > * * \sa class CwiseUnaryOp, Cwise::sin() */ -template struct ei_scalar_sin_op EIGEN_EMPTY_STRUCT { +template struct ei_scalar_sin_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_sin_op) inline const Scalar operator() (const Scalar& a) const { return ei_sin(a); } typedef typename ei_packet_traits::type Packet; inline Packet packetOp(const Packet& a) const { return ei_psin(a); } @@ -143,6 +146,7 @@ struct ei_functor_traits > */ template struct ei_scalar_inverse_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_inverse_op) inline Scalar operator() (const Scalar& a) const { return Scalar(1)/a; } template inline const PacketScalar packetOp(const PacketScalar& a) const @@ -162,6 +166,7 @@ struct ei_functor_traits > */ template struct ei_scalar_square_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_square_op) inline Scalar operator() (const Scalar& a) const { return a*a; } template inline const PacketScalar packetOp(const PacketScalar& a) const @@ -181,6 +186,7 @@ struct ei_functor_traits > */ template struct ei_scalar_cube_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_cube_op) inline Scalar operator() (const Scalar& a) const { return a*a*a; } template inline const PacketScalar packetOp(const PacketScalar& a) const diff --git a/Eigen/src/Array/Random.h b/Eigen/src/Array/Random.h index adadf99e3..b94ccda68 100644 --- a/Eigen/src/Array/Random.h +++ b/Eigen/src/Array/Random.h @@ -25,8 +25,8 @@ #ifndef EIGEN_RANDOM_H #define EIGEN_RANDOM_H -template struct ei_scalar_random_op EIGEN_EMPTY_STRUCT { - inline ei_scalar_random_op(void) {} +template struct ei_scalar_random_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_random_op) inline const Scalar operator() (int, int) const { return ei_random(); } }; template diff --git a/Eigen/src/Array/VectorwiseOp.h b/Eigen/src/Array/VectorwiseOp.h index 37ed8ac17..bb695c795 100644 --- a/Eigen/src/Array/VectorwiseOp.h +++ b/Eigen/src/Array/VectorwiseOp.h @@ -110,7 +110,8 @@ class PartialReduxExpr : ei_no_assignment_operator, #define EIGEN_MEMBER_FUNCTOR(MEMBER,COST) \ template \ - struct ei_member_##MEMBER EIGEN_EMPTY_STRUCT { \ + struct ei_member_##MEMBER { \ + EIGEN_EMPTY_STRUCT_CTOR(ei_member_##MEMBER) \ typedef ResultType result_type; \ template struct Cost \ { enum { value = COST }; }; \ diff --git a/Eigen/src/Core/Functors.h b/Eigen/src/Core/Functors.h index 6b62fb4ea..1a4edfc4a 100644 --- a/Eigen/src/Core/Functors.h +++ b/Eigen/src/Core/Functors.h @@ -32,7 +32,8 @@ * * \sa class CwiseBinaryOp, MatrixBase::operator+, class VectorwiseOp, MatrixBase::sum() */ -template struct ei_scalar_sum_op EIGEN_EMPTY_STRUCT { +template struct ei_scalar_sum_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_sum_op) EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a + b; } template EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const @@ -54,7 +55,8 @@ struct ei_functor_traits > { * * \sa class CwiseBinaryOp, Cwise::operator*(), class VectorwiseOp, MatrixBase::redux() */ -template struct ei_scalar_product_op EIGEN_EMPTY_STRUCT { +template struct ei_scalar_product_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_product_op) EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a * b; } template EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const @@ -76,7 +78,8 @@ struct ei_functor_traits > { * * \sa class CwiseBinaryOp, MatrixBase::cwiseMin, class VectorwiseOp, MatrixBase::minCoeff() */ -template struct ei_scalar_min_op EIGEN_EMPTY_STRUCT { +template struct ei_scalar_min_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_min_op) EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return std::min(a, b); } template EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const @@ -98,7 +101,8 @@ struct ei_functor_traits > { * * \sa class CwiseBinaryOp, MatrixBase::cwiseMax, class VectorwiseOp, MatrixBase::maxCoeff() */ -template struct ei_scalar_max_op EIGEN_EMPTY_STRUCT { +template struct ei_scalar_max_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_max_op) EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return std::max(a, b); } template EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const @@ -120,7 +124,8 @@ struct ei_functor_traits > { * * \sa MatrixBase::stableNorm(), class Redux */ -template struct ei_scalar_hypot_op EIGEN_EMPTY_STRUCT { +template struct ei_scalar_hypot_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_hypot_op) // typedef typename NumTraits::Real result_type; EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& _x, const Scalar& _y) const { @@ -142,7 +147,8 @@ struct ei_functor_traits > { * * \sa class CwiseBinaryOp, MatrixBase::operator- */ -template struct ei_scalar_difference_op EIGEN_EMPTY_STRUCT { +template struct ei_scalar_difference_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_difference_op) EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a - b; } template EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const @@ -161,7 +167,8 @@ struct ei_functor_traits > { * * \sa class CwiseBinaryOp, Cwise::operator/() */ -template struct ei_scalar_quotient_op EIGEN_EMPTY_STRUCT { +template struct ei_scalar_quotient_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_quotient_op) EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a / b; } template EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const @@ -185,7 +192,8 @@ struct ei_functor_traits > { * * \sa class CwiseUnaryOp, MatrixBase::operator- */ -template struct ei_scalar_opposite_op EIGEN_EMPTY_STRUCT { +template struct ei_scalar_opposite_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_opposite_op) EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return -a; } template EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const @@ -203,7 +211,8 @@ struct ei_functor_traits > * * \sa class CwiseUnaryOp, Cwise::abs */ -template struct ei_scalar_abs_op EIGEN_EMPTY_STRUCT { +template struct ei_scalar_abs_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_abs_op) typedef typename NumTraits::Real result_type; EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return ei_abs(a); } template @@ -224,7 +233,8 @@ struct ei_functor_traits > * * \sa class CwiseUnaryOp, Cwise::abs2 */ -template struct ei_scalar_abs2_op EIGEN_EMPTY_STRUCT { +template struct ei_scalar_abs2_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_abs2_op) typedef typename NumTraits::Real result_type; EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return ei_abs2(a); } template @@ -240,7 +250,8 @@ struct ei_functor_traits > * * \sa class CwiseUnaryOp, MatrixBase::conjugate() */ -template struct ei_scalar_conjugate_op EIGEN_EMPTY_STRUCT { +template struct ei_scalar_conjugate_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_conjugate_op) EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return ei_conj(a); } template EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const { return a; } @@ -260,7 +271,8 @@ struct ei_functor_traits > * \sa class CwiseUnaryOp, MatrixBase::cast() */ template -struct ei_scalar_cast_op EIGEN_EMPTY_STRUCT { +struct ei_scalar_cast_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_cast_op) typedef NewType result_type; EIGEN_STRONG_INLINE const NewType operator() (const Scalar& a) const { return static_cast(a); } }; @@ -274,7 +286,8 @@ struct ei_functor_traits > * \sa class CwiseUnaryOp, MatrixBase::real() */ template -struct ei_scalar_real_op EIGEN_EMPTY_STRUCT { +struct ei_scalar_real_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_real_op) typedef typename NumTraits::Real result_type; EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return ei_real(a); } EIGEN_STRONG_INLINE result_type& operator() (Scalar& a) const { return ei_real_ref(a); } @@ -289,7 +302,8 @@ struct ei_functor_traits > * \sa class CwiseUnaryOp, MatrixBase::imag() */ template -struct ei_scalar_imag_op EIGEN_EMPTY_STRUCT { +struct ei_scalar_imag_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_imag_op) typedef typename NumTraits::Real result_type; EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return ei_imag(a); } EIGEN_STRONG_INLINE result_type& operator() (Scalar& a) const { return ei_imag_ref(a); } @@ -304,7 +318,8 @@ struct ei_functor_traits > * * \sa class CwiseUnaryOp, Cwise::exp() */ -template struct ei_scalar_exp_op EIGEN_EMPTY_STRUCT { +template struct ei_scalar_exp_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_exp_op) inline const Scalar operator() (const Scalar& a) const { return ei_exp(a); } typedef typename ei_packet_traits::type Packet; inline Packet packetOp(const Packet& a) const { return ei_pexp(a); } @@ -319,7 +334,8 @@ struct ei_functor_traits > * * \sa class CwiseUnaryOp, Cwise::log() */ -template struct ei_scalar_log_op EIGEN_EMPTY_STRUCT { +template struct ei_scalar_log_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_log_op) inline const Scalar operator() (const Scalar& a) const { return ei_log(a); } typedef typename ei_packet_traits::type Packet; inline Packet packetOp(const Packet& a) const { return ei_plog(a); } @@ -428,7 +444,8 @@ template struct ei_functor_traits > { enum { Cost = 1, PacketAccess = ei_packet_traits::size>1, IsRepeatable = true }; }; -template struct ei_scalar_identity_op EIGEN_EMPTY_STRUCT { +template struct ei_scalar_identity_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_identity_op) EIGEN_STRONG_INLINE ei_scalar_identity_op(void) {} EIGEN_STRONG_INLINE const Scalar operator() (int row, int col) const { return row==col ? Scalar(1) : Scalar(0); } }; diff --git a/Eigen/src/Core/util/XprHelper.h b/Eigen/src/Core/util/XprHelper.h index 622c84a8e..2a9feaeeb 100644 --- a/Eigen/src/Core/util/XprHelper.h +++ b/Eigen/src/Core/util/XprHelper.h @@ -28,16 +28,11 @@ // just a workaround because GCC seems to not really like empty structs #ifdef __GNUG__ - struct ei_empty_struct - { - EIGEN_ALWAYS_INLINE_ATTRIB ei_empty_struct() {} - EIGEN_ALWAYS_INLINE_ATTRIB ei_empty_struct(const ei_empty_struct&) {} - EIGEN_ALWAYS_INLINE_ATTRIB ei_empty_struct& operator=(const ei_empty_struct&) { return *this; } - char _ei_dummy_; - }; - #define EIGEN_EMPTY_STRUCT : Eigen::ei_empty_struct + #define EIGEN_EMPTY_STRUCT_CTOR(X) \ + EIGEN_STRONG_INLINE X() {} \ + EIGEN_STRONG_INLINE X(const X&) {} #else - #define EIGEN_EMPTY_STRUCT + #define EIGEN_EMPTY_STRUCT_CTOR(X) #endif //classes inheriting ei_no_assignment_operator don't generate a default operator=. @@ -51,10 +46,10 @@ class ei_no_assignment_operator * can be accessed using value() and setValue(). * Otherwise, this class is an empty structure and value() just returns the template parameter Value. */ -template class ei_int_if_dynamic EIGEN_EMPTY_STRUCT +template class ei_int_if_dynamic { public: - ei_int_if_dynamic() {} + EIGEN_EMPTY_STRUCT_CTOR(ei_int_if_dynamic) explicit ei_int_if_dynamic(int) {} static int value() { return Value; } void setValue(int) {}