From 7f662f2c3e88d39872f28874c9c97970f618b963 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 29 May 2014 21:53:47 +0200 Subject: [PATCH] Math: C++14 constexpr in Vector. --- src/Magnum/Math/Test/VectorTest.cpp | 226 ++++++++++++++++++---------- src/Magnum/Math/Vector.h | 212 +++++++++++++------------- 2 files changed, 253 insertions(+), 185 deletions(-) diff --git a/src/Magnum/Math/Test/VectorTest.cpp b/src/Magnum/Math/Test/VectorTest.cpp index 90c5adfdd..f73b597a4 100644 --- a/src/Magnum/Math/Test/VectorTest.cpp +++ b/src/Magnum/Math/Test/VectorTest.cpp @@ -245,8 +245,8 @@ void VectorTest::data() { /* Pointer chasings, i.e. *(b.data()[3]), are not possible */ constexpr Vector4 a(1.0f, 2.0f, -3.0f, 4.5f); - constexpr Float f = a[3]; - constexpr Float g = *a.data(); + constexpr auto f = a[3]; + constexpr auto g = *a.data(); CORRADE_COMPARE(f, 4.5f); CORRADE_COMPARE(g, 1.0f); } @@ -261,101 +261,145 @@ void VectorTest::compare() { void VectorTest::compareComponentWise() { typedef BoolVector<3> BoolVector3; - CORRADE_COMPARE(Vector3(1.0f, -1.0f, 5.0f) < Vector3(1.1f, -1.0f, 3.0f), BoolVector3(0x1)); - CORRADE_COMPARE(Vector3(1.0f, -1.0f, 5.0f) <= Vector3(1.1f, -1.0f, 3.0f), BoolVector3(0x3)); - CORRADE_COMPARE(Vector3(1.0f, -1.0f, 5.0f) >= Vector3(1.1f, -1.0f, 3.0f), BoolVector3(0x6)); - CORRADE_COMPARE(Vector3(1.0f, -1.0f, 5.0f) > Vector3(1.1f, -1.0f, 3.0f), BoolVector3(0x4)); + + constexpr auto a = Vector3(1.0f, -1.0f, 5.0f) < Vector3(1.1f, -1.0f, 3.0f); + constexpr auto b = Vector3(1.0f, -1.0f, 5.0f) <= Vector3(1.1f, -1.0f, 3.0f); + constexpr auto c = Vector3(1.0f, -1.0f, 5.0f) >= Vector3(1.1f, -1.0f, 3.0f); + constexpr auto d = Vector3(1.0f, -1.0f, 5.0f) > Vector3(1.1f, -1.0f, 3.0f); + + CORRADE_COMPARE(a, BoolVector3(0x1)); + CORRADE_COMPARE(b, BoolVector3(0x3)); + CORRADE_COMPARE(c, BoolVector3(0x6)); + CORRADE_COMPARE(d, BoolVector3(0x4)); } void VectorTest::negative() { - CORRADE_COMPARE(-Vector4(1.0f, -3.0f, 5.0f, -10.0f), Vector4(-1.0f, 3.0f, -5.0f, 10.0f)); + constexpr auto a = -Vector4(1.0f, -3.0f, 5.0f, -10.0f); + CORRADE_COMPARE(a, Vector4(-1.0f, 3.0f, -5.0f, 10.0f)); } void VectorTest::addSubtract() { - Vector4 a(1.0f, -3.0f, 5.0f, -10.0f); - Vector4 b(7.5f, 33.0f, -15.0f, 0.0f); - Vector4 c(8.5f, 30.0f, -10.0f, -10.0f); + constexpr Vector4 a(1.0f, -3.0f, 5.0f, -10.0f); + constexpr Vector4 b(7.5f, 33.0f, -15.0f, 0.0f); + constexpr Vector4 c(8.5f, 30.0f, -10.0f, -10.0f); + + constexpr auto d = a + b; + constexpr auto e = c - b; - CORRADE_COMPARE(a + b, c); - CORRADE_COMPARE(c - b, a); + CORRADE_COMPARE(d, c); + CORRADE_COMPARE(e, a); } void VectorTest::multiplyDivide() { - Vector4 vector(1.0f, 2.0f, 3.0f, 4.0f); - Vector4 multiplied(-1.5f, -3.0f, -4.5f, -6.0f); + constexpr Vector4 vector(1.0f, 2.0f, 3.0f, 4.0f); + constexpr Vector4 multiplied(-1.5f, -3.0f, -4.5f, -6.0f); - CORRADE_COMPARE(vector*-1.5f, multiplied); - CORRADE_COMPARE(-1.5f*vector, multiplied); - CORRADE_COMPARE(multiplied/-1.5f, vector); + constexpr auto a = vector*-1.5f; + constexpr auto b = -1.5f*vector; + constexpr auto c = multiplied/-1.5f; + + CORRADE_COMPARE(a, multiplied); + CORRADE_COMPARE(b, multiplied); + CORRADE_COMPARE(c, vector); /* Divide vector with number and invert */ - Vector4 divisor(1.0f, 2.0f, -4.0f, 8.0f); - Vector4 result(1.0f, 0.5f, -0.25f, 0.125f); - CORRADE_COMPARE(1.0f/divisor, result); + constexpr Vector4 divisor(1.0f, 2.0f, -4.0f, 8.0f); + constexpr auto d = 1.0f/divisor; + + CORRADE_COMPARE(d, Vector4(1.0f, 0.5f, -0.25f, 0.125f)); } void VectorTest::multiplyDivideIntegral() { - Vector4i vector(32, 10, -6, 2); - Vector4i multiplied(-48, -15, 9, -3); + constexpr Vector4i vector(32, 10, -6, 2); + constexpr Vector4i multiplied(-48, -15, 9, -3); - CORRADE_COMPARE(vector*-1.5f, multiplied); - CORRADE_COMPARE(-1.5f*vector, multiplied); + constexpr auto a = vector*-1.5f; + constexpr auto b = -1.5f*vector; - CORRADE_COMPARE(multiplied/-1.5f, vector); + CORRADE_COMPARE(a, multiplied); + CORRADE_COMPARE(b, multiplied); + + constexpr auto c = multiplied/-1.5f; + + CORRADE_COMPARE(c, vector); /* Using integer vector as divisor is not supported */ } void VectorTest::multiplyDivideComponentWise() { - Vector4 vec(1.0f, 2.0f, 3.0f, 4.0f); - Vector4 multiplier(7.0f, -4.0f, -1.5f, 1.0f); - Vector4 multiplied(7.0f, -8.0f, -4.5f, 4.0f); + constexpr Vector4 vec(1.0f, 2.0f, 3.0f, 4.0f); + constexpr Vector4 multiplier(7.0f, -4.0f, -1.5f, 1.0f); + constexpr Vector4 multiplied(7.0f, -8.0f, -4.5f, 4.0f); + + constexpr auto a = vec*multiplier; + constexpr auto b = multiplied/multiplier; - CORRADE_COMPARE(vec*multiplier, multiplied); - CORRADE_COMPARE(multiplied/multiplier, vec); + CORRADE_COMPARE(a, multiplied); + CORRADE_COMPARE(b, vec); } void VectorTest::multiplyDivideComponentWiseIntegral() { - Vector4i vec(7, 2, -16, -1); - Vector4 multiplier(2.0f, -1.5f, 0.5f, 10.0f); - Vector4i multiplied(14, -3, -8, -10); + constexpr Vector4i vec(7, 2, -16, -1); + constexpr Vector4 multiplier(2.0f, -1.5f, 0.5f, 10.0f); + constexpr Vector4i multiplied(14, -3, -8, -10); + + constexpr auto a = vec*multiplier; + constexpr auto b = multiplier*vec; + + CORRADE_COMPARE(a, multiplied); + CORRADE_COMPARE(b, multiplied); - CORRADE_COMPARE(vec*multiplier, multiplied); - CORRADE_COMPARE(multiplier*vec, multiplied); + constexpr auto c = multiplied/multiplier; - CORRADE_COMPARE(multiplied/multiplier, vec); + CORRADE_COMPARE(c, vec); /* Using integer vector as divisor is not supported */ } void VectorTest::modulo() { typedef Math::Vector<2, Int> Vector2i; - const Vector2i a(4, 13); - const Vector2i b(2, 5); - CORRADE_COMPARE(a % 2, Vector2i(0, 1)); - CORRADE_COMPARE(a % b, Vector2i(0, 3)); + constexpr Vector2i a(4, 13); + constexpr Vector2i b(2, 5); + + constexpr auto c = a % 2; + constexpr auto d = a % b; + + CORRADE_COMPARE(c, Vector2i(0, 1)); + CORRADE_COMPARE(d, Vector2i(0, 3)); } void VectorTest::bitwise() { typedef Math::Vector<2, Int> Vector2i; - const Vector2i a(85, 240); - const Vector2i b(170, 85); - CORRADE_COMPARE(~a, Vector2i(-86, -241)); - CORRADE_COMPARE(a & b, Vector2i(0, 80)); - CORRADE_COMPARE(a | b, Vector2i(255, 245)); - CORRADE_COMPARE(a ^ b, Vector2i(255, 165)); + constexpr Vector2i a(85, 240); + constexpr Vector2i b(170, 85); + + constexpr auto c = ~a; + constexpr auto d = a & b; + constexpr auto e = a | b; + constexpr auto f = a ^ b; + + CORRADE_COMPARE(c, Vector2i(-86, -241)); + CORRADE_COMPARE(d, Vector2i(0, 80)); + CORRADE_COMPARE(e, Vector2i(255, 245)); + CORRADE_COMPARE(f, Vector2i(255, 165)); + + constexpr Vector2i g(7, 32); - const Vector2i c(7, 32); - CORRADE_COMPARE(c << 2, Vector2i(28, 128)); - CORRADE_COMPARE(c >> 2, Vector2i(1, 8)); + constexpr auto h = g << 2; + constexpr auto i = g >> 2; + + CORRADE_COMPARE(h, Vector2i(28, 128)); + CORRADE_COMPARE(i, Vector2i(1, 8)); } void VectorTest::dot() { - CORRADE_COMPARE(Vector4::dot({1.0f, 0.5f, 0.75f, 1.5f}, {2.0f, 4.0f, 1.0f, 7.0f}), 15.25f); + constexpr auto a = Vector4::dot({1.0f, 0.5f, 0.75f, 1.5f}, {2.0f, 4.0f, 1.0f, 7.0f}); + CORRADE_COMPARE(a, 15.25f); } void VectorTest::dotSelf() { - CORRADE_COMPARE(Vector4(1.0f, 2.0f, 3.0f, 4.0f).dot(), 30.0f); + constexpr auto a = Vector4(1.0f, 2.0f, 3.0f, 4.0f).dot(); + CORRADE_COMPARE(a, 30.0f); } void VectorTest::length() { @@ -379,11 +423,13 @@ void VectorTest::resized() { } void VectorTest::sum() { - CORRADE_COMPARE(Vector3(1.0f, 2.0f, 4.0f).sum(), 7.0f); + constexpr auto a = Vector3(1.0f, 2.0f, 4.0f).sum(); + CORRADE_COMPARE(a, 7.0f); } void VectorTest::product() { - CORRADE_COMPARE(Vector3(1.0f, 2.0f, 3.0f).product(), 6.0f); + constexpr auto a = Vector3(1.0f, 2.0f, 3.0f).product(); + CORRADE_COMPARE(a, 6.0f); } void VectorTest::min() { @@ -522,38 +568,60 @@ void VectorTest::subclass() { const Float cdata[] = {1.0f, -2.0f}; CORRADE_COMPARE(Vec2::from(cdata), Vec2(1.0f, -2.0f)); - CORRADE_COMPARE(Vec2(-2.0f, 5.0f) + Vec2(1.0f, -3.0f), Vec2(-1.0f, 2.0f)); - CORRADE_COMPARE(Vec2(-2.0f, 5.0f) - Vec2(1.0f, -3.0f), Vec2(-3.0f, 8.0f)); - - CORRADE_COMPARE(Vec2(-2.0f, 5.0f)*2.0f, Vec2(-4.0f, 10.0f)); - CORRADE_COMPARE(2.0f*Vec2(-2.0f, 5.0f), Vec2(-4.0f, 10.0f)); - CORRADE_COMPARE(Vec2(-2.0f, 5.0f)/0.5f, Vec2(-4.0f, 10.0f)); - CORRADE_COMPARE(2.0f/Vec2(-2.0f, 5.0f), Vec2(-1.0f, 0.4f)); - - CORRADE_COMPARE(Vec2(-2.0f, 5.0f)*Vec2(1.5f, -2.0f), Vec2(-3.0f, -10.0f)); - CORRADE_COMPARE(Vec2(-2.0f, 5.0f)/Vec2(2.0f/3.0f, -0.5f), Vec2(-3.0f, -10.0f)); + constexpr auto a = Vec2(-2.0f, 5.0f) + Vec2(1.0f, -3.0f); + constexpr auto b = Vec2(-2.0f, 5.0f) - Vec2(1.0f, -3.0f); + CORRADE_COMPARE(a, Vec2(-1.0f, 2.0f)); + CORRADE_COMPARE(b, Vec2(-3.0f, 8.0f)); + + constexpr auto c = Vec2(-2.0f, 5.0f)*2.0f; + constexpr auto d = 2.0f*Vec2(-2.0f, 5.0f); + constexpr auto e = Vec2(-2.0f, 5.0f)/0.5f; + constexpr auto f = 2.0f/Vec2(-2.0f, 5.0f); + CORRADE_COMPARE(c, Vec2(-4.0f, 10.0f)); + CORRADE_COMPARE(d, Vec2(-4.0f, 10.0f)); + CORRADE_COMPARE(e, Vec2(-4.0f, 10.0f)); + CORRADE_COMPARE(f, Vec2(-1.0f, 0.4f)); + + constexpr auto g = Vec2(-2.0f, 5.0f)*Vec2(1.5f, -2.0f); + constexpr auto h = Vec2(-2.0f, 5.0f)/Vec2(2.0f/3.0f, -0.5f); + CORRADE_COMPARE(g, Vec2(-3.0f, -10.0f)); + CORRADE_COMPARE(h, Vec2(-3.0f, -10.0f)); /* Modulo operations */ - CORRADE_COMPARE(Vec2i(4, 13) % 2, Vec2i(0, 1)); - CORRADE_COMPARE(Vec2i(4, 13) % Vec2i(2, 5), Vec2i(0, 3)); + constexpr auto i = Vec2i(4, 13) % 2; + constexpr auto j = Vec2i(4, 13) % Vec2i(2, 5); + CORRADE_COMPARE(i, Vec2i(0, 1)); + CORRADE_COMPARE(j, Vec2i(0, 3)); /* Bitwise operations */ - CORRADE_COMPARE(~Vec2i(85, 240), Vec2i(-86, -241)); - CORRADE_COMPARE(Vec2i(85, 240) & Vec2i(170, 85), Vec2i(0, 80)); - CORRADE_COMPARE(Vec2i(85, 240) | Vec2i(170, 85), Vec2i(255, 245)); - CORRADE_COMPARE(Vec2i(85, 240) ^ Vec2i(170, 85), Vec2i(255, 165)); - - CORRADE_COMPARE(Vec2i(7, 32) << 2, Vec2i(28, 128)); - CORRADE_COMPARE(Vec2i(7, 32) >> 2, Vec2i(1, 8)); + constexpr auto k = ~Vec2i(85, 240); + constexpr auto l = Vec2i(85, 240) & Vec2i(170, 85); + constexpr auto m = Vec2i(85, 240) | Vec2i(170, 85); + constexpr auto n = Vec2i(85, 240) ^ Vec2i(170, 85); + CORRADE_COMPARE(k, Vec2i(-86, -241)); + CORRADE_COMPARE(l, Vec2i(0, 80)); + CORRADE_COMPARE(m, Vec2i(255, 245)); + CORRADE_COMPARE(n, Vec2i(255, 165)); + + constexpr auto o = Vec2i(7, 32) << 2; + constexpr auto p = Vec2i(7, 32) >> 2; + CORRADE_COMPARE(o, Vec2i(28, 128)); + CORRADE_COMPARE(p, Vec2i(1, 8)); /* Integral multiplication/division */ - CORRADE_COMPARE(Vec2i(2, 4)*1.5f, Vec2i(3, 6)); - CORRADE_COMPARE(1.5f*Vec2i(2, 4), Vec2i(3, 6)); - CORRADE_COMPARE(Vec2i(2, 4)/(2.0f/3.0f), Vec2i(3, 6)); - - CORRADE_COMPARE(Vec2i(2, 4)*Vec2(-1.5f, 0.5f), Vec2i(-3, 2)); - CORRADE_COMPARE(Vec2(-1.5f, 0.5f)*Vec2i(2, 4), Vec2i(-3, 2)); - CORRADE_COMPARE(Vec2i(2, 4)/Vec2(-2.0f/3.0f, 2.0f), Vec2i(-3, 2)); + constexpr auto q = Vec2i(2, 4)*1.5f; + constexpr auto r = 1.5f*Vec2i(2, 4); + constexpr auto s = Vec2i(2, 4)/(2.0f/3.0f); + CORRADE_COMPARE(q, Vec2i(3, 6)); + CORRADE_COMPARE(r, Vec2i(3, 6)); + CORRADE_COMPARE(s, Vec2i(3, 6)); + + constexpr auto t = Vec2i(2, 4)*Vec2(-1.5f, 0.5f); + constexpr auto u = Vec2(-1.5f, 0.5f)*Vec2i(2, 4); + constexpr auto v = Vec2i(2, 4)/Vec2(-2.0f/3.0f, 2.0f); + CORRADE_COMPARE(t, Vec2i(-3, 2)); + CORRADE_COMPARE(u, Vec2i(-3, 2)); + CORRADE_COMPARE(v, Vec2i(-3, 2)); /* Functions */ CORRADE_COMPARE(Vec2(3.0f, 0.0f).normalized(), Vec2(1.0f, 0.0f)); diff --git a/src/Magnum/Math/Vector.h b/src/Magnum/Math/Vector.h index ea2a214cd..e298e684f 100644 --- a/src/Magnum/Math/Vector.h +++ b/src/Magnum/Math/Vector.h @@ -91,7 +91,7 @@ template class Vector { * @ref Vector2::perpendicular() * @todoc Explicit reference when Doxygen can handle const */ - static T dot(const Vector& a, const Vector& b) { + constexpr static T dot(const Vector& a, const Vector& b) { return (a*b).sum(); } @@ -155,7 +155,7 @@ template class Vector { constexpr Vector(const Vector&) = default; /** @brief Assignment operator */ - Vector& operator=(const Vector&) = default; + constexpr Vector& operator=(const Vector&) = default; /** @brief Convert vector to external representation */ template::to(std::declval>()))> constexpr explicit operator U() const { @@ -168,7 +168,7 @@ template class Vector { * * @see @ref operator[]() */ - T* data() { return _data; } + constexpr T* data() { return _data; } constexpr const T* data() const { return _data; } /**< @overload */ /** @@ -176,7 +176,7 @@ template class Vector { * * @see @ref data() */ - T& operator[](std::size_t pos) { return _data[pos]; } + constexpr T& operator[](std::size_t pos) { return _data[pos]; } constexpr T operator[](std::size_t pos) const { return _data[pos]; } /**< @overload */ /** @brief Equality comparison */ @@ -193,16 +193,16 @@ template class Vector { } /** @brief Component-wise less than */ - BoolVector operator<(const Vector& other) const; + constexpr BoolVector operator<(const Vector& other) const; /** @brief Component-wise less than or equal */ - BoolVector operator<=(const Vector& other) const; + constexpr BoolVector operator<=(const Vector& other) const; /** @brief Component-wise greater than or equal */ - BoolVector operator>=(const Vector& other) const; + constexpr BoolVector operator>=(const Vector& other) const; /** @brief Component-wise greater than */ - BoolVector operator>(const Vector& other) const; + constexpr BoolVector operator>(const Vector& other) const; /** * @brief Whether the vector is zero @@ -236,7 +236,7 @@ template class Vector { * @f] * @see @ref Vector2::perpendicular() */ - Vector operator-() const; + constexpr Vector operator-() const; /** * @brief Add and assign vector @@ -245,7 +245,7 @@ template class Vector { * \boldsymbol a_i = \boldsymbol a_i + \boldsymbol b_i * @f] */ - Vector& operator+=(const Vector& other) { + constexpr Vector& operator+=(const Vector& other) { for(std::size_t i = 0; i != size; ++i) _data[i] += other._data[i]; @@ -257,7 +257,7 @@ template class Vector { * * @see @ref operator+=(), @ref sum() */ - Vector operator+(const Vector& other) const { + constexpr Vector operator+(const Vector& other) const { return Vector(*this) += other; } @@ -268,7 +268,7 @@ template class Vector { * \boldsymbol a_i = \boldsymbol a_i - \boldsymbol b_i * @f] */ - Vector& operator-=(const Vector& other) { + constexpr Vector& operator-=(const Vector& other) { for(std::size_t i = 0; i != size; ++i) _data[i] -= other._data[i]; @@ -280,7 +280,7 @@ template class Vector { * * @see @ref operator-=() */ - Vector operator-(const Vector& other) const { + constexpr Vector operator-(const Vector& other) const { return Vector(*this) -= other; } @@ -293,7 +293,7 @@ template class Vector { * @see @ref operator*=(const Vector&), * @ref operator*=(Vector&, FloatingPoint) */ - Vector& operator*=(T number) { + constexpr Vector& operator*=(T number) { for(std::size_t i = 0; i != size; ++i) _data[i] *= number; @@ -307,7 +307,7 @@ template class Vector { * @ref operator*=(T), operator*(T, const Vector&), * @ref operator*(const Vector&, FloatingPoint) */ - Vector operator*(T number) const { + constexpr Vector operator*(T number) const { return Vector(*this) *= number; } @@ -320,7 +320,7 @@ template class Vector { * @see @ref operator/=(const Vector&), * @ref operator/=(Vector&, FloatingPoint) */ - Vector& operator/=(T number) { + constexpr Vector& operator/=(T number) { for(std::size_t i = 0; i != size; ++i) _data[i] /= number; @@ -334,7 +334,7 @@ template class Vector { * @ref operator/=(T), operator/(T, const Vector&), * @ref operator/(const Vector&, FloatingPoint) */ - Vector operator/(T number) const { + constexpr Vector operator/(T number) const { return Vector(*this) /= number; } @@ -347,7 +347,7 @@ template class Vector { * @see @ref operator*=(T), * @ref operator*=(Vector&, const Vector&) */ - Vector& operator*=(const Vector& other) { + constexpr Vector& operator*=(const Vector& other) { for(std::size_t i = 0; i != size; ++i) _data[i] *= other._data[i]; @@ -361,7 +361,7 @@ template class Vector { * @ref operator*(const Vector&, const Vector&), * @ref product() */ - Vector operator*(const Vector& other) const { + constexpr Vector operator*(const Vector& other) const { return Vector(*this) *= other; } @@ -374,7 +374,7 @@ template class Vector { * @see @ref operator/=(T), * @ref operator/=(Vector&, const Vector&) */ - Vector& operator/=(const Vector& other) { + constexpr Vector& operator/=(const Vector& other) { for(std::size_t i = 0; i != size; ++i) _data[i] /= other._data[i]; @@ -387,7 +387,7 @@ template class Vector { * @see @ref operator/(T) const, @ref operator/=(const Vector&), * @ref operator/(const Vector&, const Vector&) */ - Vector operator/(const Vector& other) const { + constexpr Vector operator/(const Vector& other) const { return Vector(*this) /= other; } @@ -401,7 +401,7 @@ template class Vector { * @see @ref dot(const Vector&, const Vector&), * @ref isNormalized() */ - T dot() const { return dot(*this, *this); } + constexpr T dot() const { return dot(*this, *this); } /** * @brief %Vector length @@ -479,14 +479,14 @@ template class Vector { * * @see @ref operator+() */ - T sum() const; + constexpr T sum() const; /** * @brief Product of values in the vector * * @see @ref operator*(const Vector&) const */ - T product() const; + constexpr T product() const; /** * @brief Minimal value in the vector @@ -517,7 +517,7 @@ template class Vector { Same as @ref Vector::operator*(T) const. */ -template inline Vector operator*( +template inline constexpr Vector operator*( #ifdef DOXYGEN_GENERATING_OUTPUT T #else @@ -536,7 +536,7 @@ template inline Vector operator*( @f] @see @ref Vector::operator/(T) const */ -template inline Vector operator/( +template inline constexpr Vector operator/( #ifdef DOXYGEN_GENERATING_OUTPUT T #else @@ -544,7 +544,7 @@ template inline Vector operator/( #endif number, const Vector& vector) { - Vector out; + Vector out{}; for(std::size_t i = 0; i != size; ++i) out[i] = number/vector[i]; @@ -557,7 +557,7 @@ template inline Vector operator/( The computation is done in-place. */ -template inline +template inline constexpr #ifdef DOXYGEN_GENERATING_OUTPUT Vector& #else @@ -573,7 +573,7 @@ operator%=(Vector& a, Integral b) { /** @relates Vector @brief Modulo of integral vector */ -template inline +template inline constexpr #ifdef DOXYGEN_GENERATING_OUTPUT Vector #else @@ -589,7 +589,7 @@ operator%(const Vector& a, Integral b) { The computation is done in-place. */ -template inline +template inline constexpr #ifdef DOXYGEN_GENERATING_OUTPUT Vector& #else @@ -605,7 +605,7 @@ operator%=(Vector& a, const Vector& b) { /** @relates Vector @brief Modulo of two integral vectors */ -template inline +template inline constexpr #ifdef DOXYGEN_GENERATING_OUTPUT Vector #else @@ -619,14 +619,14 @@ operator%(const Vector& a, const Vector& b) { /** @relates Vector @brief Bitwise NOT of integral vector */ -template inline +template inline constexpr #ifdef DOXYGEN_GENERATING_OUTPUT Vector #else typename std::enable_if::value, Vector>::type #endif operator~(const Vector& vector) { - Vector out; + Vector out{}; for(std::size_t i = 0; i != size; ++i) out[i] = ~vector[i]; @@ -639,7 +639,7 @@ operator~(const Vector& vector) { The computation is done in-place. */ -template inline +template inline constexpr #ifdef DOXYGEN_GENERATING_OUTPUT Vector& #else @@ -655,7 +655,7 @@ operator&=(Vector& a, const Vector& b) { /** @relates Vector @brief Bitwise AND of two integral vectors */ -template inline +template inline constexpr #ifdef DOXYGEN_GENERATING_OUTPUT Vector #else @@ -671,7 +671,7 @@ operator&(const Vector& a, const Vector& b) { The computation is done in-place. */ -template inline +template inline constexpr #ifdef DOXYGEN_GENERATING_OUTPUT Vector& #else @@ -687,7 +687,7 @@ operator|=(Vector& a, const Vector& b) { /** @relates Vector @brief Bitwise OR of two integral vectors */ -template inline +template inline constexpr #ifdef DOXYGEN_GENERATING_OUTPUT Vector #else @@ -703,7 +703,7 @@ operator|(const Vector& a, const Vector& b) { The computation is done in-place. */ -template inline +template inline constexpr #ifdef DOXYGEN_GENERATING_OUTPUT Vector& #else @@ -719,7 +719,7 @@ operator^=(Vector& a, const Vector& b) { /** @relates Vector @brief Bitwise XOR of two integral vectors */ -template inline +template inline constexpr #ifdef DOXYGEN_GENERATING_OUTPUT Vector #else @@ -735,7 +735,7 @@ operator^(const Vector& a, const Vector& b) { The computation is done in-place. */ -template inline +template inline constexpr #ifdef DOXYGEN_GENERATING_OUTPUT Vector& #else @@ -758,7 +758,7 @@ operator<<=(Vector& vector, /** @relates Vector @brief Bitwise left shift of integral vector */ -template inline +template inline constexpr #ifdef DOXYGEN_GENERATING_OUTPUT Vector #else @@ -781,7 +781,7 @@ operator<<(const Vector& vector, The computation is done in-place. */ -template inline +template inline constexpr #ifdef DOXYGEN_GENERATING_OUTPUT Vector& #else @@ -803,7 +803,7 @@ operator>>=(Vector& vector, /** @relates Vector @brief Bitwise left shift of integral vector */ -template inline +template inline constexpr #ifdef DOXYGEN_GENERATING_OUTPUT Vector #else @@ -826,7 +826,7 @@ operator>>(const Vector& vector, Similar to @ref Vector::operator*=(T), except that the multiplication is done in floating-point. The computation is done in-place. */ -template inline +template inline constexpr #ifdef DOXYGEN_GENERATING_OUTPUT Vector& #else @@ -845,7 +845,7 @@ operator*=(Vector& vector, FloatingPoint number) { Similar to @ref Vector::operator*(T) const, except that the multiplication is done in floating-point. */ -template inline +template inline constexpr #ifdef DOXYGEN_GENERATING_OUTPUT Vector #else @@ -861,7 +861,7 @@ operator*(const Vector& vector, FloatingPoint number) { Same as @ref operator*(const Vector&, FloatingPoint). */ -template inline +template inline constexpr #ifdef DOXYGEN_GENERATING_OUTPUT Vector #else @@ -877,7 +877,7 @@ operator*(FloatingPoint number, const Vector& vector) { Similar to @ref Vector::operator/=(T), except that the division is done in floating-point. The computation is done in-place. */ -template inline +template inline constexpr #ifdef DOXYGEN_GENERATING_OUTPUT Vector& #else @@ -896,7 +896,7 @@ operator/=(Vector& vector, FloatingPoint number) { Similar to @ref Vector::operator/(T) const, except that the division is done in floating-point. */ -template inline +template inline constexpr #ifdef DOXYGEN_GENERATING_OUTPUT Vector #else @@ -913,7 +913,7 @@ operator/(const Vector& vector, FloatingPoint number) { Similar to @ref Vector::operator*=(const Vector&), except that the multiplication is done in floating-point. The computation is done in-place. */ -template inline +template inline constexpr #ifdef DOXYGEN_GENERATING_OUTPUT Vector& #else @@ -934,7 +934,7 @@ the multiplication is done in floating-point. The result is always integral vector, convert both arguments to the same floating-point type to have floating-point result. */ -template inline +template inline constexpr #ifdef DOXYGEN_GENERATING_OUTPUT Vector #else @@ -950,7 +950,7 @@ operator*(const Vector& a, const Vector& b) Same as @ref operator*(const Vector&, const Vector&). */ -template inline +template inline constexpr #ifdef DOXYGEN_GENERATING_OUTPUT Vector #else @@ -966,7 +966,7 @@ operator*(const Vector& a, const Vector& b) Similar to @ref Vector::operator/=(const Vector&), except that the division is done in floating-point. The computation is done in-place. */ -template inline +template inline constexpr #ifdef DOXYGEN_GENERATING_OUTPUT Vector& #else @@ -987,7 +987,7 @@ the division is done in floating-point. The result is always integral vector, convert both arguments to the same floating-point type to have floating-point result. */ -template inline +template inline constexpr #ifdef DOXYGEN_GENERATING_OUTPUT Vector #else @@ -1038,54 +1038,54 @@ extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utilit return *reinterpret_cast*>(data); \ } \ \ - Type& operator=(const Type& other) { \ + constexpr Type& operator=(const Type& other) { \ Math::Vector::operator=(other); \ return *this; \ } \ \ - Type operator-() const { \ + constexpr Type operator-() const { \ return Math::Vector::operator-(); \ } \ - Type& operator+=(const Math::Vector& other) { \ + constexpr Type& operator+=(const Math::Vector& other) { \ Math::Vector::operator+=(other); \ return *this; \ } \ - Type operator+(const Math::Vector& other) const { \ + constexpr Type operator+(const Math::Vector& other) const { \ return Math::Vector::operator+(other); \ } \ - Type& operator-=(const Math::Vector& other) { \ + constexpr Type& operator-=(const Math::Vector& other) { \ Math::Vector::operator-=(other); \ return *this; \ } \ - Type operator-(const Math::Vector& other) const { \ + constexpr Type operator-(const Math::Vector& other) const { \ return Math::Vector::operator-(other); \ } \ - Type& operator*=(T number) { \ + constexpr Type& operator*=(T number) { \ Math::Vector::operator*=(number); \ return *this; \ } \ - Type operator*(T number) const { \ + constexpr Type operator*(T number) const { \ return Math::Vector::operator*(number); \ } \ - Type& operator/=(T number) { \ + constexpr Type& operator/=(T number) { \ Math::Vector::operator/=(number); \ return *this; \ } \ - Type operator/(T number) const { \ + constexpr Type operator/(T number) const { \ return Math::Vector::operator/(number); \ } \ - Type& operator*=(const Math::Vector& other) { \ + constexpr Type& operator*=(const Math::Vector& other) { \ Math::Vector::operator*=(other); \ return *this; \ } \ - Type operator*(const Math::Vector& other) const { \ + constexpr Type operator*(const Math::Vector& other) const { \ return Math::Vector::operator*(other); \ } \ - Type& operator/=(const Math::Vector& other) { \ + constexpr Type& operator/=(const Math::Vector& other) { \ Math::Vector::operator/=(other); \ return *this; \ } \ - Type operator/(const Math::Vector& other) const { \ + constexpr Type operator/(const Math::Vector& other) const { \ return Math::Vector::operator/(other); \ } \ \ @@ -1103,99 +1103,99 @@ extern template Corrade::Utility::Debug MAGNUM_EXPORT operator<<(Corrade::Utilit } #define MAGNUM_VECTORn_OPERATOR_IMPLEMENTATION(size, Type) \ - template inline Type operator*(typename std::common_type::type number, const Type& vector) { \ + template inline constexpr Type operator*(typename std::common_type::type number, const Type& vector) { \ return number*static_cast&>(vector); \ } \ - template inline Type operator/(typename std::common_type::type number, const Type& vector) { \ + template inline constexpr Type operator/(typename std::common_type::type number, const Type& vector) { \ return number/static_cast&>(vector); \ } \ \ - template inline typename std::enable_if::value, Type&>::type operator%=(Type& a, Integral b) { \ + template inline constexpr typename std::enable_if::value, Type&>::type operator%=(Type& a, Integral b) { \ static_cast&>(a) %= b; \ return a; \ } \ - template inline typename std::enable_if::value, Type>::type operator%(const Type& a, Integral b) { \ + template inline constexpr typename std::enable_if::value, Type>::type operator%(const Type& a, Integral b) { \ return static_cast&>(a) % b; \ } \ - template inline typename std::enable_if::value, Type&>::type operator%=(Type& a, const Math::Vector& b) { \ + template inline constexpr typename std::enable_if::value, Type&>::type operator%=(Type& a, const Math::Vector& b) { \ static_cast&>(a) %= b; \ return a; \ } \ - template inline typename std::enable_if::value, Type>::type operator%(const Type& a, const Math::Vector& b) { \ + template inline constexpr typename std::enable_if::value, Type>::type operator%(const Type& a, const Math::Vector& b) { \ return static_cast&>(a) % b; \ } \ \ - template inline typename std::enable_if::value, Type>::type operator~(const Type& vector) { \ + template inline constexpr typename std::enable_if::value, Type>::type operator~(const Type& vector) { \ return ~static_cast&>(vector); \ } \ - template inline typename std::enable_if::value, Type&>::type operator&=(Type& a, const Math::Vector& b) { \ + template inline constexpr typename std::enable_if::value, Type&>::type operator&=(Type& a, const Math::Vector& b) { \ static_cast&>(a) &= b; \ return a; \ } \ - template inline typename std::enable_if::value, Type>::type operator&(const Type& a, const Math::Vector& b) { \ + template inline constexpr typename std::enable_if::value, Type>::type operator&(const Type& a, const Math::Vector& b) { \ return static_cast&>(a) & b; \ } \ - template inline typename std::enable_if::value, Type&>::type operator|=(Type& a, const Math::Vector& b) { \ + template inline constexpr typename std::enable_if::value, Type&>::type operator|=(Type& a, const Math::Vector& b) { \ static_cast&>(a) |= b; \ return a; \ } \ - template inline typename std::enable_if::value, Type>::type operator|(const Type& a, const Math::Vector& b) { \ + template inline constexpr typename std::enable_if::value, Type>::type operator|(const Type& a, const Math::Vector& b) { \ return static_cast&>(a) | b; \ } \ - template inline typename std::enable_if::value, Type&>::type operator^=(Type& a, const Math::Vector& b) { \ + template inline constexpr typename std::enable_if::value, Type&>::type operator^=(Type& a, const Math::Vector& b) { \ static_cast&>(a) ^= b; \ return a; \ } \ - template inline typename std::enable_if::value, Type>::type operator^(const Type& a, const Math::Vector& b) { \ + template inline constexpr typename std::enable_if::value, Type>::type operator^(const Type& a, const Math::Vector& b) { \ return static_cast&>(a) ^ b; \ } \ - template inline typename std::enable_if::value, Type&>::type operator<<=(Type& vector, typename std::common_type::type shift) { \ + template inline constexpr typename std::enable_if::value, Type&>::type operator<<=(Type& vector, typename std::common_type::type shift) { \ static_cast&>(vector) <<= shift; \ return vector; \ } \ - template inline typename std::enable_if::value, Type>::type operator<<(const Type& vector, typename std::common_type::type shift) { \ + template inline constexpr typename std::enable_if::value, Type>::type operator<<(const Type& vector, typename std::common_type::type shift) { \ return static_cast&>(vector) << shift; \ } \ - template inline typename std::enable_if::value, Type&>::type operator>>=(Type& vector, typename std::common_type::type shift) { \ + template inline constexpr typename std::enable_if::value, Type&>::type operator>>=(Type& vector, typename std::common_type::type shift) { \ static_cast&>(vector) >>= shift; \ return vector; \ } \ - template inline typename std::enable_if::value, Type>::type operator>>(const Type& vector, typename std::common_type::type shift) { \ + template inline constexpr typename std::enable_if::value, Type>::type operator>>(const Type& vector, typename std::common_type::type shift) { \ return static_cast&>(vector) >> shift; \ } \ - template inline typename std::enable_if::value && std::is_floating_point::value, Type&>::type operator*=(Type& vector, FloatingPoint number) { \ + template inline constexpr typename std::enable_if::value && std::is_floating_point::value, Type&>::type operator*=(Type& vector, FloatingPoint number) { \ static_cast&>(vector) *= number; \ return vector; \ } \ - template inline typename std::enable_if::value && std::is_floating_point::value, Type>::type operator*(const Type& vector, FloatingPoint number) { \ + template inline constexpr typename std::enable_if::value && std::is_floating_point::value, Type>::type operator*(const Type& vector, FloatingPoint number) { \ return static_cast&>(vector)*number; \ } \ - template inline typename std::enable_if::value && std::is_floating_point::value, Type>::type operator*(FloatingPoint number, const Type& vector) { \ + template inline constexpr typename std::enable_if::value && std::is_floating_point::value, Type>::type operator*(FloatingPoint number, const Type& vector) { \ return number*static_cast&>(vector); \ } \ - template inline typename std::enable_if::value && std::is_floating_point::value, Type&>::type operator/=(Type& vector, FloatingPoint number) { \ + template inline constexpr typename std::enable_if::value && std::is_floating_point::value, Type&>::type operator/=(Type& vector, FloatingPoint number) { \ static_cast&>(vector) /= number; \ return vector; \ } \ - template inline typename std::enable_if::value && std::is_floating_point::value, Type>::type operator/(const Type& vector, FloatingPoint number) { \ + template inline constexpr typename std::enable_if::value && std::is_floating_point::value, Type>::type operator/(const Type& vector, FloatingPoint number) { \ return static_cast&>(vector)/number; \ } \ \ - template inline typename std::enable_if::value && std::is_floating_point::value, Type&>::type operator*=(Type& a, const Math::Vector& b) { \ + template inline constexpr typename std::enable_if::value && std::is_floating_point::value, Type&>::type operator*=(Type& a, const Math::Vector& b) { \ static_cast&>(a) *= b; \ return a; \ } \ - template inline typename std::enable_if::value && std::is_floating_point::value, Type>::type operator*(const Type& a, const Math::Vector& b) { \ + template inline constexpr typename std::enable_if::value && std::is_floating_point::value, Type>::type operator*(const Type& a, const Math::Vector& b) { \ return static_cast&>(a)*b; \ } \ - template inline typename std::enable_if::value && std::is_floating_point::value, Type>::type operator*(const Math::Vector& a, const Type& b) { \ + template inline constexpr typename std::enable_if::value && std::is_floating_point::value, Type>::type operator*(const Math::Vector& a, const Type& b) { \ return a*static_cast&>(b); \ } \ - template inline typename std::enable_if::value && std::is_floating_point::value, Type&>::type operator/=(Type& a, const Math::Vector& b) { \ + template inline constexpr typename std::enable_if::value && std::is_floating_point::value, Type&>::type operator/=(Type& a, const Math::Vector& b) { \ static_cast&>(a) /= b; \ return a; \ } \ - template inline typename std::enable_if::value && std::is_floating_point::value, Type>::type operator/(const Type& a, const Math::Vector& b) { \ + template inline constexpr typename std::enable_if::value && std::is_floating_point::value, Type>::type operator/(const Type& a, const Math::Vector& b) { \ return static_cast&>(a)/b; \ } #endif @@ -1206,8 +1206,8 @@ template inline Rad Vector::angle(const V return Rad(std::acos(dot(normalizedA, normalizedB))); } -template inline BoolVector Vector::operator<(const Vector& other) const { - BoolVector out; +template inline constexpr BoolVector Vector::operator<(const Vector& other) const { + BoolVector out{}; for(std::size_t i = 0; i != size; ++i) out.set(i, _data[i] < other._data[i]); @@ -1215,8 +1215,8 @@ template inline BoolVector Vector::ope return out; } -template inline BoolVector Vector::operator<=(const Vector& other) const { - BoolVector out; +template inline constexpr BoolVector Vector::operator<=(const Vector& other) const { + BoolVector out{}; for(std::size_t i = 0; i != size; ++i) out.set(i, _data[i] <= other._data[i]); @@ -1224,8 +1224,8 @@ template inline BoolVector Vector::ope return out; } -template inline BoolVector Vector::operator>=(const Vector& other) const { - BoolVector out; +template inline constexpr BoolVector Vector::operator>=(const Vector& other) const { + BoolVector out{}; for(std::size_t i = 0; i != size; ++i) out.set(i, _data[i] >= other._data[i]); @@ -1233,8 +1233,8 @@ template inline BoolVector Vector::ope return out; } -template inline BoolVector Vector::operator>(const Vector& other) const { - BoolVector out; +template inline constexpr BoolVector Vector::operator>(const Vector& other) const { + BoolVector out{}; for(std::size_t i = 0; i != size; ++i) out.set(i, _data[i] > other._data[i]); @@ -1242,8 +1242,8 @@ template inline BoolVector Vector::ope return out; } -template inline Vector Vector::operator-() const { - Vector out; +template inline constexpr Vector Vector::operator-() const { + Vector out{}; for(std::size_t i = 0; i != size; ++i) out._data[i] = -_data[i]; @@ -1257,7 +1257,7 @@ template inline Vector Vector::proj return line*dot(*this, line); } -template inline T Vector::sum() const { +template inline constexpr T Vector::sum() const { T out(_data[0]); for(std::size_t i = 1; i != size; ++i) @@ -1266,7 +1266,7 @@ template inline T Vector::sum() const { return out; } -template inline T Vector::product() const { +template inline constexpr T Vector::product() const { T out(_data[0]); for(std::size_t i = 1; i != size; ++i)