diff --git a/src/Magnum/Math/Complex.h b/src/Magnum/Math/Complex.h index 5372469f0..b299edbee 100644 --- a/src/Magnum/Math/Complex.h +++ b/src/Magnum/Math/Complex.h @@ -43,6 +43,8 @@ namespace Implementation { template constexpr static Complex complexFromMatrix(const Matrix2x2& matrix) { return {matrix[0][0], matrix[0][1]}; } + + template struct ComplexConverter; } /** @relatesalso Complex @@ -159,6 +161,14 @@ template class Complex { */ constexpr explicit Complex(const Vector2& vector): _real(vector.x()), _imaginary(vector.y()) {} + /** @brief Construct complex number from external representation */ + template::from(std::declval()))> constexpr explicit Complex(const U& other): Complex{Implementation::ComplexConverter::from(other)} {} + + /** @brief Convert complex number to external representation */ + template::to(std::declval>()))> constexpr explicit operator U() const { + return Implementation::ComplexConverter::to(*this); + } + /** @brief Equality comparison */ bool operator==(const Complex& other) const { return TypeTraits::equals(_real, other._real) && diff --git a/src/Magnum/Math/Test/ComplexTest.cpp b/src/Magnum/Math/Test/ComplexTest.cpp index 43ba7ce18..32ab90a1b 100644 --- a/src/Magnum/Math/Test/ComplexTest.cpp +++ b/src/Magnum/Math/Test/ComplexTest.cpp @@ -29,7 +29,27 @@ #include "Magnum/Math/Complex.h" #include "Magnum/Math/Matrix3.h" -namespace Magnum { namespace Math { namespace Test { +struct Cmpl { + float re, im; +}; + +namespace Magnum { namespace Math { + +namespace Implementation { + +template<> struct ComplexConverter { + constexpr static Complex from(const Cmpl& other) { + return {other.re, other.im}; + } + + constexpr static Cmpl to(const Complex& other) { + return {other.real(), other.imaginary()}; + } +}; + +} + +namespace Test { struct ComplexTest: Corrade::TestSuite::Tester { explicit ComplexTest(); @@ -38,6 +58,7 @@ struct ComplexTest: Corrade::TestSuite::Tester { void constructDefault(); void constructFromVector(); void constructCopy(); + void convert(); void compare(); void isNormalized(); @@ -69,6 +90,7 @@ ComplexTest::ComplexTest() { &ComplexTest::constructDefault, &ComplexTest::constructFromVector, &ComplexTest::constructCopy, + &ComplexTest::convert, &ComplexTest::compare, &ComplexTest::isNormalized, @@ -138,6 +160,22 @@ void ComplexTest::constructCopy() { CORRADE_COMPARE(b, Complex(2.5f, -5.0f)); } +void ComplexTest::convert() { + constexpr Cmpl a{1.5f, -3.5f}; + constexpr Complex b{1.5f, -3.5f}; + + constexpr Complex c(a); + CORRADE_COMPARE(c, b); + + constexpr Cmpl d(b); + CORRADE_COMPARE(d.re, a.re); + CORRADE_COMPARE(d.im, a.im); + + /* Implicit conversion is not allowed */ + CORRADE_VERIFY(!(std::is_convertible::value)); + CORRADE_VERIFY(!(std::is_convertible::value)); +} + void ComplexTest::compare() { CORRADE_VERIFY(Complex(3.7f, -1.0f+TypeTraits::epsilon()/2) == Complex(3.7f, -1.0f)); CORRADE_VERIFY(Complex(3.7f, -1.0f+TypeTraits::epsilon()*2) != Complex(3.7f, -1.0f));