Browse Source

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.
pull/107/head
Vladimír Vondruš 11 years ago
parent
commit
1b0da5b2df
  1. 6
      src/Magnum/Color.h
  2. 6
      src/Magnum/Math/Angle.h
  3. 5
      src/Magnum/Math/BoolVector.h
  4. 6
      src/Magnum/Math/Complex.h
  5. 9
      src/Magnum/Math/Dual.h
  6. 3
      src/Magnum/Math/DualComplex.h
  7. 3
      src/Magnum/Math/DualQuaternion.h
  8. 3
      src/Magnum/Math/Matrix.h
  9. 3
      src/Magnum/Math/Matrix3.h
  10. 3
      src/Magnum/Math/Matrix4.h
  11. 5
      src/Magnum/Math/Quaternion.h
  12. 9
      src/Magnum/Math/Range.h
  13. 5
      src/Magnum/Math/RectangularMatrix.h
  14. 23
      src/Magnum/Math/Tags.h
  15. 11
      src/Magnum/Math/Test/AngleTest.cpp
  16. 8
      src/Magnum/Math/Test/BoolVectorTest.cpp
  17. 8
      src/Magnum/Math/Test/ComplexTest.cpp
  18. 8
      src/Magnum/Math/Test/DualComplexTest.cpp
  19. 8
      src/Magnum/Math/Test/DualQuaternionTest.cpp
  20. 8
      src/Magnum/Math/Test/DualTest.cpp
  21. 12
      src/Magnum/Math/Test/Matrix3Test.cpp
  22. 14
      src/Magnum/Math/Test/Matrix4Test.cpp
  23. 14
      src/Magnum/Math/Test/MatrixTest.cpp
  24. 8
      src/Magnum/Math/Test/QuaternionTest.cpp
  25. 16
      src/Magnum/Math/Test/RangeTest.cpp
  26. 12
      src/Magnum/Math/Test/RectangularMatrixTest.cpp
  27. 8
      src/Magnum/Math/Test/UnitTest.cpp
  28. 8
      src/Magnum/Math/Test/Vector2Test.cpp
  29. 8
      src/Magnum/Math/Test/Vector3Test.cpp
  30. 8
      src/Magnum/Math/Test/Vector4Test.cpp
  31. 8
      src/Magnum/Math/Test/VectorTest.cpp
  32. 5
      src/Magnum/Math/Unit.h
  33. 5
      src/Magnum/Math/Vector.h
  34. 3
      src/Magnum/Math/Vector2.h
  35. 3
      src/Magnum/Math/Vector3.h
  36. 3
      src/Magnum/Math/Vector4.h
  37. 11
      src/Magnum/Test/ColorTest.cpp

6
src/Magnum/Color.h

@ -256,6 +256,9 @@ template<class T> class BasicColor3: public Math::Vector3<T> {
*/
constexpr /*implicit*/ BasicColor3(Math::ZeroInitT = Math::ZeroInit): Math::Vector3<T>{Math::ZeroInit} {}
/** @copydoc Vector3::Vector3(NoInitT) */
explicit BasicColor3(Math::NoInitT): Math::Vector3<T>{Math::NoInit} {}
/**
* @brief Gray constructor
* @param rgb RGB value
@ -445,6 +448,9 @@ class BasicColor4: public Math::Vector4<T> {
/** @copydoc Vector4::Vector4(ZeroInitT) */
constexpr explicit BasicColor4(Math::ZeroInitT): Math::Vector4<T>{Math::ZeroInit} {}
/** @copydoc Vector4::Vector4(NoInitT) */
explicit BasicColor4(Math::NoInitT): Math::Vector4<T>{Math::NoInit} {}
/**
* @copydoc BasicColor3::BasicColor3(T)
* @param alpha Alpha value, defaults to `1.0` for floating-point types

6
src/Magnum/Math/Angle.h

@ -126,6 +126,9 @@ template<class T> class Deg: public Unit<Deg, T> {
/** @brief Construct zero angle */
constexpr /*implicit*/ Deg(ZeroInitT = ZeroInit): Unit<Deg, T>{ZeroInit} {}
/** @brief Construct without initializing the contents */
explicit Deg(NoInitT): Unit<Deg, T>{NoInit} {}
/** @brief Explicit constructor from unitless type */
constexpr explicit Deg(T value): Unit<Math::Deg, T>(value) {}
@ -184,6 +187,9 @@ template<class T> class Rad: public Unit<Rad, T> {
/** @brief Default constructor */
constexpr /*implicit*/ Rad(ZeroInitT = ZeroInit): Unit<Rad, T>{ZeroInit} {}
/** @brief Construct without initializing the contents */
explicit Rad(NoInitT): Unit<Rad, T>{NoInit} {}
/** @brief Construct from unitless type */
constexpr explicit Rad(T value): Unit<Math::Rad, T>(value) {}

5
src/Magnum/Math/BoolVector.h

@ -73,6 +73,11 @@ template<std::size_t size> 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<decltype(_data)>{}, "");
}
/**
* @brief Construct boolean vector from segment values
* @param first Value for first 8bit segment

6
src/Magnum/Math/Complex.h

@ -145,6 +145,12 @@ template<class T> 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<decltype(_real)>{}, "");
static_assert(std::is_trivially_constructible<decltype(_imaginary)>{}, "");
}
/**
* @brief Construct complex number from real and imaginary part
*

9
src/Magnum/Math/Dual.h

@ -32,6 +32,7 @@
#include <cmath>
#include <Corrade/Utility/Debug.h>
#include "Magnum/Math/Tags.h"
#include "Magnum/Math/TypeTraits.h"
namespace Magnum { namespace Math {
@ -53,6 +54,14 @@ template<class T> class Dual {
*/
constexpr /*implicit*/ Dual(): _real(), _dual() {}
/** @brief Construct without initializing the contents */
#ifdef DOXYGEN_GENERATING_OUTPUT
explicit Dual(NoInitT);
#else
template<class U = T, class = typename std::enable_if<std::is_trivially_constructible<U>{}>::type> Dual(NoInitT) {}
template<class U = T, class V = T, class = typename std::enable_if<std::is_constructible<U, NoInitT>{}>::type> Dual(NoInitT): _real{NoInit}, _dual{NoInit} {}
#endif
/**
* @brief Construct dual number from real and dual part
*

3
src/Magnum/Math/DualComplex.h

@ -112,6 +112,9 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
/** @brief Construct zero-initialized dual complex number */
constexpr explicit DualComplex(ZeroInitT): Dual<Complex<T>>{Complex<T>{ZeroInit}, Complex<T>{ZeroInit}} {}
/** @brief Construct without initializing the contents */
explicit DualComplex(NoInitT): Dual<Complex<T>>{NoInit} {}
/**
* @brief Construct dual complex number from real and dual part
*

3
src/Magnum/Math/DualQuaternion.h

@ -118,6 +118,9 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
/** @brief Construct zero-initialized dual quaternion */
constexpr explicit DualQuaternion(ZeroInitT): Dual<Quaternion<T>>{Quaternion<T>{ZeroInit}, Quaternion<T>{ZeroInit}} {}
/** @brief Construct without initializing the contents */
explicit DualQuaternion(NoInitT): Dual<Quaternion<T>>{NoInit} {}
/**
* @brief Construct dual quaternion from real and dual part
*

3
src/Magnum/Math/Matrix.h

@ -86,6 +86,9 @@ template<std::size_t size, class T> class Matrix: public RectangularMatrix<size,
/** @copydoc RectangularMatrix::RectangularMatrix(ZeroInitT) */
constexpr explicit Matrix(ZeroInitT): RectangularMatrix<size, size, T>{ZeroInit} {}
/** @copydoc RectangularMatrix::RectangularMatrix(NoInitT) */
constexpr explicit Matrix(NoInitT): RectangularMatrix<size, size, T>{NoInit} {}
/**
* @brief Matrix from column vectors
* @param first First column vector

3
src/Magnum/Math/Matrix3.h

@ -164,6 +164,9 @@ template<class T> class Matrix3: public Matrix3x3<T> {
/** @copydoc Matrix::Matrix(ZeroInitT) */
constexpr explicit Matrix3(ZeroInitT): Matrix3x3<T>{ZeroInit} {}
/** @copydoc Matrix::Matrix(NoInitT) */
constexpr explicit Matrix3(NoInitT): Matrix3x3<T>{NoInit} {}
/** @brief Matrix from column vectors */
constexpr /*implicit*/ Matrix3(const Vector3<T>& first, const Vector3<T>& second, const Vector3<T>& third): Matrix3x3<T>(first, second, third) {}

3
src/Magnum/Math/Matrix4.h

@ -260,6 +260,9 @@ template<class T> class Matrix4: public Matrix4x4<T> {
/** @copydoc Matrix::Matrix(ZeroInitT) */
constexpr explicit Matrix4(ZeroInitT): Matrix4x4<T>{ZeroInit} {}
/** @copydoc Matrix::Matrix(NoInitT) */
constexpr explicit Matrix4(NoInitT): Matrix4x4<T>{NoInit} {}
/** @brief Matrix from column vectors */
constexpr /*implicit*/ Matrix4(const Vector4<T>& first, const Vector4<T>& second, const Vector4<T>& third, const Vector4<T>& fourth): Matrix4x4<T>(first, second, third, fourth) {}

5
src/Magnum/Math/Quaternion.h

@ -202,6 +202,11 @@ template<class T> 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<decltype(_scalar)>{}, "");
}
/**
* @brief Construct quaternion from vector and scalar
*

9
src/Magnum/Math/Range.h

@ -77,6 +77,9 @@ template<UnsignedInt dimensions, class T> 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 T> 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<T>& min, const Vector2<T>& max): Range<2, T>(min, max) {}
@ -332,6 +338,9 @@ template<class T> 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<T>& min, const Vector3<T>& max): Range<3, T>(min, max) {}

5
src/Magnum/Math/RectangularMatrix.h

@ -108,6 +108,9 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
/** @brief Construct zero-filled matrix */
constexpr /*implicit*/ RectangularMatrix(ZeroInitT = ZeroInit): RectangularMatrix<cols, rows, T>{typename Implementation::GenerateSequence<cols>::Type{}, ZeroInit} {}
/** @brief Construct matrix without initializing the contents */
explicit RectangularMatrix(NoInitT): RectangularMatrix<cols, rows, T>{typename Implementation::GenerateSequence<cols>::Type{}, NoInit} {}
/**
* @brief Construct matrix from column vectors
* @param first First column vector
@ -361,7 +364,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
/* Implementation for RectangularMatrix<cols, rows, T>::RectangularMatrix(const RectangularMatrix<cols, rows, U>&) */
template<class U, std::size_t ...sequence> constexpr explicit RectangularMatrix(Implementation::Sequence<sequence...>, const RectangularMatrix<cols, rows, U>& matrix): _data{Vector<rows, T>(matrix[sequence])...} {}
/* Implementation for RectangularMatrix<cols, rows, T>::RectangularMatrix(ZeroInitT) */
/* Implementation for RectangularMatrix<cols, rows, T>::RectangularMatrix(ZeroInitT) and RectangularMatrix<cols, rows, T>::RectangularMatrix(NoInitT) */
template<class U, std::size_t ...sequence> constexpr explicit RectangularMatrix(Implementation::Sequence<sequence...>, U): _data{Vector<rows, T>{(static_cast<void>(sequence), U{})}...} {}
template<std::size_t ...sequence> constexpr Vector<DiagonalSize, T> diagonalInternal(Implementation::Sequence<sequence...>) const;

23
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 <Corrade/Containers/Tags.h>
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

11
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<Double> 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;

8
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));

8
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);

8
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}));

8
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}));

8
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<Float> 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);

12
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},

14
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},

14
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),

8
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));

16
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<Int> 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}));

12
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));

8
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);

8
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<Int> 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));

8
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<Float> 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));

8
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));

8
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);

5
src/Magnum/Math/Unit.h

@ -49,6 +49,11 @@ template<template<class> 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<decltype(_value)>{}, "");
}
/** @brief Explicit conversion from unitless type */
constexpr explicit Unit(T value): _value(value) {}

5
src/Magnum/Math/Vector.h

@ -148,6 +148,11 @@ template<std::size_t size, class T> class Vector {
*/
constexpr /*implicit*/ Vector(ZeroInitT = ZeroInit): _data{} {}
/** @brief Construct vector without initializing the contents */
explicit Vector(NoInitT) {
static_assert(std::is_trivially_constructible<decltype(_data)>{}, "");
}
/** @todo Creating Vector from combination of vector and scalar types */
/**

3
src/Magnum/Math/Vector2.h

@ -114,6 +114,9 @@ template<class T> 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) {}

3
src/Magnum/Math/Vector3.h

@ -136,6 +136,9 @@ template<class T> 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) {}

3
src/Magnum/Math/Vector4.h

@ -62,6 +62,9 @@ template<class T> 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) {}

11
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));

Loading…
Cancel
Save