Browse Source

Math: make all constructor noexcept and test their behavior.

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

28
src/Magnum/Math/Angle.h

@ -127,20 +127,20 @@ template<class T> class Deg: public Unit<Deg, T> {
public: public:
/** @brief Construct zero angle */ /** @brief Construct zero angle */
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
constexpr /*implicit*/ Deg(ZeroInitT = ZeroInit): Unit<Math::Deg, T>(ZeroInit) {} constexpr /*implicit*/ Deg(ZeroInitT = ZeroInit) noexcept: Unit<Math::Deg, T>(ZeroInit) {}
/** @brief Construct without initializing the contents */ /** @brief Construct without initializing the contents */
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
explicit Deg(NoInitT): Unit<Math::Deg, T>(NoInit) {} explicit Deg(NoInitT) noexcept: Unit<Math::Deg, T>(NoInit) {}
/** @brief Explicit constructor from unitless type */ /** @brief Explicit constructor from unitless type */
constexpr explicit Deg(T value): Unit<Math::Deg, T>(value) {} constexpr explicit Deg(T value) noexcept: Unit<Math::Deg, T>(value) {}
/** @brief Copy constructor */
constexpr /*implicit*/ Deg(Unit<Math::Deg, T> value): Unit<Math::Deg, T>(value) {}
/** @brief Construct from another underlying type */ /** @brief Construct from another underlying type */
template<class U> constexpr explicit Deg(Unit<Math::Deg, U> value): Unit<Math::Deg, T>(value) {} template<class U> constexpr explicit Deg(Unit<Math::Deg, U> value) noexcept: Unit<Math::Deg, T>(value) {}
/** @brief Copy constructor */
constexpr /*implicit*/ Deg(Unit<Math::Deg, T> other) noexcept: Unit<Math::Deg, T>(other) {}
/** /**
* @brief Construct degrees from radians * @brief Construct degrees from radians
@ -191,20 +191,20 @@ template<class T> class Rad: public Unit<Rad, T> {
public: public:
/** @brief Default constructor */ /** @brief Default constructor */
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
constexpr /*implicit*/ Rad(ZeroInitT = ZeroInit): Unit<Math::Rad, T>(ZeroInit) {} constexpr /*implicit*/ Rad(ZeroInitT = ZeroInit) noexcept: Unit<Math::Rad, T>(ZeroInit) {}
/** @brief Construct without initializing the contents */ /** @brief Construct without initializing the contents */
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
explicit Rad(NoInitT): Unit<Math::Rad, T>(NoInit) {} explicit Rad(NoInitT) noexcept: Unit<Math::Rad, T>(NoInit) {}
/** @brief Construct from unitless type */ /** @brief Construct from unitless type */
constexpr explicit Rad(T value): Unit<Math::Rad, T>(value) {} constexpr explicit Rad(T value) noexcept: Unit<Math::Rad, T>(value) {}
/** @brief Copy constructor */
constexpr /*implicit*/ Rad(Unit<Math::Rad, T> value): Unit<Math::Rad, T>(value) {}
/** @brief Construct from another underlying type */ /** @brief Construct from another underlying type */
template<class U> constexpr explicit Rad(Unit<Math::Rad, U> value): Unit<Math::Rad, T>(value) {} template<class U> constexpr explicit Rad(Unit<Math::Rad, U> value) noexcept: Unit<Math::Rad, T>(value) {}
/** @brief Copy constructor */
constexpr /*implicit*/ Rad(Unit<Math::Rad, T> value) noexcept: Unit<Math::Rad, T>(value) {}
/** /**
* @brief Construct radians from degrees * @brief Construct radians from degrees

14
src/Magnum/Math/BoolVector.h

@ -80,10 +80,10 @@ template<std::size_t size> class BoolVector {
}; };
/** @brief Construct zero-filled boolean vector */ /** @brief Construct zero-filled boolean vector */
constexpr /*implicit*/ BoolVector(ZeroInitT = ZeroInit): _data{} {} constexpr /*implicit*/ BoolVector(ZeroInitT = ZeroInit) noexcept: _data{} {}
/** @brief Construct without initializing the contents */ /** @brief Construct without initializing the contents */
explicit BoolVector(NoInitT) {} explicit BoolVector(NoInitT) noexcept {}
/** /**
* @brief Construct boolean vector from segment values * @brief Construct boolean vector from segment values
@ -91,20 +91,20 @@ template<std::size_t size> class BoolVector {
* @param next Values for next Bbit segments * @param next Values for next Bbit segments
*/ */
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
template<class ...T> constexpr /*implicit*/ BoolVector(UnsignedByte first, T... next); template<class ...T> constexpr /*implicit*/ BoolVector(UnsignedByte first, T... next) noexcept;
#else #else
template<class ...T, class U = typename std::enable_if<sizeof...(T)+1 == DataSize, bool>::type> constexpr /*implicit*/ BoolVector(UnsignedByte first, T... next): _data{first, UnsignedByte(next)...} {} template<class ...T, class U = typename std::enable_if<sizeof...(T)+1 == DataSize, bool>::type> constexpr /*implicit*/ BoolVector(UnsignedByte first, T... next) noexcept: _data{first, UnsignedByte(next)...} {}
#endif #endif
/** @brief Construct boolean vector with one value for all fields */ /** @brief Construct boolean vector with one value for all fields */
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
inline explicit BoolVector(T value); explicit BoolVector(T value) noexcept;
#else #else
template<class T, class U = typename std::enable_if<std::is_same<bool, T>::value && size != 1, bool>::type> constexpr explicit BoolVector(T value): BoolVector(typename Implementation::GenerateSequence<DataSize>::Type(), value ? FullSegmentMask : 0) {} template<class T, class U = typename std::enable_if<std::is_same<bool, T>::value && size != 1, bool>::type> constexpr explicit BoolVector(T value) noexcept: BoolVector(typename Implementation::GenerateSequence<DataSize>::Type(), value ? FullSegmentMask : 0) {}
#endif #endif
/** @brief Copy constructor */ /** @brief Copy constructor */
constexpr BoolVector(const BoolVector<size>&) = default; constexpr /*implicit*/ BoolVector(const BoolVector<size>&) noexcept = default;
/** /**
* @brief Raw data * @brief Raw data

28
src/Magnum/Math/Color.h

@ -254,7 +254,7 @@ template<class T> class Color3: public Vector3<T> {
* *
* All components are set to zero. * All components are set to zero.
*/ */
constexpr /*implicit*/ Color3(ZeroInitT = ZeroInit) constexpr /*implicit*/ Color3(ZeroInitT = ZeroInit) noexcept
/** @todoc remove workaround when doxygen is sane */ /** @todoc remove workaround when doxygen is sane */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
@ -263,7 +263,7 @@ template<class T> class Color3: public Vector3<T> {
{} {}
/** @copydoc Vector::Vector(NoInitT) */ /** @copydoc Vector::Vector(NoInitT) */
explicit Color3(NoInitT) explicit Color3(NoInitT) noexcept
/** @todoc remove workaround when doxygen is sane */ /** @todoc remove workaround when doxygen is sane */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
@ -275,7 +275,7 @@ template<class T> class Color3: public Vector3<T> {
* @brief Gray constructor * @brief Gray constructor
* @param rgb RGB value * @param rgb RGB value
*/ */
constexpr explicit Color3(T rgb): Vector3<T>(rgb) {} constexpr explicit Color3(T rgb) noexcept: Vector3<T>(rgb) {}
/** /**
* @brief Constructor * @brief Constructor
@ -283,7 +283,7 @@ template<class T> class Color3: public Vector3<T> {
* @param g G value * @param g G value
* @param b B value * @param b B value
*/ */
constexpr /*implicit*/ Color3(T r, T g, T b): Vector3<T>(r, g, b) {} constexpr /*implicit*/ Color3(T r, T g, T b) noexcept: Vector3<T>(r, g, b) {}
/** /**
* @copydoc Vector::Vector(const Vector<size, U>&) * @copydoc Vector::Vector(const Vector<size, U>&)
@ -292,10 +292,10 @@ template<class T> class Color3: public Vector3<T> {
* @ref normalize() and @ref denormalize() instead. * @ref normalize() and @ref denormalize() instead.
* See class documentation for more information. * See class documentation for more information.
*/ */
template<class U> constexpr explicit Color3(const Vector<3, U>& other): Vector3<T>(other) {} template<class U> constexpr explicit Color3(const Vector<3, U>& other) noexcept: Vector3<T>(other) {}
/** @brief Copy constructor */ /** @brief Copy constructor */
constexpr Color3(const Vector<3, T>& other): Vector3<T>(other) {} constexpr /*implicit*/ Color3(const Vector<3, T>& other) noexcept: Vector3<T>(other) {}
/** /**
* @brief Convert to HSV * @brief Convert to HSV
@ -449,10 +449,10 @@ class Color4: public Vector4<T> {
* *
* All components are set to zero. * All components are set to zero.
*/ */
constexpr /*implicit*/ Color4(): Vector4<T>(T(0), T(0), T(0), T(0)) {} constexpr /*implicit*/ Color4() noexcept: Vector4<T>(T(0), T(0), T(0), T(0)) {}
/** @copydoc Vector::Vector(ZeroInitT) */ /** @copydoc Vector::Vector(ZeroInitT) */
constexpr explicit Color4(ZeroInitT) constexpr explicit Color4(ZeroInitT) noexcept
/** @todoc remove workaround when doxygen is sane */ /** @todoc remove workaround when doxygen is sane */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
@ -461,7 +461,7 @@ class Color4: public Vector4<T> {
{} {}
/** @copydoc Vector::Vector(NoInitT) */ /** @copydoc Vector::Vector(NoInitT) */
explicit Color4(NoInitT) explicit Color4(NoInitT) noexcept
/** @todoc remove workaround when doxygen is sane */ /** @todoc remove workaround when doxygen is sane */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
@ -474,7 +474,7 @@ class Color4: public Vector4<T> {
* @param alpha Alpha value, defaults to `1.0` for floating-point types * @param alpha Alpha value, defaults to `1.0` for floating-point types
* and maximum positive value for integral types. * and maximum positive value for integral types.
*/ */
constexpr explicit Color4(T rgb, T alpha = Implementation::fullChannel<T>()): Vector4<T>(rgb, rgb, rgb, alpha) {} constexpr explicit Color4(T rgb, T alpha = Implementation::fullChannel<T>()) noexcept: Vector4<T>(rgb, rgb, rgb, alpha) {}
/** /**
* @brief Constructor * @brief Constructor
@ -484,7 +484,7 @@ class Color4: public Vector4<T> {
* @param a A value, defaults to `1.0` for floating-point types and * @param a A value, defaults to `1.0` for floating-point types and
* maximum positive value for integral types. * maximum positive value for integral types.
*/ */
constexpr /*implicit*/ Color4(T r, T g, T b, T a = Implementation::fullChannel<T>()): Vector4<T>(r, g, b, a) {} constexpr /*implicit*/ Color4(T r, T g, T b, T a = Implementation::fullChannel<T>()) noexcept: Vector4<T>(r, g, b, a) {}
/** /**
* @brief Constructor * @brief Constructor
@ -493,7 +493,7 @@ class Color4: public Vector4<T> {
*/ */
/* Not marked as explicit, because conversion from Color3 to Color4 /* Not marked as explicit, because conversion from Color3 to Color4
is fairly common, nearly always with A set to 1 */ is fairly common, nearly always with A set to 1 */
constexpr /*implicit*/ Color4(const Vector3<T>& rgb, T a = Implementation::fullChannel<T>()): Vector4<T>(rgb[0], rgb[1], rgb[2], a) {} constexpr /*implicit*/ Color4(const Vector3<T>& rgb, T a = Implementation::fullChannel<T>()) noexcept: Vector4<T>(rgb[0], rgb[1], rgb[2], a) {}
/** /**
* @copydoc Vector::Vector(const Vector<size, U>&) * @copydoc Vector::Vector(const Vector<size, U>&)
@ -502,10 +502,10 @@ class Color4: public Vector4<T> {
* @ref normalize() and @ref denormalize() instead. * @ref normalize() and @ref denormalize() instead.
* See @ref Color3 class documentation for more information. * See @ref Color3 class documentation for more information.
*/ */
template<class U> constexpr explicit Color4(const Vector<4, U>& other): Vector4<T>(other) {} template<class U> constexpr explicit Color4(const Vector<4, U>& other) noexcept: Vector4<T>(other) {}
/** @brief Copy constructor */ /** @brief Copy constructor */
constexpr Color4(const Vector<4, T>& other): Vector4<T>(other) {} constexpr /*implicit*/ Color4(const Vector<4, T>& other) noexcept: Vector4<T>(other) {}
/** @copydoc Color3::toHSV() */ /** @copydoc Color3::toHSV() */
constexpr HSV toHSV() const { constexpr HSV toHSV() const {

15
src/Magnum/Math/Complex.h

@ -142,13 +142,13 @@ template<class T> class Complex {
* c = 1 + i0 * c = 1 + i0
* @f] * @f]
*/ */
constexpr /*implicit*/ Complex(IdentityInitT = IdentityInit): _real(T(1)), _imaginary(T(0)) {} constexpr /*implicit*/ Complex(IdentityInitT = IdentityInit) noexcept: _real(T(1)), _imaginary(T(0)) {}
/** @brief Construct zero-initialized complex number */ /** @brief Construct zero-initialized complex number */
constexpr explicit Complex(ZeroInitT): _real{}, _imaginary{} {} constexpr explicit Complex(ZeroInitT) noexcept: _real{}, _imaginary{} {}
/** @brief Construct without initializing the contents */ /** @brief Construct without initializing the contents */
explicit Complex(NoInitT) {} explicit Complex(NoInitT) noexcept {}
/** /**
* @brief Construct complex number from real and imaginary part * @brief Construct complex number from real and imaginary part
@ -157,7 +157,7 @@ template<class T> class Complex {
* c = a + ib * c = a + ib
* @f] * @f]
*/ */
constexpr /*implicit*/ Complex(T real, T imaginary): _real(real), _imaginary(imaginary) {} constexpr /*implicit*/ Complex(T real, T imaginary) noexcept: _real(real), _imaginary(imaginary) {}
/** /**
* @brief Construct complex number from vector * @brief Construct complex number from vector
@ -167,7 +167,7 @@ template<class T> class Complex {
* @f] * @f]
* @see @ref operator Vector2<T>(), @ref transformVector() * @see @ref operator Vector2<T>(), @ref transformVector()
*/ */
constexpr explicit Complex(const Vector2<T>& vector): _real(vector.x()), _imaginary(vector.y()) {} constexpr explicit Complex(const Vector2<T>& vector) noexcept: _real(vector.x()), _imaginary(vector.y()) {}
/** /**
* @brief Construct complex number from another of different type * @brief Construct complex number from another of different type
@ -175,11 +175,14 @@ template<class T> class Complex {
* Performs only default casting on the values, no rounding or anything * Performs only default casting on the values, no rounding or anything
* else. * else.
*/ */
template<class U> constexpr explicit Complex(const Complex<U>& other): _real{T(other._real)}, _imaginary{T(other._imaginary)} {} template<class U> constexpr explicit Complex(const Complex<U>& other) noexcept: _real{T(other._real)}, _imaginary{T(other._imaginary)} {}
/** @brief Construct complex number from external representation */ /** @brief Construct complex number from external representation */
template<class U, class V = decltype(Implementation::ComplexConverter<T, U>::from(std::declval<U>()))> constexpr explicit Complex(const U& other): Complex{Implementation::ComplexConverter<T, U>::from(other)} {} template<class U, class V = decltype(Implementation::ComplexConverter<T, U>::from(std::declval<U>()))> constexpr explicit Complex(const U& other): Complex{Implementation::ComplexConverter<T, U>::from(other)} {}
/** @brief Copy constructor */
constexpr /*implicit*/ Complex(const Complex<T>&) noexcept = default;
/** @brief Convert complex number to external representation */ /** @brief Convert complex number to external representation */
template<class U, class V = decltype(Implementation::ComplexConverter<T, U>::to(std::declval<Complex<T>>()))> constexpr explicit operator U() const { template<class U, class V = decltype(Implementation::ComplexConverter<T, U>::to(std::declval<Complex<T>>()))> constexpr explicit operator U() const {
return Implementation::ComplexConverter<T, U>::to(*this); return Implementation::ComplexConverter<T, U>::to(*this);

15
src/Magnum/Math/Dual.h

@ -57,15 +57,15 @@ template<class T> class Dual {
* *
* Both parts are default-constructed. * Both parts are default-constructed.
*/ */
constexpr /*implicit*/ Dual(): _real(), _dual() {} constexpr /*implicit*/ Dual() noexcept: _real{}, _dual{} {}
/** @brief Construct without initializing the contents */ /** @brief Construct without initializing the contents */
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
explicit Dual(NoInitT); explicit Dual(NoInitT) noexcept;
#else #else
/* MSVC 2015 can't handle {} instead of ::value */ /* MSVC 2015 can't handle {} instead of ::value */
template<class U = T, class = typename std::enable_if<std::is_pod<U>::value>::type> Dual(NoInitT) {} template<class U = T, class = typename std::enable_if<std::is_pod<U>::value>::type> explicit Dual(NoInitT) noexcept {}
template<class U = T, class V = T, class = typename std::enable_if<std::is_constructible<U, NoInitT>::value>::type> Dual(NoInitT): _real{NoInit}, _dual{NoInit} {} template<class U = T, class V = T, class = typename std::enable_if<std::is_constructible<U, NoInitT>::value>::type> explicit Dual(NoInitT) noexcept: _real{NoInit}, _dual{NoInit} {}
#endif #endif
/** /**
@ -75,7 +75,7 @@ template<class T> class Dual {
* \hat a = a_0 + \epsilon a_\epsilon * \hat a = a_0 + \epsilon a_\epsilon
* @f] * @f]
*/ */
constexpr /*implicit*/ Dual(const T& real, const T& dual = T()): _real(real), _dual(dual) {} constexpr /*implicit*/ Dual(const T& real, const T& dual = T()) noexcept: _real(real), _dual(dual) {}
/** /**
* @brief Construct dual number from another of different type * @brief Construct dual number from another of different type
@ -88,7 +88,10 @@ template<class T> class Dual {
* // integral == {1, 2} * // integral == {1, 2}
* @endcode * @endcode
*/ */
template<class U> constexpr explicit Dual(const Dual<U>& other): _real{T(other._real)}, _dual{T(other._dual)} {} template<class U> constexpr explicit Dual(const Dual<U>& other) noexcept: _real{T(other._real)}, _dual{T(other._dual)} {}
/** @brief Copy constructor */
constexpr /*implicit*/ Dual(const Dual<T>&) noexcept = default;
/** @brief Equality comparison */ /** @brief Equality comparison */
bool operator==(const Dual<T>& other) const { bool operator==(const Dual<T>& other) const {

18
src/Magnum/Math/DualComplex.h

@ -104,13 +104,13 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* @f] * @f]
*/ */
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
constexpr /*implicit*/ DualComplex(IdentityInitT = IdentityInit); constexpr /*implicit*/ DualComplex(IdentityInitT = IdentityInit) noexcept;
#else #else
constexpr /*implicit*/ DualComplex(IdentityInitT = IdentityInit): Dual<Complex<T>>({}, {T(0), T(0)}) {} constexpr /*implicit*/ DualComplex(IdentityInitT = IdentityInit) noexcept: Dual<Complex<T>>({}, {T(0), T(0)}) {}
#endif #endif
/** @brief Construct zero-initialized dual complex number */ /** @brief Construct zero-initialized dual complex number */
constexpr explicit DualComplex(ZeroInitT) constexpr explicit DualComplex(ZeroInitT) noexcept
/** @todoc remove workaround when doxygen is sane */ /** @todoc remove workaround when doxygen is sane */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
@ -119,7 +119,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
{} {}
/** @brief Construct without initializing the contents */ /** @brief Construct without initializing the contents */
explicit DualComplex(NoInitT) explicit DualComplex(NoInitT) noexcept
/** @todoc remove workaround when doxygen is sane */ /** @todoc remove workaround when doxygen is sane */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
@ -134,7 +134,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* \hat c = c_0 + \epsilon c_\epsilon * \hat c = c_0 + \epsilon c_\epsilon
* @f] * @f]
*/ */
constexpr /*implicit*/ DualComplex(const Complex<T>& real, const Complex<T>& dual = Complex<T>(T(0), T(0))): Dual<Complex<T>>(real, dual) {} constexpr /*implicit*/ DualComplex(const Complex<T>& real, const Complex<T>& dual = Complex<T>(T(0), T(0))) noexcept: Dual<Complex<T>>(real, dual) {}
/** /**
* @brief Construct dual complex number from vector * @brief Construct dual complex number from vector
@ -144,9 +144,9 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* @f] * @f]
*/ */
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
constexpr explicit DualComplex(const Vector2<T>& vector); constexpr explicit DualComplex(const Vector2<T>& vector) noexcept;
#else #else
constexpr explicit DualComplex(const Vector2<T>& vector): Dual<Complex<T>>({}, Complex<T>(vector)) {} constexpr explicit DualComplex(const Vector2<T>& vector) noexcept: Dual<Complex<T>>({}, Complex<T>(vector)) {}
#endif #endif
/** /**
@ -155,7 +155,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
* Performs only default casting on the values, no rounding or anything * Performs only default casting on the values, no rounding or anything
* else. * else.
*/ */
template<class U> constexpr explicit DualComplex(const DualComplex<U>& other) template<class U> constexpr explicit DualComplex(const DualComplex<U>& other) noexcept
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
: Dual<Complex<T>>(other) : Dual<Complex<T>>(other)
@ -166,7 +166,7 @@ template<class T> class DualComplex: public Dual<Complex<T>> {
template<class U, class V = decltype(Implementation::DualComplexConverter<T, U>::from(std::declval<U>()))> constexpr explicit DualComplex(const U& other): DualComplex{Implementation::DualComplexConverter<T, U>::from(other)} {} template<class U, class V = decltype(Implementation::DualComplexConverter<T, U>::from(std::declval<U>()))> constexpr explicit DualComplex(const U& other): DualComplex{Implementation::DualComplexConverter<T, U>::from(other)} {}
/** @brief Copy constructor */ /** @brief Copy constructor */
constexpr DualComplex(const Dual<Complex<T>>& other): Dual<Complex<T>>(other) {} constexpr /*implicit*/ DualComplex(const Dual<Complex<T>>& other) noexcept: Dual<Complex<T>>(other) {}
/** @brief Convert dual complex number to external representation */ /** @brief Convert dual complex number to external representation */
template<class U, class V = decltype(Implementation::DualComplexConverter<T, U>::to(std::declval<DualComplex<T>>()))> constexpr explicit operator U() const { template<class U, class V = decltype(Implementation::DualComplexConverter<T, U>::to(std::declval<DualComplex<T>>()))> constexpr explicit operator U() const {

18
src/Magnum/Math/DualQuaternion.h

@ -163,7 +163,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* \hat q = [\boldsymbol 0, 1] + \epsilon [\boldsymbol 0, 0] * \hat q = [\boldsymbol 0, 1] + \epsilon [\boldsymbol 0, 0]
* @f] * @f]
*/ */
constexpr /*implicit*/ DualQuaternion(IdentityInitT = IdentityInit) constexpr /*implicit*/ DualQuaternion(IdentityInitT = IdentityInit) noexcept
/** @todoc remove workaround when doxygen is sane */ /** @todoc remove workaround when doxygen is sane */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
: Dual<Quaternion<T>>({}, {{}, T(0)}) : Dual<Quaternion<T>>({}, {{}, T(0)})
@ -171,7 +171,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
{} {}
/** @brief Construct zero-initialized dual quaternion */ /** @brief Construct zero-initialized dual quaternion */
constexpr explicit DualQuaternion(ZeroInitT) constexpr explicit DualQuaternion(ZeroInitT) noexcept
/** @todoc remove workaround when doxygen is sane */ /** @todoc remove workaround when doxygen is sane */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
@ -180,7 +180,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
{} {}
/** @brief Construct without initializing the contents */ /** @brief Construct without initializing the contents */
explicit DualQuaternion(NoInitT) explicit DualQuaternion(NoInitT) noexcept
/** @todoc remove workaround when doxygen is sane */ /** @todoc remove workaround when doxygen is sane */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
@ -195,7 +195,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* \hat q = q_0 + \epsilon q_\epsilon * \hat q = q_0 + \epsilon q_\epsilon
* @f] * @f]
*/ */
constexpr /*implicit*/ DualQuaternion(const Quaternion<T>& real, const Quaternion<T>& dual = Quaternion<T>({}, T(0))): Dual<Quaternion<T>>(real, dual) {} constexpr /*implicit*/ DualQuaternion(const Quaternion<T>& real, const Quaternion<T>& dual = Quaternion<T>({}, T(0))) noexcept: Dual<Quaternion<T>>(real, dual) {}
/** /**
* @brief Construct dual quaternion from dual vector and scalar parts * @brief Construct dual quaternion from dual vector and scalar parts
@ -204,7 +204,7 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* \hat q = [\hat{\boldsymbol v}, \hat s] = [\boldsymbol v_0, s_0] + \epsilon [\boldsymbol v_\epsilon, s_\epsilon] * \hat q = [\hat{\boldsymbol v}, \hat s] = [\boldsymbol v_0, s_0] + \epsilon [\boldsymbol v_\epsilon, s_\epsilon]
* @f] * @f]
*/ */
constexpr /*implicit*/ DualQuaternion(const Dual<Vector3<T>>& vector, const Dual<T>& scalar) constexpr /*implicit*/ DualQuaternion(const Dual<Vector3<T>>& vector, const Dual<T>& scalar) noexcept
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
: Dual<Quaternion<T>>({vector.real(), scalar.real()}, {vector.dual(), scalar.dual()}) : Dual<Quaternion<T>>({vector.real(), scalar.real()}, {vector.dual(), scalar.dual()})
@ -220,9 +220,9 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* @see @ref transformPointNormalized() * @see @ref transformPointNormalized()
*/ */
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
constexpr explicit DualQuaternion(const Vector3<T>& vector); constexpr explicit DualQuaternion(const Vector3<T>& vector) noexcept;
#else #else
constexpr explicit DualQuaternion(const Vector3<T>& vector): Dual<Quaternion<T>>({}, {vector, T(0)}) {} constexpr explicit DualQuaternion(const Vector3<T>& vector) noexcept: Dual<Quaternion<T>>({}, {vector, T(0)}) {}
#endif #endif
/** /**
@ -231,13 +231,13 @@ template<class T> class DualQuaternion: public Dual<Quaternion<T>> {
* Performs only default casting on the values, no rounding or anything * Performs only default casting on the values, no rounding or anything
* else. * else.
*/ */
template<class U> constexpr explicit DualQuaternion(const DualQuaternion<U>& other): Dual<Quaternion<T>>(other) {} template<class U> constexpr explicit DualQuaternion(const DualQuaternion<U>& other) noexcept: Dual<Quaternion<T>>(other) {}
/** @brief Construct dual quaternion from external representation */ /** @brief Construct dual quaternion from external representation */
template<class U, class V = decltype(Implementation::DualQuaternionConverter<T, U>::from(std::declval<U>()))> constexpr explicit DualQuaternion(const U& other): DualQuaternion{Implementation::DualQuaternionConverter<T, U>::from(other)} {} template<class U, class V = decltype(Implementation::DualQuaternionConverter<T, U>::from(std::declval<U>()))> constexpr explicit DualQuaternion(const U& other): DualQuaternion{Implementation::DualQuaternionConverter<T, U>::from(other)} {}
/** @brief Copy constructor */ /** @brief Copy constructor */
constexpr DualQuaternion(const Dual<Quaternion<T>>& other): Dual<Quaternion<T>>(other) {} constexpr /*implicit*/ DualQuaternion(const Dual<Quaternion<T>>& other) noexcept: Dual<Quaternion<T>>(other) {}
/** @brief Convert dual quaternion to external representation */ /** @brief Convert dual quaternion to external representation */
template<class U, class V = decltype(Implementation::DualQuaternionConverter<T, U>::to(std::declval<DualQuaternion<T>>()))> constexpr explicit operator U() const { template<class U, class V = decltype(Implementation::DualQuaternionConverter<T, U>::to(std::declval<DualQuaternion<T>>()))> constexpr explicit operator U() const {

12
src/Magnum/Math/Matrix.h

@ -83,7 +83,7 @@ template<std::size_t size, class T> class Matrix: public RectangularMatrix<size,
* Creates identity matrix. @p value allows you to specify value on * Creates identity matrix. @p value allows you to specify value on
* diagonal. * diagonal.
*/ */
constexpr /*implicit*/ Matrix(IdentityInitT = IdentityInit, T value = T(1)) constexpr /*implicit*/ Matrix(IdentityInitT = IdentityInit, T value = T(1)) noexcept
/** @todoc remove workaround when doxygen is sane */ /** @todoc remove workaround when doxygen is sane */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
@ -92,7 +92,7 @@ template<std::size_t size, class T> class Matrix: public RectangularMatrix<size,
{} {}
/** @copydoc RectangularMatrix::RectangularMatrix(ZeroInitT) */ /** @copydoc RectangularMatrix::RectangularMatrix(ZeroInitT) */
constexpr explicit Matrix(ZeroInitT) constexpr explicit Matrix(ZeroInitT) noexcept
/** @todoc remove workaround when doxygen is sane */ /** @todoc remove workaround when doxygen is sane */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
@ -101,7 +101,7 @@ template<std::size_t size, class T> class Matrix: public RectangularMatrix<size,
{} {}
/** @copydoc RectangularMatrix::RectangularMatrix(NoInitT) */ /** @copydoc RectangularMatrix::RectangularMatrix(NoInitT) */
constexpr explicit Matrix(NoInitT) constexpr explicit Matrix(NoInitT) noexcept
/** @todoc remove workaround when doxygen is sane */ /** @todoc remove workaround when doxygen is sane */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
@ -114,7 +114,7 @@ template<std::size_t size, class T> class Matrix: public RectangularMatrix<size,
* @param first First column vector * @param first First column vector
* @param next Next column vectors * @param next Next column vectors
*/ */
template<class ...U> constexpr /*implicit*/ Matrix(const Vector<size, T>& first, const U&... next): RectangularMatrix<size, size, T>(first, next...) {} template<class ...U> constexpr /*implicit*/ Matrix(const Vector<size, T>& first, const U&... next) noexcept: RectangularMatrix<size, size, T>(first, next...) {}
/** /**
* @brief Construct matrix from another of different type * @brief Construct matrix from another of different type
@ -128,13 +128,13 @@ template<std::size_t size, class T> class Matrix: public RectangularMatrix<size,
* // integral == {{1, 2}, {-15, 7}} * // integral == {{1, 2}, {-15, 7}}
* @endcode * @endcode
*/ */
template<class U> constexpr explicit Matrix(const RectangularMatrix<size, size, U>& other): RectangularMatrix<size, size, T>(other) {} template<class U> constexpr explicit Matrix(const RectangularMatrix<size, size, U>& other) noexcept: RectangularMatrix<size, size, T>(other) {}
/** @brief Construct matrix from external representation */ /** @brief Construct matrix from external representation */
template<class U, class V = decltype(Implementation::RectangularMatrixConverter<size, size, T, U>::from(std::declval<U>()))> constexpr explicit Matrix(const U& other): RectangularMatrix<size, size, T>(Implementation::RectangularMatrixConverter<size, size, T, U>::from(other)) {} template<class U, class V = decltype(Implementation::RectangularMatrixConverter<size, size, T, U>::from(std::declval<U>()))> constexpr explicit Matrix(const U& other): RectangularMatrix<size, size, T>(Implementation::RectangularMatrixConverter<size, size, T, U>::from(other)) {}
/** @brief Copy constructor */ /** @brief Copy constructor */
constexpr Matrix(const RectangularMatrix<size, size, T>& other): RectangularMatrix<size, size, T>(other) {} constexpr /*implicit*/ Matrix(const RectangularMatrix<size, size, T>& other) noexcept: RectangularMatrix<size, size, T>(other) {}
/** /**
* @brief Whether the matrix is orthogonal * @brief Whether the matrix is orthogonal

14
src/Magnum/Math/Matrix3.h

@ -159,7 +159,7 @@ template<class T> class Matrix3: public Matrix3x3<T> {
* Creates identity matrix. @p value allows you to specify value on * Creates identity matrix. @p value allows you to specify value on
* diagonal. * diagonal.
*/ */
constexpr /*implicit*/ Matrix3(IdentityInitT = IdentityInit, T value = T{1}) constexpr /*implicit*/ Matrix3(IdentityInitT = IdentityInit, T value = T{1}) noexcept
/** @todoc remove workaround when doxygen is sane */ /** @todoc remove workaround when doxygen is sane */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
@ -168,7 +168,7 @@ template<class T> class Matrix3: public Matrix3x3<T> {
{} {}
/** @copydoc Matrix::Matrix(ZeroInitT) */ /** @copydoc Matrix::Matrix(ZeroInitT) */
constexpr explicit Matrix3(ZeroInitT) constexpr explicit Matrix3(ZeroInitT) noexcept
/** @todoc remove workaround when doxygen is sane */ /** @todoc remove workaround when doxygen is sane */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
@ -177,7 +177,7 @@ template<class T> class Matrix3: public Matrix3x3<T> {
{} {}
/** @copydoc Matrix::Matrix(NoInitT) */ /** @copydoc Matrix::Matrix(NoInitT) */
constexpr explicit Matrix3(NoInitT) constexpr explicit Matrix3(NoInitT) noexcept
/** @todoc remove workaround when doxygen is sane */ /** @todoc remove workaround when doxygen is sane */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
@ -186,16 +186,16 @@ template<class T> class Matrix3: public Matrix3x3<T> {
{} {}
/** @brief Matrix from column vectors */ /** @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) {} constexpr /*implicit*/ Matrix3(const Vector3<T>& first, const Vector3<T>& second, const Vector3<T>& third) noexcept: Matrix3x3<T>(first, second, third) {}
/** @copydoc Matrix::Matrix(const RectangularMatrix<size, size, U>&) */ /** @copydoc Matrix::Matrix(const RectangularMatrix<size, size, U>&) */
template<class U> constexpr explicit Matrix3(const RectangularMatrix<3, 3, U>& other): Matrix3x3<T>(other) {} template<class U> constexpr explicit Matrix3(const RectangularMatrix<3, 3, U>& other) noexcept: Matrix3x3<T>(other) {}
/** @brief Construct matrix from external representation */ /** @brief Construct matrix from external representation */
template<class U, class V = decltype(Implementation::RectangularMatrixConverter<3, 3, T, U>::from(std::declval<U>()))> constexpr explicit Matrix3(const U& other): Matrix3x3<T>(Implementation::RectangularMatrixConverter<3, 3, T, U>::from(other)) {} template<class U, class V = decltype(Implementation::RectangularMatrixConverter<3, 3, T, U>::from(std::declval<U>()))> constexpr explicit Matrix3(const U& other) noexcept: Matrix3x3<T>(Implementation::RectangularMatrixConverter<3, 3, T, U>::from(other)) {}
/** @brief Copy constructor */ /** @brief Copy constructor */
constexpr Matrix3(const RectangularMatrix<3, 3, T>& other): Matrix3x3<T>(other) {} constexpr /*implicit*/ Matrix3(const RectangularMatrix<3, 3, T>& other) noexcept: Matrix3x3<T>(other) {}
/** /**
* @brief Check whether the matrix represents rigid transformation * @brief Check whether the matrix represents rigid transformation

12
src/Magnum/Math/Matrix4.h

@ -255,7 +255,7 @@ template<class T> class Matrix4: public Matrix4x4<T> {
* Creates identity matrix. @p value allows you to specify value on * Creates identity matrix. @p value allows you to specify value on
* diagonal. * diagonal.
*/ */
constexpr /*implicit*/ Matrix4(IdentityInitT = IdentityInit, T value = T{1}) constexpr /*implicit*/ Matrix4(IdentityInitT = IdentityInit, T value = T{1}) noexcept
/** @todoc remove workaround when doxygen is sane */ /** @todoc remove workaround when doxygen is sane */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
@ -264,7 +264,7 @@ template<class T> class Matrix4: public Matrix4x4<T> {
{} {}
/** @copydoc Matrix::Matrix(ZeroInitT) */ /** @copydoc Matrix::Matrix(ZeroInitT) */
constexpr explicit Matrix4(ZeroInitT) constexpr explicit Matrix4(ZeroInitT) noexcept
/** @todoc remove workaround when doxygen is sane */ /** @todoc remove workaround when doxygen is sane */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
@ -273,7 +273,7 @@ template<class T> class Matrix4: public Matrix4x4<T> {
{} {}
/** @copydoc Matrix::Matrix(NoInitT) */ /** @copydoc Matrix::Matrix(NoInitT) */
constexpr explicit Matrix4(NoInitT) constexpr explicit Matrix4(NoInitT) noexcept
/** @todoc remove workaround when doxygen is sane */ /** @todoc remove workaround when doxygen is sane */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
@ -282,16 +282,16 @@ template<class T> class Matrix4: public Matrix4x4<T> {
{} {}
/** @brief Matrix from column vectors */ /** @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) {} constexpr /*implicit*/ Matrix4(const Vector4<T>& first, const Vector4<T>& second, const Vector4<T>& third, const Vector4<T>& fourth) noexcept: Matrix4x4<T>(first, second, third, fourth) {}
/** @copydoc Matrix::Matrix(const RectangularMatrix<size, size, U>&) */ /** @copydoc Matrix::Matrix(const RectangularMatrix<size, size, U>&) */
template<class U> constexpr explicit Matrix4(const RectangularMatrix<4, 4, U>& other): Matrix4x4<T>(other) {} template<class U> constexpr explicit Matrix4(const RectangularMatrix<4, 4, U>& other) noexcept: Matrix4x4<T>(other) {}
/** @brief Construct matrix from external representation */ /** @brief Construct matrix from external representation */
template<class U, class V = decltype(Implementation::RectangularMatrixConverter<4, 4, T, U>::from(std::declval<U>()))> constexpr explicit Matrix4(const U& other): Matrix4x4<T>(Implementation::RectangularMatrixConverter<4, 4, T, U>::from(other)) {} template<class U, class V = decltype(Implementation::RectangularMatrixConverter<4, 4, T, U>::from(std::declval<U>()))> constexpr explicit Matrix4(const U& other): Matrix4x4<T>(Implementation::RectangularMatrixConverter<4, 4, T, U>::from(other)) {}
/** @brief Copy constructor */ /** @brief Copy constructor */
constexpr Matrix4(const RectangularMatrix<4, 4, T>& other): Matrix4x4<T>(other) {} constexpr /*implicit*/ Matrix4(const RectangularMatrix<4, 4, T>& other) noexcept: Matrix4x4<T>(other) {}
/** /**
* @brief Check whether the matrix represents rigid transformation * @brief Check whether the matrix represents rigid transformation

15
src/Magnum/Math/Quaternion.h

@ -205,13 +205,13 @@ template<class T> class Quaternion {
* q = [\boldsymbol 0, 1] * q = [\boldsymbol 0, 1]
* @f] * @f]
*/ */
constexpr /*implicit*/ Quaternion(IdentityInitT = IdentityInit): _scalar{T(1)} {} constexpr /*implicit*/ Quaternion(IdentityInitT = IdentityInit) noexcept: _scalar{T(1)} {}
/** @brief Construct zero-initialized quaternion */ /** @brief Construct zero-initialized quaternion */
constexpr explicit Quaternion(ZeroInitT): _vector{ZeroInit}, _scalar{T{0}} {} constexpr explicit Quaternion(ZeroInitT) noexcept: _vector{ZeroInit}, _scalar{T{0}} {}
/** @brief Construct without initializing the contents */ /** @brief Construct without initializing the contents */
explicit Quaternion(NoInitT): _vector{NoInit} {} explicit Quaternion(NoInitT) noexcept: _vector{NoInit} {}
/** /**
* @brief Construct quaternion from vector and scalar * @brief Construct quaternion from vector and scalar
@ -220,7 +220,7 @@ template<class T> class Quaternion {
* q = [\boldsymbol v, s] * q = [\boldsymbol v, s]
* @f] * @f]
*/ */
constexpr /*implicit*/ Quaternion(const Vector3<T>& vector, T scalar): _vector(vector), _scalar(scalar) {} constexpr /*implicit*/ Quaternion(const Vector3<T>& vector, T scalar) noexcept: _vector(vector), _scalar(scalar) {}
/** /**
* @brief Construct quaternion from vector * @brief Construct quaternion from vector
@ -230,7 +230,7 @@ template<class T> class Quaternion {
* @f] * @f]
* @see @ref transformVector(), @ref transformVectorNormalized() * @see @ref transformVector(), @ref transformVectorNormalized()
*/ */
constexpr explicit Quaternion(const Vector3<T>& vector): _vector(vector), _scalar(T(0)) {} constexpr explicit Quaternion(const Vector3<T>& vector) noexcept: _vector(vector), _scalar(T(0)) {}
/** /**
* @brief Construct dual complex number from another of different type * @brief Construct dual complex number from another of different type
@ -238,11 +238,14 @@ template<class T> class Quaternion {
* Performs only default casting on the values, no rounding or anything * Performs only default casting on the values, no rounding or anything
* else. * else.
*/ */
template<class U> constexpr explicit Quaternion(const Quaternion<U>& other): _vector{other._vector}, _scalar{T(other._scalar)} {} template<class U> constexpr explicit Quaternion(const Quaternion<U>& other) noexcept: _vector{other._vector}, _scalar{T(other._scalar)} {}
/** @brief Construct quaternion from external representation */ /** @brief Construct quaternion from external representation */
template<class U, class V = decltype(Implementation::QuaternionConverter<T, U>::from(std::declval<U>()))> constexpr explicit Quaternion(const U& other): Quaternion{Implementation::QuaternionConverter<T, U>::from(other)} {} template<class U, class V = decltype(Implementation::QuaternionConverter<T, U>::from(std::declval<U>()))> constexpr explicit Quaternion(const U& other): Quaternion{Implementation::QuaternionConverter<T, U>::from(other)} {}
/** @brief Copy constructor */
constexpr /*implicit*/ Quaternion(const Quaternion<T>&) noexcept = default;
/** @brief Convert quaternion to external representation */ /** @brief Convert quaternion to external representation */
template<class U, class V = decltype(Implementation::QuaternionConverter<T, U>::to(std::declval<Quaternion<T>>()))> constexpr explicit operator U() const { template<class U, class V = decltype(Implementation::QuaternionConverter<T, U>::to(std::declval<Quaternion<T>>()))> constexpr explicit operator U() const {
return Implementation::QuaternionConverter<T, U>::to(*this); return Implementation::QuaternionConverter<T, U>::to(*this);

44
src/Magnum/Math/Range.h

@ -76,16 +76,13 @@ template<UnsignedInt dimensions, class T> class Range {
* *
* Construct zero-size range positioned at origin. * Construct zero-size range positioned at origin.
*/ */
constexpr /*implicit*/ Range(ZeroInitT = ZeroInit): _min{ZeroInit}, _max{ZeroInit} {} constexpr /*implicit*/ Range(ZeroInitT = ZeroInit) noexcept: _min{ZeroInit}, _max{ZeroInit} {}
/** @brief Construct without initializing the contents */ /** @brief Construct without initializing the contents */
explicit Range(NoInitT): _min{NoInit}, _max{NoInit} {} explicit Range(NoInitT) noexcept: _min{NoInit}, _max{NoInit} {}
/** @brief Construct range from minimal and maximal coordinates */ /** @brief Construct range from minimal and maximal coordinates */
constexpr /*implicit*/ Range(const VectorType& min, const VectorType& max): _min{min}, _max{max} {} constexpr /*implicit*/ Range(const VectorType& min, const VectorType& max) noexcept: _min{min}, _max{max} {}
/** @brief Copy constructor */
constexpr Range(const Range<dimensions, T>&) = default;
/** /**
* @brief Construct range from another of different type * @brief Construct range from another of different type
@ -97,11 +94,14 @@ template<UnsignedInt dimensions, class T> class Range {
* Range2D<Byte> integral(floatingPoint); // {{1, 2}, {-15, 7}} * Range2D<Byte> integral(floatingPoint); // {{1, 2}, {-15, 7}}
* @endcode * @endcode
*/ */
template<class U> constexpr explicit Range(const Range<dimensions, U>& other): _min(other._min), _max(other._max) {} template<class U> constexpr explicit Range(const Range<dimensions, U>& other) noexcept: _min(other._min), _max(other._max) {}
/** @brief Construct range from external representation */ /** @brief Construct range from external representation */
template<class U, class V = decltype(Implementation::RangeConverter<dimensions, T, U>::from(std::declval<U>()))> constexpr explicit Range(const U& other): Range{Implementation::RangeConverter<dimensions, T, U>::from(other)} {} template<class U, class V = decltype(Implementation::RangeConverter<dimensions, T, U>::from(std::declval<U>()))> constexpr explicit Range(const U& other): Range{Implementation::RangeConverter<dimensions, T, U>::from(other)} {}
/** @brief Copy constructor */
constexpr /*implicit*/ Range(const Range<dimensions, T>&) noexcept = default;
/** @brief Convert range to external representation */ /** @brief Convert range to external representation */
template<class U, class V = decltype(Implementation::RangeConverter<dimensions, T, U>::to(std::declval<Range<dimensions, T>>()))> constexpr explicit operator U() const { template<class U, class V = decltype(Implementation::RangeConverter<dimensions, T, U>::to(std::declval<Range<dimensions, T>>()))> constexpr explicit operator U() const {
return Implementation::RangeConverter<dimensions, T, U>::to(*this); return Implementation::RangeConverter<dimensions, T, U>::to(*this);
@ -230,7 +230,7 @@ See @ref Range for more information.
template<class T> class Range2D: public Range<2, T> { template<class T> class Range2D: public Range<2, T> {
public: public:
/** @copydoc Range(ZeroInitT) */ /** @copydoc Range(ZeroInitT) */
constexpr /*implicit*/ Range2D(ZeroInitT = ZeroInit) constexpr /*implicit*/ Range2D(ZeroInitT = ZeroInit) noexcept
/** @todoc remove workaround when doxygen is sane */ /** @todoc remove workaround when doxygen is sane */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
@ -239,7 +239,7 @@ template<class T> class Range2D: public Range<2, T> {
{} {}
/** @copydoc Range(NoInitT) */ /** @copydoc Range(NoInitT) */
explicit Range2D(NoInitT) explicit Range2D(NoInitT) noexcept
/** @todoc remove workaround when doxygen is sane */ /** @todoc remove workaround when doxygen is sane */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
@ -248,13 +248,10 @@ template<class T> class Range2D: public Range<2, T> {
{} {}
/** @copydoc Range(const VectorType&, const VectorType&) */ /** @copydoc Range(const VectorType&, const VectorType&) */
constexpr /*implicit*/ Range2D(const Vector2<T>& min, const Vector2<T>& max): Range<2, T>(min, max) {} constexpr /*implicit*/ Range2D(const Vector2<T>& min, const Vector2<T>& max) noexcept: Range<2, T>(min, max) {}
/** @copydoc Range(const Range&) */
constexpr /*implicit*/ Range2D(const Range<2, T>& other): Range<2, T>(other) {}
/** @copydoc Range(const Range<dimensions, U>&) */ /** @copydoc Range(const Range<dimensions, U>&) */
template<class U> constexpr explicit Range2D(const Range2D<U>& other): Range<2, T>(other) {} template<class U> constexpr explicit Range2D(const Range2D<U>& other) noexcept: Range<2, T>(other) {}
/** /**
* @brief Construct range from external representation * @brief Construct range from external representation
@ -274,6 +271,9 @@ template<class T> class Range2D: public Range<2, T> {
#endif #endif
{} {}
/** @copydoc Range(const Range&) */
constexpr /*implicit*/ Range2D(const Range<2, T>& other) noexcept: Range<2, T>(other) {}
/** /**
* @brief Bottom left corner * @brief Bottom left corner
* *
@ -364,7 +364,7 @@ See @ref Range for more information.
template<class T> class Range3D: public Range<3, T> { template<class T> class Range3D: public Range<3, T> {
public: public:
/** @copydoc Range(ZeroInitT) */ /** @copydoc Range(ZeroInitT) */
constexpr /*implicit*/ Range3D(ZeroInitT = ZeroInit) constexpr /*implicit*/ Range3D(ZeroInitT = ZeroInit) noexcept
/** @todoc remove workaround when doxygen is sane */ /** @todoc remove workaround when doxygen is sane */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
@ -373,7 +373,7 @@ template<class T> class Range3D: public Range<3, T> {
{} {}
/** @copybrief Range(NoInitT) */ /** @copybrief Range(NoInitT) */
explicit Range3D(NoInitT) explicit Range3D(NoInitT) noexcept
/** @todoc remove workaround when doxygen is sane */ /** @todoc remove workaround when doxygen is sane */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
@ -382,25 +382,25 @@ template<class T> class Range3D: public Range<3, T> {
{} {}
/** @copydoc Range(const VectorType&, const VectorType&) */ /** @copydoc Range(const VectorType&, const VectorType&) */
constexpr /*implicit*/ Range3D(const Vector3<T>& min, const Vector3<T>& max): Range<3, T>(min, max) {} constexpr /*implicit*/ Range3D(const Vector3<T>& min, const Vector3<T>& max) noexcept: Range<3, T>(min, max) {}
/** @copydoc Range(const Range&) */
constexpr /*implicit*/ Range3D(const Range<3, T>& other): Range<3, T>(other) {}
/** @copydoc Range(const Range<dimensions, U>&) */ /** @copydoc Range(const Range<dimensions, U>&) */
template<class U> constexpr explicit Range3D(const Range3D<U>& other): Range<3, T>(other) {} template<class U> constexpr explicit Range3D(const Range3D<U>& other) noexcept: Range<3, T>(other) {}
/** /**
* @brief Construct range from external representation * @brief Construct range from external representation
* @todoc Remove workaround when Doxygen no longer chokes on that line * @todoc Remove workaround when Doxygen no longer chokes on that line
*/ */
template<class U, class V = decltype(Implementation::RangeConverter<3, T, U>::from(std::declval<U>()))> constexpr explicit Range3D(const U& other) template<class U, class V = decltype(Implementation::RangeConverter<3, T, U>::from(std::declval<U>()))> constexpr explicit Range3D(const U& other) noexcept
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
: Range<3, T>(Implementation::RangeConverter<3, T, U>::from(other)) : Range<3, T>(Implementation::RangeConverter<3, T, U>::from(other))
#endif #endif
{} {}
/** @copydoc Range(const Range&) */
constexpr /*implicit*/ Range3D(const Range<3, T>& other) noexcept: Range<3, T>(other) {}
/** /**
* @brief Back bottom left corner * @brief Back bottom left corner
* *

16
src/Magnum/Math/RectangularMatrix.h

@ -103,12 +103,12 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
* *
* @see @ref diagonal() * @see @ref diagonal()
*/ */
constexpr static RectangularMatrix<cols, rows, T> fromDiagonal(const Vector<DiagonalSize, T>& diagonal) { constexpr static RectangularMatrix<cols, rows, T> fromDiagonal(const Vector<DiagonalSize, T>& diagonal) noexcept {
return RectangularMatrix(typename Implementation::GenerateSequence<cols>::Type(), diagonal); return RectangularMatrix(typename Implementation::GenerateSequence<cols>::Type(), diagonal);
} }
/** @brief Construct zero-filled matrix */ /** @brief Construct zero-filled matrix */
constexpr /*implicit*/ RectangularMatrix(ZeroInitT = ZeroInit) constexpr /*implicit*/ RectangularMatrix(ZeroInitT = ZeroInit) noexcept
/** @todoc remove workaround when doxygen is sane */ /** @todoc remove workaround when doxygen is sane */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
@ -117,7 +117,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
{} {}
/** @brief Construct matrix without initializing the contents */ /** @brief Construct matrix without initializing the contents */
explicit RectangularMatrix(NoInitT) explicit RectangularMatrix(NoInitT) noexcept
/** @todoc remove workaround when doxygen is sane */ /** @todoc remove workaround when doxygen is sane */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
@ -132,7 +132,7 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
* *
* @todo Creating matrix from arbitrary combination of matrices with n rows * @todo Creating matrix from arbitrary combination of matrices with n rows
*/ */
template<class ...U> constexpr /*implicit*/ RectangularMatrix(const Vector<rows, T>& first, const U&... next): _data{first, next...} { template<class ...U> constexpr /*implicit*/ RectangularMatrix(const Vector<rows, T>& first, const U&... next) noexcept: _data{first, next...} {
static_assert(sizeof...(next)+1 == cols, "Improper number of arguments passed to RectangularMatrix constructor"); static_assert(sizeof...(next)+1 == cols, "Improper number of arguments passed to RectangularMatrix constructor");
} }
@ -147,13 +147,13 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
* // integral == {1, 2, -15, 7} * // integral == {1, 2, -15, 7}
* @endcode * @endcode
*/ */
template<class U> constexpr explicit RectangularMatrix(const RectangularMatrix<cols, rows, U>& other): RectangularMatrix(typename Implementation::GenerateSequence<cols>::Type(), other) {} template<class U> constexpr explicit RectangularMatrix(const RectangularMatrix<cols, rows, U>& other) noexcept: RectangularMatrix(typename Implementation::GenerateSequence<cols>::Type(), other) {}
/** @brief Construct matrix from external representation */ /** @brief Construct matrix from external representation */
template<class U, class V = decltype(Implementation::RectangularMatrixConverter<cols, rows, T, U>::from(std::declval<U>()))> constexpr explicit RectangularMatrix(const U& other): RectangularMatrix(Implementation::RectangularMatrixConverter<cols, rows, T, U>::from(other)) {} template<class U, class V = decltype(Implementation::RectangularMatrixConverter<cols, rows, T, U>::from(std::declval<U>()))> constexpr explicit RectangularMatrix(const U& other): RectangularMatrix(Implementation::RectangularMatrixConverter<cols, rows, T, U>::from(other)) {}
/** @brief Copy constructor */ /** @brief Copy constructor */
constexpr RectangularMatrix(const RectangularMatrix<cols, rows, T>&) = default; constexpr /*implicit*/ RectangularMatrix(const RectangularMatrix<cols, rows, T>&) noexcept = default;
/** @brief Convert matrix to external representation */ /** @brief Convert matrix to external representation */
template<class U, class V = decltype(Implementation::RectangularMatrixConverter<cols, rows, T, U>::to(std::declval<RectangularMatrix<cols, rows, T>>()))> constexpr explicit operator U() const { template<class U, class V = decltype(Implementation::RectangularMatrixConverter<cols, rows, T, U>::to(std::declval<RectangularMatrix<cols, rows, T>>()))> constexpr explicit operator U() const {
@ -393,11 +393,11 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
private: private:
/* Implementation for RectangularMatrix<cols, rows, T>::RectangularMatrix(const RectangularMatrix<cols, rows, U>&) */ /* 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])...} {} template<class U, std::size_t ...sequence> constexpr explicit RectangularMatrix(Implementation::Sequence<sequence...>, const RectangularMatrix<cols, rows, U>& matrix) noexcept: _data{Vector<rows, T>(matrix[sequence])...} {}
/* Implementation for RectangularMatrix<cols, rows, T>::RectangularMatrix(ZeroInitT) and RectangularMatrix<cols, rows, T>::RectangularMatrix(NoInitT) */ /* Implementation for RectangularMatrix<cols, rows, T>::RectangularMatrix(ZeroInitT) and RectangularMatrix<cols, rows, T>::RectangularMatrix(NoInitT) */
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
template<class U, std::size_t ...sequence> constexpr explicit RectangularMatrix(Implementation::Sequence<sequence...>, U): _data{Vector<rows, T>((static_cast<void>(sequence), U{typename U::Init{}}))...} {} template<class U, std::size_t ...sequence> constexpr explicit RectangularMatrix(Implementation::Sequence<sequence...>, U) noexcept: _data{Vector<rows, T>((static_cast<void>(sequence), U{typename U::Init{}}))...} {}
template<std::size_t ...sequence> constexpr RectangularMatrix<cols, rows, T> flippedColsInternal(Implementation::Sequence<sequence...>) const { template<std::size_t ...sequence> constexpr RectangularMatrix<cols, rows, T> flippedColsInternal(Implementation::Sequence<sequence...>) const {
return {(*this)[sequence]...}; return {(*this)[sequence]...};

19
src/Magnum/Math/Test/AngleTest.cpp

@ -79,6 +79,9 @@ void AngleTest::construct() {
/* Implicit conversion is not allowed */ /* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Float, Rad>::value)); CORRADE_VERIFY(!(std::is_convertible<Float, Rad>::value));
CORRADE_VERIFY(!(std::is_convertible<Double, Degd>::value)); CORRADE_VERIFY(!(std::is_convertible<Double, Degd>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Deg, Float>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Rad, Float>::value));
} }
void AngleTest::constructDefault() { void AngleTest::constructDefault() {
@ -90,6 +93,11 @@ void AngleTest::constructDefault() {
constexpr Radd a2{ZeroInit}; constexpr Radd a2{ZeroInit};
CORRADE_COMPARE(Double(a1), 0.0); CORRADE_COMPARE(Double(a1), 0.0);
CORRADE_COMPARE(Double(a2), 0.0); CORRADE_COMPARE(Double(a2), 0.0);
CORRADE_VERIFY(std::is_nothrow_default_constructible<Deg>::value);
CORRADE_VERIFY(std::is_nothrow_default_constructible<Rad>::value);
CORRADE_VERIFY((std::is_nothrow_constructible<Deg, ZeroInitT>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Rad, ZeroInitT>::value));
} }
void AngleTest::constructNoInit() { void AngleTest::constructNoInit() {
@ -99,6 +107,9 @@ void AngleTest::constructNoInit() {
new(&b) Rad{NoInit}; new(&b) Rad{NoInit};
CORRADE_COMPARE(Float(a), 25.0f); CORRADE_COMPARE(Float(a), 25.0f);
CORRADE_COMPARE(Float(b), 3.14f); CORRADE_COMPARE(Float(b), 3.14f);
CORRADE_VERIFY((std::is_nothrow_constructible<Deg, NoInitT>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Rad, NoInitT>::value));
} }
void AngleTest::constructConversion() { void AngleTest::constructConversion() {
@ -113,6 +124,9 @@ void AngleTest::constructConversion() {
/* Implicit conversion is not allowed */ /* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Degd, Deg>::value)); CORRADE_VERIFY(!(std::is_convertible<Degd, Deg>::value));
CORRADE_VERIFY(!(std::is_convertible<Rad, Radd>::value)); CORRADE_VERIFY(!(std::is_convertible<Rad, Radd>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Deg, Degd>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Radd, Rad>::value));
} }
void AngleTest::constructCopy() { void AngleTest::constructCopy() {
@ -123,6 +137,11 @@ void AngleTest::constructCopy() {
CORRADE_COMPARE(c, a); CORRADE_COMPARE(c, a);
constexpr Radd d(b); constexpr Radd d(b);
CORRADE_COMPARE(d, b); CORRADE_COMPARE(d, b);
CORRADE_VERIFY(std::is_nothrow_copy_constructible<Deg>::value);
CORRADE_VERIFY(std::is_nothrow_copy_constructible<Rad>::value);
CORRADE_VERIFY(std::is_nothrow_copy_assignable<Deg>::value);
CORRADE_VERIFY(std::is_nothrow_copy_assignable<Rad>::value);
} }
void AngleTest::literals() { void AngleTest::literals() {

14
src/Magnum/Math/Test/BoolVectorTest.cpp

@ -83,6 +83,8 @@ BoolVectorTest::BoolVectorTest() {
void BoolVectorTest::construct() { void BoolVectorTest::construct() {
constexpr BoolVector19 a = {0xa5, 0x5f, 0x07}; constexpr BoolVector19 a = {0xa5, 0x5f, 0x07};
CORRADE_COMPARE(a, BoolVector19(0xa5, 0x5f, 0x07)); CORRADE_COMPARE(a, BoolVector19(0xa5, 0x5f, 0x07));
CORRADE_VERIFY((std::is_nothrow_constructible<BoolVector19, UnsignedByte, UnsignedByte, UnsignedByte>::value));
} }
void BoolVectorTest::constructDefault() { void BoolVectorTest::constructDefault() {
@ -90,12 +92,17 @@ void BoolVectorTest::constructDefault() {
constexpr BoolVector19 b{ZeroInit}; constexpr BoolVector19 b{ZeroInit};
CORRADE_COMPARE(a, BoolVector19(0x00, 0x00, 0x00)); CORRADE_COMPARE(a, BoolVector19(0x00, 0x00, 0x00));
CORRADE_COMPARE(b, BoolVector19(0x00, 0x00, 0x00)); CORRADE_COMPARE(b, BoolVector19(0x00, 0x00, 0x00));
CORRADE_VERIFY(std::is_nothrow_default_constructible<BoolVector19>::value);
CORRADE_VERIFY((std::is_nothrow_constructible<BoolVector19, ZeroInitT>::value));
} }
void BoolVectorTest::constructNoInit() { void BoolVectorTest::constructNoInit() {
BoolVector19 a{0xa5, 0x5f, 0x07}; BoolVector19 a{0xa5, 0x5f, 0x07};
new(&a) BoolVector19{NoInit}; new(&a) BoolVector19{NoInit};
CORRADE_COMPARE(a, BoolVector19(0xa5, 0x5f, 0x07)); CORRADE_COMPARE(a, BoolVector19(0xa5, 0x5f, 0x07));
CORRADE_VERIFY((std::is_nothrow_constructible<BoolVector19, NoInitT>::value));
} }
void BoolVectorTest::constructOneValue() { void BoolVectorTest::constructOneValue() {
@ -106,6 +113,8 @@ void BoolVectorTest::constructOneValue() {
CORRADE_COMPARE(b, BoolVector19(0xff, 0xff, 0x07)); CORRADE_COMPARE(b, BoolVector19(0xff, 0xff, 0x07));
CORRADE_VERIFY(!(std::is_convertible<bool, BoolVector19>::value)); CORRADE_VERIFY(!(std::is_convertible<bool, BoolVector19>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<BoolVector19, bool>::value));
} }
void BoolVectorTest::constructOneElement() { void BoolVectorTest::constructOneElement() {
@ -113,12 +122,17 @@ void BoolVectorTest::constructOneElement() {
constexpr BoolVector1 a = 0x01; constexpr BoolVector1 a = 0x01;
CORRADE_COMPARE(a, BoolVector1(0x01)); CORRADE_COMPARE(a, BoolVector1(0x01));
CORRADE_VERIFY((std::is_nothrow_constructible<BoolVector1, UnsignedByte>::value));
} }
void BoolVectorTest::constructCopy() { void BoolVectorTest::constructCopy() {
constexpr BoolVector19 a = {0xa5, 0x5f, 0x07}; constexpr BoolVector19 a = {0xa5, 0x5f, 0x07};
constexpr BoolVector19 b(a); constexpr BoolVector19 b(a);
CORRADE_COMPARE(b, BoolVector19(0xa5, 0x5f, 0x07)); CORRADE_COMPARE(b, BoolVector19(0xa5, 0x5f, 0x07));
CORRADE_VERIFY(std::is_nothrow_copy_constructible<BoolVector19>::value);
CORRADE_VERIFY(std::is_nothrow_copy_assignable<BoolVector19>::value);
} }
void BoolVectorTest::data() { void BoolVectorTest::data() {

24
src/Magnum/Math/Test/ColorTest.cpp

@ -119,6 +119,9 @@ void ColorTest::construct() {
constexpr Color4ub d = {10, 25, 176}; constexpr Color4ub d = {10, 25, 176};
CORRADE_COMPARE(c, Vector4(1.0f, 0.5f, 0.75f, 1.0f)); CORRADE_COMPARE(c, Vector4(1.0f, 0.5f, 0.75f, 1.0f));
CORRADE_COMPARE(d, Math::Vector4<UnsignedByte>(10, 25, 176, 255)); CORRADE_COMPARE(d, Math::Vector4<UnsignedByte>(10, 25, 176, 255));
CORRADE_VERIFY((std::is_nothrow_constructible<Color3, Float, Float, Float>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Color4, Float, Float, Float, Float>::value));
} }
void ColorTest::constructDefault() { void ColorTest::constructDefault() {
@ -134,6 +137,11 @@ void ColorTest::constructDefault() {
constexpr Color4ub c; constexpr Color4ub c;
CORRADE_COMPARE(c, Color4ub(0, 0, 0, 0)); CORRADE_COMPARE(c, Color4ub(0, 0, 0, 0));
CORRADE_VERIFY(std::is_nothrow_default_constructible<Color3>::value);
CORRADE_VERIFY(std::is_nothrow_default_constructible<Color4>::value);
CORRADE_VERIFY((std::is_nothrow_constructible<Color3, ZeroInitT>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Color4, ZeroInitT>::value));
} }
void ColorTest::constructNoInit() { void ColorTest::constructNoInit() {
@ -143,6 +151,9 @@ void ColorTest::constructNoInit() {
new(&b) Color4{Math::NoInit}; new(&b) Color4{Math::NoInit};
CORRADE_COMPARE(a, (Color3{1.0f, 0.5f, 0.75f})); CORRADE_COMPARE(a, (Color3{1.0f, 0.5f, 0.75f}));
CORRADE_COMPARE(b, (Color4{1.0f, 0.5f, 0.75f, 0.5f})); CORRADE_COMPARE(b, (Color4{1.0f, 0.5f, 0.75f, 0.5f}));
CORRADE_VERIFY((std::is_nothrow_constructible<Color3, NoInitT>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Color4, NoInitT>::value));
} }
void ColorTest::constructOneValue() { void ColorTest::constructOneValue() {
@ -161,6 +172,9 @@ void ColorTest::constructOneValue() {
/* Implicit conversion is not allowed */ /* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Float, Color3>::value)); CORRADE_VERIFY(!(std::is_convertible<Float, Color3>::value));
CORRADE_VERIFY(!(std::is_convertible<Float, Color4>::value)); CORRADE_VERIFY(!(std::is_convertible<Float, Color4>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Color3, Float>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Color4, Float, Float>::value));
} }
void ColorTest::constructParts() { void ColorTest::constructParts() {
@ -175,6 +189,8 @@ void ColorTest::constructParts() {
constexpr Color4ub e = c; constexpr Color4ub e = c;
CORRADE_COMPARE(d, Color4(1.0f, 0.5f, 0.75f, 1.0f)); CORRADE_COMPARE(d, Color4(1.0f, 0.5f, 0.75f, 1.0f));
CORRADE_COMPARE(e, Color4ub(10, 25, 176, 255)); CORRADE_COMPARE(e, Color4ub(10, 25, 176, 255));
CORRADE_VERIFY((std::is_nothrow_constructible<Color4, Color3, Float>::value));
} }
void ColorTest::constructConversion() { void ColorTest::constructConversion() {
@ -189,6 +205,9 @@ void ColorTest::constructConversion() {
/* Implicit conversion is not allowed */ /* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Color3, Color3ub>::value)); CORRADE_VERIFY(!(std::is_convertible<Color3, Color3ub>::value));
CORRADE_VERIFY(!(std::is_convertible<Color4, Color4ub>::value)); CORRADE_VERIFY(!(std::is_convertible<Color4, Color4ub>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Color3ub, Color3>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Color4, Color4ub>::value));
} }
void ColorTest::constructNormalization() { void ColorTest::constructNormalization() {
@ -215,6 +234,11 @@ void ColorTest::constructCopy() {
#endif #endif
Color4 d(c); Color4 d(c);
CORRADE_COMPARE(d, Color4(1.0f, 0.5f, 0.75f, 0.25f)); CORRADE_COMPARE(d, Color4(1.0f, 0.5f, 0.75f, 0.25f));
CORRADE_VERIFY(std::is_nothrow_copy_constructible<Color3>::value);
CORRADE_VERIFY(std::is_nothrow_copy_constructible<Color4>::value);
CORRADE_VERIFY(std::is_nothrow_copy_assignable<Color3>::value);
CORRADE_VERIFY(std::is_nothrow_copy_assignable<Color4>::value);
} }
void ColorTest::literals() { void ColorTest::literals() {

16
src/Magnum/Math/Test/ComplexTest.cpp

@ -141,6 +141,8 @@ void ComplexTest::construct() {
constexpr Float c = a.imaginary(); constexpr Float c = a.imaginary();
CORRADE_COMPARE(b, 0.5f); CORRADE_COMPARE(b, 0.5f);
CORRADE_COMPARE(c, -3.7f); CORRADE_COMPARE(c, -3.7f);
CORRADE_VERIFY((std::is_nothrow_constructible<Complex, Float, Float>::value));
} }
void ComplexTest::constructIdentity() { void ComplexTest::constructIdentity() {
@ -150,17 +152,24 @@ void ComplexTest::constructIdentity() {
CORRADE_COMPARE(b, Complex(1.0f, 0.0f)); CORRADE_COMPARE(b, Complex(1.0f, 0.0f));
CORRADE_COMPARE(a.length(), 1.0f); CORRADE_COMPARE(a.length(), 1.0f);
CORRADE_COMPARE(b.length(), 1.0f); CORRADE_COMPARE(b.length(), 1.0f);
CORRADE_VERIFY(std::is_nothrow_default_constructible<Complex>::value);
CORRADE_VERIFY((std::is_nothrow_constructible<Complex, IdentityInitT>::value));
} }
void ComplexTest::constructZero() { void ComplexTest::constructZero() {
constexpr Complex a{ZeroInit}; constexpr Complex a{ZeroInit};
CORRADE_COMPARE(a, Complex(0.0f, 0.0f)); CORRADE_COMPARE(a, Complex(0.0f, 0.0f));
CORRADE_VERIFY((std::is_nothrow_constructible<Complex, ZeroInitT>::value));
} }
void ComplexTest::constructNoInit() { void ComplexTest::constructNoInit() {
Complex a{0.5f, -3.7f}; Complex a{0.5f, -3.7f};
new(&a) Complex{NoInit}; new(&a) Complex{NoInit};
CORRADE_COMPARE(a, Complex(0.5f, -3.7f)); CORRADE_COMPARE(a, Complex(0.5f, -3.7f));
CORRADE_VERIFY((std::is_nothrow_constructible<Complex, NoInitT>::value));
} }
void ComplexTest::constructFromVector() { void ComplexTest::constructFromVector() {
@ -175,6 +184,8 @@ void ComplexTest::constructFromVector() {
/* Implicit conversion is not allowed */ /* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Vector2, Complex>::value)); CORRADE_VERIFY(!(std::is_convertible<Vector2, Complex>::value));
CORRADE_VERIFY(!(std::is_convertible<Complex, Vector2>::value)); CORRADE_VERIFY(!(std::is_convertible<Complex, Vector2>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Complex, Vector2>::value));
} }
void ComplexTest::constructConversion() { void ComplexTest::constructConversion() {
@ -187,12 +198,17 @@ void ComplexTest::constructConversion() {
/* Implicit conversion is not allowed */ /* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Complex, Complexi>::value)); CORRADE_VERIFY(!(std::is_convertible<Complex, Complexi>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Complex, Complexi>::value));
} }
void ComplexTest::constructCopy() { void ComplexTest::constructCopy() {
constexpr Complex a(2.5f, -5.0f); constexpr Complex a(2.5f, -5.0f);
constexpr Complex b(a); constexpr Complex b(a);
CORRADE_COMPARE(b, Complex(2.5f, -5.0f)); CORRADE_COMPARE(b, Complex(2.5f, -5.0f));
CORRADE_VERIFY(std::is_nothrow_copy_constructible<Complex>::value);
CORRADE_VERIFY(std::is_nothrow_copy_assignable<Complex>::value);
} }
void ComplexTest::convert() { void ComplexTest::convert() {

16
src/Magnum/Math/Test/DualComplexTest.cpp

@ -141,6 +141,8 @@ void DualComplexTest::construct() {
constexpr DualComplex d(Complex(-1.0f, 2.5f)); constexpr DualComplex d(Complex(-1.0f, 2.5f));
CORRADE_COMPARE(d, DualComplex({-1.0f, 2.5f}, {0.0f, 0.0f})); CORRADE_COMPARE(d, DualComplex({-1.0f, 2.5f}, {0.0f, 0.0f}));
CORRADE_VERIFY((std::is_nothrow_constructible<DualComplex, Complex, Complex>::value));
} }
void DualComplexTest::constructIdentity() { void DualComplexTest::constructIdentity() {
@ -150,17 +152,24 @@ void DualComplexTest::constructIdentity() {
CORRADE_COMPARE(b, DualComplex({1.0f, 0.0f}, {0.0f, 0.0f})); CORRADE_COMPARE(b, DualComplex({1.0f, 0.0f}, {0.0f, 0.0f}));
CORRADE_COMPARE(a.length(), 1.0f); CORRADE_COMPARE(a.length(), 1.0f);
CORRADE_COMPARE(b.length(), 1.0f); CORRADE_COMPARE(b.length(), 1.0f);
CORRADE_VERIFY(std::is_nothrow_default_constructible<DualComplex>::value);
CORRADE_VERIFY((std::is_nothrow_constructible<DualComplex, IdentityInitT>::value));
} }
void DualComplexTest::constructZero() { void DualComplexTest::constructZero() {
constexpr DualComplex a{ZeroInit}; constexpr DualComplex a{ZeroInit};
CORRADE_COMPARE(a, DualComplex({0.0f, 0.0f}, {0.0f, 0.0f})); CORRADE_COMPARE(a, DualComplex({0.0f, 0.0f}, {0.0f, 0.0f}));
CORRADE_VERIFY((std::is_nothrow_constructible<DualComplex, ZeroInitT>::value));
} }
void DualComplexTest::constructNoInit() { void DualComplexTest::constructNoInit() {
DualComplex a{{-1.0f, 2.5f}, {3.0f, -7.5f}}; DualComplex a{{-1.0f, 2.5f}, {3.0f, -7.5f}};
new(&a) DualComplex{NoInit}; new(&a) DualComplex{NoInit};
CORRADE_COMPARE(a, DualComplex({-1.0f, 2.5f}, {3.0f, -7.5f})); CORRADE_COMPARE(a, DualComplex({-1.0f, 2.5f}, {3.0f, -7.5f}));
CORRADE_VERIFY((std::is_nothrow_constructible<DualComplex, NoInitT>::value));
} }
void DualComplexTest::constructFromVector() { void DualComplexTest::constructFromVector() {
@ -169,6 +178,8 @@ void DualComplexTest::constructFromVector() {
/* Implicit conversion is not allowed */ /* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Vector2, DualComplex>::value)); CORRADE_VERIFY(!(std::is_convertible<Vector2, DualComplex>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<DualComplex, Vector2>::value));
} }
void DualComplexTest::constructConversion() { void DualComplexTest::constructConversion() {
@ -181,6 +192,8 @@ void DualComplexTest::constructConversion() {
/* Implicit conversion is not allowed */ /* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<DualComplex, DualComplexi>::value)); CORRADE_VERIFY(!(std::is_convertible<DualComplex, DualComplexi>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<DualComplex, DualComplexi>::value));
} }
void DualComplexTest::constructCopy() { void DualComplexTest::constructCopy() {
@ -190,6 +203,9 @@ void DualComplexTest::constructCopy() {
#endif #endif
DualComplex b(a); DualComplex b(a);
CORRADE_COMPARE(b, DualComplex({-1.0f, 2.5f}, {3.0f, -7.5f})); CORRADE_COMPARE(b, DualComplex({-1.0f, 2.5f}, {3.0f, -7.5f}));
CORRADE_VERIFY(std::is_nothrow_copy_constructible<DualComplex>::value);
CORRADE_VERIFY(std::is_nothrow_copy_assignable<DualComplex>::value);
} }
void DualComplexTest::convert() { void DualComplexTest::convert() {

18
src/Magnum/Math/Test/DualQuaternionTest.cpp

@ -150,6 +150,8 @@ void DualQuaternionTest::construct() {
constexpr DualQuaternion d({{1.0f, 2.0f, 3.0f}, -4.0f}); constexpr DualQuaternion d({{1.0f, 2.0f, 3.0f}, -4.0f});
CORRADE_COMPARE(d, DualQuaternion({{1.0f, 2.0f, 3.0f}, -4.0f}, {{0.0f, 0.0f, 0.0f}, 0.0f})); CORRADE_COMPARE(d, DualQuaternion({{1.0f, 2.0f, 3.0f}, -4.0f}, {{0.0f, 0.0f, 0.0f}, 0.0f}));
CORRADE_VERIFY((std::is_nothrow_constructible<DualQuaternion, Quaternion, Quaternion>::value));
} }
void DualQuaternionTest::constructVectorScalar() { void DualQuaternionTest::constructVectorScalar() {
@ -161,6 +163,8 @@ void DualQuaternionTest::constructVectorScalar() {
constexpr Quaternion c = a.dual(); constexpr Quaternion c = a.dual();
CORRADE_COMPARE(c, Quaternion({0.5f, -3.1f, 3.3f}, 2.0f)); CORRADE_COMPARE(c, Quaternion({0.5f, -3.1f, 3.3f}, 2.0f));
CORRADE_VERIFY((std::is_nothrow_constructible<DualQuaternion, Math::Dual<Vector3>, Math::Dual<Float>>::value));
} }
void DualQuaternionTest::constructIdentity() { void DualQuaternionTest::constructIdentity() {
@ -170,17 +174,24 @@ void DualQuaternionTest::constructIdentity() {
CORRADE_COMPARE(b, DualQuaternion({{0.0f, 0.0f, 0.0f}, 1.0f}, {{0.0f, 0.0f, 0.0f}, 0.0f})); CORRADE_COMPARE(b, DualQuaternion({{0.0f, 0.0f, 0.0f}, 1.0f}, {{0.0f, 0.0f, 0.0f}, 0.0f}));
CORRADE_COMPARE(a.length(), 1.0f); CORRADE_COMPARE(a.length(), 1.0f);
CORRADE_COMPARE(b.length(), 1.0f); CORRADE_COMPARE(b.length(), 1.0f);
CORRADE_VERIFY(std::is_nothrow_default_constructible<DualQuaternion>::value);
CORRADE_VERIFY((std::is_nothrow_constructible<DualQuaternion, IdentityInitT>::value));
} }
void DualQuaternionTest::constructZero() { void DualQuaternionTest::constructZero() {
constexpr DualQuaternion a{ZeroInit}; constexpr DualQuaternion a{ZeroInit};
CORRADE_COMPARE(a, DualQuaternion({{0.0f, 0.0f, 0.0f}, 0.0f}, {{0.0f, 0.0f, 0.0f}, 0.0f})); CORRADE_COMPARE(a, DualQuaternion({{0.0f, 0.0f, 0.0f}, 0.0f}, {{0.0f, 0.0f, 0.0f}, 0.0f}));
CORRADE_VERIFY((std::is_nothrow_constructible<DualQuaternion, ZeroInitT>::value));
} }
void DualQuaternionTest::constructNoInit() { void DualQuaternionTest::constructNoInit() {
DualQuaternion a{{{1.0f, 2.0f, 3.0f}, -4.0f}, {{0.5f, -3.1f, 3.3f}, 2.0f}}; DualQuaternion a{{{1.0f, 2.0f, 3.0f}, -4.0f}, {{0.5f, -3.1f, 3.3f}, 2.0f}};
new(&a) DualQuaternion{NoInit}; new(&a) DualQuaternion{NoInit};
CORRADE_COMPARE(a, DualQuaternion({{1.0f, 2.0f, 3.0f}, -4.0f}, {{0.5f, -3.1f, 3.3f}, 2.0f})); CORRADE_COMPARE(a, DualQuaternion({{1.0f, 2.0f, 3.0f}, -4.0f}, {{0.5f, -3.1f, 3.3f}, 2.0f}));
CORRADE_VERIFY((std::is_nothrow_constructible<DualQuaternion, NoInitT>::value));
} }
void DualQuaternionTest::constructFromVector() { void DualQuaternionTest::constructFromVector() {
@ -189,6 +200,8 @@ void DualQuaternionTest::constructFromVector() {
/* Implicit conversion is not allowed */ /* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Vector3, DualQuaternion>::value)); CORRADE_VERIFY(!(std::is_convertible<Vector3, DualQuaternion>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<DualQuaternion, Vector3>::value));
} }
void DualQuaternionTest::constructConversion() { void DualQuaternionTest::constructConversion() {
@ -201,6 +214,8 @@ void DualQuaternionTest::constructConversion() {
/* Implicit conversion is not allowed */ /* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<DualQuaternion, DualQuaternioni>::value)); CORRADE_VERIFY(!(std::is_convertible<DualQuaternion, DualQuaternioni>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<DualQuaternion, DualQuaternioni>::value));
} }
void DualQuaternionTest::constructCopy() { void DualQuaternionTest::constructCopy() {
@ -210,6 +225,9 @@ void DualQuaternionTest::constructCopy() {
#endif #endif
DualQuaternion b(a); DualQuaternion b(a);
CORRADE_COMPARE(b, DualQuaternion({{1.0f, 2.0f, -3.0f}, -3.5f}, {{4.5f, -7.0f, 2.0f}, 1.0f})); CORRADE_COMPARE(b, DualQuaternion({{1.0f, 2.0f, -3.0f}, -3.5f}, {{4.5f, -7.0f, 2.0f}, 1.0f}));
CORRADE_VERIFY(std::is_nothrow_copy_constructible<DualQuaternion>::value);
CORRADE_VERIFY(std::is_nothrow_copy_assignable<DualQuaternion>::value);
} }
void DualQuaternionTest::convert() { void DualQuaternionTest::convert() {

18
src/Magnum/Math/Test/DualTest.cpp

@ -27,6 +27,7 @@
#include <Corrade/TestSuite/Tester.h> #include <Corrade/TestSuite/Tester.h>
#include "Magnum/Math/Dual.h" #include "Magnum/Math/Dual.h"
#include "Magnum/Math/Quaternion.h"
#include "Magnum/Math/Vector2.h" #include "Magnum/Math/Vector2.h"
namespace Magnum { namespace Math { namespace Test { namespace Magnum { namespace Math { namespace Test {
@ -106,17 +107,29 @@ void DualTest::construct() {
constexpr Dual d(3.0f); constexpr Dual d(3.0f);
CORRADE_COMPARE(d.real(), 3.0f); CORRADE_COMPARE(d.real(), 3.0f);
CORRADE_COMPARE(d.dual(), 0.0f); CORRADE_COMPARE(d.dual(), 0.0f);
CORRADE_VERIFY((std::is_nothrow_constructible<Dual, Float, Float>::value));
} }
void DualTest::constructDefault() { void DualTest::constructDefault() {
constexpr Dual a; constexpr Dual a;
constexpr Math::Dual<Math::Quaternion<Float>> b;
CORRADE_COMPARE(a, Dual(0.0f, 0.0f)); CORRADE_COMPARE(a, Dual(0.0f, 0.0f));
CORRADE_COMPARE(b, Math::Dual<Math::Quaternion<Float>>({{0.0f, 0.0f, 0.0f}, 1.0f}, {{0.0f, 0.0f, 0.0f}, 1.0f}));
CORRADE_VERIFY(std::is_nothrow_default_constructible<Dual>::value);
} }
void DualTest::constructNoInit() { void DualTest::constructNoInit() {
Dual a{2.0f, -7.5f}; Dual a{2.0f, -7.5f};
Math::Dual<Math::Quaternion<Float>> b{{{3.0f, 0.1f, 1.0f}, 1.0f}, {{0.1f, 0.0f, 1.0f}, 0.3f}};
new(&a) Dual{NoInit}; new(&a) Dual{NoInit};
new(&b) Math::Dual<Math::Quaternion<Float>>{NoInit};
CORRADE_COMPARE(a, Dual(2.0f, -7.5f)); CORRADE_COMPARE(a, Dual(2.0f, -7.5f));
CORRADE_COMPARE(b, (Math::Dual<Math::Quaternion<Float>>{{{3.0f, 0.1f, 1.0f}, 1.0f}, {{0.1f, 0.0f, 1.0f}, 0.3f}}));
CORRADE_VERIFY((std::is_nothrow_constructible<Dual, NoInitT>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Math::Dual<Math::Quaternion<Float>>, NoInitT>::value));
} }
void DualTest::constructConversion() { void DualTest::constructConversion() {
@ -129,12 +142,17 @@ void DualTest::constructConversion() {
/* Implicit conversion is not allowed */ /* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Dual, Duali>::value)); CORRADE_VERIFY(!(std::is_convertible<Dual, Duali>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Dual, Duali>::value));
} }
void DualTest::constructCopy() { void DualTest::constructCopy() {
constexpr Dual a(2.0f, 3.0f); constexpr Dual a(2.0f, 3.0f);
constexpr Dual b(a); constexpr Dual b(a);
CORRADE_COMPARE(b, Dual(2.0f, 3.0f)); CORRADE_COMPARE(b, Dual(2.0f, 3.0f));
CORRADE_VERIFY(std::is_nothrow_copy_constructible<Dual>::value);
CORRADE_VERIFY(std::is_nothrow_copy_assignable<Dual>::value);
} }
void DualTest::compare() { void DualTest::compare() {

14
src/Magnum/Math/Test/Matrix3Test.cpp

@ -136,6 +136,8 @@ void Matrix3Test::construct() {
CORRADE_COMPARE(a, Matrix3({3.0f, 5.0f, 8.0f}, CORRADE_COMPARE(a, Matrix3({3.0f, 5.0f, 8.0f},
{4.5f, 4.0f, 7.0f}, {4.5f, 4.0f, 7.0f},
{7.9f, -1.0f, 8.0f})); {7.9f, -1.0f, 8.0f}));
CORRADE_VERIFY((std::is_nothrow_constructible<Matrix3, Vector3, Vector3, Vector3>::value));
} }
void Matrix3Test::constructIdentity() { void Matrix3Test::constructIdentity() {
@ -154,6 +156,9 @@ void Matrix3Test::constructIdentity() {
CORRADE_COMPARE(identity, identityExpected); CORRADE_COMPARE(identity, identityExpected);
CORRADE_COMPARE(identity2, identityExpected); CORRADE_COMPARE(identity2, identityExpected);
CORRADE_COMPARE(identity3, identity3Expected); CORRADE_COMPARE(identity3, identity3Expected);
CORRADE_VERIFY(std::is_nothrow_default_constructible<Matrix3>::value);
CORRADE_VERIFY((std::is_nothrow_constructible<Matrix3, IdentityInitT>::value));
} }
void Matrix3Test::constructZero() { void Matrix3Test::constructZero() {
@ -161,6 +166,8 @@ void Matrix3Test::constructZero() {
CORRADE_COMPARE(a, Matrix3({0.0f, 0.0f, 0.0f}, CORRADE_COMPARE(a, Matrix3({0.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 0.0f})); {0.0f, 0.0f, 0.0f}));
CORRADE_VERIFY((std::is_nothrow_constructible<Matrix3, ZeroInitT>::value));
} }
void Matrix3Test::constructNoInit() { void Matrix3Test::constructNoInit() {
@ -171,6 +178,8 @@ void Matrix3Test::constructNoInit() {
CORRADE_COMPARE(a, Matrix3({3.0f, 5.0f, 8.0f}, CORRADE_COMPARE(a, Matrix3({3.0f, 5.0f, 8.0f},
{4.5f, 4.0f, 7.0f}, {4.5f, 4.0f, 7.0f},
{7.9f, -1.0f, 8.0f})); {7.9f, -1.0f, 8.0f}));
CORRADE_VERIFY((std::is_nothrow_constructible<Matrix3, NoInitT>::value));
} }
void Matrix3Test::constructConversion() { void Matrix3Test::constructConversion() {
@ -184,6 +193,8 @@ void Matrix3Test::constructConversion() {
/* Implicit conversion is not allowed */ /* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Matrix3, Matrix3i>::value)); CORRADE_VERIFY(!(std::is_convertible<Matrix3, Matrix3i>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Matrix3, Matrix3i>::value));
} }
void Matrix3Test::constructCopy() { void Matrix3Test::constructCopy() {
@ -197,6 +208,9 @@ void Matrix3Test::constructCopy() {
CORRADE_COMPARE(b, Matrix3({3.0f, 5.0f, 8.0f}, CORRADE_COMPARE(b, Matrix3({3.0f, 5.0f, 8.0f},
{4.5f, 4.0f, 7.0f}, {4.5f, 4.0f, 7.0f},
{7.9f, -1.0f, 8.0f})); {7.9f, -1.0f, 8.0f}));
CORRADE_VERIFY(std::is_nothrow_copy_constructible<Matrix3>::value);
CORRADE_VERIFY(std::is_nothrow_copy_assignable<Matrix3>::value);
} }
void Matrix3Test::convert() { void Matrix3Test::convert() {

15
src/Magnum/Math/Test/Matrix4Test.cpp

@ -107,6 +107,7 @@ typedef Math::Matrix4<Float> Matrix4;
typedef Math::Matrix4<Int> Matrix4i; typedef Math::Matrix4<Int> Matrix4i;
typedef Math::Matrix<3, Float> Matrix3x3; typedef Math::Matrix<3, Float> Matrix3x3;
typedef Math::Vector3<Float> Vector3; typedef Math::Vector3<Float> Vector3;
typedef Math::Vector4<Float> Vector4;
typedef Math::Constants<Float> Constants; typedef Math::Constants<Float> Constants;
Matrix4Test::Matrix4Test() { Matrix4Test::Matrix4Test() {
@ -159,6 +160,8 @@ void Matrix4Test::construct() {
{4.5f, 4.0f, 7.0f, 2.0f}, {4.5f, 4.0f, 7.0f, 2.0f},
{1.0f, 2.0f, 3.0f, -1.0f}, {1.0f, 2.0f, 3.0f, -1.0f},
{7.9f, -1.0f, 8.0f, -1.5f})); {7.9f, -1.0f, 8.0f, -1.5f}));
CORRADE_VERIFY((std::is_nothrow_constructible<Matrix4, Vector4, Vector4, Vector4, Vector4>::value));
} }
void Matrix4Test::constructIdentity() { void Matrix4Test::constructIdentity() {
@ -179,6 +182,9 @@ void Matrix4Test::constructIdentity() {
CORRADE_COMPARE(identity, identityExpected); CORRADE_COMPARE(identity, identityExpected);
CORRADE_COMPARE(identity2, identityExpected); CORRADE_COMPARE(identity2, identityExpected);
CORRADE_COMPARE(identity3, identity3Expected); CORRADE_COMPARE(identity3, identity3Expected);
CORRADE_VERIFY(std::is_nothrow_default_constructible<Matrix4>::value);
CORRADE_VERIFY((std::is_nothrow_constructible<Matrix4, IdentityInitT>::value));
} }
void Matrix4Test::constructZero() { void Matrix4Test::constructZero() {
@ -187,6 +193,8 @@ void Matrix4Test::constructZero() {
{0.0f, 0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 0.0f, 0.0f})); {0.0f, 0.0f, 0.0f, 0.0f}));
CORRADE_VERIFY((std::is_nothrow_constructible<Matrix4, ZeroInitT>::value));
} }
void Matrix4Test::constructNoInit() { void Matrix4Test::constructNoInit() {
@ -199,6 +207,8 @@ void Matrix4Test::constructNoInit() {
{4.5f, 4.0f, 7.0f, 2.0f}, {4.5f, 4.0f, 7.0f, 2.0f},
{1.0f, 2.0f, 3.0f, -1.0f}, {1.0f, 2.0f, 3.0f, -1.0f},
{7.9f, -1.0f, 8.0f, -1.5f})); {7.9f, -1.0f, 8.0f, -1.5f}));
CORRADE_VERIFY((std::is_nothrow_constructible<Matrix4, NoInitT>::value));
} }
void Matrix4Test::constructConversion() { void Matrix4Test::constructConversion() {
@ -214,6 +224,8 @@ void Matrix4Test::constructConversion() {
/* Implicit conversion is not allowed */ /* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Matrix4, Matrix4i>::value)); CORRADE_VERIFY(!(std::is_convertible<Matrix4, Matrix4i>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Matrix4, Matrix4i>::value));
} }
void Matrix4Test::constructCopy() { void Matrix4Test::constructCopy() {
@ -229,6 +241,9 @@ void Matrix4Test::constructCopy() {
{4.5f, 4.0f, 7.0f, 2.0f}, {4.5f, 4.0f, 7.0f, 2.0f},
{1.0f, 2.0f, 3.0f, -1.0f}, {1.0f, 2.0f, 3.0f, -1.0f},
{7.9f, -1.0f, 8.0f, -1.5f})); {7.9f, -1.0f, 8.0f, -1.5f}));
CORRADE_VERIFY(std::is_nothrow_copy_constructible<Matrix4>::value);
CORRADE_VERIFY(std::is_nothrow_copy_assignable<Matrix4>::value);
} }
void Matrix4Test::convert() { void Matrix4Test::convert() {

14
src/Magnum/Math/Test/MatrixTest.cpp

@ -123,6 +123,8 @@ void MatrixTest::construct() {
Vector4(4.5f, 4.0f, 7.0f, 2.0f), Vector4(4.5f, 4.0f, 7.0f, 2.0f),
Vector4(1.0f, 2.0f, 3.0f, -1.0f), Vector4(1.0f, 2.0f, 3.0f, -1.0f),
Vector4(7.9f, -1.0f, 8.0f, -1.5f))); Vector4(7.9f, -1.0f, 8.0f, -1.5f)));
CORRADE_VERIFY((std::is_nothrow_constructible<Matrix4x4, Vector4, Vector4, Vector4, Vector4>::value));
} }
void MatrixTest::constructIdentity() { void MatrixTest::constructIdentity() {
@ -143,6 +145,9 @@ void MatrixTest::constructIdentity() {
CORRADE_COMPARE(identity, identityExpected); CORRADE_COMPARE(identity, identityExpected);
CORRADE_COMPARE(identity2, identityExpected); CORRADE_COMPARE(identity2, identityExpected);
CORRADE_COMPARE(identity3, identity3Expected); CORRADE_COMPARE(identity3, identity3Expected);
CORRADE_VERIFY(std::is_nothrow_default_constructible<Matrix4x4>::value);
CORRADE_VERIFY((std::is_nothrow_constructible<Matrix4x4, IdentityInitT>::value));
} }
void MatrixTest::constructZero() { void MatrixTest::constructZero() {
@ -151,6 +156,8 @@ void MatrixTest::constructZero() {
Vector4(0.0f, 0.0f, 0.0f, 0.0f), Vector4(0.0f, 0.0f, 0.0f, 0.0f),
Vector4(0.0f, 0.0f, 0.0f, 0.0f), Vector4(0.0f, 0.0f, 0.0f, 0.0f),
Vector4(0.0f, 0.0f, 0.0f, 0.0f))); Vector4(0.0f, 0.0f, 0.0f, 0.0f)));
CORRADE_VERIFY((std::is_nothrow_constructible<Matrix4x4, ZeroInitT>::value));
} }
void MatrixTest::constructNoInit() { void MatrixTest::constructNoInit() {
@ -163,6 +170,8 @@ void MatrixTest::constructNoInit() {
Vector4(4.5f, 4.0f, 7.0f, 2.0f), Vector4(4.5f, 4.0f, 7.0f, 2.0f),
Vector4(1.0f, 2.0f, 3.0f, -1.0f), Vector4(1.0f, 2.0f, 3.0f, -1.0f),
Vector4(7.9f, -1.0f, 8.0f, -1.5f))); Vector4(7.9f, -1.0f, 8.0f, -1.5f)));
CORRADE_VERIFY((std::is_nothrow_constructible<Matrix4x4, NoInitT>::value));
} }
void MatrixTest::constructConversion() { void MatrixTest::constructConversion() {
@ -178,6 +187,8 @@ void MatrixTest::constructConversion() {
/* Implicit conversion is not allowed */ /* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Matrix4x4, Matrix4x4i>::value)); CORRADE_VERIFY(!(std::is_convertible<Matrix4x4, Matrix4x4i>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Matrix4x4, Matrix4x4i>::value));
} }
void MatrixTest::constructCopy() { void MatrixTest::constructCopy() {
@ -193,6 +204,9 @@ void MatrixTest::constructCopy() {
Vector4(4.5f, 4.0f, 7.0f, 2.0f), Vector4(4.5f, 4.0f, 7.0f, 2.0f),
Vector4(1.0f, 2.0f, 3.0f, -1.0f), Vector4(1.0f, 2.0f, 3.0f, -1.0f),
Vector4(7.9f, -1.0f, 8.0f, -1.5f))); Vector4(7.9f, -1.0f, 8.0f, -1.5f)));
CORRADE_VERIFY(std::is_nothrow_copy_constructible<Matrix4x4>::value);
CORRADE_VERIFY(std::is_nothrow_copy_assignable<Matrix4x4>::value);
} }
void MatrixTest::convert() { void MatrixTest::convert() {

16
src/Magnum/Math/Test/QuaternionTest.cpp

@ -148,6 +148,8 @@ void QuaternionTest::construct() {
constexpr Float c = a.scalar(); constexpr Float c = a.scalar();
CORRADE_COMPARE(b, Vector3(1.0f, 2.0f, 3.0f)); CORRADE_COMPARE(b, Vector3(1.0f, 2.0f, 3.0f));
CORRADE_COMPARE(c, -4.0f); CORRADE_COMPARE(c, -4.0f);
CORRADE_VERIFY((std::is_nothrow_constructible<Quaternion, Vector3, Float>::value));
} }
void QuaternionTest::constructIdentity() { void QuaternionTest::constructIdentity() {
@ -157,17 +159,24 @@ void QuaternionTest::constructIdentity() {
CORRADE_COMPARE(b, Quaternion({0.0f, 0.0f, 0.0f}, 1.0f)); CORRADE_COMPARE(b, Quaternion({0.0f, 0.0f, 0.0f}, 1.0f));
CORRADE_COMPARE(a.length(), 1.0f); CORRADE_COMPARE(a.length(), 1.0f);
CORRADE_COMPARE(b.length(), 1.0f); CORRADE_COMPARE(b.length(), 1.0f);
CORRADE_VERIFY(std::is_nothrow_default_constructible<Quaternion>::value);
CORRADE_VERIFY((std::is_nothrow_constructible<Quaternion, IdentityInitT>::value));
} }
void QuaternionTest::constructZero() { void QuaternionTest::constructZero() {
constexpr Quaternion a{ZeroInit}; constexpr Quaternion a{ZeroInit};
CORRADE_COMPARE(a, Quaternion({0.0f, 0.0f, 0.0f}, 0.0f)); CORRADE_COMPARE(a, Quaternion({0.0f, 0.0f, 0.0f}, 0.0f));
CORRADE_VERIFY((std::is_nothrow_constructible<Quaternion, ZeroInitT>::value));
} }
void QuaternionTest::constructNoInit() { void QuaternionTest::constructNoInit() {
Quaternion a{{1.0f, 2.0f, 3.0f}, -4.0f}; Quaternion a{{1.0f, 2.0f, 3.0f}, -4.0f};
new(&a) Quaternion{NoInit}; new(&a) Quaternion{NoInit};
CORRADE_COMPARE(a, Quaternion({1.0f, 2.0f, 3.0f}, -4.0f)); CORRADE_COMPARE(a, Quaternion({1.0f, 2.0f, 3.0f}, -4.0f));
CORRADE_VERIFY((std::is_nothrow_constructible<Quaternion, NoInitT>::value));
} }
void QuaternionTest::constructFromVector() { void QuaternionTest::constructFromVector() {
@ -176,6 +185,8 @@ void QuaternionTest::constructFromVector() {
/* Implicit conversion is not allowed */ /* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Vector3, Quaternion>::value)); CORRADE_VERIFY(!(std::is_convertible<Vector3, Quaternion>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Quaternion, Vector3>::value));
} }
void QuaternionTest::constructConversion() { void QuaternionTest::constructConversion() {
@ -188,12 +199,17 @@ void QuaternionTest::constructConversion() {
/* Implicit conversion is not allowed */ /* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Quaternion, Quaternioni>::value)); CORRADE_VERIFY(!(std::is_convertible<Quaternion, Quaternioni>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Quaternion, Quaternioni>::value));
} }
void QuaternionTest::constructCopy() { void QuaternionTest::constructCopy() {
constexpr Quaternion a({1.0f, -3.0f, 7.0f}, 2.5f); constexpr Quaternion a({1.0f, -3.0f, 7.0f}, 2.5f);
constexpr Quaternion b(a); constexpr Quaternion b(a);
CORRADE_COMPARE(b, Quaternion({1.0f, -3.0f, 7.0f}, 2.5f)); CORRADE_COMPARE(b, Quaternion({1.0f, -3.0f, 7.0f}, 2.5f));
CORRADE_VERIFY(std::is_nothrow_copy_constructible<Quaternion>::value);
CORRADE_VERIFY(std::is_nothrow_copy_assignable<Quaternion>::value);
} }
void QuaternionTest::convert() { void QuaternionTest::convert() {

26
src/Magnum/Math/Test/RangeTest.cpp

@ -178,6 +178,10 @@ void RangeTest::construct() {
CORRADE_COMPARE(a, (Range<1, Int>(3, 23))); CORRADE_COMPARE(a, (Range<1, Int>(3, 23)));
CORRADE_COMPARE(b, (Range<2, Int>({3, 5}, {23, 78}))); CORRADE_COMPARE(b, (Range<2, Int>({3, 5}, {23, 78})));
CORRADE_COMPARE(c, (Range<3, Int>({3, 5, -7}, {23, 78, 2}))); CORRADE_COMPARE(c, (Range<3, Int>({3, 5, -7}, {23, 78, 2})));
CORRADE_VERIFY((std::is_nothrow_constructible<Range1Di, Int, Int>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Range2Di, Vector2i, Vector2i>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Range3Di, Vector3i, Vector3i>::value));
} }
void RangeTest::constructDefault() { void RangeTest::constructDefault() {
@ -194,6 +198,13 @@ void RangeTest::constructDefault() {
CORRADE_COMPARE(b2, Range2Di({0, 0}, {0, 0})); CORRADE_COMPARE(b2, Range2Di({0, 0}, {0, 0}));
CORRADE_COMPARE(c1, Range3Di({0, 0, 0}, {0, 0, 0})); CORRADE_COMPARE(c1, Range3Di({0, 0, 0}, {0, 0, 0}));
CORRADE_COMPARE(c2, Range3Di({0, 0, 0}, {0, 0, 0})); CORRADE_COMPARE(c2, Range3Di({0, 0, 0}, {0, 0, 0}));
CORRADE_VERIFY(std::is_nothrow_default_constructible<Range1Di>::value);
CORRADE_VERIFY(std::is_nothrow_default_constructible<Range2Di>::value);
CORRADE_VERIFY(std::is_nothrow_default_constructible<Range3Di>::value);
CORRADE_VERIFY((std::is_nothrow_constructible<Range1Di, ZeroInitT>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Range2Di, ZeroInitT>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Range3Di, ZeroInitT>::value));
} }
void RangeTest::constructNoInit() { void RangeTest::constructNoInit() {
@ -208,6 +219,10 @@ void RangeTest::constructNoInit() {
CORRADE_COMPARE(a, (Range1Di{3, 23})); CORRADE_COMPARE(a, (Range1Di{3, 23}));
CORRADE_COMPARE(b, (Range2Di{{3, 5}, {23, 78}})); CORRADE_COMPARE(b, (Range2Di{{3, 5}, {23, 78}}));
CORRADE_COMPARE(c, (Range3Di{{3, 5, -7}, {23, 78, 2}})); CORRADE_COMPARE(c, (Range3Di{{3, 5, -7}, {23, 78, 2}}));
CORRADE_VERIFY((std::is_nothrow_constructible<Range1Di, NoInitT>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Range2Di, NoInitT>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Range3Di, NoInitT>::value));
} }
void RangeTest::constructFromSize() { void RangeTest::constructFromSize() {
@ -235,6 +250,10 @@ void RangeTest::constructConversion() {
CORRADE_VERIFY(!(std::is_convertible<Range1D, Range1Di>::value)); CORRADE_VERIFY(!(std::is_convertible<Range1D, Range1Di>::value));
CORRADE_VERIFY(!(std::is_convertible<Range2D, Range2Di>::value)); CORRADE_VERIFY(!(std::is_convertible<Range2D, Range2Di>::value));
CORRADE_VERIFY(!(std::is_convertible<Range3D, Range3Di>::value)); CORRADE_VERIFY(!(std::is_convertible<Range3D, Range3Di>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Range1D, Range1Di>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Range2D, Range2Di>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Range3D, Range3Di>::value));
} }
void RangeTest::constructCopy() { void RangeTest::constructCopy() {
@ -249,6 +268,13 @@ void RangeTest::constructCopy() {
CORRADE_COMPARE(d, Range1Di(3, 23)); CORRADE_COMPARE(d, Range1Di(3, 23));
CORRADE_COMPARE(e, Range2Di({3, 5}, {23, 78})); CORRADE_COMPARE(e, Range2Di({3, 5}, {23, 78}));
CORRADE_COMPARE(f, Range3Di({3, 5, -7}, {23, 78, 2})); CORRADE_COMPARE(f, Range3Di({3, 5, -7}, {23, 78, 2}));
CORRADE_VERIFY(std::is_nothrow_copy_constructible<Range1Di>::value);
CORRADE_VERIFY(std::is_nothrow_copy_constructible<Range2Di>::value);
CORRADE_VERIFY(std::is_nothrow_copy_constructible<Range3Di>::value);
CORRADE_VERIFY(std::is_nothrow_copy_assignable<Range1Di>::value);
CORRADE_VERIFY(std::is_nothrow_copy_assignable<Range2Di>::value);
CORRADE_VERIFY(std::is_nothrow_copy_assignable<Range3Di>::value);
} }
void RangeTest::convert() { void RangeTest::convert() {

12
src/Magnum/Math/Test/RectangularMatrixTest.cpp

@ -150,6 +150,8 @@ void RectangularMatrixTest::construct() {
CORRADE_COMPARE(a, Matrix3x4(Vector4(1.0f, 2.0f, 3.0f, 4.0f), CORRADE_COMPARE(a, Matrix3x4(Vector4(1.0f, 2.0f, 3.0f, 4.0f),
Vector4(5.0f, 6.0f, 7.0f, 8.0f), Vector4(5.0f, 6.0f, 7.0f, 8.0f),
Vector4(9.0f, 10.0f, 11.0f, 12.0f))); Vector4(9.0f, 10.0f, 11.0f, 12.0f)));
CORRADE_VERIFY((std::is_nothrow_constructible<Matrix3x4, Vector4, Vector4, Vector4>::value));
} }
void RectangularMatrixTest::constructDefault() { void RectangularMatrixTest::constructDefault() {
@ -163,6 +165,9 @@ void RectangularMatrixTest::constructDefault() {
Vector3(0.0f, 0.0f, 0.0f), Vector3(0.0f, 0.0f, 0.0f),
Vector3(0.0f, 0.0f, 0.0f), Vector3(0.0f, 0.0f, 0.0f),
Vector3(0.0f, 0.0f, 0.0f))); Vector3(0.0f, 0.0f, 0.0f)));
CORRADE_VERIFY(std::is_nothrow_default_constructible<Matrix4x3>::value);
CORRADE_VERIFY((std::is_nothrow_constructible<Matrix4x3, ZeroInitT>::value));
} }
void RectangularMatrixTest::constructNoInit() { void RectangularMatrixTest::constructNoInit() {
@ -173,6 +178,8 @@ void RectangularMatrixTest::constructNoInit() {
CORRADE_COMPARE(a, Matrix3x4(Vector4(1.0f, 2.0f, 3.0f, 4.0f), CORRADE_COMPARE(a, Matrix3x4(Vector4(1.0f, 2.0f, 3.0f, 4.0f),
Vector4(5.0f, 6.0f, 7.0f, 8.0f), Vector4(5.0f, 6.0f, 7.0f, 8.0f),
Vector4(9.0f, 10.0f, 11.0f, 12.0f))); Vector4(9.0f, 10.0f, 11.0f, 12.0f)));
CORRADE_VERIFY((std::is_nothrow_constructible<Matrix3x4, NoInitT>::value));
} }
void RectangularMatrixTest::constructConversion() { void RectangularMatrixTest::constructConversion() {
@ -185,6 +192,8 @@ void RectangularMatrixTest::constructConversion() {
/* Implicit conversion is not allowed */ /* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Matrix2x2, Matrix2x2i>::value)); CORRADE_VERIFY(!(std::is_convertible<Matrix2x2, Matrix2x2i>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Matrix2x2, Matrix2x2i>::value));
} }
void RectangularMatrixTest::constructFromData() { void RectangularMatrixTest::constructFromData() {
@ -226,6 +235,9 @@ void RectangularMatrixTest::constructCopy() {
CORRADE_COMPARE(b, Matrix3x4(Vector4(1.0f, 2.0f, 3.0f, 4.0f), CORRADE_COMPARE(b, Matrix3x4(Vector4(1.0f, 2.0f, 3.0f, 4.0f),
Vector4(5.0f, 6.0f, 7.0f, 8.0f), Vector4(5.0f, 6.0f, 7.0f, 8.0f),
Vector4(9.0f, 10.0f, 11.0f, 12.0f))); Vector4(9.0f, 10.0f, 11.0f, 12.0f)));
CORRADE_VERIFY(std::is_nothrow_copy_constructible<Matrix3x4>::value);
CORRADE_VERIFY(std::is_nothrow_copy_assignable<Matrix3x4>::value);
} }
void RectangularMatrixTest::convert() { void RectangularMatrixTest::convert() {

8
src/Magnum/Math/Test/UnitTest.cpp

@ -74,17 +74,23 @@ void UnitTest::construct() {
/* Implicit conversion is not allowed */ /* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Float, Sec>::value)); CORRADE_VERIFY(!(std::is_convertible<Float, Sec>::value));
CORRADE_VERIFY(!(std::is_convertible<Sec, Float>::value)); CORRADE_VERIFY(!(std::is_convertible<Sec, Float>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Sec, Float>::value));
} }
void UnitTest::constructDefault() { void UnitTest::constructDefault() {
constexpr Sec b; constexpr Sec b;
CORRADE_COMPARE(b, Sec(0.0f)); CORRADE_COMPARE(b, Sec(0.0f));
CORRADE_VERIFY(std::is_nothrow_default_constructible<Sec>::value);
} }
void UnitTest::constructNoInit() { void UnitTest::constructNoInit() {
Sec a{25.0f}; Sec a{25.0f};
new(&a) Sec{NoInit}; new(&a) Sec{NoInit};
CORRADE_COMPARE(a, Sec{25.0f}); CORRADE_COMPARE(a, Sec{25.0f});
CORRADE_VERIFY((std::is_nothrow_constructible<Sec, NoInitT>::value));
} }
void UnitTest::constructConversion() { void UnitTest::constructConversion() {
@ -94,6 +100,8 @@ void UnitTest::constructConversion() {
/* Implicit conversion is not allowed */ /* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Sec, Seci>::value)); CORRADE_VERIFY(!(std::is_convertible<Sec, Seci>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Sec, Seci>::value));
} }
void UnitTest::compare() { void UnitTest::compare() {

14
src/Magnum/Math/Test/Vector2Test.cpp

@ -104,6 +104,8 @@ Vector2Test::Vector2Test() {
void Vector2Test::construct() { void Vector2Test::construct() {
constexpr Vector2 a = {1.5f, 2.5f}; constexpr Vector2 a = {1.5f, 2.5f};
CORRADE_COMPARE(a, (Vector<2, Float>(1.5f, 2.5f))); CORRADE_COMPARE(a, (Vector<2, Float>(1.5f, 2.5f)));
CORRADE_VERIFY((std::is_nothrow_constructible<Vector2, Float, Float>::value));
} }
void Vector2Test::constructDefault() { void Vector2Test::constructDefault() {
@ -111,12 +113,17 @@ void Vector2Test::constructDefault() {
constexpr Vector2 b{ZeroInit}; constexpr Vector2 b{ZeroInit};
CORRADE_COMPARE(a, Vector2(0.0f, 0.0f)); CORRADE_COMPARE(a, Vector2(0.0f, 0.0f));
CORRADE_COMPARE(b, Vector2(0.0f, 0.0f)); CORRADE_COMPARE(b, Vector2(0.0f, 0.0f));
CORRADE_VERIFY(std::is_nothrow_default_constructible<Vector2>::value);
CORRADE_VERIFY((std::is_nothrow_constructible<Vector2, ZeroInitT>::value));
} }
void Vector2Test::constructNoInit() { void Vector2Test::constructNoInit() {
Vector2 a{1.5f, 2.5f}; Vector2 a{1.5f, 2.5f};
new(&a) Vector2{NoInit}; new(&a) Vector2{NoInit};
CORRADE_COMPARE(a, (Vector2{1.5f, 2.5f})); CORRADE_COMPARE(a, (Vector2{1.5f, 2.5f}));
CORRADE_VERIFY((std::is_nothrow_constructible<Vector2, NoInitT>::value));
} }
void Vector2Test::constructOneValue() { void Vector2Test::constructOneValue() {
@ -125,6 +132,8 @@ void Vector2Test::constructOneValue() {
/* Implicit conversion is not allowed */ /* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Float, Vector2>::value)); CORRADE_VERIFY(!(std::is_convertible<Float, Vector2>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Vector2, Float>::value));
} }
void Vector2Test::constructConversion() { void Vector2Test::constructConversion() {
@ -134,6 +143,8 @@ void Vector2Test::constructConversion() {
/* Implicit conversion is not allowed */ /* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Vector2, Vector2i>::value)); CORRADE_VERIFY(!(std::is_convertible<Vector2, Vector2i>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Vector2, Vector2i>::value));
} }
void Vector2Test::constructCopy() { void Vector2Test::constructCopy() {
@ -143,6 +154,9 @@ void Vector2Test::constructCopy() {
#endif #endif
Vector2 b(a); Vector2 b(a);
CORRADE_COMPARE(b, Vector2(1.5f, 2.5f)); CORRADE_COMPARE(b, Vector2(1.5f, 2.5f));
CORRADE_VERIFY(std::is_nothrow_copy_constructible<Vector2>::value);
CORRADE_VERIFY(std::is_nothrow_copy_assignable<Vector2>::value);
} }
void Vector2Test::convert() { void Vector2Test::convert() {

16
src/Magnum/Math/Test/Vector3Test.cpp

@ -102,6 +102,8 @@ Vector3Test::Vector3Test() {
void Vector3Test::construct() { void Vector3Test::construct() {
constexpr Vector3 a = {1.0f, 2.5f, -3.0f}; constexpr Vector3 a = {1.0f, 2.5f, -3.0f};
CORRADE_COMPARE(a, (Vector<3, Float>(1.0f, 2.5f, -3.0f))); CORRADE_COMPARE(a, (Vector<3, Float>(1.0f, 2.5f, -3.0f)));
CORRADE_VERIFY((std::is_nothrow_constructible<Vector3, Float, Float, Float>::value));
} }
void Vector3Test::constructDefault() { void Vector3Test::constructDefault() {
@ -109,12 +111,17 @@ void Vector3Test::constructDefault() {
constexpr Vector3 b{ZeroInit}; constexpr Vector3 b{ZeroInit};
CORRADE_COMPARE(a, Vector3(0.0f, 0.0f, 0.0f)); CORRADE_COMPARE(a, Vector3(0.0f, 0.0f, 0.0f));
CORRADE_COMPARE(b, Vector3(0.0f, 0.0f, 0.0f)); CORRADE_COMPARE(b, Vector3(0.0f, 0.0f, 0.0f));
CORRADE_VERIFY(std::is_nothrow_default_constructible<Vector3>::value);
CORRADE_VERIFY((std::is_nothrow_constructible<Vector3, ZeroInitT>::value));
} }
void Vector3Test::constructNoInit() { void Vector3Test::constructNoInit() {
Vector3 a{1.0f, 2.5f, -3.0f}; Vector3 a{1.0f, 2.5f, -3.0f};
new(&a) Vector3{NoInit}; new(&a) Vector3{NoInit};
CORRADE_COMPARE(a, (Vector3{1.0f, 2.5f, -3.0f})); CORRADE_COMPARE(a, (Vector3{1.0f, 2.5f, -3.0f}));
CORRADE_VERIFY((std::is_nothrow_constructible<Vector3, NoInitT>::value));
} }
void Vector3Test::constructOneValue() { void Vector3Test::constructOneValue() {
@ -123,12 +130,16 @@ void Vector3Test::constructOneValue() {
/* Implicit conversion is not allowed */ /* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Float, Vector3>::value)); CORRADE_VERIFY(!(std::is_convertible<Float, Vector3>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Vector3, Float>::value));
} }
void Vector3Test::constructParts() { void Vector3Test::constructParts() {
constexpr Vector2 a(1.0f, 2.0f); constexpr Vector2 a(1.0f, 2.0f);
constexpr Vector3 b = {a, 3.0f}; constexpr Vector3 b = {a, 3.0f};
CORRADE_COMPARE(b, Vector3(1.0f, 2.0f, 3.0f)); CORRADE_COMPARE(b, Vector3(1.0f, 2.0f, 3.0f));
CORRADE_VERIFY((std::is_nothrow_constructible<Vector3, Vector2, Float>::value));
} }
void Vector3Test::constructConversion() { void Vector3Test::constructConversion() {
@ -138,6 +149,8 @@ void Vector3Test::constructConversion() {
/* Implicit conversion is not allowed */ /* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Vector3, Vector3i>::value)); CORRADE_VERIFY(!(std::is_convertible<Vector3, Vector3i>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Vector3, Vector3i>::value));
} }
void Vector3Test::constructCopy() { void Vector3Test::constructCopy() {
@ -147,6 +160,9 @@ void Vector3Test::constructCopy() {
#endif #endif
Vector3 b(a); Vector3 b(a);
CORRADE_COMPARE(b, Vector3(1.0f, 2.5f, -3.0f)); CORRADE_COMPARE(b, Vector3(1.0f, 2.5f, -3.0f));
CORRADE_VERIFY(std::is_nothrow_copy_constructible<Vector3>::value);
CORRADE_VERIFY(std::is_nothrow_copy_assignable<Vector3>::value);
} }
void Vector3Test::convert() { void Vector3Test::convert() {

16
src/Magnum/Math/Test/Vector4Test.cpp

@ -101,6 +101,8 @@ Vector4Test::Vector4Test() {
void Vector4Test::construct() { void Vector4Test::construct() {
constexpr Vector4 a = {1.0f, -2.5f, 3.0f, 4.1f}; constexpr Vector4 a = {1.0f, -2.5f, 3.0f, 4.1f};
CORRADE_COMPARE(a, (Vector<4, Float>(1.0f, -2.5f, 3.0f, 4.1f))); CORRADE_COMPARE(a, (Vector<4, Float>(1.0f, -2.5f, 3.0f, 4.1f)));
CORRADE_VERIFY((std::is_nothrow_constructible<Vector4, Float, Float, Float, Float>::value));
} }
void Vector4Test::constructPad() { void Vector4Test::constructPad() {
@ -124,12 +126,17 @@ void Vector4Test::constructDefault() {
constexpr Vector4 b{ZeroInit}; constexpr Vector4 b{ZeroInit};
CORRADE_COMPARE(a, Vector4(0.0f, 0.0f, 0.0f, 0.0f)); CORRADE_COMPARE(a, Vector4(0.0f, 0.0f, 0.0f, 0.0f));
CORRADE_COMPARE(b, Vector4(0.0f, 0.0f, 0.0f, 0.0f)); CORRADE_COMPARE(b, Vector4(0.0f, 0.0f, 0.0f, 0.0f));
CORRADE_VERIFY(std::is_nothrow_default_constructible<Vector4>::value);
CORRADE_VERIFY((std::is_nothrow_constructible<Vector4, ZeroInitT>::value));
} }
void Vector4Test::constructNoInit() { void Vector4Test::constructNoInit() {
Vector4 a{1.0f, -2.5f, 3.0f, 4.1f}; Vector4 a{1.0f, -2.5f, 3.0f, 4.1f};
new(&a) Vector4{NoInit}; new(&a) Vector4{NoInit};
CORRADE_COMPARE(a, (Vector4{1.0f, -2.5f, 3.0f, 4.1f})); CORRADE_COMPARE(a, (Vector4{1.0f, -2.5f, 3.0f, 4.1f}));
CORRADE_VERIFY((std::is_nothrow_constructible<Vector4, NoInitT>::value));
} }
void Vector4Test::constructOneValue() { void Vector4Test::constructOneValue() {
@ -138,12 +145,16 @@ void Vector4Test::constructOneValue() {
/* Implicit conversion is not allowed */ /* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Float, Vector4>::value)); CORRADE_VERIFY(!(std::is_convertible<Float, Vector4>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Vector4, Float>::value));
} }
void Vector4Test::constructParts() { void Vector4Test::constructParts() {
constexpr Vector3 a(1.0f, 2.0f, 3.0f); constexpr Vector3 a(1.0f, 2.0f, 3.0f);
constexpr Vector4 b = {a, 4.0f}; constexpr Vector4 b = {a, 4.0f};
CORRADE_COMPARE(b, Vector4(1.0f, 2.0f, 3.0f, 4.0f)); CORRADE_COMPARE(b, Vector4(1.0f, 2.0f, 3.0f, 4.0f));
CORRADE_VERIFY((std::is_nothrow_constructible<Vector4, Vector3, Float>::value));
} }
void Vector4Test::constructConversion() { void Vector4Test::constructConversion() {
@ -153,6 +164,8 @@ void Vector4Test::constructConversion() {
/* Implicit conversion is not allowed */ /* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Vector4, Vector4i>::value)); CORRADE_VERIFY(!(std::is_convertible<Vector4, Vector4i>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Vector4, Vector4i>::value));
} }
void Vector4Test::constructCopy() { void Vector4Test::constructCopy() {
@ -162,6 +175,9 @@ void Vector4Test::constructCopy() {
#endif #endif
Vector4 b(a); Vector4 b(a);
CORRADE_COMPARE(b, Vector4(1.0f, -2.5f, 3.0f, 4.1f)); CORRADE_COMPARE(b, Vector4(1.0f, -2.5f, 3.0f, 4.1f));
CORRADE_VERIFY(std::is_nothrow_copy_constructible<Vector4>::value);
CORRADE_VERIFY(std::is_nothrow_copy_assignable<Vector4>::value);
} }
void Vector4Test::convert() { void Vector4Test::convert() {

16
src/Magnum/Math/Test/VectorTest.cpp

@ -174,6 +174,8 @@ VectorTest::VectorTest() {
void VectorTest::construct() { void VectorTest::construct() {
constexpr Vector4 a = {1.0f, 2.0f, -3.0f, 4.5f}; constexpr Vector4 a = {1.0f, 2.0f, -3.0f, 4.5f};
CORRADE_COMPARE(a, Vector4(1.0f, 2.0f, -3.0f, 4.5f)); CORRADE_COMPARE(a, Vector4(1.0f, 2.0f, -3.0f, 4.5f));
CORRADE_VERIFY((std::is_nothrow_constructible<Vector4, Float, Float, Float, Float>::value));
} }
void VectorTest::constructFromData() { void VectorTest::constructFromData() {
@ -198,12 +200,17 @@ void VectorTest::constructDefault() {
constexpr Vector4 b{ZeroInit}; constexpr Vector4 b{ZeroInit};
CORRADE_COMPARE(a, Vector4(0.0f, 0.0f, 0.0f, 0.0f)); CORRADE_COMPARE(a, Vector4(0.0f, 0.0f, 0.0f, 0.0f));
CORRADE_COMPARE(b, Vector4(0.0f, 0.0f, 0.0f, 0.0f)); CORRADE_COMPARE(b, Vector4(0.0f, 0.0f, 0.0f, 0.0f));
CORRADE_VERIFY(std::is_nothrow_default_constructible<Vector4>::value);
CORRADE_VERIFY((std::is_nothrow_constructible<Vector4, ZeroInitT>::value));
} }
void VectorTest::constructNoInit() { void VectorTest::constructNoInit() {
Vector4 a{1.0f, 2.0f, -3.0f, 4.5f}; Vector4 a{1.0f, 2.0f, -3.0f, 4.5f};
new(&a) Vector4{NoInit}; new(&a) Vector4{NoInit};
CORRADE_COMPARE(a, (Vector4{1.0f, 2.0f, -3.0f, 4.5f})); CORRADE_COMPARE(a, (Vector4{1.0f, 2.0f, -3.0f, 4.5f}));
CORRADE_VERIFY((std::is_nothrow_constructible<Vector4, NoInitT>::value));
} }
void VectorTest::constructOneValue() { void VectorTest::constructOneValue() {
@ -213,6 +220,8 @@ void VectorTest::constructOneValue() {
/* Implicit conversion is not allowed */ /* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Float, Vector4>::value)); CORRADE_VERIFY(!(std::is_convertible<Float, Vector4>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Vector4, Float>::value));
} }
void VectorTest::constructOneComponent() { void VectorTest::constructOneComponent() {
@ -221,6 +230,8 @@ void VectorTest::constructOneComponent() {
/* Implicit constructor must work */ /* Implicit constructor must work */
constexpr Vector1 vec = 1.0f; constexpr Vector1 vec = 1.0f;
CORRADE_COMPARE(vec, Vector1(1)); CORRADE_COMPARE(vec, Vector1(1));
CORRADE_VERIFY((std::is_nothrow_constructible<Vector1, Float>::value));
} }
void VectorTest::constructConversion() { void VectorTest::constructConversion() {
@ -231,12 +242,17 @@ void VectorTest::constructConversion() {
/* Implicit conversion is not allowed */ /* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<Vector4, Vector4i>::value)); CORRADE_VERIFY(!(std::is_convertible<Vector4, Vector4i>::value));
CORRADE_VERIFY((std::is_nothrow_constructible<Vector4, Vector4i>::value));
} }
void VectorTest::constructCopy() { void VectorTest::constructCopy() {
constexpr Vector4 a(1.0f, 3.5f, 4.0f, -2.7f); constexpr Vector4 a(1.0f, 3.5f, 4.0f, -2.7f);
constexpr Vector4 b(a); constexpr Vector4 b(a);
CORRADE_COMPARE(b, Vector4(1.0f, 3.5f, 4.0f, -2.7f)); CORRADE_COMPARE(b, Vector4(1.0f, 3.5f, 4.0f, -2.7f));
CORRADE_VERIFY(std::is_nothrow_copy_constructible<Vector4>::value);
CORRADE_VERIFY(std::is_nothrow_copy_assignable<Vector4>::value);
} }
void VectorTest::convert() { void VectorTest::convert() {

11
src/Magnum/Math/Unit.h

@ -47,16 +47,19 @@ template<template<class> class Derived, class T> class Unit {
typedef T Type; /**< @brief Underlying data type */ typedef T Type; /**< @brief Underlying data type */
/** @brief Construct zero value */ /** @brief Construct zero value */
constexpr /*implicit*/ Unit(ZeroInitT = ZeroInit): _value(T(0)) {} constexpr /*implicit*/ Unit(ZeroInitT = ZeroInit) noexcept: _value(T(0)) {}
/** @brief Construct without initializing the contents */ /** @brief Construct without initializing the contents */
explicit Unit(NoInitT) {} explicit Unit(NoInitT) noexcept {}
/** @brief Explicit conversion from unitless type */ /** @brief Explicit conversion from unitless type */
constexpr explicit Unit(T value): _value(value) {} constexpr explicit Unit(T value) noexcept: _value(value) {}
/** @brief Construct from another underlying type */ /** @brief Construct from another underlying type */
template<class U> constexpr explicit Unit(Unit<Derived, U> value): _value(T(value._value)) {} template<class U> constexpr explicit Unit(Unit<Derived, U> value) noexcept: _value(T(value._value)) {}
/** @brief Copy constructor */
constexpr /*implicit*/ Unit(const Unit<Derived, T>& other) noexcept = default;
/** @brief Explicit conversion to underlying type */ /** @brief Explicit conversion to underlying type */
constexpr explicit operator T() const { return _value; } constexpr explicit operator T() const { return _value; }

22
src/Magnum/Math/Vector.h

@ -173,10 +173,10 @@ template<std::size_t size, class T> class Vector {
* \boldsymbol v = \boldsymbol 0 * \boldsymbol v = \boldsymbol 0
* @f] * @f]
*/ */
constexpr /*implicit*/ Vector(ZeroInitT = ZeroInit): _data{} {} constexpr /*implicit*/ Vector(ZeroInitT = ZeroInit) noexcept: _data{} {}
/** @brief Construct vector without initializing the contents */ /** @brief Construct vector without initializing the contents */
explicit Vector(NoInitT) {} explicit Vector(NoInitT) noexcept {}
/** @todo Creating Vector from combination of vector and scalar types */ /** @todo Creating Vector from combination of vector and scalar types */
@ -186,16 +186,16 @@ template<std::size_t size, class T> class Vector {
* @param next Next values * @param next Next values
*/ */
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
template<class ...U> constexpr /*implicit*/ Vector(T first, U... next); template<class ...U> constexpr /*implicit*/ Vector(T first, U... next) noexcept;
#else #else
template<class ...U, class V = typename std::enable_if<sizeof...(U)+1 == size, T>::type> constexpr /*implicit*/ Vector(T first, U... next): _data{first, next...} {} template<class ...U, class V = typename std::enable_if<sizeof...(U)+1 == size, T>::type> constexpr /*implicit*/ Vector(T first, U... next) noexcept: _data{first, next...} {}
#endif #endif
/** @brief Construct vector with one value for all fields */ /** @brief Construct vector with one value for all fields */
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
constexpr explicit Vector(T value); constexpr explicit Vector(T value) noexcept;
#else #else
template<class U, class V = typename std::enable_if<std::is_same<T, U>::value && size != 1, T>::type> constexpr explicit Vector(U value): Vector(typename Implementation::GenerateSequence<size>::Type(), value) {} template<class U, class V = typename std::enable_if<std::is_same<T, U>::value && size != 1, T>::type> constexpr explicit Vector(U value) noexcept: Vector(typename Implementation::GenerateSequence<size>::Type(), value) {}
#endif #endif
/** /**
@ -209,13 +209,13 @@ template<std::size_t size, class T> class Vector {
* // integral == {1, 2, -15, 7} * // integral == {1, 2, -15, 7}
* @endcode * @endcode
*/ */
template<class U> constexpr explicit Vector(const Vector<size, U>& other): Vector(typename Implementation::GenerateSequence<size>::Type(), other) {} template<class U> constexpr explicit Vector(const Vector<size, U>& other) noexcept: Vector(typename Implementation::GenerateSequence<size>::Type(), other) {}
/** @brief Construct vector from external representation */ /** @brief Construct vector from external representation */
template<class U, class V = decltype(Implementation::VectorConverter<size, T, U>::from(std::declval<U>()))> constexpr explicit Vector(const U& other): Vector(Implementation::VectorConverter<size, T, U>::from(other)) {} template<class U, class V = decltype(Implementation::VectorConverter<size, T, U>::from(std::declval<U>()))> constexpr explicit Vector(const U& other) noexcept: Vector(Implementation::VectorConverter<size, T, U>::from(other)) {}
/** @brief Copy constructor */ /** @brief Copy constructor */
constexpr Vector(const Vector<size, T>&) = default; constexpr /*implicit*/ Vector(const Vector<size, T>&) noexcept = default;
/** @brief Convert vector to external representation */ /** @brief Convert vector to external representation */
template<class U, class V = decltype(Implementation::VectorConverter<size, T, U>::to(std::declval<Vector<size, T>>()))> constexpr explicit operator U() const { template<class U, class V = decltype(Implementation::VectorConverter<size, T, U>::to(std::declval<Vector<size, T>>()))> constexpr explicit operator U() const {
@ -574,10 +574,10 @@ template<std::size_t size, class T> class Vector {
private: private:
/* Implementation for Vector<size, T>::Vector(const Vector<size, U>&) */ /* Implementation for Vector<size, T>::Vector(const Vector<size, U>&) */
template<class U, std::size_t ...sequence> constexpr explicit Vector(Implementation::Sequence<sequence...>, const Vector<size, U>& vector): _data{T(vector._data[sequence])...} {} template<class U, std::size_t ...sequence> constexpr explicit Vector(Implementation::Sequence<sequence...>, const Vector<size, U>& vector) noexcept: _data{T(vector._data[sequence])...} {}
/* Implementation for Vector<size, T>::Vector(U) */ /* Implementation for Vector<size, T>::Vector(U) */
template<std::size_t ...sequence> constexpr explicit Vector(Implementation::Sequence<sequence...>, T value): _data{Implementation::repeat(value, sequence)...} {} template<std::size_t ...sequence> constexpr explicit Vector(Implementation::Sequence<sequence...>, T value) noexcept: _data{Implementation::repeat(value, sequence)...} {}
template<std::size_t otherSize, std::size_t ...sequence> constexpr static Vector<size, T> padInternal(Implementation::Sequence<sequence...>, const Vector<otherSize, T>& a, T value) { template<std::size_t otherSize, std::size_t ...sequence> constexpr static Vector<size, T> padInternal(Implementation::Sequence<sequence...>, const Vector<otherSize, T>& a, T value) {
return {sequence < otherSize ? a[sequence] : value...}; return {sequence < otherSize ? a[sequence] : value...};

12
src/Magnum/Math/Vector2.h

@ -112,7 +112,7 @@ template<class T> class Vector2: public Vector<2, T> {
#endif #endif
/** @copydoc Vector::Vector(ZeroInitT) */ /** @copydoc Vector::Vector(ZeroInitT) */
constexpr /*implicit*/ Vector2(ZeroInitT = ZeroInit) constexpr /*implicit*/ Vector2(ZeroInitT = ZeroInit) noexcept
/** @todoc remove workaround when doxygen is sane */ /** @todoc remove workaround when doxygen is sane */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
@ -121,7 +121,7 @@ template<class T> class Vector2: public Vector<2, T> {
{} {}
/** @copydoc Vector::Vector(NoInitT) */ /** @copydoc Vector::Vector(NoInitT) */
explicit Vector2(NoInitT) explicit Vector2(NoInitT) noexcept
/** @todoc remove workaround when doxygen is sane */ /** @todoc remove workaround when doxygen is sane */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
@ -130,7 +130,7 @@ template<class T> class Vector2: public Vector<2, T> {
{} {}
/** @copydoc Vector::Vector(T) */ /** @copydoc Vector::Vector(T) */
constexpr explicit Vector2(T value): Vector<2, T>(value) {} constexpr explicit Vector2(T value) noexcept: Vector<2, T>(value) {}
/** /**
* @brief Constructor * @brief Constructor
@ -139,10 +139,10 @@ template<class T> class Vector2: public Vector<2, T> {
* \boldsymbol v = \begin{pmatrix} x \\ y \end{pmatrix} * \boldsymbol v = \begin{pmatrix} x \\ y \end{pmatrix}
* @f] * @f]
*/ */
constexpr /*implicit*/ Vector2(T x, T y): Vector<2, T>(x, y) {} constexpr /*implicit*/ Vector2(T x, T y) noexcept: Vector<2, T>(x, y) {}
/** @copydoc Vector::Vector(const Vector<size, U>&) */ /** @copydoc Vector::Vector(const Vector<size, U>&) */
template<class U> constexpr explicit Vector2(const Vector<2, U>& other): Vector<2, T>(other) {} template<class U> constexpr explicit Vector2(const Vector<2, U>& other) noexcept: Vector<2, T>(other) {}
/** @brief Construct vector from external representation */ /** @brief Construct vector from external representation */
template<class U, class V = template<class U, class V =
@ -155,7 +155,7 @@ template<class T> class Vector2: public Vector<2, T> {
constexpr explicit Vector2(const U& other): Vector<2, T>(Implementation::VectorConverter<2, T, U>::from(other)) {} constexpr explicit Vector2(const U& other): Vector<2, T>(Implementation::VectorConverter<2, T, U>::from(other)) {}
/** @brief Copy constructor */ /** @brief Copy constructor */
constexpr Vector2(const Vector<2, T>& other): Vector<2, T>(other) {} constexpr /*implicit*/ Vector2(const Vector<2, T>& other) noexcept: Vector<2, T>(other) {}
T& x() { return (*this)[0]; } /**< @brief X component */ T& x() { return (*this)[0]; } /**< @brief X component */
constexpr T x() const { return (*this)[0]; } /**< @overload */ constexpr T x() const { return (*this)[0]; } /**< @overload */

14
src/Magnum/Math/Vector3.h

@ -134,7 +134,7 @@ template<class T> class Vector3: public Vector<3, T> {
#endif #endif
/** @copydoc Vector::Vector(ZeroInitT) */ /** @copydoc Vector::Vector(ZeroInitT) */
constexpr /*implicit*/ Vector3(ZeroInitT = ZeroInit) constexpr /*implicit*/ Vector3(ZeroInitT = ZeroInit) noexcept
/** @todoc remove workaround when doxygen is sane */ /** @todoc remove workaround when doxygen is sane */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
@ -143,7 +143,7 @@ template<class T> class Vector3: public Vector<3, T> {
{} {}
/** @copydoc Vector::Vector(NoInitT) */ /** @copydoc Vector::Vector(NoInitT) */
explicit Vector3(NoInitT) explicit Vector3(NoInitT) noexcept
/** @todoc remove workaround when doxygen is sane */ /** @todoc remove workaround when doxygen is sane */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
@ -152,7 +152,7 @@ template<class T> class Vector3: public Vector<3, T> {
{} {}
/** @copydoc Vector::Vector(T) */ /** @copydoc Vector::Vector(T) */
constexpr explicit Vector3(T value): Vector<3, T>(value) {} constexpr explicit Vector3(T value) noexcept: Vector<3, T>(value) {}
/** /**
* @brief Constructor * @brief Constructor
@ -161,7 +161,7 @@ template<class T> class Vector3: public Vector<3, T> {
* \boldsymbol v = \begin{pmatrix} x \\ y \\ z \end{pmatrix} * \boldsymbol v = \begin{pmatrix} x \\ y \\ z \end{pmatrix}
* @f] * @f]
*/ */
constexpr /*implicit*/ Vector3(T x, T y, T z): Vector<3, T>(x, y, z) {} constexpr /*implicit*/ Vector3(T x, T y, T z) noexcept: Vector<3, T>(x, y, z) {}
/** /**
* @brief Constructor * @brief Constructor
@ -170,10 +170,10 @@ template<class T> class Vector3: public Vector<3, T> {
* \boldsymbol v = \begin{pmatrix} v_x \\ v_y \\ z \end{pmatrix} * \boldsymbol v = \begin{pmatrix} v_x \\ v_y \\ z \end{pmatrix}
* @f] * @f]
*/ */
constexpr /*implicit*/ Vector3(const Vector2<T>& xy, T z): Vector<3, T>(xy[0], xy[1], z) {} constexpr /*implicit*/ Vector3(const Vector2<T>& xy, T z) noexcept: Vector<3, T>(xy[0], xy[1], z) {}
/** @copydoc Vector::Vector(const Vector<size, U>&) */ /** @copydoc Vector::Vector(const Vector<size, U>&) */
template<class U> constexpr explicit Vector3(const Vector<3, U>& other): Vector<3, T>(other) {} template<class U> constexpr explicit Vector3(const Vector<3, U>& other) noexcept: Vector<3, T>(other) {}
/** @brief Construct vector from external representation */ /** @brief Construct vector from external representation */
template<class U, class V = template<class U, class V =
@ -186,7 +186,7 @@ template<class T> class Vector3: public Vector<3, T> {
constexpr explicit Vector3(const U& other): Vector<3, T>(Implementation::VectorConverter<3, T, U>::from(other)) {} constexpr explicit Vector3(const U& other): Vector<3, T>(Implementation::VectorConverter<3, T, U>::from(other)) {}
/** @brief Copy constructor */ /** @brief Copy constructor */
constexpr Vector3(const Vector<3, T>& other): Vector<3, T>(other) {} constexpr /*implicit*/ Vector3(const Vector<3, T>& other) noexcept: Vector<3, T>(other) {}
/** /**
* @brief X component * @brief X component

14
src/Magnum/Math/Vector4.h

@ -60,7 +60,7 @@ template<class T> class Vector4: public Vector<4, T> {
} }
/** @copydoc Vector::Vector(ZeroInitT) */ /** @copydoc Vector::Vector(ZeroInitT) */
constexpr /*implicit*/ Vector4(ZeroInitT = ZeroInit) constexpr /*implicit*/ Vector4(ZeroInitT = ZeroInit) noexcept
/** @todoc remove workaround when doxygen is sane */ /** @todoc remove workaround when doxygen is sane */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
@ -69,7 +69,7 @@ template<class T> class Vector4: public Vector<4, T> {
{} {}
/** @copydoc Vector::Vector(NoInitT) */ /** @copydoc Vector::Vector(NoInitT) */
explicit Vector4(NoInitT) explicit Vector4(NoInitT) noexcept
/** @todoc remove workaround when doxygen is sane */ /** @todoc remove workaround when doxygen is sane */
#ifndef DOXYGEN_GENERATING_OUTPUT #ifndef DOXYGEN_GENERATING_OUTPUT
/* MSVC 2015 can't handle {} here */ /* MSVC 2015 can't handle {} here */
@ -78,7 +78,7 @@ template<class T> class Vector4: public Vector<4, T> {
{} {}
/** @copydoc Vector::Vector(T) */ /** @copydoc Vector::Vector(T) */
constexpr explicit Vector4(T value): Vector<4, T>(value) {} constexpr explicit Vector4(T value) noexcept: Vector<4, T>(value) {}
/** /**
* @brief Constructor * @brief Constructor
@ -87,7 +87,7 @@ template<class T> class Vector4: public Vector<4, T> {
* \boldsymbol v = \begin{pmatrix} x \\ y \\ z \\ w \end{pmatrix} * \boldsymbol v = \begin{pmatrix} x \\ y \\ z \\ w \end{pmatrix}
* @f] * @f]
*/ */
constexpr /*implicit*/ Vector4(T x, T y, T z, T w): Vector<4, T>(x, y, z, w) {} constexpr /*implicit*/ Vector4(T x, T y, T z, T w) noexcept: Vector<4, T>(x, y, z, w) {}
/** /**
* @brief Constructor * @brief Constructor
@ -96,16 +96,16 @@ template<class T> class Vector4: public Vector<4, T> {
* \boldsymbol v = \begin{pmatrix} v_x \\ v_y \\ v_z \\ w \end{pmatrix} * \boldsymbol v = \begin{pmatrix} v_x \\ v_y \\ v_z \\ w \end{pmatrix}
* @f] * @f]
*/ */
constexpr /*implicit*/ Vector4(const Vector3<T>& xyz, T w): Vector<4, T>(xyz[0], xyz[1], xyz[2], w) {} constexpr /*implicit*/ Vector4(const Vector3<T>& xyz, T w) noexcept: Vector<4, T>(xyz[0], xyz[1], xyz[2], w) {}
/** @copydoc Vector::Vector(const Vector<size, U>&) */ /** @copydoc Vector::Vector(const Vector<size, U>&) */
template<class U> constexpr explicit Vector4(const Vector<4, U>& other): Vector<4, T>(other) {} template<class U> constexpr explicit Vector4(const Vector<4, U>& other) noexcept: Vector<4, T>(other) {}
/** @brief Construct vector from external representation */ /** @brief Construct vector from external representation */
template<class U, class V = decltype(Implementation::VectorConverter<4, T, U>::from(std::declval<U>()))> constexpr explicit Vector4(const U& other): Vector<4, T>(Implementation::VectorConverter<4, T, U>::from(other)) {} template<class U, class V = decltype(Implementation::VectorConverter<4, T, U>::from(std::declval<U>()))> constexpr explicit Vector4(const U& other): Vector<4, T>(Implementation::VectorConverter<4, T, U>::from(other)) {}
/** @brief Copy constructor */ /** @brief Copy constructor */
constexpr Vector4(const Vector<4, T>& other): Vector<4, T>(other) {} constexpr /*implicit*/ Vector4(const Vector<4, T>& other) noexcept: Vector<4, T>(other) {}
/** /**
* @brief X component * @brief X component

Loading…
Cancel
Save