mirror of
https://gitlab.com/libeigen/eigen.git
synced 2024-12-15 07:10:37 +08:00
Quaternion : add Flags on Quaternion's traits with the LvalueBit set if needed
Quaternion : change PacketAccess to IsAligned to mimic other traits test : add a test and 4 failtest on Map<const Quaternion> based on Eigen::Map ones
This commit is contained in:
parent
f85db18c1c
commit
392eb9fee8
@ -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) */
|
||||
|
@ -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>() ));
|
||||
|
Loading…
Reference in New Issue
Block a user