diff --git a/doc/changelog.dox b/doc/changelog.dox index 023c8ee41..2977d1c51 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -179,6 +179,7 @@ See also: @ref Math::Intersection::pointCircle() / @relativeref{Math::Intersection,pointSphere()}, which are just wrappers over trivial code but easier to discover +- Added an unary @cpp operator+() @ce to all @ref Math classes @subsubsection changelog-latest-new-meshtools MeshTools library diff --git a/src/Magnum/Math/Complex.h b/src/Magnum/Math/Complex.h index 38d706991..c0554338d 100644 --- a/src/Magnum/Math/Complex.h +++ b/src/Magnum/Math/Complex.h @@ -288,6 +288,14 @@ template class Complex { Vector<2, T>(-_imaginary, _real)}; } + /** + * @brief Promotion + * @m_since_latest + * + * Returns the value as-is. + */ + Complex operator+() const { return *this; } + /** * @brief Add a complex number and assign * diff --git a/src/Magnum/Math/Dual.h b/src/Magnum/Math/Dual.h index fcf7594c8..36476af01 100644 --- a/src/Magnum/Math/Dual.h +++ b/src/Magnum/Math/Dual.h @@ -169,6 +169,14 @@ template class Dual { result. WTF, C++?! */ constexpr const T dual() const { return _dual; } /**< @overload */ + /** + * @brief Promotion + * @m_since_latest + * + * Returns the value as-is. + */ + Dual operator+() const { return *this; } + /** * @brief Add and assign dual number * @@ -306,6 +314,9 @@ template operator+() const { \ + return Math::Dual>::operator+(); \ + } \ Type operator-() const { \ return Math::Dual>::operator-(); \ } \ diff --git a/src/Magnum/Math/Quaternion.h b/src/Magnum/Math/Quaternion.h index 8ef1e333d..042bae3f6 100644 --- a/src/Magnum/Math/Quaternion.h +++ b/src/Magnum/Math/Quaternion.h @@ -465,6 +465,14 @@ template class Quaternion { */ Vector3> toEuler() const; + /** + * @brief Promotion + * @m_since_latest + * + * Returns the value as-is. + */ + Quaternion operator+() const { return *this; } + /** * @brief Negated quaternion * diff --git a/src/Magnum/Math/RectangularMatrix.h b/src/Magnum/Math/RectangularMatrix.h index 4ec965101..fb55f0d9b 100644 --- a/src/Magnum/Math/RectangularMatrix.h +++ b/src/Magnum/Math/RectangularMatrix.h @@ -334,6 +334,14 @@ template class RectangularMatrix { return toVector() > other.toVector(); } + /** + * @brief Promotion + * @m_since_latest + * + * Returns the value as-is. + */ + RectangularMatrix operator+() const { return *this; } + /** * @brief Negated matrix * @@ -732,6 +740,9 @@ extern template MAGNUM_EXPORT Corrade::Utility::Debug& operator<<(Corrade::Utili return Math::RectangularMatrix::fromDiagonal(diagonal); \ } \ \ + __VA_ARGS__ operator+() const { \ + return Math::RectangularMatrix::operator+(); \ + } \ __VA_ARGS__ operator-() const { \ return Math::RectangularMatrix::operator-(); \ } \ diff --git a/src/Magnum/Math/Test/ComplexTest.cpp b/src/Magnum/Math/Test/ComplexTest.cpp index 54919e528..b0a3095bd 100644 --- a/src/Magnum/Math/Test/ComplexTest.cpp +++ b/src/Magnum/Math/Test/ComplexTest.cpp @@ -72,8 +72,8 @@ struct ComplexTest: Corrade::TestSuite::Tester { void isNormalized(); template void isNormalizedEpsilon(); + void promotedNegated(); void addSubtract(); - void negated(); void multiplyDivideScalar(); void multiplyDivideVector(); void multiply(); @@ -123,8 +123,8 @@ ComplexTest::ComplexTest() { &ComplexTest::isNormalizedEpsilon, &ComplexTest::isNormalizedEpsilon, + &ComplexTest::promotedNegated, &ComplexTest::addSubtract, - &ComplexTest::negated, &ComplexTest::multiplyDivideScalar, &ComplexTest::multiplyDivideVector, &ComplexTest::multiply, @@ -324,6 +324,11 @@ template void ComplexTest::isNormalizedEpsilon() { CORRADE_VERIFY(!Math::Complex{T(0.801775644243754) + TypeTraits::epsilon()*T(2.0), T(0.597625146975521)}.isNormalized()); } +void ComplexTest::promotedNegated() { + CORRADE_COMPARE(+Complex(2.5f, -7.4f), Complex(2.5f, -7.4f)); + CORRADE_COMPARE(-Complex(2.5f, -7.4f), Complex(-2.5f, 7.4f)); +} + void ComplexTest::addSubtract() { Complex a( 1.7f, -3.7f); Complex b(-3.6f, 0.2f); @@ -333,10 +338,6 @@ void ComplexTest::addSubtract() { CORRADE_COMPARE(c - b, a); } -void ComplexTest::negated() { - CORRADE_COMPARE(-Complex(2.5f, -7.4f), Complex(-2.5f, 7.4f)); -} - void ComplexTest::multiplyDivideScalar() { Complex a( 2.5f, -0.5f); Complex b(-7.5f, 1.5f); diff --git a/src/Magnum/Math/Test/DualTest.cpp b/src/Magnum/Math/Test/DualTest.cpp index 5bbde26c0..5ae70e0ef 100644 --- a/src/Magnum/Math/Test/DualTest.cpp +++ b/src/Magnum/Math/Test/DualTest.cpp @@ -49,8 +49,8 @@ struct DualTest: Corrade::TestSuite::Tester { void compare(); + void promotedNegated(); void addSubtract(); - void negated(); void multiplyDivide(); void multiplyDivideScalar(); void multiplyDivideDifferentType(); @@ -90,8 +90,8 @@ DualTest::DualTest() { &DualTest::compare, + &DualTest::promotedNegated, &DualTest::addSubtract, - &DualTest::negated, &DualTest::multiplyDivide, &DualTest::multiplyDivideScalar, &DualTest::multiplyDivideDifferentType, @@ -229,6 +229,11 @@ void DualTest::compare() { CORRADE_VERIFY(Dual(1.0f, 3.0f) != 1.0f); } +void DualTest::promotedNegated() { + CORRADE_COMPARE(+Dual(1.0f, -6.5f), Dual(1.0f, -6.5f)); + CORRADE_COMPARE(-Dual(1.0f, -6.5f), Dual(-1.0f, 6.5f)); +} + void DualTest::addSubtract() { Dual a(2.0f, -7.5f); Dual b(-3.3f, 0.2f); @@ -238,10 +243,6 @@ void DualTest::addSubtract() { CORRADE_COMPARE(c - b, a); } -void DualTest::negated() { - CORRADE_COMPARE(-Dual(1.0f, -6.5f), Dual(-1.0f, 6.5f)); -} - void DualTest::multiplyDivide() { Dual a(1.5f, -4.0f); Dual b(-2.0f, 0.5f); @@ -329,6 +330,7 @@ typedef BasicDualVec2 DualVec2; void DualTest::subclassTypes() { const DualVec2 a; + CORRADE_VERIFY(std::is_same::value); CORRADE_VERIFY(std::is_same::value); CORRADE_VERIFY(std::is_same::value); CORRADE_VERIFY(std::is_same::value); @@ -356,6 +358,7 @@ void DualTest::subclass() { const DualVec2 c{Vector2{4.5f, 0.8f}, Vector2{-3.8f, 0.3f}}; const DualVec2 d{Vector2{4.5f, -2.4f}, Vector2{-11.7f, -3.56f}}; + CORRADE_COMPARE(+a, (DualVec2{Vector2{1.5f, 2.0f}, Vector2{-4.0f, 1.3f}})); CORRADE_COMPARE(-a, (DualVec2{Vector2{-1.5f, -2.0f}, Vector2{4.0f, -1.3f}})); CORRADE_COMPARE(a + b, c); CORRADE_COMPARE(c - b, a); diff --git a/src/Magnum/Math/Test/QuaternionTest.cpp b/src/Magnum/Math/Test/QuaternionTest.cpp index 7db81c627..d3d8ccb82 100644 --- a/src/Magnum/Math/Test/QuaternionTest.cpp +++ b/src/Magnum/Math/Test/QuaternionTest.cpp @@ -76,8 +76,8 @@ struct QuaternionTest: Corrade::TestSuite::Tester { void axisAngle(); void axisAngleNotNormalized(); + void promotedNegated(); void addSubtract(); - void negated(); void multiplyDivideScalar(); void multiply(); @@ -156,8 +156,8 @@ QuaternionTest::QuaternionTest() { &QuaternionTest::axisAngle, &QuaternionTest::axisAngleNotNormalized, + &QuaternionTest::promotedNegated, &QuaternionTest::addSubtract, - &QuaternionTest::negated, &QuaternionTest::multiplyDivideScalar, &QuaternionTest::multiply, @@ -383,6 +383,13 @@ void QuaternionTest::axisAngleNotNormalized() { "Math::Quaternion::axis(): Quaternion({0.239242, -0.318989, 0}, 1.95985) is not normalized\n"); } +void QuaternionTest::promotedNegated() { + CORRADE_COMPARE(+Quaternion({1.0f, 2.0f, -3.0f}, -4.0f), + Quaternion({1.0f, 2.0f, -3.0f}, -4.0f)); + CORRADE_COMPARE(-Quaternion({1.0f, 2.0f, -3.0f}, -4.0f), + Quaternion({-1.0f, -2.0f, 3.0f}, 4.0f)); +} + void QuaternionTest::addSubtract() { Quaternion a({ 1.0f, 3.0f, -2.0f}, -4.0f); Quaternion b({-0.5f, 1.4f, 3.0f}, 12.0f); @@ -392,10 +399,6 @@ void QuaternionTest::addSubtract() { CORRADE_COMPARE(c - b, a); } -void QuaternionTest::negated() { - CORRADE_COMPARE(-Quaternion({1.0f, 2.0f, -3.0f}, -4.0f), Quaternion({-1.0f, -2.0f, 3.0f}, 4.0f)); -} - void QuaternionTest::multiplyDivideScalar() { Quaternion a({ 1.0f, 3.0f, -2.0f}, -4.0f); Quaternion b({-1.5f, -4.5f, 3.0f}, 6.0f); diff --git a/src/Magnum/Math/Test/RectangularMatrixTest.cpp b/src/Magnum/Math/Test/RectangularMatrixTest.cpp index 03696923d..d830f159f 100644 --- a/src/Magnum/Math/Test/RectangularMatrixTest.cpp +++ b/src/Magnum/Math/Test/RectangularMatrixTest.cpp @@ -78,7 +78,7 @@ struct RectangularMatrixTest: Corrade::TestSuite::Tester { void compare(); void compareComponentWise(); - void negative(); + void promotedNegated(); void addSubtract(); void multiplyDivide(); void multiply(); @@ -139,7 +139,7 @@ RectangularMatrixTest::RectangularMatrixTest() { &RectangularMatrixTest::compare, &RectangularMatrixTest::compareComponentWise, - &RectangularMatrixTest::negative, + &RectangularMatrixTest::promotedNegated, &RectangularMatrixTest::addSubtract, &RectangularMatrixTest::multiplyDivide, &RectangularMatrixTest::multiply, @@ -478,11 +478,12 @@ void RectangularMatrixTest::compareComponentWise() { CORRADE_COMPARE(Matrix3x1(1.0f, -1.0f, 5.0f) > Matrix3x1(1.1f, -1.0f, 3.0f), BitVector3(0x4)); } -void RectangularMatrixTest::negative() { +void RectangularMatrixTest::promotedNegated() { Matrix2x2 matrix(Vector2(1.0f, -3.0f), Vector2(5.0f, -10.0f)); Matrix2x2 negated(Vector2(-1.0f, 3.0f), Vector2(-5.0f, 10.0f)); + CORRADE_COMPARE(+matrix, matrix); CORRADE_COMPARE(-matrix, negated); } @@ -676,6 +677,7 @@ void RectangularMatrixTest::subclassTypes() { /* Const operators */ const Mat2x2 c; + CORRADE_VERIFY(std::is_same::value); CORRADE_VERIFY(std::is_same::value); CORRADE_VERIFY(std::is_same::value); CORRADE_VERIFY(std::is_same::value); @@ -718,6 +720,8 @@ void RectangularMatrixTest::subclass() { /* Constexpr constructor */ constexpr Mat2x2 a(Vector2(1.0f, -3.0f), Vector2(-3.0f, 1.0f)); + CORRADE_COMPARE(+a, Mat2x2(Vector2(1.0f, -3.0f), + Vector2(-3.0f, 1.0f))); CORRADE_COMPARE(-a, Mat2x2(Vector2(-1.0f, 3.0f), Vector2(3.0f, -1.0f))); diff --git a/src/Magnum/Math/Test/UnitTest.cpp b/src/Magnum/Math/Test/UnitTest.cpp index 6fa6b3024..e34fcab75 100644 --- a/src/Magnum/Math/Test/UnitTest.cpp +++ b/src/Magnum/Math/Test/UnitTest.cpp @@ -44,7 +44,7 @@ struct UnitTest: Corrade::TestSuite::Tester { void compare(); void compareNaN(); - void negated(); + void promotedNegated(); void addSubtract(); void multiplyDivide(); }; @@ -59,7 +59,7 @@ UnitTest::UnitTest() { &UnitTest::compare, &UnitTest::compareNaN, - &UnitTest::negated, + &UnitTest::promotedNegated, &UnitTest::addSubtract, &UnitTest::multiplyDivide}); } @@ -178,10 +178,12 @@ void UnitTest::compareNaN() { CORRADE_VERIFY(!(Sec{Constants::nan()} == Sec{Constants::nan()})); } -void UnitTest::negated() { +void UnitTest::promotedNegated() { constexpr Sec a(25.0f); - constexpr Sec b(-a); - CORRADE_COMPARE(b, Sec(-25.0f)); + constexpr Sec b(+a); + constexpr Sec c(-a); + CORRADE_COMPARE(b, Sec(+25.0f)); + CORRADE_COMPARE(c, Sec(-25.0f)); } void UnitTest::addSubtract() { diff --git a/src/Magnum/Math/Test/VectorTest.cpp b/src/Magnum/Math/Test/VectorTest.cpp index e351fb23e..64ea4db73 100644 --- a/src/Magnum/Math/Test/VectorTest.cpp +++ b/src/Magnum/Math/Test/VectorTest.cpp @@ -76,7 +76,7 @@ struct VectorTest: Corrade::TestSuite::Tester { void data(); - void negative(); + void promotedNegated(); void addSubtract(); void multiplyDivide(); void multiplyDivideIntegral(); @@ -151,7 +151,7 @@ VectorTest::VectorTest() { &VectorTest::data, - &VectorTest::negative, + &VectorTest::promotedNegated, &VectorTest::addSubtract, &VectorTest::multiplyDivide, &VectorTest::multiplyDivideIntegral, @@ -392,8 +392,11 @@ void VectorTest::compareComponentWise() { CORRADE_COMPARE(Vector3(1.0f, -1.0f, 5.0f) > Vector3(1.1f, -1.0f, 3.0f), BitVector3(0x4)); } -void VectorTest::negative() { - CORRADE_COMPARE(-Vector4(1.0f, -3.0f, 5.0f, -10.0f), Vector4(-1.0f, 3.0f, -5.0f, 10.0f)); +void VectorTest::promotedNegated() { + CORRADE_COMPARE(+Vector4(1.0f, -3.0f, 5.0f, -10.0f), + Vector4(1.0f, -3.0f, 5.0f, -10.0f)); + CORRADE_COMPARE(-Vector4(1.0f, -3.0f, 5.0f, -10.0f), + Vector4(-1.0f, 3.0f, -5.0f, 10.0f)); } void VectorTest::addSubtract() { @@ -651,6 +654,7 @@ void VectorTest::subclassTypes() { /* Const operators */ const Vec2 c; const Vec2 c2; + CORRADE_VERIFY(std::is_same::value); CORRADE_VERIFY(std::is_same::value); CORRADE_VERIFY(std::is_same::value); CORRADE_VERIFY(std::is_same::value); @@ -734,6 +738,7 @@ void VectorTest::subclass() { constexpr const Vec2 a{-2.0f, 5.0f}; CORRADE_COMPARE(a[0], -2.0f); + CORRADE_COMPARE(+Vec2(-2.0f, 5.0f), Vec2(-2.0f, 5.0f)); CORRADE_COMPARE(-Vec2(-2.0f, 5.0f), Vec2(2.0f, -5.0f)); CORRADE_COMPARE(Vec2(-2.0f, 5.0f) + Vec2(1.0f, -3.0f), Vec2(-1.0f, 2.0f)); CORRADE_COMPARE(Vec2(-2.0f, 5.0f) - Vec2(1.0f, -3.0f), Vec2(-3.0f, 8.0f)); diff --git a/src/Magnum/Math/Unit.h b/src/Magnum/Math/Unit.h index 3be1efaa6..1dd005bb0 100644 --- a/src/Magnum/Math/Unit.h +++ b/src/Magnum/Math/Unit.h @@ -98,6 +98,14 @@ template class Derived, class T> class Unit { return !operator<(other); } + /** + * @brief Promotion + * @m_since_latest + * + * Returns the value as-is. + */ + constexpr Unit operator+() const { return *this; } + /** @brief Negated value */ constexpr Unit operator-() const { return Unit(-_value); diff --git a/src/Magnum/Math/Vector.h b/src/Magnum/Math/Vector.h index 4efbf4485..46c6b7382 100644 --- a/src/Magnum/Math/Vector.h +++ b/src/Magnum/Math/Vector.h @@ -330,6 +330,14 @@ template class Vector { return Implementation::isNormalizedSquared(dot()); } + /** + * @brief Promotion + * @m_since_latest + * + * Returns the value as-is. + */ + Vector operator+() const { return *this; } + /** * @brief Negated vector * @@ -1280,6 +1288,9 @@ extern template MAGNUM_EXPORT Corrade::Utility::Debug& operator<<(Corrade::Utili return Math::Vector::pad(a, value); \ } \ \ + Type operator+() const { \ + return Math::Vector::operator+(); \ + } \ template typename std::enable_if::value, Type>::type \ operator-() const { \ return Math::Vector::operator-(); \