aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Eigen/src/Geometry/Quaternion.h72
-rw-r--r--test/geo_quaternion.cpp22
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>() ));