diff --git a/src/Magnum/Math/Matrix.h b/src/Magnum/Math/Matrix.h index 3f165c07d..b010ee17b 100644 --- a/src/Magnum/Math/Matrix.h +++ b/src/Magnum/Math/Matrix.h @@ -112,6 +112,9 @@ template class Matrix: public RectangularMatrix constexpr /*implicit*/ Matrix(const Vector& first, const U&... next) noexcept: RectangularMatrix(first, next...) {} + /** @brief Construct matrix with one value for all elements */ + constexpr explicit Matrix(T value) noexcept: RectangularMatrix{typename Implementation::GenerateSequence::Type(), value} {} + /** * @brief Construct matrix from another of different type * diff --git a/src/Magnum/Math/Matrix3.h b/src/Magnum/Math/Matrix3.h index 7c0891719..38ae00857 100644 --- a/src/Magnum/Math/Matrix3.h +++ b/src/Magnum/Math/Matrix3.h @@ -230,6 +230,9 @@ template class Matrix3: public Matrix3x3 { /** @brief Construct matrix from column vectors */ constexpr /*implicit*/ Matrix3(const Vector3& first, const Vector3& second, const Vector3& third) noexcept: Matrix3x3(first, second, third) {} + /** @brief Construct matrix with one value for all elements */ + constexpr explicit Matrix3(T value) noexcept: Matrix3x3{value} {} + /** @copydoc Matrix::Matrix(const RectangularMatrix&) */ template constexpr explicit Matrix3(const RectangularMatrix<3, 3, U>& other) noexcept: Matrix3x3(other) {} diff --git a/src/Magnum/Math/Matrix4.h b/src/Magnum/Math/Matrix4.h index b66246246..be9ace11d 100644 --- a/src/Magnum/Math/Matrix4.h +++ b/src/Magnum/Math/Matrix4.h @@ -401,6 +401,9 @@ template class Matrix4: public Matrix4x4 { /** @brief Construct matrix from column vectors */ constexpr /*implicit*/ Matrix4(const Vector4& first, const Vector4& second, const Vector4& third, const Vector4& fourth) noexcept: Matrix4x4(first, second, third, fourth) {} + /** @brief Construct matrix with one value for all elements */ + constexpr explicit Matrix4(T value) noexcept: Matrix4x4{value} {} + /** @copydoc Matrix::Matrix(const RectangularMatrix&) */ template constexpr explicit Matrix4(const RectangularMatrix<4, 4, U>& other) noexcept: Matrix4x4(other) {} diff --git a/src/Magnum/Math/RectangularMatrix.h b/src/Magnum/Math/RectangularMatrix.h index 71479521c..20ca87ef5 100644 --- a/src/Magnum/Math/RectangularMatrix.h +++ b/src/Magnum/Math/RectangularMatrix.h @@ -130,6 +130,9 @@ template class RectangularMatrix { static_assert(sizeof...(next)+1 == cols, "Improper number of arguments passed to RectangularMatrix constructor"); } + /** @brief Construct matrix with one value for all components */ + constexpr explicit RectangularMatrix(T value) noexcept: RectangularMatrix{typename Implementation::GenerateSequence::Type(), value} {} + /** * @brief Construct matrix from another of different type * @@ -435,6 +438,10 @@ template class RectangularMatrix { /* Implementation for RectangularMatrix::fromDiagonal() and Matrix(IdentityInitT, T) */ template constexpr explicit RectangularMatrix(Implementation::Sequence, const Vector& diagonal); + /* Implementation for RectangularMatrix::RectangularMatrix(T) and Matrix(T) */ + /* MSVC 2015 can't handle {} here */ + template constexpr explicit RectangularMatrix(Implementation::Sequence, T value) noexcept: _data{Vector((static_cast(sequence), value))...} {} + private: /* Implementation for RectangularMatrix::RectangularMatrix(const RectangularMatrix&) */ template constexpr explicit RectangularMatrix(Implementation::Sequence, const RectangularMatrix& matrix) noexcept: _data{Vector(matrix[sequence])...} {} diff --git a/src/Magnum/Math/Test/Matrix3Test.cpp b/src/Magnum/Math/Test/Matrix3Test.cpp index ba387b852..fcd7d71d6 100644 --- a/src/Magnum/Math/Test/Matrix3Test.cpp +++ b/src/Magnum/Math/Test/Matrix3Test.cpp @@ -63,6 +63,7 @@ struct Matrix3Test: Corrade::TestSuite::Tester { void constructIdentity(); void constructZero(); void constructNoInit(); + void constructOneValue(); void constructConversion(); void constructCopy(); void convert(); @@ -102,6 +103,7 @@ Matrix3Test::Matrix3Test() { &Matrix3Test::constructIdentity, &Matrix3Test::constructZero, &Matrix3Test::constructNoInit, + &Matrix3Test::constructOneValue, &Matrix3Test::constructConversion, &Matrix3Test::constructCopy, &Matrix3Test::convert, @@ -190,6 +192,18 @@ void Matrix3Test::constructNoInit() { CORRADE_VERIFY(!(std::is_convertible::value)); } +void Matrix3Test::constructOneValue() { + constexpr Matrix3 a{1.5f}; + CORRADE_COMPARE(a, (Matrix3{Vector3{1.5f, 1.5f, 1.5f}, + Vector3{1.5f, 1.5f, 1.5f}, + Vector3{1.5f, 1.5f, 1.5f}})); + + /* Implicit conversion is not allowed */ + CORRADE_VERIFY(!(std::is_convertible::value)); + + CORRADE_VERIFY((std::is_nothrow_constructible::value)); +} + void Matrix3Test::constructConversion() { constexpr Matrix3 a({3.0f, 5.0f, 8.0f}, {4.5f, 4.0f, 7.0f}, diff --git a/src/Magnum/Math/Test/Matrix4Test.cpp b/src/Magnum/Math/Test/Matrix4Test.cpp index b188adfd8..e1974660a 100644 --- a/src/Magnum/Math/Test/Matrix4Test.cpp +++ b/src/Magnum/Math/Test/Matrix4Test.cpp @@ -66,6 +66,7 @@ struct Matrix4Test: Corrade::TestSuite::Tester { void constructIdentity(); void constructZero(); void constructNoInit(); + void constructOneValue(); void constructConversion(); void constructCopy(); void convert(); @@ -118,6 +119,7 @@ Matrix4Test::Matrix4Test() { &Matrix4Test::constructIdentity, &Matrix4Test::constructZero, &Matrix4Test::constructNoInit, + &Matrix4Test::constructOneValue, &Matrix4Test::constructConversion, &Matrix4Test::constructCopy, &Matrix4Test::convert, @@ -224,6 +226,19 @@ void Matrix4Test::constructNoInit() { CORRADE_VERIFY(!(std::is_convertible::value)); } +void Matrix4Test::constructOneValue() { + constexpr Matrix4 a{1.5f}; + CORRADE_COMPARE(a, (Matrix4{{1.5f, 1.5f, 1.5f, 1.5f}, + {1.5f, 1.5f, 1.5f, 1.5f}, + {1.5f, 1.5f, 1.5f, 1.5f}, + {1.5f, 1.5f, 1.5f, 1.5f}})); + + /* Implicit conversion is not allowed */ + CORRADE_VERIFY(!(std::is_convertible::value)); + + CORRADE_VERIFY((std::is_nothrow_constructible::value)); +} + void Matrix4Test::constructConversion() { constexpr Matrix4 a({3.0f, 5.0f, 8.0f, -3.0f}, {4.5f, 4.0f, 7.0f, 2.0f}, diff --git a/src/Magnum/Math/Test/MatrixTest.cpp b/src/Magnum/Math/Test/MatrixTest.cpp index 702bbcf49..25f8f473d 100644 --- a/src/Magnum/Math/Test/MatrixTest.cpp +++ b/src/Magnum/Math/Test/MatrixTest.cpp @@ -63,6 +63,8 @@ struct MatrixTest: Corrade::TestSuite::Tester { void constructIdentity(); void constructZero(); void constructNoInit(); + void constructOneValue(); + void constructOneComponent(); void constructConversion(); void constructCopy(); void convert(); @@ -95,6 +97,8 @@ MatrixTest::MatrixTest() { &MatrixTest::constructIdentity, &MatrixTest::constructZero, &MatrixTest::constructNoInit, + &MatrixTest::constructOneValue, + &MatrixTest::constructOneComponent, &MatrixTest::constructConversion, &MatrixTest::constructCopy, &MatrixTest::convert, @@ -182,6 +186,33 @@ void MatrixTest::constructNoInit() { CORRADE_VERIFY(!(std::is_convertible::value)); } +void MatrixTest::constructOneValue() { + constexpr Matrix3x3 a{1.5f}; + CORRADE_COMPARE(a, (Matrix3x3{Vector3{1.5f, 1.5f, 1.5f}, + Vector3{1.5f, 1.5f, 1.5f}, + Vector3{1.5f, 1.5f, 1.5f}})); + + /* Implicit conversion is not allowed */ + CORRADE_VERIFY(!(std::is_convertible::value)); + + CORRADE_VERIFY((std::is_nothrow_constructible::value)); +} + +void MatrixTest::constructOneComponent() { + typedef Math::Matrix<1, Float> Matrix1x1; + typedef Math::Vector<1, Float> Vector1; + + constexpr Matrix1x1 a{1.5f}; + constexpr Matrix1x1 b{Vector1{1.5f}}; + CORRADE_COMPARE(a, b); + + /* Implicit constructor must work */ + constexpr Matrix1x1 c = Vector1{1.5f}; + CORRADE_COMPARE(c, Matrix1x1{Vector1{1.5f}}); + + CORRADE_VERIFY((std::is_nothrow_constructible::value)); +} + void MatrixTest::constructConversion() { constexpr Matrix4x4 a(Vector4(3.0f, 5.0f, 8.0f, -3.0f), Vector4(4.5f, 4.0f, 7.0f, 2.0f), diff --git a/src/Magnum/Math/Test/RectangularMatrixTest.cpp b/src/Magnum/Math/Test/RectangularMatrixTest.cpp index 5ffcc75b3..8d69bd59b 100644 --- a/src/Magnum/Math/Test/RectangularMatrixTest.cpp +++ b/src/Magnum/Math/Test/RectangularMatrixTest.cpp @@ -60,6 +60,8 @@ struct RectangularMatrixTest: Corrade::TestSuite::Tester { void construct(); void constructDefault(); void constructNoInit(); + void constructOneValue(); + void constructOneComponent(); void constructConversion(); void constructFromData(); void constructFromDiagonal(); @@ -110,6 +112,8 @@ RectangularMatrixTest::RectangularMatrixTest() { addTests({&RectangularMatrixTest::construct, &RectangularMatrixTest::constructDefault, &RectangularMatrixTest::constructNoInit, + &RectangularMatrixTest::constructOneValue, + &RectangularMatrixTest::constructOneComponent, &RectangularMatrixTest::constructConversion, &RectangularMatrixTest::constructFromData, &RectangularMatrixTest::constructFromDiagonal, @@ -189,6 +193,33 @@ void RectangularMatrixTest::constructNoInit() { CORRADE_VERIFY(!(std::is_convertible::value)); } +void RectangularMatrixTest::constructOneValue() { + constexpr Matrix3x4 a{1.5f}; + CORRADE_COMPARE(a, (Matrix3x4{Vector4{1.5f, 1.5f, 1.5f, 1.5f}, + Vector4{1.5f, 1.5f, 1.5f, 1.5f}, + Vector4{1.5f, 1.5f, 1.5f, 1.5f}})); + + /* Implicit conversion is not allowed */ + CORRADE_VERIFY(!(std::is_convertible::value)); + + CORRADE_VERIFY((std::is_nothrow_constructible::value)); +} + +void RectangularMatrixTest::constructOneComponent() { + typedef Math::RectangularMatrix<1, 1, Float> Matrix1x1; + typedef Math::Vector<1, Float> Vector1; + + constexpr Matrix1x1 a{1.5f}; + constexpr Matrix1x1 b{Vector1{1.5f}}; + CORRADE_COMPARE(a, b); + + /* Implicit constructor must work */ + constexpr Matrix1x1 c = Vector1{1.5f}; + CORRADE_COMPARE(c, Matrix1x1{Vector1{1.5f}}); + + CORRADE_VERIFY((std::is_nothrow_constructible::value)); +} + void RectangularMatrixTest::constructConversion() { constexpr Matrix2x2 a(Vector2( 1.3f, 2.7f), Vector2(-15.0f, 7.0f));