diff --git a/src/Magnum/Math/Math.h b/src/Magnum/Math/Math.h index be95511dc7..019c822eb5 100644 --- a/src/Magnum/Math/Math.h +++ b/src/Magnum/Math/Math.h @@ -116,4 +116,34 @@ namespace Implementation { }} +#include +// TODO remove this once corrade#152 gets merged +#ifndef CORRADE_CONSTEXPR17 +#if __cpp_constexpr >= 201304 +#define CORRADE_CONSTEXPR14 constexpr +#else +#define CORRADE_CONSTEXPR14 +#endif +#if __cpp_constexpr >= 201603 +#define CORRADE_CONSTEXPR17 constexpr +#else +#define CORRADE_CONSTEXPR17 +#endif +#if __cpp_constexpr >= 202002 +#define CORRADE_CONSTEXPR20 constexpr +#else +#define CORRADE_CONSTEXPR20 +#endif +#if defined(__clang__) && __clang_major__ >= 9 || defined(__GNUG__) && __GNUG__ >= 9 || defined(_MSC_VER) && _MSC_VER >= 1931 +#define CORRADE_CONSTEVAL (__builtin_is_constant_evaluated()) +#elif CORRADE_CXX_STANDARD >= 202002L +#define CORRADE_CONSTEVAL (std::is_constant_evaluated()) /*include type_traits*/ +#elif __cpp_if_constexpr >= 201606 +#define CORRADE_CONSTEVAL constexpr(false) +#else +#define CORRADE_CONSTEVAL (false) +#define CORRADE_NO_CONSTEVAL +#endif +#endif + #endif diff --git a/src/Magnum/Math/Test/CMakeLists.txt b/src/Magnum/Math/Test/CMakeLists.txt index 9251da3964..31c1cd0ce3 100644 --- a/src/Magnum/Math/Test/CMakeLists.txt +++ b/src/Magnum/Math/Test/CMakeLists.txt @@ -41,6 +41,16 @@ corrade_add_test(MathVectorTest VectorTest.cpp LIBRARIES MagnumMathTestLib) corrade_add_test(MathVector2Test Vector2Test.cpp LIBRARIES MagnumMathTestLib) corrade_add_test(MathVector3Test Vector3Test.cpp LIBRARIES MagnumMathTestLib) corrade_add_test(MathVector4Test Vector4Test.cpp LIBRARIES MagnumMathTestLib) +#TODO +#if(MSVC AND MSVC_VERSION GREATER_EQUAL 1931 OR +# CMAKE_CXX_COMPILER_ID MATCHES "Clang$" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 9 OR +# CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 9 +# ) +corrade_add_test(MathVectorConstexpr14 VectorConstexpr14.cpp LIBRARIES MagnumMathTestLib) +set_target_properties( + MathVectorConstexpr14 + PROPERTIES CORRADE_CXX_STANDARD 14) + corrade_add_test(MathColorTest ColorTest.cpp LIBRARIES MagnumMathTestLib) corrade_add_test(MathRectangularMatrixTest RectangularMatrixTest.cpp LIBRARIES MagnumMathTestLib) diff --git a/src/Magnum/Math/Test/VectorConstexpr14.cpp b/src/Magnum/Math/Test/VectorConstexpr14.cpp new file mode 100644 index 0000000000..97f6ac4920 --- /dev/null +++ b/src/Magnum/Math/Test/VectorConstexpr14.cpp @@ -0,0 +1,117 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021, 2022 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include +#include +#include +#include + +namespace Magnum { namespace Math { namespace Test { namespace { + +struct Constexpr14Test: Corrade::TestSuite::Tester { + explicit Constexpr14Test(); +#ifndef CORRADE_NO_CONSTEVAL + template void simple(); + template void integer(); + template void scalar(); + template static constexpr int simpleBody(); + template static constexpr int integerBody(); + template static constexpr int scalarBody(); +#else + void no_consteval_on_this_compiler() { CORRADE_COMPARE(0, 0); } +#endif +}; + +Constexpr14Test::Constexpr14Test() { + addTests({ +#ifndef CORRADE_NO_CONSTEVAL + &Constexpr14Test::simple, + &Constexpr14Test::simple, + &Constexpr14Test::simple, int>, + &Constexpr14Test::simple, Short>, + &Constexpr14Test::simple, unsigned>, + &Constexpr14Test::simple, float>, + &Constexpr14Test::simple, double>, + &Constexpr14Test::integer, int>, + &Constexpr14Test::integer, + &Constexpr14Test::integer, + &Constexpr14Test::integer, int>, + &Constexpr14Test::integer, Short>, + &Constexpr14Test::integer, unsigned> +#else + &Constexpr14Test::no_consteval_on_this_compiler +#endif + }); +} + +#ifndef CORRADE_NO_CONSTEVAL +template +void Constexpr14Test::simple() { + setTestCaseTemplateName(TypeTraits::name()); + constexpr int ret = simpleBody(); + static_assert(ret == 0, ""); + CORRADE_COMPARE(0, ret); +} + +#define ASSERT(...) if constexpr(__VA_ARGS__) (void)0; else throw "failed" + +template +constexpr int Constexpr14Test::simpleBody() { + constexpr Vec a{T(1), T(2)}, b{T(2), T(3)}; + ASSERT(a[0] == T(1) && a[1] == T(2)); + ASSERT(a + b == Vec(T(3), T(5))); + ASSERT(a - b == Vec(T(-1), T(-1))); + ASSERT(a * b == Vec(T(2), T(6))); + ASSERT(b / a == (std::is_integral::value ? (Vec(T(2), T(1))) : (Vec(T(2), T(1.5))))); + ASSERT(b.product() == T(6)); + ASSERT(b.sum() == T(5)); + return 0; +} + +template +void Constexpr14Test::integer() +{ + setTestCaseTemplateName(TypeTraits::name()); + constexpr int ret = integerBody(); + static_assert(ret == 0, ""); + CORRADE_COMPARE(0, ret); +} + +template +constexpr int Constexpr14Test::integerBody() +{ + constexpr Vec a{T(1), T(2)}, b{T(3), T(4)}; + ASSERT(a[0] == T(1) && a[1] == T(2)); + ASSERT(b % a == Vec(T(0), T(0))); + ASSERT(a % b == Vec(T(1), T(2))); + ASSERT((~a)[0] == ~a[0]); + ASSERT((~b)[0] == ~b[0]); + return 0; +} +#endif + +}}}} + +CORRADE_TEST_MAIN(Magnum::Math::Test::Constexpr14Test) diff --git a/src/Magnum/Math/TypeTraits.h b/src/Magnum/Math/TypeTraits.h index 3dda3fb046..c0cc774f85 100644 --- a/src/Magnum/Math/TypeTraits.h +++ b/src/Magnum/Math/TypeTraits.h @@ -392,7 +392,7 @@ Calls @ref TypeTraits::equals() --- using fuzzy compare for floating-point types and doing equality comparison on integral types. Scalar complement to @ref equal(const Vector& a, const Vector&). */ -template inline typename std::enable_if::value, bool>::type equal(T a, T b) { +template constexpr inline typename std::enable_if::value, bool>::type equal(T a, T b) { return TypeTraits::equals(a, b); } @@ -404,7 +404,7 @@ Calls @ref TypeTraits::equals() --- using fuzzy compare for floating-point types and doing equality comparison on integral types. Scalar complement to @ref notEqual(const Vector& a, const Vector&). */ -template inline typename std::enable_if::value, bool>::type notEqual(T a, T b) { +template constexpr inline typename std::enable_if::value, bool>::type notEqual(T a, T b) { return !TypeTraits::equals(a, b); } @@ -467,17 +467,19 @@ namespace Implementation { template struct TypeTraitsFloatingPoint: TypeTraitsName { TypeTraitsFloatingPoint() = delete; - static bool equals(T a, T b); - static bool equalsZero(T a, T epsilon); + static constexpr T abs(T x) { return x < 0 ? -x : x; } + static CORRADE_CONSTEXPR14 bool equals(T a, T b); + static CORRADE_CONSTEXPR14 bool equalsZero(T a, T epsilon); }; -template bool TypeTraitsFloatingPoint::equals(const T a, const T b) { +template CORRADE_CONSTEXPR14 bool TypeTraitsFloatingPoint::equals(const T a, const T b) { /* Shortcut for binary equality (also infinites) */ if(a == b) return true; - const T absA = std::abs(a); - const T absB = std::abs(b); - const T difference = std::abs(a - b); + const T absA = abs(a); + const T absB = abs(b); + const T difference = abs(a - b); + /* One of the numbers is zero or both are extremely close to it, relative error is meaningless */ @@ -488,11 +490,11 @@ template bool TypeTraitsFloatingPoint::equals(const T a, const T b) return difference/(absA + absB) < TypeTraits::epsilon(); } -template bool TypeTraitsFloatingPoint::equalsZero(const T a, const T magnitude) { +template CORRADE_CONSTEXPR14 bool TypeTraitsFloatingPoint::equalsZero(const T a, const T magnitude) { /* Shortcut for binary equality */ if(a == T(0.0)) return true; - const T absA = std::abs(a); + const T absA = abs(a); /* The value is extremely close to zero, relative error is meaningless */ if(absA < TypeTraits::epsilon()) @@ -538,7 +540,7 @@ namespace Implementation { [1 - epsilon, 1 + epsilon] or dot() in range [1 - 2*epsilon + epsilon^2, 1 + 2*epsilon + epsilon^2]. Because epsilon^2 is way off machine precision, it's omitted. */ -template inline bool isNormalizedSquared(T lengthSquared) { +template constexpr inline bool isNormalizedSquared(T lengthSquared) { return std::abs(lengthSquared - T(1)) < T(2)*TypeTraits::epsilon(); } diff --git a/src/Magnum/Math/Vector.h b/src/Magnum/Math/Vector.h index 46c6b7382d..38348908ae 100644 --- a/src/Magnum/Math/Vector.h +++ b/src/Magnum/Math/Vector.h @@ -64,20 +64,21 @@ template constexpr typename std::enable_if::value, T>::type namespace Implementation { template struct VectorConverter; /* Needed by DualQuaternion and Functions.h (to avoid dependency between them) */ - template T lerp(const T& a, const T& b, U t) { + template constexpr T lerp(const T& a, const T& b, U t) { return T((U(1) - t)*a + t*b); } template struct IsZero; template<> struct IsZero { - template bool operator()(const Vector& vec) const { + template static constexpr T abs(T x) { return x < 0 ? -x : x; } + template constexpr bool operator()(const Vector& vec) const { /* Proper comparison should be with epsilon^2, but the value is not representable in given precision. Comparing to epsilon instead. */ - return std::abs(vec.dot()) < TypeTraits::epsilon(); + return abs(vec.dot()) < TypeTraits::epsilon(); } }; template<> struct IsZero { - template bool operator()(const Vector& vec) const { + template constexpr bool operator()(const Vector& vec) const { return vec == Vector{}; } }; @@ -101,7 +102,7 @@ the same general direction, `1` when two *normalized* vectors are parallel, @f] @see @ref Vector::dot() const, @ref Vector::operator-(), @ref Vector2::perpendicular() */ -template inline T dot(const Vector& a, const Vector& b) { +template CORRADE_CONSTEXPR14 inline T dot(const Vector& a, const Vector& b) { T out{}; for(std::size_t i = 0; i != size; ++i) out += a._data[i]*b._data[i]; @@ -245,7 +246,7 @@ template class Vector { T* data(); constexpr const T* data() const; /**< @overload */ #else - auto data() -> T(&)[size] { return _data; } + CORRADE_CONSTEXPR14 auto data() -> T(&)[size] { return _data; } constexpr auto data() const -> const T(&)[size] { return _data; } #endif @@ -254,7 +255,7 @@ template class Vector { * * @see @ref data() */ - T& operator[](std::size_t pos) { return _data[pos]; } + CORRADE_CONSTEXPR14 T& operator[](std::size_t pos) { return _data[pos]; } constexpr T operator[](std::size_t pos) const { return _data[pos]; } /**< @overload */ /** @@ -262,7 +263,7 @@ template class Vector { * * @see @ref Math::equal() */ - bool operator==(const Vector& other) const { + CORRADE_CONSTEXPR14 bool operator==(const Vector& other) const { for(std::size_t i = 0; i != size; ++i) if(!TypeTraits::equals(_data[i], other._data[i])) return false; @@ -336,7 +337,7 @@ template class Vector { * * Returns the value as-is. */ - Vector operator+() const { return *this; } + CORRADE_CONSTEXPR14 Vector operator+() const { return *this; } /** * @brief Negated vector @@ -349,7 +350,7 @@ template class Vector { #ifdef DOXYGEN_GENERATING_OUTPUT Vector #else - template typename std::enable_if::value, Vector>::type + template CORRADE_CONSTEXPR14 typename std::enable_if::value, Vector>::type #endif operator-() const; @@ -360,7 +361,7 @@ template class Vector { * \boldsymbol a_i = \boldsymbol a_i + \boldsymbol b_i * @f] */ - Vector& operator+=(const Vector& other) { + CORRADE_CONSTEXPR14 Vector& operator+=(const Vector& other) { for(std::size_t i = 0; i != size; ++i) _data[i] += other._data[i]; @@ -372,7 +373,7 @@ template class Vector { * * @see @ref operator+=(), @ref sum() */ - Vector operator+(const Vector& other) const { + CORRADE_CONSTEXPR14 Vector operator+(const Vector& other) const { return Vector(*this) += other; } @@ -383,7 +384,7 @@ template class Vector { * \boldsymbol a_i = \boldsymbol a_i - \boldsymbol b_i * @f] */ - Vector& operator-=(const Vector& other) { + CORRADE_CONSTEXPR14 Vector& operator-=(const Vector& other) { for(std::size_t i = 0; i != size; ++i) _data[i] -= other._data[i]; @@ -395,7 +396,7 @@ template class Vector { * * @see @ref operator-=() */ - Vector operator-(const Vector& other) const { + CORRADE_CONSTEXPR14 Vector operator-(const Vector& other) const { return Vector(*this) -= other; } @@ -408,7 +409,7 @@ template class Vector { * @see @ref operator*=(const Vector&), * @ref operator*=(Vector&, FloatingPoint) */ - Vector& operator*=(T scalar) { + CORRADE_CONSTEXPR14 Vector& operator*=(T scalar) { for(std::size_t i = 0; i != size; ++i) _data[i] *= scalar; @@ -422,7 +423,7 @@ template class Vector { * @ref operator*=(T), @ref operator*(T, const Vector&), * @ref operator*(const Vector&, FloatingPoint) */ - Vector operator*(T scalar) const { + CORRADE_CONSTEXPR14 Vector operator*(T scalar) const { return Vector(*this) *= scalar; } @@ -435,7 +436,7 @@ template class Vector { * @see @ref operator/=(const Vector&), * @ref operator/=(Vector&, FloatingPoint) */ - Vector& operator/=(T scalar) { + CORRADE_CONSTEXPR14 Vector& operator/=(T scalar) { for(std::size_t i = 0; i != size; ++i) _data[i] /= scalar; @@ -449,7 +450,7 @@ template class Vector { * @ref operator/=(T), @ref operator/(T, const Vector&), * @ref operator/(const Vector&, FloatingPoint) */ - Vector operator/(T scalar) const { + CORRADE_CONSTEXPR14 Vector operator/(T scalar) const { return Vector(*this) /= scalar; } @@ -462,7 +463,7 @@ template class Vector { * @see @ref operator*=(T), * @ref operator*=(Vector&, const Vector&) */ - Vector& operator*=(const Vector& other) { + CORRADE_CONSTEXPR14 Vector& operator*=(const Vector& other) { for(std::size_t i = 0; i != size; ++i) _data[i] *= other._data[i]; @@ -476,7 +477,7 @@ template class Vector { * @ref operator*(const Vector&, const Vector&), * @ref product() */ - Vector operator*(const Vector& other) const { + CORRADE_CONSTEXPR14 Vector operator*(const Vector& other) const { return Vector(*this) *= other; } @@ -489,7 +490,7 @@ template class Vector { * @see @ref operator/=(T), * @ref operator/=(Vector&, const Vector&) */ - Vector& operator/=(const Vector& other) { + CORRADE_CONSTEXPR14 Vector& operator/=(const Vector& other) { for(std::size_t i = 0; i != size; ++i) _data[i] /= other._data[i]; @@ -502,7 +503,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 { + CORRADE_CONSTEXPR14 Vector operator/(const Vector& other) const { return Vector(*this) /= other; } @@ -517,7 +518,7 @@ template class Vector { * @ref isNormalized(), @ref Distance::pointPointSquared(), * @ref Intersection::pointSphere() */ - T dot() const { return Math::dot(*this, *this); } + CORRADE_CONSTEXPR14 T dot() const { return Math::dot(*this, *this); } /** * @brief Vector length @@ -544,7 +545,7 @@ template class Vector { * @ref Intersection::pointSphere() * @todo something like std::hypot() for possibly better precision? */ - T length() const { return T(std::sqrt(dot())); } + CORRADE_CONSTEXPR14 T length() const { return T(std::sqrt(dot())); } /** * @brief Inverse vector length @@ -558,7 +559,7 @@ template class Vector { #ifdef DOXYGEN_GENERATING_OUTPUT T #else - template typename std::enable_if::value, T>::type + template CORRADE_CONSTEXPR14 typename std::enable_if::value, T>::type #endif lengthInverted() const { return T(1)/length(); } @@ -572,7 +573,7 @@ template class Vector { #ifdef DOXYGEN_GENERATING_OUTPUT Vector #else - template typename std::enable_if::value, Vector>::type + template CORRADE_CONSTEXPR14 typename std::enable_if::value, Vector>::type #endif normalized() const { return *this*lengthInverted(); } @@ -590,7 +591,7 @@ template class Vector { #ifdef DOXYGEN_GENERATING_OUTPUT Vector #else - template typename std::enable_if::value, Vector>::type + template CORRADE_CONSTEXPR14 typename std::enable_if::value, Vector>::type #endif resized(T length) const { return *this*(lengthInverted()*length); @@ -608,7 +609,7 @@ template class Vector { #ifdef DOXYGEN_GENERATING_OUTPUT Vector #else - template typename std::enable_if::value, Vector>::type + template CORRADE_CONSTEXPR14 typename std::enable_if::value, Vector>::type #endif projected(const Vector& line) const { return line*Math::dot(*this, line)/line.dot(); @@ -627,7 +628,7 @@ template class Vector { #ifdef DOXYGEN_GENERATING_OUTPUT Vector #else - template typename std::enable_if::value, Vector>::type + template CORRADE_CONSTEXPR14 typename std::enable_if::value, Vector>::type #endif projectedOntoNormalized(const Vector& line) const; @@ -647,14 +648,14 @@ template class Vector { * * @see @ref operator+(), @ref length() */ - T sum() const; + CORRADE_CONSTEXPR14 T sum() const; /** * @brief Product of values in the vector * * @see @ref operator*(const Vector&) const */ - T product() const; + CORRADE_CONSTEXPR14 T product() const; /** * @brief Minimal value in the vector @@ -662,7 +663,7 @@ template class Vector { * NaNs are ignored, unless the vector is all NaNs. * @see @ref Math::min(), @ref minmax(), @ref Math::isNan() */ - T min() const; + CORRADE_CONSTEXPR14 T min() const; /** * @brief Maximal value in the vector @@ -670,7 +671,7 @@ template class Vector { * NaNs are ignored, unless the vector is all NaNs. * @see @ref Math::max(), @ref minmax(), @ref Math::isNan() */ - T max() const; + CORRADE_CONSTEXPR14 T max() const; /** * @brief Minimal and maximal value in the vector @@ -678,7 +679,7 @@ template class Vector { * NaNs are ignored, unless the vector is all NaNs. * @see @ref min(), @ref max(), @ref Math::minmax(), @ref Math::isNan() */ - std::pair minmax() const; + CORRADE_CONSTEXPR14 std::pair minmax() const; #ifndef DOXYGEN_GENERATING_OUTPUT protected: @@ -710,7 +711,7 @@ template class Vector { template friend BitVector equal(const Vector&, const Vector&); template friend BitVector notEqual(const Vector&, const Vector&); - template friend U dot(const Vector&, const Vector&); + template friend CORRADE_CONSTEXPR14 U dot(const Vector&, const Vector&); /* Implementation for Vector::Vector(const Vector&) */ template constexpr explicit Vector(Corrade::Containers::Implementation::Sequence, const Vector& vector) noexcept: _data{T(vector._data[sequence])...} {} @@ -764,7 +765,7 @@ template inline BitVector notEqual(const Vector Same as @ref Vector::operator*(T) const. */ -template inline Vector operator*( +template inline Vector CORRADE_CONSTEXPR14 operator*( #ifdef DOXYGEN_GENERATING_OUTPUT T #else @@ -783,7 +784,7 @@ template inline Vector operator*( @f] @see @ref Vector::operator/(T) const */ -template inline Vector operator/( +template inline Vector CORRADE_CONSTEXPR14 operator/( #ifdef DOXYGEN_GENERATING_OUTPUT T #else @@ -804,7 +805,7 @@ template inline Vector operator/( The computation is done in-place. */ -template inline +template CORRADE_CONSTEXPR14 inline #ifdef DOXYGEN_GENERATING_OUTPUT Vector& #else @@ -820,7 +821,7 @@ operator%=(Vector& a, Integral b) { /** @relates Vector @brief Modulo of an integral vector */ -template inline +template CORRADE_CONSTEXPR14 inline #ifdef DOXYGEN_GENERATING_OUTPUT Vector #else @@ -836,7 +837,7 @@ operator%(const Vector& a, Integral b) { The computation is done in-place. */ -template inline +template CORRADE_CONSTEXPR14 inline #ifdef DOXYGEN_GENERATING_OUTPUT Vector& #else @@ -852,7 +853,7 @@ operator%=(Vector& a, const Vector& b) { /** @relates Vector @brief Modulo of two integral vectors */ -template inline +template CORRADE_CONSTEXPR14 inline #ifdef DOXYGEN_GENERATING_OUTPUT Vector #else @@ -866,7 +867,7 @@ operator%(const Vector& a, const Vector& b) { /** @relates Vector @brief Bitwise NOT of an integral vector */ -template inline +template CORRADE_CONSTEXPR14 inline #ifdef DOXYGEN_GENERATING_OUTPUT Vector #else @@ -886,7 +887,7 @@ operator~(const Vector& vector) { The computation is done in-place. */ -template inline +template CORRADE_CONSTEXPR14 inline #ifdef DOXYGEN_GENERATING_OUTPUT Vector& #else @@ -902,7 +903,7 @@ operator&=(Vector& a, const Vector& b) { /** @relates Vector @brief Bitwise AND of two integral vectors */ -template inline +template CORRADE_CONSTEXPR14 inline #ifdef DOXYGEN_GENERATING_OUTPUT Vector #else @@ -918,7 +919,7 @@ operator&(const Vector& a, const Vector& b) { The computation is done in-place. */ -template inline +template CORRADE_CONSTEXPR14 inline #ifdef DOXYGEN_GENERATING_OUTPUT Vector& #else @@ -934,7 +935,7 @@ operator|=(Vector& a, const Vector& b) { /** @relates Vector @brief Bitwise OR of two integral vectors */ -template inline +template CORRADE_CONSTEXPR14 inline #ifdef DOXYGEN_GENERATING_OUTPUT Vector #else @@ -950,7 +951,7 @@ operator|(const Vector& a, const Vector& b) { The computation is done in-place. */ -template inline +template CORRADE_CONSTEXPR14 inline #ifdef DOXYGEN_GENERATING_OUTPUT Vector& #else @@ -966,7 +967,7 @@ operator^=(Vector& a, const Vector& b) { /** @relates Vector @brief Bitwise XOR of two integral vectors */ -template inline +template CORRADE_CONSTEXPR14 inline #ifdef DOXYGEN_GENERATING_OUTPUT Vector #else @@ -982,7 +983,7 @@ operator^(const Vector& a, const Vector& b) { The computation is done in-place. */ -template inline +template CORRADE_CONSTEXPR14 inline #ifdef DOXYGEN_GENERATING_OUTPUT Vector& #else @@ -1005,7 +1006,7 @@ operator<<=(Vector& vector, /** @relates Vector @brief Bitwise left shift of an integral vector */ -template inline +template CORRADE_CONSTEXPR14 inline #ifdef DOXYGEN_GENERATING_OUTPUT Vector #else @@ -1028,7 +1029,7 @@ operator<<(const Vector& vector, The computation is done in-place. */ -template inline +template CORRADE_CONSTEXPR14 inline #ifdef DOXYGEN_GENERATING_OUTPUT Vector& #else @@ -1050,7 +1051,7 @@ operator>>=(Vector& vector, /** @relates Vector @brief Bitwise left shift of an integral vector */ -template inline +template CORRADE_CONSTEXPR14 inline #ifdef DOXYGEN_GENERATING_OUTPUT Vector #else @@ -1073,7 +1074,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 CORRADE_CONSTEXPR14 inline #ifdef DOXYGEN_GENERATING_OUTPUT Vector& #else @@ -1092,7 +1093,7 @@ operator*=(Vector& vector, FloatingPoint scalar) { Similar to @ref Vector::operator*(T) const, except that the multiplication is done in floating-point. */ -template inline +template CORRADE_CONSTEXPR14 inline #ifdef DOXYGEN_GENERATING_OUTPUT Vector #else @@ -1108,7 +1109,7 @@ operator*(const Vector& vector, FloatingPoint scalar) { Same as @ref operator*(const Vector&, FloatingPoint). */ -template inline +template constexpr inline #ifdef DOXYGEN_GENERATING_OUTPUT Vector #else @@ -1124,7 +1125,7 @@ operator*(FloatingPoint scalar, 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 CORRADE_CONSTEXPR14 inline #ifdef DOXYGEN_GENERATING_OUTPUT Vector& #else @@ -1143,7 +1144,7 @@ operator/=(Vector& vector, FloatingPoint scalar) { Similar to @ref Vector::operator/(T) const, except that the division is done in floating-point. */ -template inline +template CORRADE_CONSTEXPR14 inline #ifdef DOXYGEN_GENERATING_OUTPUT Vector #else @@ -1160,7 +1161,7 @@ operator/(const Vector& vector, FloatingPoint scalar) { 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 CORRADE_CONSTEXPR14 inline #ifdef DOXYGEN_GENERATING_OUTPUT Vector& #else @@ -1181,7 +1182,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 CORRADE_CONSTEXPR14 inline #ifdef DOXYGEN_GENERATING_OUTPUT Vector #else @@ -1197,7 +1198,7 @@ operator*(const Vector& a, const Vector& b) Same as @ref operator*(const Vector&, const Vector&). */ -template inline +template CORRADE_CONSTEXPR14 inline #ifdef DOXYGEN_GENERATING_OUTPUT Vector #else @@ -1213,7 +1214,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 CORRADE_CONSTEXPR14 inline #ifdef DOXYGEN_GENERATING_OUTPUT Vector& #else @@ -1234,7 +1235,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 CORRADE_CONSTEXPR14 inline #ifdef DOXYGEN_GENERATING_OUTPUT Vector #else @@ -1288,66 +1289,66 @@ extern template MAGNUM_EXPORT Corrade::Utility::Debug& operator<<(Corrade::Utili return Math::Vector::pad(a, value); \ } \ \ - Type operator+() const { \ + constexpr Type operator+() const { \ return Math::Vector::operator+(); \ } \ - template typename std::enable_if::value, Type>::type \ - operator-() const { \ + template typename std::enable_if::value, Type>::type \ + constexpr operator-() const { \ return Math::Vector::operator-(); \ } \ - Type& operator+=(const Math::Vector& other) { \ + CORRADE_CONSTEXPR14 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) { \ + CORRADE_CONSTEXPR14 Type& operator-=(const Math::Vector& other) { \ Math::Vector::operator-=(other); \ return *this; \ } \ - Type operator-(const Math::Vector& other) const { \ + CORRADE_CONSTEXPR14 Type operator-(const Math::Vector& other) const { \ return Math::Vector::operator-(other); \ } \ - Type& operator*=(T number) { \ + CORRADE_CONSTEXPR14 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) { \ + CORRADE_CONSTEXPR14 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) { \ + CORRADE_CONSTEXPR14 Type& operator*=(const Math::Vector& other) { \ Math::Vector::operator*=(other); \ return *this; \ } \ - Type operator*(const Math::Vector& other) const { \ + CORRADE_CONSTEXPR14 Type operator*(const Math::Vector& other) const { \ return Math::Vector::operator*(other); \ } \ - Type& operator/=(const Math::Vector& other) { \ + CORRADE_CONSTEXPR14 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); \ } \ \ - template typename std::enable_if::value, Type>::type normalized() const { \ + template constexpr typename std::enable_if::value, Type>::type normalized() const { \ return Math::Vector::normalized(); \ } \ - template typename std::enable_if::value, Type>::type resized(T length) const { \ + template constexpr typename std::enable_if::value, Type>::type resized(T length) const { \ return Math::Vector::resized(length); \ } \ - template typename std::enable_if::value, Type>::type projected(const Math::Vector& other) const { \ + template constexpr typename std::enable_if::value, Type>::type projected(const Math::Vector& other) const { \ return Math::Vector::projected(other); \ } \ - template typename std::enable_if::value, Type>::type projectedOntoNormalized(const Math::Vector& other) const { \ + template constexpr typename std::enable_if::value, Type>::type projectedOntoNormalized(const Math::Vector& other) const { \ return Math::Vector::projectedOntoNormalized(other); \ } \ constexpr Type flipped() const { \ @@ -1355,99 +1356,99 @@ extern template MAGNUM_EXPORT Corrade::Utility::Debug& operator<<(Corrade::Utili } #define MAGNUM_VECTORn_OPERATOR_IMPLEMENTATION(size, Type) \ - template inline Type operator*(typename std::common_type::type number, const Type& vector) { \ + template constexpr inline 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 constexpr inline 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 CORRADE_CONSTEXPR14 inline 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 constexpr inline 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 CORRADE_CONSTEXPR14 inline 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 constexpr inline 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 constexpr inline 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 CORRADE_CONSTEXPR14 inline 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 constexpr inline 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 CORRADE_CONSTEXPR14 inline 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 constexpr inline 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 CORRADE_CONSTEXPR14 inline 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 CORRADE_CONSTEXPR14 inline 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 CORRADE_CONSTEXPR14 inline 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 constexpr inline 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 CORRADE_CONSTEXPR14 inline 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 CORRADE_CONSTEXPR14 inline 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 CORRADE_CONSTEXPR14 inline 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 constexpr inline 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 constexpr inline 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 CORRADE_CONSTEXPR14 inline 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 constexpr inline 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 CORRADE_CONSTEXPR14 inline 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 constexpr inline 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 constexpr inline 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 CORRADE_CONSTEXPR14 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 CORRADE_CONSTEXPR14 inline 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 @@ -1494,7 +1495,7 @@ inline Vector #else template inline typename std::enable_if::value, Vector>::type #endif -Vector::operator-() const { +CORRADE_CONSTEXPR14 Vector::operator-() const { Vector out; for(std::size_t i = 0; i != size; ++i) @@ -1507,7 +1508,7 @@ template #ifdef DOXYGEN_GENERATING_OUTPUT inline Vector #else -template inline typename std::enable_if::value, Vector>::type +template CORRADE_CONSTEXPR14 inline typename std::enable_if::value, Vector>::type #endif Vector::projectedOntoNormalized(const Vector& line) const { CORRADE_ASSERT(line.isNormalized(), @@ -1515,7 +1516,7 @@ Vector::projectedOntoNormalized(const Vector& line) const { return line*Math::dot(*this, line); } -template inline T Vector::sum() const { +template CORRADE_CONSTEXPR14 inline T Vector::sum() const { T out(_data[0]); for(std::size_t i = 1; i != size; ++i) @@ -1524,7 +1525,7 @@ template inline T Vector::sum() const { return out; } -template inline T Vector::product() const { +template CORRADE_CONSTEXPR14 inline T Vector::product() const { T out(_data[0]); for(std::size_t i = 1; i != size; ++i) @@ -1549,7 +1550,7 @@ namespace Implementation { } } -template inline T Vector::min() const { +template CORRADE_CONSTEXPR14 inline T Vector::min() const { std::size_t i = Implementation::firstNonNan(_data, IsFloatingPoint{}); T out(_data[i]); @@ -1559,7 +1560,7 @@ template inline T Vector::min() const { return out; } -template inline T Vector::max() const { +template CORRADE_CONSTEXPR14 inline T Vector::max() const { std::size_t i = Implementation::firstNonNan(_data, IsFloatingPoint{}); T out(_data[i]); @@ -1569,7 +1570,7 @@ template inline T Vector::max() const { return out; } -template inline std::pair Vector::minmax() const { +template CORRADE_CONSTEXPR14 inline std::pair Vector::minmax() const { std::size_t i = Implementation::firstNonNan(_data, IsFloatingPoint{}); T min{_data[i]}, max{_data[i]}; diff --git a/src/Magnum/Math/Vector2.h b/src/Magnum/Math/Vector2.h index f3588d2f55..56b7cacc24 100644 --- a/src/Magnum/Math/Vector2.h +++ b/src/Magnum/Math/Vector2.h @@ -47,7 +47,7 @@ perpendicular. @f[ @see @ref Vector2::perpendicular(), @ref dot(const Vector&, const Vector&) */ -template inline T cross(const Vector2& a, const Vector2& b) { +template constexpr inline T cross(const Vector2& a, const Vector2& b) { return a._data[0]*b._data[1] - a._data[1]*b._data[0]; } @@ -142,9 +142,9 @@ template class Vector2: public Vector<2, T> { /** @brief Copy constructor */ constexpr /*implicit*/ Vector2(const Vector<2, T>& other) noexcept: Vector<2, T>(other) {} - T& x() { return Vector<2, T>::_data[0]; } /**< @brief X component */ + CORRADE_CONSTEXPR14 T& x() { return Vector<2, T>::_data[0]; } /**< @brief X component */ constexpr T x() const { return Vector<2, T>::_data[0]; } /**< @overload */ - T& y() { return Vector<2, T>::_data[1]; } /**< @brief Y component */ + CORRADE_CONSTEXPR14 T& y() { return Vector<2, T>::_data[1]; } /**< @brief Y component */ constexpr T y() const { return Vector<2, T>::_data[1]; } /**< @overload */ /** @@ -162,7 +162,7 @@ template class Vector2: public Vector<2, T> { #ifdef DOXYGEN_GENERATING_OUTPUT Vector2 #else - template typename std::enable_if::value, Vector2>::type + template constexpr typename std::enable_if::value, Vector2>::type #endif perpendicular() const { return {-y(), x()}; } @@ -177,14 +177,14 @@ template class Vector2: public Vector<2, T> { #ifdef DOXYGEN_GENERATING_OUTPUT T #else - template typename std::enable_if::value, T>::type + template constexpr typename std::enable_if::value, T>::type #endif aspectRatio() const { return x()/y(); } MAGNUM_VECTOR_SUBCLASS_IMPLEMENTATION(2, Vector2) private: - template friend U cross(const Vector2&, const Vector2&); + template friend constexpr U cross(const Vector2&, const Vector2&); }; #ifndef DOXYGEN_GENERATING_OUTPUT diff --git a/src/Magnum/Math/Vector3.h b/src/Magnum/Math/Vector3.h index 1a814a5e34..36b68bb172 100644 --- a/src/Magnum/Math/Vector3.h +++ b/src/Magnum/Math/Vector3.h @@ -48,7 +48,7 @@ are corners of a triangle in a counterclockwise order, gives the direction of its normal. @see @ref cross(const Vector2&, const Vector2&), @ref planeEquation() */ -template inline Vector3 cross(const Vector3& a, const Vector3& b) { +template constexpr inline Vector3 cross(const Vector3& a, const Vector3& b) { return { a._data[1]*b._data[2] - b._data[1]*a._data[2], a._data[2]*b._data[0] - b._data[2]*a._data[0], @@ -178,7 +178,7 @@ template class Vector3: public Vector<3, T> { * * @see @ref r() */ - T& x() { return Vector<3, T>::_data[0]; } + CORRADE_CONSTEXPR14 T& x() { return Vector<3, T>::_data[0]; } constexpr T x() const { return Vector<3, T>::_data[0]; } /**< @overload */ /** @@ -186,7 +186,7 @@ template class Vector3: public Vector<3, T> { * * @see @ref g() */ - T& y() { return Vector<3, T>::_data[1]; } + CORRADE_CONSTEXPR14 T& y() { return Vector<3, T>::_data[1]; } constexpr T y() const { return Vector<3, T>::_data[1]; } /**< @overload */ /** @@ -194,7 +194,7 @@ template class Vector3: public Vector<3, T> { * * @see @ref b() */ - T& z() { return Vector<3, T>::_data[2]; } + CORRADE_CONSTEXPR14 T& z() { return Vector<3, T>::_data[2]; } constexpr T z() const { return Vector<3, T>::_data[2]; } /**< @overload */ /** @@ -202,7 +202,7 @@ template class Vector3: public Vector<3, T> { * * Equivalent to @ref x(). */ - T& r() { return Vector<3, T>::_data[0]; } + CORRADE_CONSTEXPR14 T& r() { return Vector<3, T>::_data[0]; } constexpr T r() const { return Vector<3, T>::_data[0]; } /**< @overload */ /** @@ -210,7 +210,7 @@ template class Vector3: public Vector<3, T> { * * Equivalent to @ref y(). */ - T& g() { return Vector<3, T>::_data[1]; } + CORRADE_CONSTEXPR14 T& g() { return Vector<3, T>::_data[1]; } constexpr T g() const { return Vector<3, T>::_data[1]; } /**< @overload */ /** @@ -218,7 +218,7 @@ template class Vector3: public Vector<3, T> { * * Equivalent to @ref z(). */ - T& b() { return Vector<3, T>::_data[2]; } + CORRADE_CONSTEXPR14 T& b() { return Vector<3, T>::_data[2]; } constexpr T b() const { return Vector<3, T>::_data[2]; } /**< @overload */ /** @@ -227,7 +227,7 @@ template class Vector3: public Vector<3, T> { * * @see @ref gather(), @ref scatter() */ - Vector2& xy() { return Vector2::from(Vector<3, T>::data()); } + CORRADE_CONSTEXPR14 Vector2& xy() { return Vector2::from(Vector<3, T>::data()); } constexpr const Vector2 xy() const { return {Vector<3, T>::_data[0], Vector<3, T>::_data[1]}; } /**< @overload */ @@ -235,7 +235,7 @@ template class Vector3: public Vector<3, T> { MAGNUM_VECTOR_SUBCLASS_IMPLEMENTATION(3, Vector3) private: - template friend Vector3 cross(const Vector3&, const Vector3&); + template friend constexpr Vector3 cross(const Vector3&, const Vector3&); }; #ifndef DOXYGEN_GENERATING_OUTPUT diff --git a/src/Magnum/Math/Vector4.h b/src/Magnum/Math/Vector4.h index c2254ec50d..f7ff6c4101 100644 --- a/src/Magnum/Math/Vector4.h +++ b/src/Magnum/Math/Vector4.h @@ -120,7 +120,7 @@ template class Vector4: public Vector<4, T> { * * @see @ref r() */ - T& x() { return Vector<4, T>::_data[0]; } + CORRADE_CONSTEXPR14 T& x() { return Vector<4, T>::_data[0]; } constexpr T x() const { return Vector<4, T>::_data[0]; } /**< @overload */ /** @@ -128,7 +128,7 @@ template class Vector4: public Vector<4, T> { * * @see @ref g() */ - T& y() { return Vector<4, T>::_data[1]; } + CORRADE_CONSTEXPR14 T& y() { return Vector<4, T>::_data[1]; } constexpr T y() const { return Vector<4, T>::_data[1]; } /**< @overload */ /** @@ -136,7 +136,7 @@ template class Vector4: public Vector<4, T> { * * @see @ref b() */ - T& z() { return Vector<4, T>::_data[2]; } + CORRADE_CONSTEXPR14 T& z() { return Vector<4, T>::_data[2]; } constexpr T z() const { return Vector<4, T>::_data[2]; } /**< @overload */ /** @@ -144,7 +144,7 @@ template class Vector4: public Vector<4, T> { * * @see @ref a() */ - T& w() { return Vector<4, T>::_data[3]; } + CORRADE_CONSTEXPR14 T& w() { return Vector<4, T>::_data[3]; } constexpr T w() const { return Vector<4, T>::_data[3]; } /**< @overload */ /** @@ -152,7 +152,7 @@ template class Vector4: public Vector<4, T> { * * Equivalent to @ref x(). */ - T& r() { return Vector<4, T>::_data[0]; } + CORRADE_CONSTEXPR14 T& r() { return Vector<4, T>::_data[0]; } constexpr T r() const { return Vector<4, T>::_data[0]; } /**< @overload */ /** @@ -160,7 +160,7 @@ template class Vector4: public Vector<4, T> { * * Equivalent to @ref y(). */ - T& g() { return Vector<4, T>::_data[1]; } + CORRADE_CONSTEXPR14 T& g() { return Vector<4, T>::_data[1]; } constexpr T g() const { return Vector<4, T>::_data[1]; } /**< @overload */ /** @@ -168,7 +168,7 @@ template class Vector4: public Vector<4, T> { * * Equivalent to @ref z(). */ - T& b() { return Vector<4, T>::_data[2]; } + CORRADE_CONSTEXPR14 T& b() { return Vector<4, T>::_data[2]; } constexpr T b() const { return Vector<4, T>::_data[2]; } /**< @overload */ /** @@ -176,7 +176,7 @@ template class Vector4: public Vector<4, T> { * * Equivalent to @ref w(). */ - T& a() { return Vector<4, T>::_data[3]; } + CORRADE_CONSTEXPR14 T& a() { return Vector<4, T>::_data[3]; } constexpr T a() const { return Vector<4, T>::_data[3]; } /**< @overload */ /** @@ -185,7 +185,7 @@ template class Vector4: public Vector<4, T> { * * @see @ref rgb(), @ref gather(), @ref scatter() */ - Vector3& xyz() { return Vector3::from(Vector<4, T>::data()); } + CORRADE_CONSTEXPR14 Vector3& xyz() { return Vector3::from(Vector<4, T>::data()); } constexpr const Vector3 xyz() const { return {Vector<4, T>::_data[0], Vector<4, T>::_data[1], Vector<4, T>::_data[2]}; } /**< @overload */ @@ -197,7 +197,7 @@ template class Vector4: public Vector<4, T> { * Equivalent to @ref xyz(). * @see @ref gather(), @ref scatter() */ - Vector3& rgb() { return Vector3::from(Vector<4, T>::data()); } + CORRADE_CONSTEXPR14 Vector3& rgb() { return Vector3::from(Vector<4, T>::data()); } constexpr const Vector3 rgb() const { return {Vector<4, T>::_data[0], Vector<4, T>::_data[1], Vector<4, T>::_data[2]}; } /**< @overload */ @@ -208,7 +208,7 @@ template class Vector4: public Vector<4, T> { * * @see @ref gather(), @ref scatter() */ - Vector2& xy() { return Vector2::from(Vector<4, T>::data()); } + CORRADE_CONSTEXPR14 Vector2& xy() { return Vector2::from(Vector<4, T>::data()); } constexpr const Vector2 xy() const { return {Vector<4, T>::_data[0], Vector<4, T>::_data[1]}; } /**< @overload */ @@ -237,7 +237,7 @@ when assigning @f$ \boldsymbol{p_i} @f$ to @f$ x @f$, @f$ y @f$, @f$ z @f$. @f[ @see @ref planeEquation(const Vector3&, const Vector3&), @ref cross(), @ref dot() */ -template Vector4 planeEquation(const Vector3& p0, const Vector3& p1, const Vector3& p2) { +template CORRADE_CONSTEXPR14 Vector4 planeEquation(const Vector3& p0, const Vector3& p1, const Vector3& p2) { const Vector3 normal = Math::cross(p1 - p0, p2 - p0).normalized(); return {normal, -Math::dot(normal, p0)}; } @@ -260,7 +260,7 @@ using a dot product with the normal @f$ \boldsymbol{n} @f$ using the point @see @ref planeEquation(const Vector3&, const Vector3&, const Vector3&), @ref dot(), @ref Frustum */ -template Vector4 planeEquation(const Vector3& normal, const Vector3& point) { +template CORRADE_CONSTEXPR14 Vector4 planeEquation(const Vector3& normal, const Vector3& point) { return {normal, -Math::dot(normal, point)}; }