diff options
-rw-r--r-- | Eigen/src/Geometry/Quaternion.h | 72 | ||||
-rw-r--r-- | test/geo_quaternion.cpp | 22 |
2 files changed, 69 insertions, 25 deletions
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<Derived>::Scalar Scalar; typedef typename NumTraits<Scalar>::Real RealScalar; typedef typename internal::traits<Derived>::Coefficients Coefficients; + enum { + Flags = Eigen::internal::traits<Derived>::Flags + }; // typedef typename Matrix<Scalar,4,1> Coefficients; /** the type of a 3D vector */ @@ -222,7 +225,8 @@ struct traits<Quaternion<_Scalar,_Options> > 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<double> Quaterniond; ***************************************************************************/ namespace internal { -template<typename _Scalar, int _PacketAccess> -struct traits<Map<Quaternion<_Scalar>, _PacketAccess> >: -traits<Quaternion<_Scalar> > -{ - typedef _Scalar Scalar; - typedef Map<Matrix<_Scalar,4,1>, _PacketAccess> Coefficients; - enum { - PacketAccess = _PacketAccess + template<typename _Scalar, int _Options> + struct traits<Map<Quaternion<_Scalar>, _Options> >: + traits<Quaternion<_Scalar, _Options> > + { + typedef _Scalar Scalar; + typedef Map<Matrix<_Scalar,4,1>, _Options> Coefficients; + + typedef traits<Quaternion<_Scalar, _Options> > TraitsBase; + enum { + IsAligned = TraitsBase::IsAligned, + + Flags = TraitsBase::Flags + }; + }; +} + +namespace internal { + template<typename _Scalar, int _Options> + struct traits<Map<const Quaternion<_Scalar>, _Options> >: + traits<Quaternion<_Scalar> > + { + typedef _Scalar Scalar; + typedef Map<const Matrix<_Scalar,4,1>, _Options> Coefficients; + + typedef traits<Quaternion<_Scalar, _Options> > 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<typename _Scalar, int PacketAccess> -class Map<const Quaternion<_Scalar>, PacketAccess > - : public QuaternionBase<Map<const Quaternion<_Scalar>, PacketAccess> > +template<typename _Scalar, int _Options> +class Map<const Quaternion<_Scalar>, _Options > + : public QuaternionBase<Map<const Quaternion<_Scalar>, _Options> > { - typedef QuaternionBase<Map<Quaternion<_Scalar>, PacketAccess> > Base; + typedef QuaternionBase<Map<const Quaternion<_Scalar>, _Options> > Base; public: typedef _Scalar Scalar; @@ -333,7 +357,7 @@ class Map<const Quaternion<_Scalar>, 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<const Quaternion<_Scalar>, 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<typename _Scalar, int PacketAccess> -class Map<Quaternion<_Scalar>, PacketAccess > - : public QuaternionBase<Map<Quaternion<_Scalar>, PacketAccess> > +template<typename _Scalar, int _Options> +class Map<Quaternion<_Scalar>, _Options > + : public QuaternionBase<Map<Quaternion<_Scalar>, _Options> > { - typedef QuaternionBase<Map<Quaternion<_Scalar>, PacketAccess> > Base; + typedef QuaternionBase<Map<Quaternion<_Scalar>, _Options> > Base; public: typedef _Scalar Scalar; @@ -369,7 +393,7 @@ class Map<Quaternion<_Scalar>, 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<Quaternion<double>, Aligned> QuaternionMapAlignedd; // Generic Quaternion * Quaternion product // This product can be specialized for a given architecture via the Arch template argument. namespace internal { -template<int Arch, class Derived1, class Derived2, typename Scalar, int PacketAccess> struct quat_product +template<int Arch, class Derived1, class Derived2, typename Scalar, int _Options> struct quat_product { EIGEN_STRONG_INLINE static Quaternion<Scalar> run(const QuaternionBase<Derived1>& a, const QuaternionBase<Derived2>& b){ return Quaternion<Scalar> @@ -423,7 +447,7 @@ QuaternionBase<Derived>::operator* (const QuaternionBase<OtherDerived>& 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<Architecture::Target, Derived, OtherDerived, typename internal::traits<Derived>::Scalar, - internal::traits<Derived>::PacketAccess && internal::traits<OtherDerived>::PacketAccess>::run(*this, other); + internal::traits<Derived>::IsAligned && internal::traits<OtherDerived>::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<typename Scalar, int Options> void quaternion(void) template<typename Scalar> void mapQuaternion(void){ typedef Map<Quaternion<Scalar>, Aligned> MQuaternionA; - typedef Map<Quaternion<Scalar> > MQuaternionUA; + typedef Map<Quaternion<Scalar> > MQuaternionUA;
+ typedef Map<const Quaternion<Scalar> > MCQuaternionUA; typedef Quaternion<Scalar> Quaternionx; EIGEN_ALIGN16 Scalar array1[4]; @@ -139,9 +140,11 @@ template<typename Scalar> 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<typename Scalar> void quaternionAlignment(void){ #endif } +template<typename PlainObjectType> 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<PlainObjectType>::type ConstPlainObjectType; + VERIFY( !(internal::traits<Map<ConstPlainObjectType> >::Flags & LvalueBit) ); + VERIFY( !(internal::traits<Map<ConstPlainObjectType, Aligned> >::Flags & LvalueBit) ); + VERIFY( !(Map<ConstPlainObjectType>::Flags & LvalueBit) ); + VERIFY( !(Map<ConstPlainObjectType, Aligned>::Flags & LvalueBit) ); +} + + void test_geo_quaternion() { for(int i = 0; i < g_repeat; i++) { CALL_SUBTEST_1(( quaternion<float,AutoAlign>() )); + CALL_SUBTEST_1( check_const_correctness(Quaternionf()) ); CALL_SUBTEST_2(( quaternion<double,AutoAlign>() )); + CALL_SUBTEST_2( check_const_correctness(Quaterniond()) ); CALL_SUBTEST_3(( quaternion<float,DontAlign>() )); CALL_SUBTEST_4(( quaternion<double,DontAlign>() )); CALL_SUBTEST_5(( quaternionAlignment<float>() )); |