From 1b0da5b2df85bfb9cf5acdc747930d42c40b8e2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 21 Jun 2015 01:34:14 +0200 Subject: [PATCH] Math: ability to construct all types without initializing the contents. Useful for squeezing out last bits of performance, e.g. in this case: Vector3 a; a[0] = something++; a[1] = something++; a[2] = something++; In the code all elements are first zeroed out and then overwritten later, thus it might be good to avoid the zero-initialization: Vector3 a{Math::NoInit}; a[0] = something++; a[1] = something++; a[2] = something++; This will of course be more useful in far larger data types and arrays of these. --- src/Magnum/Color.h | 6 +++++ src/Magnum/Math/Angle.h | 6 +++++ src/Magnum/Math/BoolVector.h | 5 ++++ src/Magnum/Math/Complex.h | 6 +++++ src/Magnum/Math/Dual.h | 9 ++++++++ src/Magnum/Math/DualComplex.h | 3 +++ src/Magnum/Math/DualQuaternion.h | 3 +++ src/Magnum/Math/Matrix.h | 3 +++ src/Magnum/Math/Matrix3.h | 3 +++ src/Magnum/Math/Matrix4.h | 3 +++ src/Magnum/Math/Quaternion.h | 5 ++++ src/Magnum/Math/Range.h | 9 ++++++++ src/Magnum/Math/RectangularMatrix.h | 5 +++- src/Magnum/Math/Tags.h | 23 ++++++++++++++++++- src/Magnum/Math/Test/AngleTest.cpp | 11 +++++++++ src/Magnum/Math/Test/BoolVectorTest.cpp | 8 +++++++ src/Magnum/Math/Test/ComplexTest.cpp | 8 +++++++ src/Magnum/Math/Test/DualComplexTest.cpp | 8 +++++++ src/Magnum/Math/Test/DualQuaternionTest.cpp | 8 +++++++ src/Magnum/Math/Test/DualTest.cpp | 8 +++++++ src/Magnum/Math/Test/Matrix3Test.cpp | 12 ++++++++++ src/Magnum/Math/Test/Matrix4Test.cpp | 14 +++++++++++ src/Magnum/Math/Test/MatrixTest.cpp | 14 +++++++++++ src/Magnum/Math/Test/QuaternionTest.cpp | 8 +++++++ src/Magnum/Math/Test/RangeTest.cpp | 16 +++++++++++++ .../Math/Test/RectangularMatrixTest.cpp | 12 ++++++++++ src/Magnum/Math/Test/UnitTest.cpp | 8 +++++++ src/Magnum/Math/Test/Vector2Test.cpp | 8 +++++++ src/Magnum/Math/Test/Vector3Test.cpp | 8 +++++++ src/Magnum/Math/Test/Vector4Test.cpp | 8 +++++++ src/Magnum/Math/Test/VectorTest.cpp | 8 +++++++ src/Magnum/Math/Unit.h | 5 ++++ src/Magnum/Math/Vector.h | 5 ++++ src/Magnum/Math/Vector2.h | 3 +++ src/Magnum/Math/Vector3.h | 3 +++ src/Magnum/Math/Vector4.h | 3 +++ src/Magnum/Test/ColorTest.cpp | 11 +++++++++ 37 files changed, 284 insertions(+), 2 deletions(-) diff --git a/src/Magnum/Color.h b/src/Magnum/Color.h index 4c3b5d754..95c1c7fd4 100644 --- a/src/Magnum/Color.h +++ b/src/Magnum/Color.h @@ -256,6 +256,9 @@ template class BasicColor3: public Math::Vector3 { */ constexpr /*implicit*/ BasicColor3(Math::ZeroInitT = Math::ZeroInit): Math::Vector3{Math::ZeroInit} {} + /** @copydoc Vector3::Vector3(NoInitT) */ + explicit BasicColor3(Math::NoInitT): Math::Vector3{Math::NoInit} {} + /** * @brief Gray constructor * @param rgb RGB value @@ -445,6 +448,9 @@ class BasicColor4: public Math::Vector4 { /** @copydoc Vector4::Vector4(ZeroInitT) */ constexpr explicit BasicColor4(Math::ZeroInitT): Math::Vector4{Math::ZeroInit} {} + /** @copydoc Vector4::Vector4(NoInitT) */ + explicit BasicColor4(Math::NoInitT): Math::Vector4{Math::NoInit} {} + /** * @copydoc BasicColor3::BasicColor3(T) * @param alpha Alpha value, defaults to `1.0` for floating-point types diff --git a/src/Magnum/Math/Angle.h b/src/Magnum/Math/Angle.h index 6a4c83092..bfaaeaae2 100644 --- a/src/Magnum/Math/Angle.h +++ b/src/Magnum/Math/Angle.h @@ -126,6 +126,9 @@ template class Deg: public Unit { /** @brief Construct zero angle */ constexpr /*implicit*/ Deg(ZeroInitT = ZeroInit): Unit{ZeroInit} {} + /** @brief Construct without initializing the contents */ + explicit Deg(NoInitT): Unit{NoInit} {} + /** @brief Explicit constructor from unitless type */ constexpr explicit Deg(T value): Unit(value) {} @@ -184,6 +187,9 @@ template class Rad: public Unit { /** @brief Default constructor */ constexpr /*implicit*/ Rad(ZeroInitT = ZeroInit): Unit{ZeroInit} {} + /** @brief Construct without initializing the contents */ + explicit Rad(NoInitT): Unit{NoInit} {} + /** @brief Construct from unitless type */ constexpr explicit Rad(T value): Unit(value) {} diff --git a/src/Magnum/Math/BoolVector.h b/src/Magnum/Math/BoolVector.h index 3e4c951f8..1e0c73f2f 100644 --- a/src/Magnum/Math/BoolVector.h +++ b/src/Magnum/Math/BoolVector.h @@ -73,6 +73,11 @@ template class BoolVector { /** @brief Construct zero-filled boolean vector */ constexpr /*implicit*/ BoolVector(ZeroInitT = ZeroInit): _data{} {} + /** @brief Construct without initializing the contents */ + explicit BoolVector(NoInitT) { + static_assert(std::is_trivially_constructible{}, ""); + } + /** * @brief Construct boolean vector from segment values * @param first Value for first 8bit segment diff --git a/src/Magnum/Math/Complex.h b/src/Magnum/Math/Complex.h index bd98c6f2a..c0699637e 100644 --- a/src/Magnum/Math/Complex.h +++ b/src/Magnum/Math/Complex.h @@ -145,6 +145,12 @@ template class Complex { /** @brief Construct zero-initialized complex number */ constexpr explicit Complex(ZeroInitT): _real{}, _imaginary{} {} + /** @brief Construct without initializing the contents */ + explicit Complex(NoInitT) { + static_assert(std::is_trivially_constructible{}, ""); + static_assert(std::is_trivially_constructible{}, ""); + } + /** * @brief Construct complex number from real and imaginary part * diff --git a/src/Magnum/Math/Dual.h b/src/Magnum/Math/Dual.h index ae86d28eb..643db1182 100644 --- a/src/Magnum/Math/Dual.h +++ b/src/Magnum/Math/Dual.h @@ -32,6 +32,7 @@ #include #include +#include "Magnum/Math/Tags.h" #include "Magnum/Math/TypeTraits.h" namespace Magnum { namespace Math { @@ -53,6 +54,14 @@ template class Dual { */ constexpr /*implicit*/ Dual(): _real(), _dual() {} + /** @brief Construct without initializing the contents */ + #ifdef DOXYGEN_GENERATING_OUTPUT + explicit Dual(NoInitT); + #else + template{}>::type> Dual(NoInitT) {} + template{}>::type> Dual(NoInitT): _real{NoInit}, _dual{NoInit} {} + #endif + /** * @brief Construct dual number from real and dual part * diff --git a/src/Magnum/Math/DualComplex.h b/src/Magnum/Math/DualComplex.h index 763359036..d126ae41f 100644 --- a/src/Magnum/Math/DualComplex.h +++ b/src/Magnum/Math/DualComplex.h @@ -112,6 +112,9 @@ template class DualComplex: public Dual> { /** @brief Construct zero-initialized dual complex number */ constexpr explicit DualComplex(ZeroInitT): Dual>{Complex{ZeroInit}, Complex{ZeroInit}} {} + /** @brief Construct without initializing the contents */ + explicit DualComplex(NoInitT): Dual>{NoInit} {} + /** * @brief Construct dual complex number from real and dual part * diff --git a/src/Magnum/Math/DualQuaternion.h b/src/Magnum/Math/DualQuaternion.h index b7b57bad0..531cfff4e 100644 --- a/src/Magnum/Math/DualQuaternion.h +++ b/src/Magnum/Math/DualQuaternion.h @@ -118,6 +118,9 @@ template class DualQuaternion: public Dual> { /** @brief Construct zero-initialized dual quaternion */ constexpr explicit DualQuaternion(ZeroInitT): Dual>{Quaternion{ZeroInit}, Quaternion{ZeroInit}} {} + /** @brief Construct without initializing the contents */ + explicit DualQuaternion(NoInitT): Dual>{NoInit} {} + /** * @brief Construct dual quaternion from real and dual part * diff --git a/src/Magnum/Math/Matrix.h b/src/Magnum/Math/Matrix.h index be5c8fe37..0f447da5b 100644 --- a/src/Magnum/Math/Matrix.h +++ b/src/Magnum/Math/Matrix.h @@ -86,6 +86,9 @@ template class Matrix: public RectangularMatrix{ZeroInit} {} + /** @copydoc RectangularMatrix::RectangularMatrix(NoInitT) */ + constexpr explicit Matrix(NoInitT): RectangularMatrix{NoInit} {} + /** * @brief Matrix from column vectors * @param first First column vector diff --git a/src/Magnum/Math/Matrix3.h b/src/Magnum/Math/Matrix3.h index 52cc74fb1..4df6b70bf 100644 --- a/src/Magnum/Math/Matrix3.h +++ b/src/Magnum/Math/Matrix3.h @@ -164,6 +164,9 @@ template class Matrix3: public Matrix3x3 { /** @copydoc Matrix::Matrix(ZeroInitT) */ constexpr explicit Matrix3(ZeroInitT): Matrix3x3{ZeroInit} {} + /** @copydoc Matrix::Matrix(NoInitT) */ + constexpr explicit Matrix3(NoInitT): Matrix3x3{NoInit} {} + /** @brief Matrix from column vectors */ constexpr /*implicit*/ Matrix3(const Vector3& first, const Vector3& second, const Vector3& third): Matrix3x3(first, second, third) {} diff --git a/src/Magnum/Math/Matrix4.h b/src/Magnum/Math/Matrix4.h index ca60d272a..60925e25b 100644 --- a/src/Magnum/Math/Matrix4.h +++ b/src/Magnum/Math/Matrix4.h @@ -260,6 +260,9 @@ template class Matrix4: public Matrix4x4 { /** @copydoc Matrix::Matrix(ZeroInitT) */ constexpr explicit Matrix4(ZeroInitT): Matrix4x4{ZeroInit} {} + /** @copydoc Matrix::Matrix(NoInitT) */ + constexpr explicit Matrix4(NoInitT): Matrix4x4{NoInit} {} + /** @brief Matrix from column vectors */ constexpr /*implicit*/ Matrix4(const Vector4& first, const Vector4& second, const Vector4& third, const Vector4& fourth): Matrix4x4(first, second, third, fourth) {} diff --git a/src/Magnum/Math/Quaternion.h b/src/Magnum/Math/Quaternion.h index fca917c68..d7e855c3f 100644 --- a/src/Magnum/Math/Quaternion.h +++ b/src/Magnum/Math/Quaternion.h @@ -202,6 +202,11 @@ template class Quaternion { /** @brief Construct zero-initialized quaternion */ constexpr explicit Quaternion(ZeroInitT): _vector{ZeroInit}, _scalar{T{0}} {} + /** @brief Construct without initializing the contents */ + explicit Quaternion(NoInitT): _vector{NoInit} { + static_assert(std::is_trivially_constructible{}, ""); + } + /** * @brief Construct quaternion from vector and scalar * diff --git a/src/Magnum/Math/Range.h b/src/Magnum/Math/Range.h index 13396346d..b8e9cdbcd 100644 --- a/src/Magnum/Math/Range.h +++ b/src/Magnum/Math/Range.h @@ -77,6 +77,9 @@ template class Range { */ constexpr /*implicit*/ Range(ZeroInitT = ZeroInit): _min{ZeroInit}, _max{ZeroInit} {} + /** @brief Construct without initializing the contents */ + explicit Range(NoInitT): _min{NoInit}, _max{NoInit} {} + /** @brief Construct range from minimal and maximal coordinates */ constexpr /*implicit*/ Range(const VectorType& min, const VectorType& max): _min{min}, _max{max} {} @@ -221,6 +224,9 @@ template class Range2D: public Range<2, T> { /** @copydoc Range(ZeroInitT) */ constexpr /*implicit*/ Range2D(ZeroInitT = ZeroInit): Range<2, T>{ZeroInit} {} + /** @copydoc Range(NoInitT) */ + explicit Range2D(NoInitT): Range<2, T>{NoInit} {} + /** @copydoc Range(const VectorType&, const VectorType&) */ constexpr /*implicit*/ Range2D(const Vector2& min, const Vector2& max): Range<2, T>(min, max) {} @@ -332,6 +338,9 @@ template class Range3D: public Range<3, T> { /** @copydoc Range(ZeroInitT) */ constexpr /*implicit*/ Range3D(ZeroInitT = ZeroInit): Range<3, T>{ZeroInit} {} + /** @copybrief Range(NoInitT) */ + explicit Range3D(NoInitT): Range<3, T>{NoInit} {} + /** @copydoc Range(const VectorType&, const VectorType&) */ constexpr /*implicit*/ Range3D(const Vector3& min, const Vector3& max): Range<3, T>(min, max) {} diff --git a/src/Magnum/Math/RectangularMatrix.h b/src/Magnum/Math/RectangularMatrix.h index e2f731023..7474453b0 100644 --- a/src/Magnum/Math/RectangularMatrix.h +++ b/src/Magnum/Math/RectangularMatrix.h @@ -108,6 +108,9 @@ template class RectangularMatrix { /** @brief Construct zero-filled matrix */ constexpr /*implicit*/ RectangularMatrix(ZeroInitT = ZeroInit): RectangularMatrix{typename Implementation::GenerateSequence::Type{}, ZeroInit} {} + /** @brief Construct matrix without initializing the contents */ + explicit RectangularMatrix(NoInitT): RectangularMatrix{typename Implementation::GenerateSequence::Type{}, NoInit} {} + /** * @brief Construct matrix from column vectors * @param first First column vector @@ -361,7 +364,7 @@ template class RectangularMatrix { /* Implementation for RectangularMatrix::RectangularMatrix(const RectangularMatrix&) */ template constexpr explicit RectangularMatrix(Implementation::Sequence, const RectangularMatrix& matrix): _data{Vector(matrix[sequence])...} {} - /* Implementation for RectangularMatrix::RectangularMatrix(ZeroInitT) */ + /* Implementation for RectangularMatrix::RectangularMatrix(ZeroInitT) and RectangularMatrix::RectangularMatrix(NoInitT) */ template constexpr explicit RectangularMatrix(Implementation::Sequence, U): _data{Vector{(static_cast(sequence), U{})}...} {} template constexpr Vector diagonalInternal(Implementation::Sequence) const; diff --git a/src/Magnum/Math/Tags.h b/src/Magnum/Math/Tags.h index ce1037b67..98a77b5ed 100644 --- a/src/Magnum/Math/Tags.h +++ b/src/Magnum/Math/Tags.h @@ -26,11 +26,21 @@ */ /** @file - * @brief Tag type @ref Magnum::Math::ZeroInitT, @ref Magnum::Math::IdentityInitT, tag @ref Magnum::Math::ZeroInit, @ref Magnum::Math::IdentityInit + * @brief Tag type @ref Magnum::Math::NoInitT, @ref Magnum::Math::ZeroInitT, @ref Magnum::Math::IdentityInitT, tag @ref Magnum::Math::NoInit, @ref Magnum::Math::ZeroInit, @ref Magnum::Math::IdentityInit */ +#include + namespace Magnum { namespace Math { +/** +@brief No initialization tag type + +Used to distinguish construction with no initialization at all. +@see @ref NoInit +*/ +typedef Corrade::Containers::NoInitT NoInitT; + /** @brief Zero initialization tag type @@ -47,6 +57,17 @@ Used to distinguish construction with transformation set to identity. */ struct IdentityInitT {}; +/** +@brief No initialization tag + +Use for construction with no initialization at all. +*/ +#ifdef DOXYGEN_GENERATING_OUTPUT +constexpr NoInitT NoInit{}; +#else +using Corrade::Containers::NoInit; +#endif + /** @brief Zero initialization tag diff --git a/src/Magnum/Math/Test/AngleTest.cpp b/src/Magnum/Math/Test/AngleTest.cpp index 50a8708a2..70d488d28 100644 --- a/src/Magnum/Math/Test/AngleTest.cpp +++ b/src/Magnum/Math/Test/AngleTest.cpp @@ -34,6 +34,7 @@ struct AngleTest: Corrade::TestSuite::Tester { explicit AngleTest(); void construct(); + void constructNoInit(); void literals(); void conversion(); @@ -50,6 +51,7 @@ typedef Math::Rad Radd; AngleTest::AngleTest() { addTests({&AngleTest::construct, + &AngleTest::constructNoInit, &AngleTest::literals, &AngleTest::conversion, @@ -109,6 +111,15 @@ void AngleTest::construct() { #endif } +void AngleTest::constructNoInit() { + Deg a{25.0f}; + Rad b{3.14f}; + new(&a) Deg{NoInit}; + new(&b) Rad{NoInit}; + CORRADE_COMPARE(Float(a), 25.0f); + CORRADE_COMPARE(Float(b), 3.14f); +} + void AngleTest::literals() { #ifndef MAGNUM_TARGET_GLES constexpr auto a = 25.0_deg; diff --git a/src/Magnum/Math/Test/BoolVectorTest.cpp b/src/Magnum/Math/Test/BoolVectorTest.cpp index 03933ff43..2ff19490c 100644 --- a/src/Magnum/Math/Test/BoolVectorTest.cpp +++ b/src/Magnum/Math/Test/BoolVectorTest.cpp @@ -35,6 +35,7 @@ struct BoolVectorTest: Corrade::TestSuite::Tester { void construct(); void constructDefault(); + void constructNoInit(); void constructOneValue(); void constructOneElement(); void constructCopy(); @@ -61,6 +62,7 @@ typedef Math::BoolVector<19> BoolVector19; BoolVectorTest::BoolVectorTest() { addTests({&BoolVectorTest::construct, &BoolVectorTest::constructDefault, + &BoolVectorTest::constructNoInit, &BoolVectorTest::constructOneValue, &BoolVectorTest::constructOneElement, &BoolVectorTest::constructCopy, @@ -90,6 +92,12 @@ void BoolVectorTest::constructDefault() { CORRADE_COMPARE(b, BoolVector19(0x00, 0x00, 0x00)); } +void BoolVectorTest::constructNoInit() { + BoolVector19 a{0xa5, 0x5f, 0x07}; + new(&a) BoolVector19{NoInit}; + CORRADE_COMPARE(a, BoolVector19(0xa5, 0x5f, 0x07)); +} + void BoolVectorTest::constructOneValue() { constexpr BoolVector19 a(false); CORRADE_COMPARE(a, BoolVector19(0x00, 0x00, 0x00)); diff --git a/src/Magnum/Math/Test/ComplexTest.cpp b/src/Magnum/Math/Test/ComplexTest.cpp index 3cc7c04e0..9228e77f8 100644 --- a/src/Magnum/Math/Test/ComplexTest.cpp +++ b/src/Magnum/Math/Test/ComplexTest.cpp @@ -60,6 +60,7 @@ struct ComplexTest: Corrade::TestSuite::Tester { void construct(); void constructIdentity(); void constructZero(); + void constructNoInit(); void constructFromVector(); void constructCopy(); void convert(); @@ -93,6 +94,7 @@ ComplexTest::ComplexTest() { addTests({&ComplexTest::construct, &ComplexTest::constructIdentity, &ComplexTest::constructZero, + &ComplexTest::constructNoInit, &ComplexTest::constructFromVector, &ComplexTest::constructCopy, &ComplexTest::convert, @@ -153,6 +155,12 @@ void ComplexTest::constructZero() { CORRADE_COMPARE(a, Complex(0.0f, 0.0f)); } +void ComplexTest::constructNoInit() { + Complex a{0.5f, -3.7f}; + new(&a) Complex{NoInit}; + CORRADE_COMPARE(a, Complex(0.5f, -3.7f)); +} + void ComplexTest::constructFromVector() { constexpr Vector2 vec(1.5f, -3.0f); diff --git a/src/Magnum/Math/Test/DualComplexTest.cpp b/src/Magnum/Math/Test/DualComplexTest.cpp index fb4365d71..55dd3d4d3 100644 --- a/src/Magnum/Math/Test/DualComplexTest.cpp +++ b/src/Magnum/Math/Test/DualComplexTest.cpp @@ -60,6 +60,7 @@ struct DualComplexTest: Corrade::TestSuite::Tester { void construct(); void constructIdentity(); void constructZero(); + void constructNoInit(); void constructFromVector(); void constructCopy(); void convert(); @@ -99,6 +100,7 @@ DualComplexTest::DualComplexTest() { addTests({&DualComplexTest::construct, &DualComplexTest::constructIdentity, &DualComplexTest::constructZero, + &DualComplexTest::constructNoInit, &DualComplexTest::constructFromVector, &DualComplexTest::constructCopy, &DualComplexTest::convert, @@ -153,6 +155,12 @@ void DualComplexTest::constructZero() { CORRADE_COMPARE(a, DualComplex({0.0f, 0.0f}, {0.0f, 0.0f})); } +void DualComplexTest::constructNoInit() { + DualComplex a{{-1.0f, 2.5f}, {3.0f, -7.5f}}; + new(&a) DualComplex{NoInit}; + CORRADE_COMPARE(a, DualComplex({-1.0f, 2.5f}, {3.0f, -7.5f})); +} + void DualComplexTest::constructFromVector() { constexpr DualComplex a(Vector2(1.5f, -3.0f)); CORRADE_COMPARE(a, DualComplex({1.0f, 0.0f}, {1.5f, -3.0f})); diff --git a/src/Magnum/Math/Test/DualQuaternionTest.cpp b/src/Magnum/Math/Test/DualQuaternionTest.cpp index dc20c9bbc..59a1912fd 100644 --- a/src/Magnum/Math/Test/DualQuaternionTest.cpp +++ b/src/Magnum/Math/Test/DualQuaternionTest.cpp @@ -62,6 +62,7 @@ struct DualQuaternionTest: Corrade::TestSuite::Tester { void construct(); void constructIdentity(); void constructZero(); + void constructNoInit(); void constructFromVector(); void constructCopy(); void convert(); @@ -100,6 +101,7 @@ DualQuaternionTest::DualQuaternionTest() { addTests({&DualQuaternionTest::construct, &DualQuaternionTest::constructIdentity, &DualQuaternionTest::constructZero, + &DualQuaternionTest::constructNoInit, &DualQuaternionTest::constructFromVector, &DualQuaternionTest::constructCopy, &DualQuaternionTest::convert, @@ -154,6 +156,12 @@ void DualQuaternionTest::constructZero() { CORRADE_COMPARE(a, DualQuaternion({{0.0f, 0.0f, 0.0f}, 0.0f}, {{0.0f, 0.0f, 0.0f}, 0.0f})); } +void DualQuaternionTest::constructNoInit() { + DualQuaternion a{{{1.0f, 2.0f, 3.0f}, -4.0f}, {{0.5f, -3.1f, 3.3f}, 2.0f}}; + new(&a) DualQuaternion{NoInit}; + CORRADE_COMPARE(a, DualQuaternion({{1.0f, 2.0f, 3.0f}, -4.0f}, {{0.5f, -3.1f, 3.3f}, 2.0f})); +} + void DualQuaternionTest::constructFromVector() { constexpr DualQuaternion a(Vector3(1.0f, 2.0f, 3.0f)); CORRADE_COMPARE(a, DualQuaternion({{0.0f, 0.0f, 0.0f}, 1.0f}, {{1.0f, 2.0f, 3.0f}, 0.0f})); diff --git a/src/Magnum/Math/Test/DualTest.cpp b/src/Magnum/Math/Test/DualTest.cpp index 01ec3b44d..41a716eb7 100644 --- a/src/Magnum/Math/Test/DualTest.cpp +++ b/src/Magnum/Math/Test/DualTest.cpp @@ -35,6 +35,7 @@ struct DualTest: Corrade::TestSuite::Tester { void construct(); void constructDefault(); + void constructNoInit(); void constructCopy(); void compare(); @@ -54,6 +55,7 @@ typedef Math::Dual Dual; DualTest::DualTest() { addTests({&DualTest::construct, &DualTest::constructDefault, + &DualTest::constructNoInit, &DualTest::constructCopy, &DualTest::compare, @@ -85,6 +87,12 @@ void DualTest::constructDefault() { CORRADE_COMPARE(a, Dual(0.0f, 0.0f)); } +void DualTest::constructNoInit() { + Dual a{2.0f, -7.5f}; + new(&a) Dual{NoInit}; + CORRADE_COMPARE(a, Dual(2.0f, -7.5f)); +} + void DualTest::constructCopy() { constexpr Dual a(2.0f, 3.0f); constexpr Dual b(a); diff --git a/src/Magnum/Math/Test/Matrix3Test.cpp b/src/Magnum/Math/Test/Matrix3Test.cpp index f12313f45..c58e59bff 100644 --- a/src/Magnum/Math/Test/Matrix3Test.cpp +++ b/src/Magnum/Math/Test/Matrix3Test.cpp @@ -62,6 +62,7 @@ struct Matrix3Test: Corrade::TestSuite::Tester { void construct(); void constructIdentity(); void constructZero(); + void constructNoInit(); void constructConversion(); void constructCopy(); void convert(); @@ -100,6 +101,7 @@ Matrix3Test::Matrix3Test() { addTests({&Matrix3Test::construct, &Matrix3Test::constructIdentity, &Matrix3Test::constructZero, + &Matrix3Test::constructNoInit, &Matrix3Test::constructConversion, &Matrix3Test::constructCopy, &Matrix3Test::convert, @@ -161,6 +163,16 @@ void Matrix3Test::constructZero() { {0.0f, 0.0f, 0.0f})); } +void Matrix3Test::constructNoInit() { + Matrix3 a{{3.0f, 5.0f, 8.0f}, + {4.5f, 4.0f, 7.0f}, + {7.9f, -1.0f, 8.0f}}; + new(&a) Matrix3{NoInit}; + CORRADE_COMPARE(a, Matrix3({3.0f, 5.0f, 8.0f}, + {4.5f, 4.0f, 7.0f}, + {7.9f, -1.0f, 8.0f})); +} + 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 66a300d84..bb1fd0048 100644 --- a/src/Magnum/Math/Test/Matrix4Test.cpp +++ b/src/Magnum/Math/Test/Matrix4Test.cpp @@ -64,6 +64,7 @@ struct Matrix4Test: Corrade::TestSuite::Tester { void construct(); void constructIdentity(); void constructZero(); + void constructNoInit(); void constructConversion(); void constructCopy(); void convert(); @@ -111,6 +112,7 @@ Matrix4Test::Matrix4Test() { addTests({&Matrix4Test::construct, &Matrix4Test::constructIdentity, &Matrix4Test::constructZero, + &Matrix4Test::constructNoInit, &Matrix4Test::constructConversion, &Matrix4Test::constructCopy, &Matrix4Test::convert, @@ -186,6 +188,18 @@ void Matrix4Test::constructZero() { {0.0f, 0.0f, 0.0f, 0.0f})); } +void Matrix4Test::constructNoInit() { + Matrix4 a = {{3.0f, 5.0f, 8.0f, -3.0f}, + {4.5f, 4.0f, 7.0f, 2.0f}, + {1.0f, 2.0f, 3.0f, -1.0f}, + {7.9f, -1.0f, 8.0f, -1.5f}}; + new(&a) Matrix4{NoInit}; + CORRADE_COMPARE(a, Matrix4({3.0f, 5.0f, 8.0f, -3.0f}, + {4.5f, 4.0f, 7.0f, 2.0f}, + {1.0f, 2.0f, 3.0f, -1.0f}, + {7.9f, -1.0f, 8.0f, -1.5f})); +} + 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 1f2946e40..207e96e44 100644 --- a/src/Magnum/Math/Test/MatrixTest.cpp +++ b/src/Magnum/Math/Test/MatrixTest.cpp @@ -62,6 +62,7 @@ struct MatrixTest: Corrade::TestSuite::Tester { void construct(); void constructIdentity(); void constructZero(); + void constructNoInit(); void constructConversion(); void constructCopy(); void convert(); @@ -93,6 +94,7 @@ MatrixTest::MatrixTest() { addTests({&MatrixTest::construct, &MatrixTest::constructIdentity, &MatrixTest::constructZero, + &MatrixTest::constructNoInit, &MatrixTest::constructConversion, &MatrixTest::constructCopy, &MatrixTest::convert, @@ -151,6 +153,18 @@ void MatrixTest::constructZero() { Vector4(0.0f, 0.0f, 0.0f, 0.0f))); } +void MatrixTest::constructNoInit() { + Matrix4x4 a{Vector4(3.0f, 5.0f, 8.0f, -3.0f), + Vector4(4.5f, 4.0f, 7.0f, 2.0f), + Vector4(1.0f, 2.0f, 3.0f, -1.0f), + Vector4(7.9f, -1.0f, 8.0f, -1.5f)}; + new(&a) Matrix4x4{NoInit}; + CORRADE_COMPARE(a, Matrix4x4(Vector4(3.0f, 5.0f, 8.0f, -3.0f), + Vector4(4.5f, 4.0f, 7.0f, 2.0f), + Vector4(1.0f, 2.0f, 3.0f, -1.0f), + Vector4(7.9f, -1.0f, 8.0f, -1.5f))); +} + 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/QuaternionTest.cpp b/src/Magnum/Math/Test/QuaternionTest.cpp index d947161fb..bd8d19753 100644 --- a/src/Magnum/Math/Test/QuaternionTest.cpp +++ b/src/Magnum/Math/Test/QuaternionTest.cpp @@ -60,6 +60,7 @@ struct QuaternionTest: Corrade::TestSuite::Tester { void construct(); void constructIdentity(); void constructZero(); + void constructNoInit(); void constructFromVector(); void constructCopy(); void convert(); @@ -104,6 +105,7 @@ QuaternionTest::QuaternionTest() { addTests({&QuaternionTest::construct, &QuaternionTest::constructIdentity, &QuaternionTest::constructZero, + &QuaternionTest::constructNoInit, &QuaternionTest::constructFromVector, &QuaternionTest::constructCopy, &QuaternionTest::convert, @@ -160,6 +162,12 @@ void QuaternionTest::constructZero() { CORRADE_COMPARE(a, Quaternion({0.0f, 0.0f, 0.0f}, 0.0f)); } +void QuaternionTest::constructNoInit() { + Quaternion a{{1.0f, 2.0f, 3.0f}, -4.0f}; + new(&a) Quaternion{NoInit}; + CORRADE_COMPARE(a, Quaternion({1.0f, 2.0f, 3.0f}, -4.0f)); +} + void QuaternionTest::constructFromVector() { constexpr Quaternion a(Vector3(1.0f, 2.0f, 3.0f)); CORRADE_COMPARE(a, Quaternion({1.0f, 2.0f, 3.0f}, 0.0f)); diff --git a/src/Magnum/Math/Test/RangeTest.cpp b/src/Magnum/Math/Test/RangeTest.cpp index b2863dfe5..53d647a82 100644 --- a/src/Magnum/Math/Test/RangeTest.cpp +++ b/src/Magnum/Math/Test/RangeTest.cpp @@ -108,6 +108,7 @@ struct RangeTest: Corrade::TestSuite::Tester { void construct(); void constructDefault(); + void constructNoInit(); void constructFromSize(); void constructConversion(); void constructCopy(); @@ -141,6 +142,7 @@ typedef Vector3 Vector3i; RangeTest::RangeTest() { addTests({&RangeTest::construct, &RangeTest::constructDefault, + &RangeTest::constructNoInit, &RangeTest::constructFromSize, &RangeTest::constructConversion, &RangeTest::constructCopy, @@ -188,6 +190,20 @@ void RangeTest::constructDefault() { CORRADE_COMPARE(c2, Range3Di({0, 0, 0}, {0, 0, 0})); } +void RangeTest::constructNoInit() { + Range1Di a{3, 23}; + Range2Di b{{3, 5}, {23, 78}}; + Range3Di c{{3, 5, -7}, {23, 78, 2}}; + + new(&a) Range1Di{NoInit}; + new(&b) Range2Di{NoInit}; + new(&c) Range3Di{NoInit}; + + CORRADE_COMPARE(a, (Range1Di{3, 23})); + CORRADE_COMPARE(b, (Range2Di{{3, 5}, {23, 78}})); + CORRADE_COMPARE(c, (Range3Di{{3, 5, -7}, {23, 78, 2}})); +} + void RangeTest::constructFromSize() { CORRADE_COMPARE(Range1Di::fromSize(3, 23), Range1Di(3, 26)); CORRADE_COMPARE(Range2Di::fromSize({3, 5}, {23, 78}), Range2Di({3, 5}, {26, 83})); diff --git a/src/Magnum/Math/Test/RectangularMatrixTest.cpp b/src/Magnum/Math/Test/RectangularMatrixTest.cpp index faa0e141c..570ec772e 100644 --- a/src/Magnum/Math/Test/RectangularMatrixTest.cpp +++ b/src/Magnum/Math/Test/RectangularMatrixTest.cpp @@ -62,6 +62,7 @@ struct RectangularMatrixTest: Corrade::TestSuite::Tester { void construct(); void constructDefault(); + void constructNoInit(); void constructConversion(); void constructFromData(); void constructFromDiagonal(); @@ -108,6 +109,7 @@ typedef Vector<2, Int> Vector2i; RectangularMatrixTest::RectangularMatrixTest() { addTests({&RectangularMatrixTest::construct, &RectangularMatrixTest::constructDefault, + &RectangularMatrixTest::constructNoInit, &RectangularMatrixTest::constructConversion, &RectangularMatrixTest::constructFromData, &RectangularMatrixTest::constructFromDiagonal, @@ -159,6 +161,16 @@ void RectangularMatrixTest::constructDefault() { Vector3(0.0f, 0.0f, 0.0f))); } +void RectangularMatrixTest::constructNoInit() { + Matrix3x4 a{Vector4(1.0f, 2.0f, 3.0f, 4.0f), + Vector4(5.0f, 6.0f, 7.0f, 8.0f), + Vector4(9.0f, 10.0f, 11.0f, 12.0f)}; + new(&a) Matrix3x4{NoInit}; + CORRADE_COMPARE(a, Matrix3x4(Vector4(1.0f, 2.0f, 3.0f, 4.0f), + Vector4(5.0f, 6.0f, 7.0f, 8.0f), + Vector4(9.0f, 10.0f, 11.0f, 12.0f))); +} + void RectangularMatrixTest::constructConversion() { constexpr Matrix2x2 a(Vector2( 1.3f, 2.7f), Vector2(-15.0f, 7.0f)); diff --git a/src/Magnum/Math/Test/UnitTest.cpp b/src/Magnum/Math/Test/UnitTest.cpp index 3886516e9..d677681e4 100644 --- a/src/Magnum/Math/Test/UnitTest.cpp +++ b/src/Magnum/Math/Test/UnitTest.cpp @@ -35,6 +35,7 @@ struct UnitTest: Corrade::TestSuite::Tester { void construct(); void constructDefault(); + void constructNoInit(); void constructConversion(); void compare(); void compareNaN(); @@ -47,6 +48,7 @@ struct UnitTest: Corrade::TestSuite::Tester { UnitTest::UnitTest() { addTests({&UnitTest::construct, &UnitTest::constructDefault, + &UnitTest::constructNoInit, &UnitTest::constructConversion, &UnitTest::compare, &UnitTest::compareNaN, @@ -79,6 +81,12 @@ void UnitTest::constructDefault() { CORRADE_COMPARE(b, Sec(0.0f)); } +void UnitTest::constructNoInit() { + Sec a{25.0f}; + new(&a) Sec{NoInit}; + CORRADE_COMPARE(a, Sec{25.0f}); +} + void UnitTest::constructConversion() { constexpr Seci a(25); constexpr Sec b(a); diff --git a/src/Magnum/Math/Test/Vector2Test.cpp b/src/Magnum/Math/Test/Vector2Test.cpp index 4ba013675..514f788da 100644 --- a/src/Magnum/Math/Test/Vector2Test.cpp +++ b/src/Magnum/Math/Test/Vector2Test.cpp @@ -56,6 +56,7 @@ struct Vector2Test: Corrade::TestSuite::Tester { void construct(); void constructDefault(); + void constructNoInit(); void constructOneValue(); void constructConversion(); void constructCopy(); @@ -81,6 +82,7 @@ typedef Math::Vector2 Vector2i; Vector2Test::Vector2Test() { addTests({&Vector2Test::construct, &Vector2Test::constructDefault, + &Vector2Test::constructNoInit, &Vector2Test::constructOneValue, &Vector2Test::constructConversion, &Vector2Test::constructCopy, @@ -111,6 +113,12 @@ void Vector2Test::constructDefault() { CORRADE_COMPARE(b, Vector2(0.0f, 0.0f)); } +void Vector2Test::constructNoInit() { + Vector2 a{1.5f, 2.5f}; + new(&a) Vector2{NoInit}; + CORRADE_COMPARE(a, (Vector2{1.5f, 2.5f})); +} + void Vector2Test::constructOneValue() { constexpr Vector2 a(3.0f); CORRADE_COMPARE(a, Vector2(3.0f, 3.0f)); diff --git a/src/Magnum/Math/Test/Vector3Test.cpp b/src/Magnum/Math/Test/Vector3Test.cpp index 37fd2c972..763447019 100644 --- a/src/Magnum/Math/Test/Vector3Test.cpp +++ b/src/Magnum/Math/Test/Vector3Test.cpp @@ -56,6 +56,7 @@ struct Vector3Test: Corrade::TestSuite::Tester { void construct(); void constructDefault(); + void constructNoInit(); void constructOneValue(); void constructParts(); void constructConversion(); @@ -80,6 +81,7 @@ typedef Math::Vector2 Vector2; Vector3Test::Vector3Test() { addTests({&Vector3Test::construct, &Vector3Test::constructDefault, + &Vector3Test::constructNoInit, &Vector3Test::constructOneValue, &Vector3Test::constructParts, &Vector3Test::constructConversion, @@ -109,6 +111,12 @@ void Vector3Test::constructDefault() { CORRADE_COMPARE(b, Vector3(0.0f, 0.0f, 0.0f)); } +void Vector3Test::constructNoInit() { + Vector3 a{1.0f, 2.5f, -3.0f}; + new(&a) Vector3{NoInit}; + CORRADE_COMPARE(a, (Vector3{1.0f, 2.5f, -3.0f})); +} + void Vector3Test::constructOneValue() { constexpr Vector3 a(-3.0f); CORRADE_COMPARE(a, Vector3(-3.0f, -3.0f, -3.0f)); diff --git a/src/Magnum/Math/Test/Vector4Test.cpp b/src/Magnum/Math/Test/Vector4Test.cpp index ecee35c5a..dc706c1a7 100644 --- a/src/Magnum/Math/Test/Vector4Test.cpp +++ b/src/Magnum/Math/Test/Vector4Test.cpp @@ -57,6 +57,7 @@ struct Vector4Test: Corrade::TestSuite::Tester { void construct(); void constructPad(); void constructDefault(); + void constructNoInit(); void constructOneValue(); void constructParts(); void constructConversion(); @@ -81,6 +82,7 @@ Vector4Test::Vector4Test() { addTests({&Vector4Test::construct, &Vector4Test::constructPad, &Vector4Test::constructDefault, + &Vector4Test::constructNoInit, &Vector4Test::constructOneValue, &Vector4Test::constructParts, &Vector4Test::constructConversion, @@ -118,6 +120,12 @@ void Vector4Test::constructDefault() { CORRADE_COMPARE(b, Vector4(0.0f, 0.0f, 0.0f, 0.0f)); } +void Vector4Test::constructNoInit() { + Vector4 a{1.0f, -2.5f, 3.0f, 4.1f}; + new(&a) Vector4{NoInit}; + CORRADE_COMPARE(a, (Vector4{1.0f, -2.5f, 3.0f, 4.1f})); +} + void Vector4Test::constructOneValue() { constexpr Vector4 a(4.3f); CORRADE_COMPARE(a, Vector4(4.3f, 4.3f, 4.3f, 4.3f)); diff --git a/src/Magnum/Math/Test/VectorTest.cpp b/src/Magnum/Math/Test/VectorTest.cpp index 1f6266dae..a567e3d74 100644 --- a/src/Magnum/Math/Test/VectorTest.cpp +++ b/src/Magnum/Math/Test/VectorTest.cpp @@ -61,6 +61,7 @@ struct VectorTest: Corrade::TestSuite::Tester { void constructFromData(); void constructPad(); void constructDefault(); + void constructNoInit(); void constructOneValue(); void constructOneComponent(); void constructConversion(); @@ -117,6 +118,7 @@ VectorTest::VectorTest() { &VectorTest::constructFromData, &VectorTest::constructPad, &VectorTest::constructDefault, + &VectorTest::constructNoInit, &VectorTest::constructOneValue, &VectorTest::constructOneComponent, &VectorTest::constructConversion, @@ -192,6 +194,12 @@ void VectorTest::constructDefault() { CORRADE_COMPARE(b, Vector4(0.0f, 0.0f, 0.0f, 0.0f)); } +void VectorTest::constructNoInit() { + Vector4 a{1.0f, 2.0f, -3.0f, 4.5f}; + new(&a) Vector4{NoInit}; + CORRADE_COMPARE(a, (Vector4{1.0f, 2.0f, -3.0f, 4.5f})); +} + void VectorTest::constructOneValue() { constexpr Vector4 a(7.25f); diff --git a/src/Magnum/Math/Unit.h b/src/Magnum/Math/Unit.h index 5e679eade..20ae2a08d 100644 --- a/src/Magnum/Math/Unit.h +++ b/src/Magnum/Math/Unit.h @@ -49,6 +49,11 @@ template class Derived, class T> class Unit { /** @brief Construct zero value */ constexpr /*implicit*/ Unit(ZeroInitT = ZeroInit): _value(T(0)) {} + /** @brief Construct without initializing the contents */ + explicit Unit(NoInitT) { + static_assert(std::is_trivially_constructible{}, ""); + } + /** @brief Explicit conversion from unitless type */ constexpr explicit Unit(T value): _value(value) {} diff --git a/src/Magnum/Math/Vector.h b/src/Magnum/Math/Vector.h index 18e75e256..e214819a1 100644 --- a/src/Magnum/Math/Vector.h +++ b/src/Magnum/Math/Vector.h @@ -148,6 +148,11 @@ template class Vector { */ constexpr /*implicit*/ Vector(ZeroInitT = ZeroInit): _data{} {} + /** @brief Construct vector without initializing the contents */ + explicit Vector(NoInitT) { + static_assert(std::is_trivially_constructible{}, ""); + } + /** @todo Creating Vector from combination of vector and scalar types */ /** diff --git a/src/Magnum/Math/Vector2.h b/src/Magnum/Math/Vector2.h index 04c1c4673..e4e6854e0 100644 --- a/src/Magnum/Math/Vector2.h +++ b/src/Magnum/Math/Vector2.h @@ -114,6 +114,9 @@ template class Vector2: public Vector<2, T> { /** @copydoc Vector::Vector(ZeroInitT) */ constexpr /*implicit*/ Vector2(ZeroInitT = ZeroInit): Vector<2, T>{ZeroInit} {} + /** @copydoc Vector::Vector(NoInitT) */ + explicit Vector2(NoInitT): Vector<2, T>{NoInit} {} + /** @copydoc Vector::Vector(T) */ constexpr explicit Vector2(T value): Vector<2, T>(value) {} diff --git a/src/Magnum/Math/Vector3.h b/src/Magnum/Math/Vector3.h index 2200498bb..70fe40f10 100644 --- a/src/Magnum/Math/Vector3.h +++ b/src/Magnum/Math/Vector3.h @@ -136,6 +136,9 @@ template class Vector3: public Vector<3, T> { /** @copydoc Vector::Vector(ZeroInitT) */ constexpr /*implicit*/ Vector3(ZeroInitT = ZeroInit): Vector<3, T>{ZeroInit} {} + /** @copydoc Vector::Vector(NoInitT) */ + explicit Vector3(NoInitT): Vector<3, T>{NoInit} {} + /** @copydoc Vector::Vector(T) */ constexpr explicit Vector3(T value): Vector<3, T>(value) {} diff --git a/src/Magnum/Math/Vector4.h b/src/Magnum/Math/Vector4.h index 1db87832a..b71311214 100644 --- a/src/Magnum/Math/Vector4.h +++ b/src/Magnum/Math/Vector4.h @@ -62,6 +62,9 @@ template class Vector4: public Vector<4, T> { /** @copydoc Vector::Vector(ZeroInitT) */ constexpr /*implicit*/ Vector4(ZeroInitT = ZeroInit): Vector<4, T>{ZeroInit} {} + /** @copydoc Vector::Vector(NoInitT) */ + explicit Vector4(NoInitT): Vector<4, T>{NoInit} {} + /** @copydoc Vector::Vector(T) */ constexpr explicit Vector4(T value): Vector<4, T>(value) {} diff --git a/src/Magnum/Test/ColorTest.cpp b/src/Magnum/Test/ColorTest.cpp index a8632825b..12c295041 100644 --- a/src/Magnum/Test/ColorTest.cpp +++ b/src/Magnum/Test/ColorTest.cpp @@ -37,6 +37,7 @@ struct ColorTest: TestSuite::Tester { void construct(); void constructDefault(); void constructZero(); + void constructNoInit(); void constructOneValue(); void constructParts(); void constructConversion(); @@ -66,6 +67,7 @@ ColorTest::ColorTest() { addTests({&ColorTest::construct, &ColorTest::constructDefault, &ColorTest::constructZero, + &ColorTest::constructNoInit, &ColorTest::constructOneValue, &ColorTest::constructParts, &ColorTest::constructConversion, @@ -124,6 +126,15 @@ void ColorTest::constructZero() { CORRADE_COMPARE(b, Color4(0.0f, 0.0f, 0.0f, 0.0f)); } +void ColorTest::constructNoInit() { + Color3 a{1.0f, 0.5f, 0.75f}; + Color4 b{1.0f, 0.5f, 0.75f, 0.5f}; + new(&a) Color3{Math::NoInit}; + new(&b) Color4{Math::NoInit}; + CORRADE_COMPARE(a, (Color3{1.0f, 0.5f, 0.75f})); + CORRADE_COMPARE(b, (Color4{1.0f, 0.5f, 0.75f, 0.5f})); +} + void ColorTest::constructOneValue() { constexpr Color3 a(0.25f); CORRADE_COMPARE(a, Color3(0.25f, 0.25f, 0.25f));