From f297d593bf7d730870220591a6b19739443bdaea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Mon, 11 Aug 2025 19:31:45 +0200 Subject: [PATCH] Math: make all trivial mutable getters constexpr under C++14. Technically speaking there are many more opportunities to mark things as C++14 constexpr, such as various operators, but doing so would make them impossible to optimize with various (SIMD) intrisnics unless basically providing two separate implementations for them, one scalar, slow and constexpr and the other fast but not compile time, and dispatching with std::is_constant_evaluated() or some such from C++20. In other words, such functions cannot and will not be marked as constexpr in C++17 or older anyway, because the preference is and still should be runtime perf rather than doing excessive work at compile time, where it's hard to debug or reasonably test etc etc., and the more you rebuild the more you'll hate the cost of extra compile time caused by that. Co-authored-by: Stanislaw Halik --- src/Magnum/Math/Bezier.h | 6 +- src/Magnum/Math/BitVector.h | 5 +- src/Magnum/Math/Complex.h | 4 +- src/Magnum/Math/CubicHermite.h | 6 +- src/Magnum/Math/Dual.h | 4 +- src/Magnum/Math/Frustum.h | 18 ++-- src/Magnum/Math/Quaternion.h | 4 +- src/Magnum/Math/Range.h | 32 +++--- src/Magnum/Math/RectangularMatrix.h | 2 +- src/Magnum/Math/Test/BezierCpp14Test.cpp | 64 +++++++++++ src/Magnum/Math/Test/BitVectorCpp14Test.cpp | 62 +++++++++++ src/Magnum/Math/Test/CMakeLists.txt | 38 +++++++ src/Magnum/Math/Test/ComplexCpp14Test.cpp | 61 +++++++++++ .../Math/Test/CubicHermiteCpp14Test.cpp | 62 +++++++++++ src/Magnum/Math/Test/DualCpp14Test.cpp | 61 +++++++++++ src/Magnum/Math/Test/FrustumCpp14Test.cpp | 75 +++++++++++++ src/Magnum/Math/Test/QuaternionCpp14Test.cpp | 62 +++++++++++ src/Magnum/Math/Test/RangeCpp14Test.cpp | 102 ++++++++++++++++++ .../Math/Test/RectangularMatrixCpp14Test.cpp | 62 +++++++++++ src/Magnum/Math/Test/Vector2Cpp14Test.cpp | 63 +++++++++++ src/Magnum/Math/Test/Vector3Cpp14Test.cpp | 65 +++++++++++ src/Magnum/Math/Test/Vector4Cpp14Test.cpp | 67 ++++++++++++ src/Magnum/Math/Test/VectorCpp14Test.cpp | 61 +++++++++++ src/Magnum/Math/Vector.h | 6 +- src/Magnum/Math/Vector2.h | 8 +- src/Magnum/Math/Vector3.h | 12 +-- src/Magnum/Math/Vector4.h | 16 +-- 27 files changed, 967 insertions(+), 61 deletions(-) create mode 100644 src/Magnum/Math/Test/BezierCpp14Test.cpp create mode 100644 src/Magnum/Math/Test/BitVectorCpp14Test.cpp create mode 100644 src/Magnum/Math/Test/ComplexCpp14Test.cpp create mode 100644 src/Magnum/Math/Test/CubicHermiteCpp14Test.cpp create mode 100644 src/Magnum/Math/Test/DualCpp14Test.cpp create mode 100644 src/Magnum/Math/Test/FrustumCpp14Test.cpp create mode 100644 src/Magnum/Math/Test/QuaternionCpp14Test.cpp create mode 100644 src/Magnum/Math/Test/RangeCpp14Test.cpp create mode 100644 src/Magnum/Math/Test/RectangularMatrixCpp14Test.cpp create mode 100644 src/Magnum/Math/Test/Vector2Cpp14Test.cpp create mode 100644 src/Magnum/Math/Test/Vector3Cpp14Test.cpp create mode 100644 src/Magnum/Math/Test/Vector4Cpp14Test.cpp create mode 100644 src/Magnum/Math/Test/VectorCpp14Test.cpp diff --git a/src/Magnum/Math/Bezier.h b/src/Magnum/Math/Bezier.h index 1cafce876..4ec4d1fbe 100644 --- a/src/Magnum/Math/Bezier.h +++ b/src/Magnum/Math/Bezier.h @@ -174,10 +174,10 @@ template class Bezier { * post-processing step (https://github.com/mosra/m.css/issues/56) */ #ifdef DOXYGEN_GENERATING_OUTPUT - VectorType* data(); + CORRADE_CONSTEXPR14 VectorType* data(); constexpr const VectorType* data() const; /**< @overload */ #else - auto data() -> VectorType(&)[order + 1] { return _data; } + CORRADE_CONSTEXPR14 auto data() -> VectorType(&)[order + 1] { return _data; } constexpr auto data() const -> const VectorType(&)[order + 1] { return _data; } #endif @@ -208,7 +208,7 @@ template class Bezier { * * @p i should not be larger than @ref Order. */ - VectorType& operator[](std::size_t i) { return _data[i]; } + CORRADE_CONSTEXPR14 VectorType& operator[](std::size_t i) { return _data[i]; } /* returns const& so [][] operations are also constexpr */ constexpr const VectorType& operator[](std::size_t i) const { return _data[i]; } /**< @overload */ diff --git a/src/Magnum/Math/BitVector.h b/src/Magnum/Math/BitVector.h index 73b81b37c..f53fee546 100644 --- a/src/Magnum/Math/BitVector.h +++ b/src/Magnum/Math/BitVector.h @@ -38,6 +38,7 @@ #ifndef CORRADE_SINGLES_NO_DEBUG #include #endif +#include /* CORRADE_CONSTEXPR14 */ #include "Magnum/Magnum.h" #include "Magnum/Math/Math.h" @@ -151,10 +152,10 @@ template class BitVector { * post-processing step (https://github.com/mosra/m.css/issues/56) */ #ifdef DOXYGEN_GENERATING_OUTPUT - UnsignedByte* data(); + CORRADE_CONSTEXPR14 UnsignedByte* data(); constexpr const UnsignedByte* data() const; /**< @overload */ #else - auto data() -> UnsignedByte(&)[DataSize] { return _data; } + CORRADE_CONSTEXPR14 auto data() -> UnsignedByte(&)[DataSize] { return _data; } constexpr auto data() const -> const UnsignedByte(&)[DataSize] { return _data; } #endif diff --git a/src/Magnum/Math/Complex.h b/src/Magnum/Math/Complex.h index 305d62317..78788ef38 100644 --- a/src/Magnum/Math/Complex.h +++ b/src/Magnum/Math/Complex.h @@ -248,7 +248,7 @@ template class Complex { * * @see @ref data() */ - T& real() { return _real; } + CORRADE_CONSTEXPR14 T& real() { return _real; } constexpr T real() const { return _real; } /**< @overload */ /** @@ -256,7 +256,7 @@ template class Complex { * * @see @ref data() */ - T& imaginary() { return _imaginary; } + CORRADE_CONSTEXPR14 T& imaginary() { return _imaginary; } constexpr T imaginary() const { return _imaginary; } /**< @overload */ /** diff --git a/src/Magnum/Math/CubicHermite.h b/src/Magnum/Math/CubicHermite.h index 3c480eb80..e93f32d57 100644 --- a/src/Magnum/Math/CubicHermite.h +++ b/src/Magnum/Math/CubicHermite.h @@ -190,17 +190,17 @@ template class CubicHermite { } /** @brief In-tangent @f$ \boldsymbol{m} @f$ */ - T& inTangent() { return _inTangent; } + CORRADE_CONSTEXPR14 T& inTangent() { return _inTangent; } /* returns const& so [] operations are also constexpr */ constexpr const T& inTangent() const { return _inTangent; } /**< @overload */ /** @brief Point @f$ \boldsymbol{p} @f$ */ - T& point() { return _point; } + CORRADE_CONSTEXPR14 T& point() { return _point; } /* returns const& so [] operations are also constexpr */ constexpr const T& point() const { return _point; } /**< @overload */ /** @brief Out-tangent @f$ \boldsymbol{n} @f$ */ - T& outTangent() { return _outTangent; } + CORRADE_CONSTEXPR14 T& outTangent() { return _outTangent; } /* returns const& so [] operations are also constexpr */ constexpr const T& outTangent() const { return _outTangent; } /**< @overload */ diff --git a/src/Magnum/Math/Dual.h b/src/Magnum/Math/Dual.h index f633c3006..b4b61dbab 100644 --- a/src/Magnum/Math/Dual.h +++ b/src/Magnum/Math/Dual.h @@ -185,7 +185,7 @@ template class Dual { * * @see @ref data() */ - T& real() { return _real; } + CORRADE_CONSTEXPR14 T& real() { return _real; } /* Returning const so it's possible to call constexpr functions on the result. WTF, C++?! */ constexpr const T real() const { return _real; } /**< @overload */ @@ -195,7 +195,7 @@ template class Dual { * * @see @ref data() */ - T& dual() { return _dual; } + CORRADE_CONSTEXPR14 T& dual() { return _dual; } /* Returning const so it's possible to call constexpr functions on the result. WTF, C++?! */ constexpr const T dual() const { return _dual; } /**< @overload */ diff --git a/src/Magnum/Math/Frustum.h b/src/Magnum/Math/Frustum.h index 2b0c31dc6..609d3ac99 100644 --- a/src/Magnum/Math/Frustum.h +++ b/src/Magnum/Math/Frustum.h @@ -177,7 +177,7 @@ template class Frustum { * * Expects that @p i is less than @cpp 6 @ce. */ - Vector4& operator[](std::size_t i) { + CORRADE_CONSTEXPR14 Vector4& operator[](std::size_t i) { CORRADE_DEBUG_ASSERT(i < 6, "Math::Frustum::operator[](): index" << i << "out of range", _data[i]); return _data[i]; @@ -199,7 +199,7 @@ template class Frustum { * * @snippet Math.cpp Frustum-range */ - Vector4* begin() { return _data; } + CORRADE_CONSTEXPR14 Vector4* begin() { return _data; } /** * @overload @@ -217,7 +217,7 @@ template class Frustum { * @brief (One after) last plane * @m_since{2019,10} */ - Vector4* end() { return _data + 6; } + CORRADE_CONSTEXPR14 Vector4* end() { return _data + 6; } /** * @overload @@ -235,42 +235,42 @@ template class Frustum { * @brief Left plane * @m_since{2020,06} */ - Vector4& left() { return _data[0]; } + CORRADE_CONSTEXPR14 Vector4& left() { return _data[0]; } constexpr Vector4 left() const { return _data[0]; } /**< @overload */ /** * @brief Right plane * @m_since{2020,06} */ - Vector4& right() { return _data[1]; } + CORRADE_CONSTEXPR14 Vector4& right() { return _data[1]; } constexpr Vector4 right() const { return _data[1]; } /**< @overload */ /** * @brief Bottom plane * @m_since{2020,06} */ - Vector4& bottom() { return _data[2]; } + CORRADE_CONSTEXPR14 Vector4& bottom() { return _data[2]; } constexpr Vector4 bottom() const { return _data[2]; } /**< @overload */ /** * @brief Top plane * @m_since{2020,06} */ - Vector4& top() { return _data[3]; } + CORRADE_CONSTEXPR14 Vector4& top() { return _data[3]; } constexpr Vector4 top() const { return _data[3]; } /**< @overload */ /** * @brief Near plane * @m_since{2020,06} */ - Vector4& near() { return _data[4]; } + CORRADE_CONSTEXPR14 Vector4& near() { return _data[4]; } constexpr Vector4 near() const { return _data[4]; } /**< @overload */ /** * @brief Far plane * @m_since{2020,06} */ - Vector4& far() { return _data[5]; } + CORRADE_CONSTEXPR14 Vector4& far() { return _data[5]; } constexpr Vector4 far() const { return _data[5]; } /**< @overload */ private: diff --git a/src/Magnum/Math/Quaternion.h b/src/Magnum/Math/Quaternion.h index dda7035c4..8c5ba1ce8 100644 --- a/src/Magnum/Math/Quaternion.h +++ b/src/Magnum/Math/Quaternion.h @@ -482,7 +482,7 @@ template class Quaternion { * * @see @ref xyzw(), @ref wxyz() */ - Vector3& vector() { return _vector; } + CORRADE_CONSTEXPR14 Vector3& vector() { return _vector; } /* Returning const so it's possible to call constexpr functions on the result. WTF, C++?! */ constexpr const Vector3 vector() const { return _vector; } /**< @overload */ @@ -492,7 +492,7 @@ template class Quaternion { * * @see @ref xyzw(), @ref wxyz() */ - T& scalar() { return _scalar; } + CORRADE_CONSTEXPR14 T& scalar() { return _scalar; } constexpr T scalar() const { return _scalar; } /**< @overload */ /** diff --git a/src/Magnum/Math/Range.h b/src/Magnum/Math/Range.h index c7ebf415a..5b45005ea 100644 --- a/src/Magnum/Math/Range.h +++ b/src/Magnum/Math/Range.h @@ -241,7 +241,7 @@ template class Range { * @see @ref size(), @ref Range2D::bottomLeft(), * @ref Range3D::backBottomLeft() */ - VectorType& min() { return _min; } + CORRADE_CONSTEXPR14 VectorType& min() { return _min; } constexpr const VectorType min() const { return _min; } /**< @overload */ /** @@ -251,7 +251,7 @@ template class Range { * @see @ref size(), @ref Range2D::topRight(), * @ref Range3D::frontTopRight() */ - VectorType& max() { return _max; } + CORRADE_CONSTEXPR14 VectorType& max() { return _max; } constexpr const VectorType max() const { return _max; } /**< @overload */ /** @@ -501,7 +501,7 @@ template class Range2D: public Range<2, T> { * * Equivalent to @ref min(). */ - Vector2& bottomLeft() { return Range<2, T>::min(); } + CORRADE_CONSTEXPR14 Vector2& bottomLeft() { return Range<2, T>::min(); } constexpr Vector2 bottomLeft() const { return Range<2, T>::min(); } /**< @overload */ /** @brief Bottom right corner */ @@ -519,23 +519,23 @@ template class Range2D: public Range<2, T> { * * Equivalent to @ref max(). */ - Vector2& topRight() { return Range<2, T>::max(); } + CORRADE_CONSTEXPR14 Vector2& topRight() { return Range<2, T>::max(); } constexpr Vector2 topRight() const { return Range<2, T>::max(); } /**< @overload */ /** @brief Left edge */ - T& left() { return Range<2, T>::min().x(); } + CORRADE_CONSTEXPR14 T& left() { return Range<2, T>::min().x(); } constexpr T left() const { return Range<2, T>::min().x(); } /**< @overload */ /** @brief Right edge */ - T& right() { return Range<2, T>::max().x(); } + CORRADE_CONSTEXPR14 T& right() { return Range<2, T>::max().x(); } constexpr T right() const { return Range<2, T>::max().x(); } /**< @overload */ /** @brief Bottom edge */ - T& bottom() { return Range<2, T>::min().y(); } + CORRADE_CONSTEXPR14 T& bottom() { return Range<2, T>::min().y(); } constexpr T bottom() const { return Range<2, T>::min().y(); } /**< @overload */ /** @brief Top edge */ - T& top() { return Range<2, T>::max().y(); } + CORRADE_CONSTEXPR14 T& top() { return Range<2, T>::max().y(); } constexpr T top() const { return Range<2, T>::max().y(); } /**< @overload */ /** @brief Range in the X axis */ @@ -650,7 +650,7 @@ template class Range3D: public Range<3, T> { * * Equivalent to @ref min(). */ - Vector3& backBottomLeft() { return Range<3, T>::min(); } + CORRADE_CONSTEXPR14 Vector3& backBottomLeft() { return Range<3, T>::min(); } constexpr Vector3 backBottomLeft() const { return Range<3, T>::min(); } /**< @overload */ /** @brief Back bottom right corner */ @@ -673,7 +673,7 @@ template class Range3D: public Range<3, T> { * * Equivalent to @ref max(). */ - Vector3& frontTopRight() { return Range<3, T>::max(); } + CORRADE_CONSTEXPR14 Vector3& frontTopRight() { return Range<3, T>::max(); } constexpr Vector3 frontTopRight() const { return Range<3, T>::max(); } /**< @overload */ /** @brief Front top left corner */ @@ -692,27 +692,27 @@ template class Range3D: public Range<3, T> { } /** @brief Left edge */ - T& left() { return Range<3, T>::min().x(); } + CORRADE_CONSTEXPR14 T& left() { return Range<3, T>::min().x(); } constexpr T left() const { return Range<3, T>::min().x(); } /**< @overload */ /** @brief Right edge */ - T& right() { return Range<3, T>::max().x(); } + CORRADE_CONSTEXPR14 T& right() { return Range<3, T>::max().x(); } constexpr T right() const { return Range<3, T>::max().x(); } /**< @overload */ /** @brief Bottom edge */ - T& bottom() { return Range<3, T>::min().y(); } + CORRADE_CONSTEXPR14 T& bottom() { return Range<3, T>::min().y(); } constexpr T bottom() const { return Range<3, T>::min().y(); } /**< @overload */ /** @brief Top edge */ - T& top() { return Range<3, T>::max().y(); } + CORRADE_CONSTEXPR14 T& top() { return Range<3, T>::max().y(); } constexpr T top() const { return Range<3, T>::max().y(); } /**< @overload */ /** @brief Back edge */ - T& back() { return Range<3, T>::min().z(); } + CORRADE_CONSTEXPR14 T& back() { return Range<3, T>::min().z(); } constexpr T back() const { return Range<3, T>::min().z(); } /**< @overload */ /** @brief Front edge */ - T& front() { return Range<3, T>::max().z(); } + CORRADE_CONSTEXPR14 T& front() { return Range<3, T>::max().z(); } constexpr T front() const { return Range<3, T>::max().z(); } /**< @overload */ /** @brief Range in the X axis */ diff --git a/src/Magnum/Math/RectangularMatrix.h b/src/Magnum/Math/RectangularMatrix.h index 31d555d3c..d8fc6aae1 100644 --- a/src/Magnum/Math/RectangularMatrix.h +++ b/src/Magnum/Math/RectangularMatrix.h @@ -283,7 +283,7 @@ template class RectangularMatrix { * * @see @ref row(), @ref data() */ - Vector& operator[](std::size_t col) { return _data[col]; } + CORRADE_CONSTEXPR14 Vector& operator[](std::size_t col) { return _data[col]; } /* returns const& so [][] operations are also constexpr */ constexpr const Vector& operator[](std::size_t col) const { return _data[col]; } /**< @overload */ diff --git a/src/Magnum/Math/Test/BezierCpp14Test.cpp b/src/Magnum/Math/Test/BezierCpp14Test.cpp new file mode 100644 index 000000000..2a8af488d --- /dev/null +++ b/src/Magnum/Math/Test/BezierCpp14Test.cpp @@ -0,0 +1,64 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021, 2022, 2023, 2024, 2025 + 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 "Magnum/Math/Bezier.h" +#include "Magnum/Math/Vector2.h" + +namespace Magnum { namespace Math { namespace Test { namespace { + +struct BezierCpp14Test: TestSuite::Tester { + explicit BezierCpp14Test(); + + void accessConstexpr(); +}; + +/* What's a typedef and not a using differs from the typedefs in root Magnum + namespace, or is not present there at all */ +using Magnum::Vector2; +using Magnum::QuadraticBezier2D; + +BezierCpp14Test::BezierCpp14Test() { + addTests({&BezierCpp14Test::accessConstexpr}); +} + +constexpr QuadraticBezier2D populate() { + QuadraticBezier2D a; + a.data()[1] = {3.0f, 2.0f}; + a[0] = {0.0f, 1.0f}; + return a; +}; + +void BezierCpp14Test::accessConstexpr() { + constexpr QuadraticBezier2D a = populate(); + CORRADE_COMPARE(a[0], (Vector2{0.0f, 1.0f})); + CORRADE_COMPARE(a[1], (Vector2{3.0f, 2.0f})); +} + +}}}} + +CORRADE_TEST_MAIN(Magnum::Math::Test::BezierCpp14Test) diff --git a/src/Magnum/Math/Test/BitVectorCpp14Test.cpp b/src/Magnum/Math/Test/BitVectorCpp14Test.cpp new file mode 100644 index 000000000..652afc3b0 --- /dev/null +++ b/src/Magnum/Math/Test/BitVectorCpp14Test.cpp @@ -0,0 +1,62 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021, 2022, 2023, 2024, 2025 + 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 "Magnum/Math/BitVector.h" + +namespace Magnum { namespace Math { namespace Test { namespace { + +struct BitVectorCpp14Test: TestSuite::Tester { + explicit BitVectorCpp14Test(); + + void accessConstexpr(); +}; + +/* What's a typedef and not a using differs from the typedefs in root Magnum + namespace, or is not present there at all */ +typedef Math::BitVector<19> BitVector19; + +BitVectorCpp14Test::BitVectorCpp14Test() { + addTests({&BitVectorCpp14Test::accessConstexpr}); +} + +constexpr BitVector19 populate() { + BitVector19 a; + a.data()[2] = 0xee; + a.data()[0] = 0xc0; + a.data()[1] = 0xff; + return a; +}; + +void BitVectorCpp14Test::accessConstexpr() { + constexpr BitVector19 a = populate(); + CORRADE_COMPARE(a, (BitVector19{0xc0, 0xff, 0xee})); +} + +}}}} + +CORRADE_TEST_MAIN(Magnum::Math::Test::BitVectorCpp14Test) diff --git a/src/Magnum/Math/Test/CMakeLists.txt b/src/Magnum/Math/Test/CMakeLists.txt index 1c0b74ac1..9b85da837 100644 --- a/src/Magnum/Math/Test/CMakeLists.txt +++ b/src/Magnum/Math/Test/CMakeLists.txt @@ -110,3 +110,41 @@ set_property(TARGET MathDistanceTest MathIntersectionTest APPEND PROPERTY COMPILE_DEFINITIONS "CORRADE_GRACEFUL_ASSERT") + +# Build these only if there's no explicit -std= passed in the flags +if(NOT CMAKE_CXX_FLAGS MATCHES "-std=") + # Copied verbatim from src/Corrade/Test/CMakeLists.txt, please keep in sync + if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "5.0") OR + (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "3.4") OR + (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "6.0.1") OR + (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "19.10")) + corrade_add_test(MathBezierCpp14Test BezierCpp14Test.cpp LIBRARIES MagnumMathTestLib) + corrade_add_test(MathBitVectorCpp14Test BitVectorCpp14Test.cpp LIBRARIES MagnumMathTestLib) + corrade_add_test(MathComplexCpp14Test ComplexCpp14Test.cpp LIBRARIES MagnumMathTestLib) + corrade_add_test(MathCubicHermiteCpp14Test CubicHermiteCpp14Test.cpp LIBRARIES MagnumMathTestLib) + corrade_add_test(MathDualCpp14Test DualCpp14Test.cpp LIBRARIES MagnumMathTestLib) + corrade_add_test(MathFrustumCpp14Test FrustumCpp14Test.cpp LIBRARIES MagnumMathTestLib) + corrade_add_test(MathQuaternionCpp14Test QuaternionCpp14Test.cpp LIBRARIES MagnumMathTestLib) + corrade_add_test(MathRangeCpp14Test RangeCpp14Test.cpp LIBRARIES MagnumMathTestLib) + corrade_add_test(MathRectangularMatrixCpp14Test RectangularMatrixCpp14Test.cpp LIBRARIES MagnumMathTestLib) + corrade_add_test(MathVectorCpp14Test VectorCpp14Test.cpp LIBRARIES MagnumMathTestLib) + corrade_add_test(MathVector2Cpp14Test Vector2Cpp14Test.cpp LIBRARIES MagnumMathTestLib) + corrade_add_test(MathVector3Cpp14Test Vector3Cpp14Test.cpp LIBRARIES MagnumMathTestLib) + corrade_add_test(MathVector4Cpp14Test Vector4Cpp14Test.cpp LIBRARIES MagnumMathTestLib) + set_target_properties( + MathBezierCpp14Test + MathBitVectorCpp14Test + MathComplexCpp14Test + MathCubicHermiteCpp14Test + MathDualCpp14Test + MathFrustumCpp14Test + MathQuaternionCpp14Test + MathRangeCpp14Test + MathRectangularMatrixCpp14Test + MathVectorCpp14Test + MathVector2Cpp14Test + MathVector3Cpp14Test + MathVector4Cpp14Test + PROPERTIES CORRADE_CXX_STANDARD 14) + endif() +endif() diff --git a/src/Magnum/Math/Test/ComplexCpp14Test.cpp b/src/Magnum/Math/Test/ComplexCpp14Test.cpp new file mode 100644 index 000000000..39bd031a5 --- /dev/null +++ b/src/Magnum/Math/Test/ComplexCpp14Test.cpp @@ -0,0 +1,61 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021, 2022, 2023, 2024, 2025 + 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 "Magnum/Math/Complex.h" + +namespace Magnum { namespace Math { namespace Test { namespace { + +struct ComplexCpp14Test: TestSuite::Tester { + explicit ComplexCpp14Test(); + + void accessConstexpr(); +}; + +/* What's a typedef and not a using differs from the typedefs in root Magnum + namespace, or is not present there at all */ +using Magnum::Complex; + +ComplexCpp14Test::ComplexCpp14Test() { + addTests({&ComplexCpp14Test::accessConstexpr}); +} + +constexpr Complex populate() { + Complex a; + a.real() = 3.0f; + a.imaginary() = 2.0f; + return a; +}; + +void ComplexCpp14Test::accessConstexpr() { + constexpr Complex a = populate(); + CORRADE_COMPARE(a, (Complex{3.0f, 2.0f})); +} + +}}}} + +CORRADE_TEST_MAIN(Magnum::Math::Test::ComplexCpp14Test) diff --git a/src/Magnum/Math/Test/CubicHermiteCpp14Test.cpp b/src/Magnum/Math/Test/CubicHermiteCpp14Test.cpp new file mode 100644 index 000000000..1491b7728 --- /dev/null +++ b/src/Magnum/Math/Test/CubicHermiteCpp14Test.cpp @@ -0,0 +1,62 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021, 2022, 2023, 2024, 2025 + 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 "Magnum/Math/CubicHermite.h" + +namespace Magnum { namespace Math { namespace Test { namespace { + +struct CubicHermiteCpp14Test: TestSuite::Tester { + explicit CubicHermiteCpp14Test(); + + void accessConstexpr(); +}; + +/* What's a typedef and not a using differs from the typedefs in root Magnum + namespace, or is not present there at all */ +using Magnum::CubicHermite2D; + +CubicHermiteCpp14Test::CubicHermiteCpp14Test() { + addTests({&CubicHermiteCpp14Test::accessConstexpr}); +} + +constexpr CubicHermite2D populate() { + CubicHermite2D a; + a.inTangent() = {1.0f, 2.0f}; + a.point() = {3.0f, 4.0f}; + a.outTangent() = {6.0f, 5.0f}; + return a; +}; + +void CubicHermiteCpp14Test::accessConstexpr() { + constexpr CubicHermite2D a = populate(); + CORRADE_COMPARE(a, (CubicHermite2D{{1.0f, 2.0f}, {3.0f, 4.0f}, {6.0f, 5.0f}})); +} + +}}}} + +CORRADE_TEST_MAIN(Magnum::Math::Test::CubicHermiteCpp14Test) diff --git a/src/Magnum/Math/Test/DualCpp14Test.cpp b/src/Magnum/Math/Test/DualCpp14Test.cpp new file mode 100644 index 000000000..7536c3138 --- /dev/null +++ b/src/Magnum/Math/Test/DualCpp14Test.cpp @@ -0,0 +1,61 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021, 2022, 2023, 2024, 2025 + 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 "Magnum/Math/Dual.h" + +namespace Magnum { namespace Math { namespace Test { namespace { + +struct DualCpp14Test: TestSuite::Tester { + explicit DualCpp14Test(); + + void accessConstexpr(); +}; + +/* What's a typedef and not a using differs from the typedefs in root Magnum + namespace, or is not present there at all */ +typedef Math::Dual Dual; + +DualCpp14Test::DualCpp14Test() { + addTests({&DualCpp14Test::accessConstexpr}); +} + +constexpr Dual populate() { + Dual a; + a.real() = 3.0f; + a.dual() = 2.0f; + return a; +}; + +void DualCpp14Test::accessConstexpr() { + constexpr Dual a = populate(); + CORRADE_COMPARE(a, (Dual{3.0f, 2.0f})); +} + +}}}} + +CORRADE_TEST_MAIN(Magnum::Math::Test::DualCpp14Test) diff --git a/src/Magnum/Math/Test/FrustumCpp14Test.cpp b/src/Magnum/Math/Test/FrustumCpp14Test.cpp new file mode 100644 index 000000000..a794d2948 --- /dev/null +++ b/src/Magnum/Math/Test/FrustumCpp14Test.cpp @@ -0,0 +1,75 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021, 2022, 2023, 2024, 2025 + 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 "Magnum/Math/Frustum.h" + +namespace Magnum { namespace Math { namespace Test { namespace { + +struct FrustumCpp14Test: TestSuite::Tester { + explicit FrustumCpp14Test(); + + void accessConstexpr(); +}; + +/* What's a typedef and not a using differs from the typedefs in root Magnum + namespace, or is not present there at all */ +using Magnum::Vector4; +using Magnum::Frustum; + +FrustumCpp14Test::FrustumCpp14Test() { + addTests({&FrustumCpp14Test::accessConstexpr}); +} + +constexpr Frustum populate() { + Frustum a; + a.left() = {-2.0f, 2.0f, -3.0f, 0.1f}; /* gets 1 added to X */ + a.right() = { 1.0f, -4.0f, 3.0f, 0.2f}; /* gets Y divided by 2 */ + a.bottom() = {-4.0f, 5.0f, -6.0f, 0.3f}; + a.top() = { 4.0f, -5.0f, 3.0f, 0.4f}; /* gets Z multiplied by 2 */ + a.near() = {-7.0f, 8.0f, -9.0f, 0.5f}; + a.far() = { 7.0f, 8.0f, 9.0f, 0.6f}; + a.begin()->x() += 1.0f; + a[1].y() /= 2.0f; + (a.end() - 3)->z() *= 2.0f; + return a; +}; + +void FrustumCpp14Test::accessConstexpr() { + constexpr Frustum a = populate(); + CORRADE_COMPARE(a, (Frustum{ + {-1.0f, 2.0f, -3.0f, 0.1f}, + { 1.0f, -2.0f, 3.0f, 0.2f}, + {-4.0f, 5.0f, -6.0f, 0.3f}, + { 4.0f, -5.0f, 6.0f, 0.4f}, + {-7.0f, 8.0f, -9.0f, 0.5f}, + { 7.0f, 8.0f, 9.0f, 0.6f}})); +} + +}}}} + +CORRADE_TEST_MAIN(Magnum::Math::Test::FrustumCpp14Test) diff --git a/src/Magnum/Math/Test/QuaternionCpp14Test.cpp b/src/Magnum/Math/Test/QuaternionCpp14Test.cpp new file mode 100644 index 000000000..2cfe0046f --- /dev/null +++ b/src/Magnum/Math/Test/QuaternionCpp14Test.cpp @@ -0,0 +1,62 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021, 2022, 2023, 2024, 2025 + 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 "Magnum/Math/Quaternion.h" + +namespace Magnum { namespace Math { namespace Test { namespace { + +struct QuaternionCpp14Test: TestSuite::Tester { + explicit QuaternionCpp14Test(); + + void accessConstexpr(); +}; + +/* What's a typedef and not a using differs from the typedefs in root Magnum + namespace, or is not present there at all */ +using Magnum::Quaternion; +using Magnum::Vector3; + +QuaternionCpp14Test::QuaternionCpp14Test() { + addTests({&QuaternionCpp14Test::accessConstexpr}); +} + +constexpr Quaternion populate() { + Quaternion a; + a.vector() = {3.0f, 1.0f, 0.0f}; + a.scalar() = 2.0f; + return a; +}; + +void QuaternionCpp14Test::accessConstexpr() { + constexpr Quaternion a = populate(); + CORRADE_COMPARE(a, (Quaternion{{3.0f, 1.0f, 0.0f}, 2.0f})); +} + +}}}} + +CORRADE_TEST_MAIN(Magnum::Math::Test::QuaternionCpp14Test) diff --git a/src/Magnum/Math/Test/RangeCpp14Test.cpp b/src/Magnum/Math/Test/RangeCpp14Test.cpp new file mode 100644 index 000000000..266187133 --- /dev/null +++ b/src/Magnum/Math/Test/RangeCpp14Test.cpp @@ -0,0 +1,102 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021, 2022, 2023, 2024, 2025 + 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 "Magnum/Math/Range.h" + +namespace Magnum { namespace Math { namespace Test { namespace { + +struct RangeCpp14Test: TestSuite::Tester { + explicit RangeCpp14Test(); + + void accessConstexpr(); + /* Range1D doesn't have any dedicated getters on top of the generic base */ + void accessConstexpr2D(); + void accessConstexpr3D(); +}; + +/* What's a typedef and not a using differs from the typedefs in root Magnum + namespace, or is not present there at all */ +using Magnum::Range1D; +using Magnum::Range2D; +using Magnum::Range3D; + +RangeCpp14Test::RangeCpp14Test() { + addTests({&RangeCpp14Test::accessConstexpr, + &RangeCpp14Test::accessConstexpr2D, + &RangeCpp14Test::accessConstexpr3D}); +} + +constexpr Range2D populate() { + Range2D a; + a.min() = {1.0f, 0.0f}; + a.max() = {2.0f, 3.0f}; + return a; +}; + +void RangeCpp14Test::accessConstexpr() { + constexpr Range2D a = populate(); + CORRADE_COMPARE(a, (Range2D{{1.0f, 0.0f}, {2.0f, 3.0f}})); +} + +constexpr Range2D populate2D() { + Range2D a; + a.bottomLeft() = {0.0f, -2.0f}; + a.topRight() = {4.0f, 1.5f}; + a.bottom() += 2.0f; + a.left() += 1.0f; + a.top() *= 2.0f; + a.right() /= 2.0f; + return a; +}; + +void RangeCpp14Test::accessConstexpr2D() { + constexpr Range2D a = populate2D(); + CORRADE_COMPARE(a, (Range2D{{1.0f, 0.0f}, {2.0f, 3.0f}})); +} + +constexpr Range3D populate3D() { + Range3D a; + a.backBottomLeft() = {0.0f, -2.0f, 5.0f}; + a.frontTopRight() = {4.0f, 1.5f, 4.5f}; + a.bottom() += 2.0f; + a.left() += 1.0f; + a.top() *= 2.0f; + a.right() /= 2.0f; + a.back() -= 1.0f; + a.front() += 0.5f; + return a; +}; + +void RangeCpp14Test::accessConstexpr3D() { + constexpr Range3D a = populate3D(); + CORRADE_COMPARE(a, (Range3D{{1.0f, 0.0f, 4.0f}, {2.0f, 3.0f, 5.0f}})); +} + +}}}} + +CORRADE_TEST_MAIN(Magnum::Math::Test::RangeCpp14Test) diff --git a/src/Magnum/Math/Test/RectangularMatrixCpp14Test.cpp b/src/Magnum/Math/Test/RectangularMatrixCpp14Test.cpp new file mode 100644 index 000000000..a922e723b --- /dev/null +++ b/src/Magnum/Math/Test/RectangularMatrixCpp14Test.cpp @@ -0,0 +1,62 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021, 2022, 2023, 2024, 2025 + 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 "Magnum/Math/RectangularMatrix.h" + +namespace Magnum { namespace Math { namespace Test { namespace { + +struct RectangularMatrixCpp14Test: TestSuite::Tester { + explicit RectangularMatrixCpp14Test(); + + void accessConstexpr(); +}; + +/* What's a typedef and not a using differs from the typedefs in root Magnum + namespace, or is not present there at all */ +typedef RectangularMatrix<2, 2, Float> Matrix2x2; +typedef Vector<2, Float> Vector2; + +RectangularMatrixCpp14Test::RectangularMatrixCpp14Test() { + addTests({&RectangularMatrixCpp14Test::accessConstexpr}); +} + +constexpr Matrix2x2 populate() { + Matrix2x2 a; + a[0] = {3.0f, 2.0f}; + a[1] = {0.0f, 1.0f}; + return a; +}; + +void RectangularMatrixCpp14Test::accessConstexpr() { + constexpr Matrix2x2 a = populate(); + CORRADE_COMPARE(a, (Matrix2x2{{{3.0f, 2.0f}, {0.0f, 1.0f}}})); +} + +}}}} + +CORRADE_TEST_MAIN(Magnum::Math::Test::RectangularMatrixCpp14Test) diff --git a/src/Magnum/Math/Test/Vector2Cpp14Test.cpp b/src/Magnum/Math/Test/Vector2Cpp14Test.cpp new file mode 100644 index 000000000..72ed0efc0 --- /dev/null +++ b/src/Magnum/Math/Test/Vector2Cpp14Test.cpp @@ -0,0 +1,63 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021, 2022, 2023, 2024, 2025 + 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 "Magnum/Math/Vector2.h" + +namespace Magnum { namespace Math { namespace Test { namespace { + +struct Vector2Cpp14Test: TestSuite::Tester { + explicit Vector2Cpp14Test(); + + void accessConstexpr(); +}; + +/* What's a typedef and not a using differs from the typedefs in root Magnum + namespace, or is not present there at all */ +using Magnum::Vector2; + +Vector2Cpp14Test::Vector2Cpp14Test() { + addTests({&Vector2Cpp14Test::accessConstexpr}); +} + +constexpr Vector2 populate() { + Vector2 a; + a.x() = 6.0f; + a.y() = 3.0f; + a.r() *= 0.5f; + a.g() -= 1.0f; + return a; +}; + +void Vector2Cpp14Test::accessConstexpr() { + constexpr Vector2 a = populate(); + CORRADE_COMPARE(a, (Vector2{3.0f, 2.0f})); +} + +}}}} + +CORRADE_TEST_MAIN(Magnum::Math::Test::Vector2Cpp14Test) diff --git a/src/Magnum/Math/Test/Vector3Cpp14Test.cpp b/src/Magnum/Math/Test/Vector3Cpp14Test.cpp new file mode 100644 index 000000000..04baba8a6 --- /dev/null +++ b/src/Magnum/Math/Test/Vector3Cpp14Test.cpp @@ -0,0 +1,65 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021, 2022, 2023, 2024, 2025 + 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 "Magnum/Math/Vector3.h" + +namespace Magnum { namespace Math { namespace Test { namespace { + +struct Vector3Cpp14Test: TestSuite::Tester { + explicit Vector3Cpp14Test(); + + void accessConstexpr(); +}; + +/* What's a typedef and not a using differs from the typedefs in root Magnum + namespace, or is not present there at all */ +using Magnum::Vector3; + +Vector3Cpp14Test::Vector3Cpp14Test() { + addTests({&Vector3Cpp14Test::accessConstexpr}); +} + +constexpr Vector3 populate() { + Vector3 a; + a.x() = 6.0f; + a.y() = 3.0f; + a.z() = 2.0f; + a.r() *= 0.5f; + a.g() -= 1.0f; + a.b() /= 2.0f; + return a; +}; + +void Vector3Cpp14Test::accessConstexpr() { + constexpr Vector3 a = populate(); + CORRADE_COMPARE(a, (Vector3{3.0f, 2.0f, 1.0f})); +} + +}}}} + +CORRADE_TEST_MAIN(Magnum::Math::Test::Vector3Cpp14Test) diff --git a/src/Magnum/Math/Test/Vector4Cpp14Test.cpp b/src/Magnum/Math/Test/Vector4Cpp14Test.cpp new file mode 100644 index 000000000..52f6b9148 --- /dev/null +++ b/src/Magnum/Math/Test/Vector4Cpp14Test.cpp @@ -0,0 +1,67 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021, 2022, 2023, 2024, 2025 + 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 "Magnum/Math/Vector4.h" + +namespace Magnum { namespace Math { namespace Test { namespace { + +struct Vector4Cpp14Test: TestSuite::Tester { + explicit Vector4Cpp14Test(); + + void accessConstexpr(); +}; + +/* What's a typedef and not a using differs from the typedefs in root Magnum + namespace, or is not present there at all */ +using Magnum::Vector4; + +Vector4Cpp14Test::Vector4Cpp14Test() { + addTests({&Vector4Cpp14Test::accessConstexpr}); +} + +constexpr Vector4 populate() { + Vector4 a; + a.x() = 6.0f; + a.y() = 3.0f; + a.z() = -1.0f; + a.w() = 2.0f; + a.r() *= 0.5f; + a.g() -= 1.0f; + a.b() += 1.0f; + a.a() /= 2.0f; + return a; +}; + +void Vector4Cpp14Test::accessConstexpr() { + constexpr Vector4 a = populate(); + CORRADE_COMPARE(a, (Vector4{3.0f, 2.0f, 0.0f, 1.0f})); +} + +}}}} + +CORRADE_TEST_MAIN(Magnum::Math::Test::Vector4Cpp14Test) diff --git a/src/Magnum/Math/Test/VectorCpp14Test.cpp b/src/Magnum/Math/Test/VectorCpp14Test.cpp new file mode 100644 index 000000000..71478b177 --- /dev/null +++ b/src/Magnum/Math/Test/VectorCpp14Test.cpp @@ -0,0 +1,61 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, + 2020, 2021, 2022, 2023, 2024, 2025 + 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 "Magnum/Math/Vector.h" + +namespace Magnum { namespace Math { namespace Test { namespace { + +struct VectorCpp14Test: TestSuite::Tester { + explicit VectorCpp14Test(); + + void accessConstexpr(); +}; + +/* What's a typedef and not a using differs from the typedefs in root Magnum + namespace, or is not present there at all */ +typedef Vector<2, Float> Vector2; + +VectorCpp14Test::VectorCpp14Test() { + addTests({&VectorCpp14Test::accessConstexpr}); +} + +constexpr Vector2 populate() { + Vector2 a; + a[0] = 3.0f; + a.data()[1] = 2.0f; + return a; +}; + +void VectorCpp14Test::accessConstexpr() { + constexpr Vector2 a = populate(); + CORRADE_COMPARE(a, (Vector2{3.0f, 2.0f})); +} + +}}}} + +CORRADE_TEST_MAIN(Magnum::Math::Test::VectorCpp14Test) diff --git a/src/Magnum/Math/Vector.h b/src/Magnum/Math/Vector.h index 299804f99..4a4990c7f 100644 --- a/src/Magnum/Math/Vector.h +++ b/src/Magnum/Math/Vector.h @@ -275,10 +275,10 @@ template class Vector { * post-processing step (https://github.com/mosra/m.css/issues/56) */ #ifdef DOXYGEN_GENERATING_OUTPUT - T* data(); + CORRADE_CONSTEXPR14 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 @@ -287,7 +287,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 */ /** diff --git a/src/Magnum/Math/Vector2.h b/src/Magnum/Math/Vector2.h index 475fc59d9..82848bcf9 100644 --- a/src/Magnum/Math/Vector2.h +++ b/src/Magnum/Math/Vector2.h @@ -171,7 +171,7 @@ template class Vector2: public Vector<2, T> { * * @see @ref r() */ - T& x() { return Vector<2, T>::_data[0]; } + CORRADE_CONSTEXPR14 T& x() { return Vector<2, T>::_data[0]; } constexpr const T& x() const { return Vector<2, T>::_data[0]; } /**< @overload */ /** @@ -179,7 +179,7 @@ template class Vector2: public Vector<2, T> { * * @see @ref g() */ - T& y() { return Vector<2, T>::_data[1]; } + CORRADE_CONSTEXPR14 T& y() { return Vector<2, T>::_data[1]; } constexpr const T& y() const { return Vector<2, T>::_data[1]; } /**< @overload */ /** @@ -188,7 +188,7 @@ template class Vector2: public Vector<2, T> { * * Equivalent to @ref x(). */ - T& r() { return Vector<2, T>::_data[0]; } + CORRADE_CONSTEXPR14 T& r() { return Vector<2, T>::_data[0]; } /** * @overload * @m_since_latest @@ -201,7 +201,7 @@ template class Vector2: public Vector<2, T> { * * Equivalent to @ref y(). */ - T& g() { return Vector<2, T>::_data[1]; } + CORRADE_CONSTEXPR14 T& g() { return Vector<2, T>::_data[1]; } /** * @overload * @m_since_latest diff --git a/src/Magnum/Math/Vector3.h b/src/Magnum/Math/Vector3.h index b3c547eeb..4f4a33d8a 100644 --- a/src/Magnum/Math/Vector3.h +++ b/src/Magnum/Math/Vector3.h @@ -200,7 +200,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]; } /** @overload */ constexpr const T& x() const { return Vector<3, T>::_data[0]; } @@ -209,7 +209,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]; } /** @overload */ constexpr const T& y() const { return Vector<3, T>::_data[1]; } @@ -218,7 +218,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]; } /** @overload */ constexpr const T& z() const { return Vector<3, T>::_data[2]; } @@ -227,7 +227,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]; } /** @overload */ constexpr const T& r() const { return Vector<3, T>::_data[0]; } @@ -236,7 +236,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]; } /** @overload */ constexpr const T& g() const { return Vector<3, T>::_data[1]; } @@ -245,7 +245,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]; } /** @overload */ constexpr const T& b() const { return Vector<3, T>::_data[2]; } diff --git a/src/Magnum/Math/Vector4.h b/src/Magnum/Math/Vector4.h index 0884e7705..b0cf10a84 100644 --- a/src/Magnum/Math/Vector4.h +++ b/src/Magnum/Math/Vector4.h @@ -141,7 +141,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]; } /** @overload */ constexpr const T& x() const { return Vector<4, T>::_data[0]; } @@ -150,7 +150,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]; } /** @overload */ constexpr const T& y() const { return Vector<4, T>::_data[1]; } @@ -159,7 +159,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]; } /** @overload */ constexpr const T& z() const { return Vector<4, T>::_data[2]; } @@ -168,7 +168,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]; } /** @overload */ constexpr const T& w() const { return Vector<4, T>::_data[3]; } @@ -177,7 +177,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]; } /** @overload */ constexpr const T& r() const { return Vector<4, T>::_data[0]; } @@ -186,7 +186,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]; } /** @overload */ constexpr const T& g() const { return Vector<4, T>::_data[1]; } @@ -195,7 +195,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]; } /** @overload */ constexpr const T& b() const { return Vector<4, T>::_data[2]; } @@ -204,7 +204,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]; } /** @overload */ constexpr const T& a() const { return Vector<4, T>::_data[3]; }