bug #369 - Quaternion alignment is broken

The problem was two-fold:
 * missing aligned operator new
 * Flags were mis-computed, the Aligned constant was misused
This commit is contained in:
Benoit Jacob 2011-10-31 09:23:41 -04:00
parent 0609dbeec6
commit 9df2f5c923
2 changed files with 13 additions and 5 deletions

View File

@ -185,7 +185,7 @@ public:
return typename internal::cast_return_type<Derived,Quaternion<NewScalarType> >::type(
coeffs().template cast<NewScalarType>());
}
#ifdef EIGEN_QUATERNIONBASE_PLUGIN
# include EIGEN_QUATERNIONBASE_PLUGIN
#endif
@ -225,22 +225,25 @@ struct traits<Quaternion<_Scalar,_Options> >
typedef _Scalar Scalar;
typedef Matrix<_Scalar,4,1,_Options> Coefficients;
enum{
IsAligned = bool(EIGEN_ALIGN) && ((int(_Options)&Aligned)==Aligned),
IsAligned = internal::traits<Coefficients>::Flags & AlignedBit,
Flags = IsAligned ? (AlignedBit | LvalueBit) : LvalueBit
};
};
}
template<typename _Scalar, int _Options>
class Quaternion : public QuaternionBase<Quaternion<_Scalar,_Options> >{
class Quaternion : public QuaternionBase<Quaternion<_Scalar,_Options> >
{
typedef QuaternionBase<Quaternion<_Scalar,_Options> > Base;
enum { IsAligned = internal::traits<Quaternion>::IsAligned };
public:
typedef _Scalar Scalar;
EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Quaternion)
using Base::operator*=;
typedef typename internal::traits<Quaternion<Scalar,_Options> >::Coefficients Coefficients;
typedef typename internal::traits<Quaternion>::Coefficients Coefficients;
typedef typename Base::AngleAxisType AngleAxisType;
/** Default constructor leaving the quaternion uninitialized. */
@ -274,6 +277,8 @@ public:
inline Coefficients& coeffs() { return m_coeffs;}
inline const Coefficients& coeffs() const { return m_coeffs;}
EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(IsAligned)
protected:
Coefficients m_coeffs;

View File

@ -120,6 +120,10 @@ template<typename Scalar, int Options> void quaternion(void)
VERIFY_IS_APPROX(q1f.template cast<Scalar>(),q1);
Quaternion<double> q1d = q1.template cast<double>();
VERIFY_IS_APPROX(q1d.template cast<Scalar>(),q1);
// test bug 369 - improper alignment.
Quaternionx *q = new Quaternionx;
delete q;
}
template<typename Scalar> void mapQuaternion(void){
@ -191,7 +195,6 @@ template<typename PlainObjectType> void check_const_correctness(const PlainObjec
VERIFY( !(Map<ConstPlainObjectType, Aligned>::Flags & LvalueBit) );
}
void test_geo_quaternion()
{
for(int i = 0; i < g_repeat; i++) {