diff --git a/Eigen/src/Geometry/Quaternion.h b/Eigen/src/Geometry/Quaternion.h index ecf839335..7abe3c702 100644 --- a/Eigen/src/Geometry/Quaternion.h +++ b/Eigen/src/Geometry/Quaternion.h @@ -49,6 +49,9 @@ public: typedef typename internal::traits::Scalar Scalar; typedef typename NumTraits::Real RealScalar; typedef typename internal::traits::Coefficients Coefficients; + enum { + Flags = Eigen::internal::traits::Flags + }; // typedef typename Matrix Coefficients; /** the type of a 3D vector */ @@ -222,7 +225,8 @@ struct traits > typedef _Scalar Scalar; typedef Matrix<_Scalar,4,1,_Options> Coefficients; enum{ - PacketAccess = _Options & DontAlign ? Unaligned : Aligned + IsAligned = bool(EIGEN_ALIGN) && ((int(_Options)&Aligned)==Aligned), + Flags = IsAligned ? (AlignedBit | LvalueBit) : LvalueBit }; }; } @@ -294,33 +298,53 @@ typedef Quaternion Quaterniond; ***************************************************************************/ namespace internal { -template -struct traits, _PacketAccess> >: -traits > -{ - typedef _Scalar Scalar; - typedef Map, _PacketAccess> Coefficients; - enum { - PacketAccess = _PacketAccess + template + struct traits, _Options> >: + traits > + { + typedef _Scalar Scalar; + typedef Map, _Options> Coefficients; + + typedef traits > TraitsBase; + enum { + IsAligned = TraitsBase::IsAligned, + + Flags = TraitsBase::Flags + }; + }; +} + +namespace internal { + template + struct traits, _Options> >: + traits > + { + typedef _Scalar Scalar; + typedef Map, _Options> Coefficients; + + typedef traits > TraitsBase; + enum { + IsAligned = TraitsBase::IsAligned, + Flags = TraitsBase::Flags & ~LvalueBit + }; }; -}; } /** \brief Quaternion expression mapping a constant memory buffer * * \param _Scalar the type of the Quaternion coefficients - * \param PacketAccess see class Map + * \param _Options see class Map * * This is a specialization of class Map for Quaternion. This class allows to view * a 4 scalar memory buffer as an Eigen's Quaternion object. * * \sa class Map, class Quaternion, class QuaternionBase */ -template -class Map, PacketAccess > - : public QuaternionBase, PacketAccess> > +template +class Map, _Options > + : public QuaternionBase, _Options> > { - typedef QuaternionBase, PacketAccess> > Base; + typedef QuaternionBase, _Options> > Base; public: typedef _Scalar Scalar; @@ -333,7 +357,7 @@ class Map, PacketAccess > * The pointer \a coeffs must reference the four coeffecients of Quaternion in the following order: * \code *coeffs == {x, y, z, w} \endcode * - * If the template parameter PacketAccess is set to Aligned, then the pointer coeffs must be aligned. */ + * If the template parameter _Options is set to Aligned, then the pointer coeffs must be aligned. */ EIGEN_STRONG_INLINE Map(const Scalar* coeffs) : m_coeffs(coeffs) {} inline const Coefficients& coeffs() const { return m_coeffs;} @@ -345,18 +369,18 @@ class Map, PacketAccess > /** \brief Expression of a quaternion from a memory buffer * * \param _Scalar the type of the Quaternion coefficients - * \param PacketAccess see class Map + * \param _Options see class Map * * This is a specialization of class Map for Quaternion. This class allows to view * a 4 scalar memory buffer as an Eigen's Quaternion object. * * \sa class Map, class Quaternion, class QuaternionBase */ -template -class Map, PacketAccess > - : public QuaternionBase, PacketAccess> > +template +class Map, _Options > + : public QuaternionBase, _Options> > { - typedef QuaternionBase, PacketAccess> > Base; + typedef QuaternionBase, _Options> > Base; public: typedef _Scalar Scalar; @@ -369,7 +393,7 @@ class Map, PacketAccess > * The pointer \a coeffs must reference the four coeffecients of Quaternion in the following order: * \code *coeffs == {x, y, z, w} \endcode * - * If the template parameter PacketAccess is set to Aligned, then the pointer coeffs must be aligned. */ + * If the template parameter _Options is set to Aligned, then the pointer coeffs must be aligned. */ EIGEN_STRONG_INLINE Map(Scalar* coeffs) : m_coeffs(coeffs) {} inline Coefficients& coeffs() { return m_coeffs; } @@ -399,7 +423,7 @@ typedef Map, Aligned> QuaternionMapAlignedd; // Generic Quaternion * Quaternion product // This product can be specialized for a given architecture via the Arch template argument. namespace internal { -template struct quat_product +template struct quat_product { EIGEN_STRONG_INLINE static Quaternion run(const QuaternionBase& a, const QuaternionBase& b){ return Quaternion @@ -423,7 +447,7 @@ QuaternionBase::operator* (const QuaternionBase& other) c YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) return internal::quat_product::Scalar, - internal::traits::PacketAccess && internal::traits::PacketAccess>::run(*this, other); + internal::traits::IsAligned && internal::traits::IsAligned>::run(*this, other); } /** \sa operator*(Quaternion) */ diff --git a/test/geo_quaternion.cpp b/test/geo_quaternion.cpp index e5b64e939..c1c0f279c 100644 --- a/test/geo_quaternion.cpp +++ b/test/geo_quaternion.cpp @@ -124,7 +124,8 @@ template void quaternion(void) template void mapQuaternion(void){ typedef Map, Aligned> MQuaternionA; - typedef Map > MQuaternionUA; + typedef Map > MQuaternionUA; + typedef Map > MCQuaternionUA; typedef Quaternion Quaternionx; EIGEN_ALIGN16 Scalar array1[4]; @@ -139,9 +140,11 @@ template void mapQuaternion(void){ Quaternionx q1 = MQuaternionA(array1); Quaternionx q2 = MQuaternionA(array2); Quaternionx q3 = MQuaternionUA(array3unaligned); + Quaternionx q4 = MCQuaternionUA(array3unaligned); VERIFY_IS_APPROX(q1.coeffs(), q2.coeffs()); VERIFY_IS_APPROX(q1.coeffs(), q3.coeffs()); + VERIFY_IS_APPROX(q4.coeffs(), q3.coeffs()); #ifdef EIGEN_VECTORIZE VERIFY_RAISES_ASSERT((MQuaternionA(array3unaligned))); #endif @@ -171,11 +174,28 @@ template void quaternionAlignment(void){ #endif } +template void check_const_correctness(const PlainObjectType&) +{ + // there's a lot that we can't test here while still having this test compile! + // the only possible approach would be to run a script trying to compile stuff and checking that it fails. + // CMake can help with that. + + // verify that map-to-const don't have LvalueBit + typedef typename internal::add_const::type ConstPlainObjectType; + VERIFY( !(internal::traits >::Flags & LvalueBit) ); + VERIFY( !(internal::traits >::Flags & LvalueBit) ); + VERIFY( !(Map::Flags & LvalueBit) ); + VERIFY( !(Map::Flags & LvalueBit) ); +} + + void test_geo_quaternion() { for(int i = 0; i < g_repeat; i++) { CALL_SUBTEST_1(( quaternion() )); + CALL_SUBTEST_1( check_const_correctness(Quaternionf()) ); CALL_SUBTEST_2(( quaternion() )); + CALL_SUBTEST_2( check_const_correctness(Quaterniond()) ); CALL_SUBTEST_3(( quaternion() )); CALL_SUBTEST_4(( quaternion() )); CALL_SUBTEST_5(( quaternionAlignment() ));