From 5be7fbe1e85e28adc89d3ca86afe1abce059f397 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 16 May 2020 17:11:59 +0200 Subject: [PATCH] Math: make Range2D and Range3D properly convertible from std::pair. Not sure what was I doing in 64f8a900958be56e8a2e22f501e79f5ac923e971. --- doc/changelog.dox | 3 +++ doc/snippets/MagnumMath.cpp | 14 +++++++--- src/Magnum/Math/Range.h | 43 ++++++++++++++++++++++++++++-- src/Magnum/Math/Test/RangeTest.cpp | 17 +++++++++--- 4 files changed, 69 insertions(+), 8 deletions(-) diff --git a/doc/changelog.dox b/doc/changelog.dox index 65119f4ec..b6a734047 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -548,6 +548,9 @@ See also: wireframe rendering artifacts - @ref Math::angle() got fixed to not produce NaN results for vectors, complex numbers or quaternions very close to each other +- @ref Math::Range was made to be implicitly convertible from @ref std::pair + in 2018.10, but the @ref Math::Range2D and @ref Math::Range3D were only + explicitly, and even that only by an accident - Fixed various cases where @ref GL::Context would call GL 3+ APIs on GL 2.1 contexts, causing GL errors. This makes context creation completely error-free on Mesa's Zink GL-over-Vulkan driver. diff --git a/doc/snippets/MagnumMath.cpp b/doc/snippets/MagnumMath.cpp index 167b490f3..54ff8cd32 100644 --- a/doc/snippets/MagnumMath.cpp +++ b/doc/snippets/MagnumMath.cpp @@ -1064,10 +1064,18 @@ static_cast(c); } { -/* [Range-construct-minmax] */ +/* [Range-construct-minmax2D] */ +Vector2 texcoords[50]; +Range2D bounds = Math::minmax(texcoords); +/* [Range-construct-minmax2D] */ +static_cast(bounds); +} + +{ +/* [Range-construct-minmax3D] */ Vector3 a, b, c; -Range3D bounds{Math::minmax({a, b, c})}; -/* [Range-construct-minmax] */ +Range3D bounds = Math::minmax({a, b, c}); +/* [Range-construct-minmax3D] */ static_cast(bounds); } diff --git a/src/Magnum/Math/Range.h b/src/Magnum/Math/Range.h index 7ef674ae4..67245a2c4 100644 --- a/src/Magnum/Math/Range.h +++ b/src/Magnum/Math/Range.h @@ -122,9 +122,10 @@ template class Range { * Useful in combination with e.g. @ref minmax(), here for example to * calculate bounds of a triangle: * - * @snippet MagnumMath.cpp Range-construct-minmax + * @snippet MagnumMath.cpp Range-construct-minmax3D * - * @todo std::pair constructors are not constexpr in C++11, make it so in C++14 */ + * @todo std::pair constructors are not constexpr in C++11, make it so in C++14 + */ /*implicit*/ Range(const std::pair& minmax) noexcept: _min{minmax.first}, _max{minmax.second} {} @@ -377,6 +378,25 @@ template class Range2D: public Range<2, T> { /** @copydoc Range(const VectorType&, const VectorType&) */ constexpr /*implicit*/ Range2D(const Vector2& min, const Vector2& max) noexcept: Range<2, T>(min, max) {} + /** + * @brief Construct a range from a pair of minimal and maximal coordinates + * @m_since_latest + * + * Useful in combination with e.g. @ref minmax(), here for example to + * calculate texture bounds: + * + * @snippet MagnumMath.cpp Range-construct-minmax2D + * + * @todo std::pair constructors are not constexpr in C++11, make it so in C++14 + */ + /*implicit*/ Range2D(const std::pair, Vector2>& minmax) noexcept: Range<2, T>{minmax.first, minmax.second} {} + + /** + * @overload + * @m_since_latest + */ + /*implicit*/ Range2D(const std::pair, Vector<2, T>>& minmax) noexcept: Range<2, T>{minmax.first, minmax.second} {} + /** @copydoc Range(const Range&) */ template constexpr explicit Range2D(const Range2D& other) noexcept: Range<2, T>(other) {} @@ -512,6 +532,25 @@ template class Range3D: public Range<3, T> { /** @copydoc Range(const VectorType&, const VectorType&) */ constexpr /*implicit*/ Range3D(const Vector3& min, const Vector3& max) noexcept: Range<3, T>(min, max) {} + /** + * @brief Construct a range from a pair of minimal and maximal coordinates + * @m_since_latest + * + * Useful in combination with e.g. @ref minmax(), here for example to + * calculate bounds of a triangle: + * + * @snippet MagnumMath.cpp Range-construct-minmax3D + * + * @todo std::pair constructors are not constexpr in C++11, make it so in C++14 + */ + /*implicit*/ Range3D(const std::pair, Vector3>& minmax) noexcept: Range<3, T>{minmax.first, minmax.second} {} + + /** + * @overload + * @m_since_latest + */ + /*implicit*/ Range3D(const std::pair, Vector<3, T>>& minmax) noexcept: Range<3, T>{minmax.first, minmax.second} {} + /** @copydoc Range(const Range&) */ template constexpr explicit Range3D(const Range3D& other) noexcept: Range<3, T>(other) {} diff --git a/src/Magnum/Math/Test/RangeTest.cpp b/src/Magnum/Math/Test/RangeTest.cpp index 99b9e0f66..18f4e79b4 100644 --- a/src/Magnum/Math/Test/RangeTest.cpp +++ b/src/Magnum/Math/Test/RangeTest.cpp @@ -283,15 +283,26 @@ void RangeTest::constructPair() { Vector2i b{30, 18}; Vector2i c{20, 25}; - Range1Di bounds1a{Math::minmax({a.x(), b.x(), c.x()})}; + /* Conversion should be implicit, so not using {} */ + Range1Di bounds1a = Math::minmax({a.x(), b.x(), c.x()}); Range1Di bounds1c{10, 30}; CORRADE_COMPARE(bounds1a, bounds1c); - Range2Di bounds2a{Math::minmax({a, b, c})}; - Range2Di bounds2b{std::pair, Math::Vector<2, Int>>{{10, 18}, {30, 25}}}; + Range2Di bounds2a = Math::minmax({a, b, c}); + Range2Di bounds2b = std::pair, Math::Vector<2, Int>>{{10, 18}, {30, 25}}; Range2Di bounds2c{{10, 18}, {30, 25}}; CORRADE_COMPARE(bounds2a, bounds2c); CORRADE_COMPARE(bounds2b, bounds2c); + + Vector3i a3{a, 122}; + Vector3i b3{b, 122}; + Vector3i c3{c, 123}; + + Range3Di bounds3a = Math::minmax({a3, b3, c3}); + Range3Di bounds3b = std::pair, Math::Vector<3, Int>>{{10, 18, 122}, {30, 25, 123}}; + Range3Di bounds3c{{10, 18, 122}, {30, 25, 123}}; + CORRADE_COMPARE(bounds3a, bounds3c); + CORRADE_COMPARE(bounds3b, bounds3c); } void RangeTest::constructConversion() {