Browse Source

Math: explicit conversion constructors for Dual, Complex and Quaternion.

Similarly to what's already in all Vector and Matrix classes. Not sure
why this wasn't there already.
pull/118/head
Vladimír Vondruš 11 years ago
parent
commit
34df5a0aaa
  1. 10
      src/Magnum/Math/Complex.h
  2. 13
      src/Magnum/Math/Dual.h
  3. 12
      src/Magnum/Math/DualComplex.h
  4. 8
      src/Magnum/Math/DualQuaternion.h
  5. 10
      src/Magnum/Math/Quaternion.h
  6. 14
      src/Magnum/Math/Test/ComplexTest.cpp
  7. 14
      src/Magnum/Math/Test/DualComplexTest.cpp
  8. 14
      src/Magnum/Math/Test/DualQuaternionTest.cpp
  9. 14
      src/Magnum/Math/Test/DualTest.cpp
  10. 14
      src/Magnum/Math/Test/QuaternionTest.cpp

10
src/Magnum/Math/Complex.h

@ -83,6 +83,8 @@ Represents 2D rotation. See @ref transformations for brief introduction.
@see @ref Magnum::Complex, @ref Magnum::Complexd, @ref Matrix3
*/
template<class T> class Complex {
template<class> friend class Complex;
public:
typedef T Type; /**< @brief Underlying data type */
@ -167,6 +169,14 @@ template<class T> class Complex {
*/
constexpr explicit Complex(const Vector2<T>& vector): _real(vector.x()), _imaginary(vector.y()) {}
/**
* @brief Construct complex number from another of different type
*
* Performs only default casting on the values, no rounding or anything
* else.
*/
template<class U> constexpr explicit Complex(const Complex<U>& other): _real{T(other._real)}, _imaginary{T(other._imaginary)} {}
/** @brief Construct complex number from external representation */
template<class U, class V = decltype(Implementation::ComplexConverter<T, U>::from(std::declval<U>()))>
#ifndef CORRADE_MSVC2015_COMPATIBILITY

13
src/Magnum/Math/Dual.h

@ -72,6 +72,19 @@ template<class T> class Dual {
*/
constexpr /*implicit*/ Dual(const T& real, const T& dual = T()): _real(real), _dual(dual) {}
/**
* @brief Construct dual number from another of different type
*
* Performs only default casting on the values, no rounding or anything
* else. Example usage:
* @code
* Dual<Float> floatingPoint(1.3f, 2.7f);
* Dual<Byte> integral(floatingPoint);
* // integral == {1, 2}
* @endcode
*/
template<class U> constexpr explicit Dual(const Dual<U>& other): _real{T(other._real)}, _dual{T(other._dual)} {}
/** @brief Equality comparison */
bool operator==(const Dual<T>& other) const {
return TypeTraits<T>::equals(_real, other._real) &&

12
src/Magnum/Math/DualComplex.h

@ -149,6 +149,18 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
constexpr explicit DualComplex(const Vector2<T>& vector): Dual<Complex<T>>({}, Complex<T>(vector)) {}
#endif
/**
* @brief Construct dual complex number from another of different type
*
* Performs only default casting on the values, no rounding or anything
* else.
*/
template<class U> constexpr explicit DualComplex(const DualComplex<U>& other)
#ifndef DOXYGEN_GENERATING_OUTPUT
: Dual<Complex<T>>{other}
#endif
{}
/** @brief Construct dual complex number from external representation */
template<class U, class V = decltype(Implementation::DualComplexConverter<T, U>::from(std::declval<U>()))>
#ifndef CORRADE_MSVC2015_COMPATIBILITY

8
src/Magnum/Math/DualQuaternion.h

@ -215,6 +215,14 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
constexpr explicit DualQuaternion(const Vector3<T>& vector): Dual<Quaternion<T>>({}, {vector, T(0)}) {}
#endif
/**
* @brief Construct dual quaternion from another of different type
*
* Performs only default casting on the values, no rounding or anything
* else.
*/
template<class U> constexpr explicit DualQuaternion(const DualQuaternion<U>& other): Dual<Quaternion<T>>(other) {}
/** @brief Construct dual quaternion from external representation */
template<class U, class V = decltype(Implementation::DualQuaternionConverter<T, U>::from(std::declval<U>()))>
#ifndef CORRADE_MSVC2015_COMPATIBILITY

10
src/Magnum/Math/Quaternion.h

@ -125,6 +125,8 @@ Represents 3D rotation. See @ref transformations for brief introduction.
@ref Matrix4
*/
template<class T> class Quaternion {
template<class> friend class Quaternion;
public:
typedef T Type; /**< @brief Underlying data type */
@ -224,6 +226,14 @@ template<class T> class Quaternion {
*/
constexpr explicit Quaternion(const Vector3<T>& vector): _vector(vector), _scalar(T(0)) {}
/**
* @brief Construct dual complex number from another of different type
*
* Performs only default casting on the values, no rounding or anything
* else.
*/
template<class U> constexpr explicit Quaternion(const Quaternion<U>& other): _vector{other._vector}, _scalar{T(other._scalar)} {}
/** @brief Construct quaternion from external representation */
template<class U, class V = decltype(Implementation::QuaternionConverter<T, U>::from(std::declval<U>()))>
#ifndef CORRADE_MSVC2015_COMPATIBILITY

14
src/Magnum/Math/Test/ComplexTest.cpp

@ -62,6 +62,7 @@ struct ComplexTest: Corrade::TestSuite::Tester {
void constructZero();
void constructNoInit();
void constructFromVector();
void constructConversion();
void constructCopy();
void convert();
@ -96,6 +97,7 @@ ComplexTest::ComplexTest() {
&ComplexTest::constructZero,
&ComplexTest::constructNoInit,
&ComplexTest::constructFromVector,
&ComplexTest::constructConversion,
&ComplexTest::constructCopy,
&ComplexTest::convert,
@ -175,6 +177,18 @@ void ComplexTest::constructFromVector() {
CORRADE_VERIFY(!(std::is_convertible<Complex, Vector2>::value));
}
void ComplexTest::constructConversion() {
typedef Math::Complex<Int> Complexi;
constexpr Complex a{1.3f, 2.7f};
constexpr Complexi b{a};
CORRADE_COMPARE(b, (Complexi{1, 2}));
/* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Complex, Complexi>::value));
}
void ComplexTest::constructCopy() {
constexpr Complex a(2.5f, -5.0f);
constexpr Complex b(a);

14
src/Magnum/Math/Test/DualComplexTest.cpp

@ -62,6 +62,7 @@ struct DualComplexTest: Corrade::TestSuite::Tester {
void constructZero();
void constructNoInit();
void constructFromVector();
void constructConversion();
void constructCopy();
void convert();
@ -102,6 +103,7 @@ DualComplexTest::DualComplexTest() {
&DualComplexTest::constructZero,
&DualComplexTest::constructNoInit,
&DualComplexTest::constructFromVector,
&DualComplexTest::constructConversion,
&DualComplexTest::constructCopy,
&DualComplexTest::convert,
@ -169,6 +171,18 @@ void DualComplexTest::constructFromVector() {
CORRADE_VERIFY(!(std::is_convertible<Vector2, DualComplex>::value));
}
void DualComplexTest::constructConversion() {
typedef Math::DualComplex<Int> DualComplexi;
constexpr DualComplex a{{1.3f, 2.7f}, {-15.0f, 7.0f}};
constexpr DualComplexi b{a};
CORRADE_COMPARE(b, (DualComplexi{{1, 2}, {-15, 7}}));
/* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<DualComplex, DualComplexi>::value));
}
void DualComplexTest::constructCopy() {
constexpr Math::Dual<Complex> a({-1.0f, 2.5f}, {3.0f, -7.5f});
#ifndef CORRADE_MSVC2015_COMPATIBILITY /* Why can't be copy constexpr? */

14
src/Magnum/Math/Test/DualQuaternionTest.cpp

@ -64,6 +64,7 @@ struct DualQuaternionTest: Corrade::TestSuite::Tester {
void constructZero();
void constructNoInit();
void constructFromVector();
void constructConversion();
void constructCopy();
void convert();
@ -105,6 +106,7 @@ DualQuaternionTest::DualQuaternionTest() {
&DualQuaternionTest::constructZero,
&DualQuaternionTest::constructNoInit,
&DualQuaternionTest::constructFromVector,
&DualQuaternionTest::constructConversion,
&DualQuaternionTest::constructCopy,
&DualQuaternionTest::convert,
@ -174,6 +176,18 @@ void DualQuaternionTest::constructFromVector() {
CORRADE_VERIFY(!(std::is_convertible<Vector3, DualQuaternion>::value));
}
void DualQuaternionTest::constructConversion() {
typedef Math::DualQuaternion<Int> DualQuaternioni;
constexpr DualQuaternion a{{{1.3f, 2.7f, -15.0f}, 7.0f}, {{1.0f, -2.0f, 3.0f}, 0.0f}};
constexpr DualQuaternioni b{a};
CORRADE_COMPARE(b, (DualQuaternioni{{{1, 2, -15}, 7}, {{1, -2, 3}, 0}}));
/* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<DualQuaternion, DualQuaternioni>::value));
}
void DualQuaternionTest::constructCopy() {
constexpr Math::Dual<Quaternion> a({{1.0f, 2.0f, -3.0f}, -3.5f}, {{4.5f, -7.0f, 2.0f}, 1.0f});
#ifndef CORRADE_MSVC2015_COMPATIBILITY /* Why can't be copy constexpr? */

14
src/Magnum/Math/Test/DualTest.cpp

@ -37,6 +37,7 @@ struct DualTest: Corrade::TestSuite::Tester {
void construct();
void constructDefault();
void constructNoInit();
void constructConversion();
void constructCopy();
void compare();
@ -63,6 +64,7 @@ DualTest::DualTest() {
addTests({&DualTest::construct,
&DualTest::constructDefault,
&DualTest::constructNoInit,
&DualTest::constructConversion,
&DualTest::constructCopy,
&DualTest::compare,
@ -104,6 +106,18 @@ void DualTest::constructNoInit() {
CORRADE_COMPARE(a, Dual(2.0f, -7.5f));
}
void DualTest::constructConversion() {
typedef Math::Dual<Int> Duali;
constexpr Dual a{1.3f, 2.7f};
constexpr Duali b{a};
CORRADE_COMPARE(b, (Duali{1, 2}));
/* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Dual, Duali>::value));
}
void DualTest::constructCopy() {
constexpr Dual a(2.0f, 3.0f);
constexpr Dual b(a);

14
src/Magnum/Math/Test/QuaternionTest.cpp

@ -62,6 +62,7 @@ struct QuaternionTest: Corrade::TestSuite::Tester {
void constructZero();
void constructNoInit();
void constructFromVector();
void constructConversion();
void constructCopy();
void convert();
@ -107,6 +108,7 @@ QuaternionTest::QuaternionTest() {
&QuaternionTest::constructZero,
&QuaternionTest::constructNoInit,
&QuaternionTest::constructFromVector,
&QuaternionTest::constructConversion,
&QuaternionTest::constructCopy,
&QuaternionTest::convert,
@ -176,6 +178,18 @@ void QuaternionTest::constructFromVector() {
CORRADE_VERIFY(!(std::is_convertible<Vector3, Quaternion>::value));
}
void QuaternionTest::constructConversion() {
typedef Math::Quaternion<Int> Quaternioni;
constexpr Quaternion a{{1.3f, 2.7f, -15.0f}, 7.0f};
constexpr Quaternioni b{a};
CORRADE_COMPARE(b, (Quaternioni{{1, 2, -15}, 7}));
/* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Quaternion, Quaternioni>::value));
}
void QuaternionTest::constructCopy() {
constexpr Quaternion a({1.0f, -3.0f, 7.0f}, 2.5f);
constexpr Quaternion b(a);

Loading…
Cancel
Save