Browse Source

Math: add scatterInto().

Because doing `foo = Math::scatter<'y', 'w'>(foo, ...)` is just too
long, especially when the expression is already too long to begin with.
pull/686/head
Vladimír Vondruš 4 months ago
parent
commit
7e5a9472e4
  1. 4
      doc/changelog.dox
  2. 8
      doc/snippets/Math.cpp
  3. 24
      src/Magnum/Math/Swizzle.h
  4. 2
      src/Magnum/Math/Test/CMakeLists.txt
  5. 61
      src/Magnum/Math/Test/SwizzleCpp14Test.cpp
  6. 14
      src/Magnum/Math/Test/SwizzleTest.cpp

4
doc/changelog.dox

@ -317,6 +317,10 @@ See also:
@link Literals::ColorLiterals::operator""_srgbh() _srgbh @endlink and @link Literals::ColorLiterals::operator""_srgbh() _srgbh @endlink and
@link Literals::ColorLiterals::operator""_srgbah() _srgbah @endlink @link Literals::ColorLiterals::operator""_srgbah() _srgbah @endlink
literals for convenient @ref Color3h and @ref Color4h creation literals for convenient @ref Color3h and @ref Color4h creation
- Added @ref Math::scatterInto() as an in-place variant of
@ref Math::scatter(), which is now marked with @ref CORRADE_NODISCARD to
better convey that it returns the modified value instead of mutating it
in-place
@subsubsection changelog-latest-new-materialtools MaterialTools library @subsubsection changelog-latest-new-materialtools MaterialTools library

8
doc/snippets/Math.cpp

@ -1443,6 +1443,14 @@ vec2 = Math::scatter<'w', 'x', 'y'>(vec2, Math::gather<'x', 'w', 'y'>(vec));
/* [scatter] */ /* [scatter] */
} }
{
/* [scatterInto] */
Vector4 vec{1.5f, 3.0f, 0.1f, 1.1f};
Vector2 coords{5.0f, -2.0f};
Math::scatterInto<'z', 'w'>(vec, coords); // { 1.5, 3.0, 5.0, -2.0 }
/* [scatterInto] */
}
{ {
Float a{}, b{}; Float a{}, b{};
/* [TypeTraits-equalsZero] */ /* [TypeTraits-equalsZero] */

24
src/Magnum/Math/Swizzle.h

@ -27,7 +27,7 @@
*/ */
/** @file /** @file
* @brief Function @ref Magnum::Math::gather(), @ref Magnum::Math::scatter() * @brief Function @ref Magnum::Math::gather(), @ref Magnum::Math::scatter(), @ref Magnum::Math::scatterInto()
*/ */
#include "Magnum/Math/Vector.h" #include "Magnum/Math/Vector.h"
@ -141,6 +141,7 @@ Inverse to @ref gather(), supporting the same component addressing except for
@snippet Math.cpp scatter @snippet Math.cpp scatter
Use @ref scatterInto() to update the vector in-place.
@see @ref matrix-vector-component-access, @ref Vector4::xyz(), @see @ref matrix-vector-component-access, @ref Vector4::xyz(),
@ref Vector4::rgb(), @ref Vector4::xy(), @ref Vector3::xy() @ref Vector4::rgb(), @ref Vector4::xy(), @ref Vector3::xy()
*/ */
@ -155,6 +156,27 @@ template<char ...components, class T> CORRADE_NODISCARD constexpr T scatter(cons
return Implementation::scatterRecursive<T, sizeof...(components), components...>(vector, values, 0); return Implementation::scatterRecursive<T, sizeof...(components), components...>(vector, values, 0);
} }
/**
@brief Scatter @ref Vector components in-place
@param[in,out] vector Vector to update
@param[in] values Values to update it with
@m_since_latest
Like @ref scatter(), but updates the @p vector in-place. Example usage:
@snippet Math.cpp scatterInto
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
template<char ...components, class T> CORRADE_CONSTEXPR14 void scatterInto(T& vector, const Vector<sizeof...(components), typename T::Type>& values)
#else
/* Using std::common_type otherwise GCC 4.8 fails to match the arguments
in SwizzleTest::scatterOneComponent() */
template<char ...components, class T> CORRADE_CONSTEXPR14 void scatterInto(T& vector, const typename std::common_type<Vector<sizeof...(components), typename T::Type>>::type& values)
#endif
{
vector = Implementation::scatterRecursive<T, sizeof...(components), components...>(vector, values, 0);
}
}} }}
#endif #endif

2
src/Magnum/Math/Test/CMakeLists.txt

@ -127,6 +127,7 @@ if(NOT CMAKE_CXX_FLAGS MATCHES "-std=")
corrade_add_test(MathQuaternionCpp14Test QuaternionCpp14Test.cpp LIBRARIES MagnumMathTestLib) corrade_add_test(MathQuaternionCpp14Test QuaternionCpp14Test.cpp LIBRARIES MagnumMathTestLib)
corrade_add_test(MathRangeCpp14Test RangeCpp14Test.cpp LIBRARIES MagnumMathTestLib) corrade_add_test(MathRangeCpp14Test RangeCpp14Test.cpp LIBRARIES MagnumMathTestLib)
corrade_add_test(MathRectangularMatrixCpp14Test RectangularMatrixCpp14Test.cpp LIBRARIES MagnumMathTestLib) corrade_add_test(MathRectangularMatrixCpp14Test RectangularMatrixCpp14Test.cpp LIBRARIES MagnumMathTestLib)
corrade_add_test(MathSwizzleCpp14Test SwizzleCpp14Test.cpp LIBRARIES MagnumMathTestLib)
corrade_add_test(MathVectorCpp14Test VectorCpp14Test.cpp LIBRARIES MagnumMathTestLib) corrade_add_test(MathVectorCpp14Test VectorCpp14Test.cpp LIBRARIES MagnumMathTestLib)
corrade_add_test(MathVector2Cpp14Test Vector2Cpp14Test.cpp LIBRARIES MagnumMathTestLib) corrade_add_test(MathVector2Cpp14Test Vector2Cpp14Test.cpp LIBRARIES MagnumMathTestLib)
corrade_add_test(MathVector3Cpp14Test Vector3Cpp14Test.cpp LIBRARIES MagnumMathTestLib) corrade_add_test(MathVector3Cpp14Test Vector3Cpp14Test.cpp LIBRARIES MagnumMathTestLib)
@ -141,6 +142,7 @@ if(NOT CMAKE_CXX_FLAGS MATCHES "-std=")
MathQuaternionCpp14Test MathQuaternionCpp14Test
MathRangeCpp14Test MathRangeCpp14Test
MathRectangularMatrixCpp14Test MathRectangularMatrixCpp14Test
MathSwizzleCpp14Test
MathVectorCpp14Test MathVectorCpp14Test
MathVector2Cpp14Test MathVector2Cpp14Test
MathVector3Cpp14Test MathVector3Cpp14Test

61
src/Magnum/Math/Test/SwizzleCpp14Test.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š <mosra@centrum.cz>
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 <Corrade/TestSuite/Tester.h>
#include "Magnum/Math/Swizzle.h"
namespace Magnum { namespace Math { namespace Test { namespace {
struct SwizzleCpp14Test: TestSuite::Tester {
explicit SwizzleCpp14Test();
void scatterIntoConstexpr();
};
/* 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, Int> Vector2i;
typedef Vector<4, Int> Vector4i;
SwizzleCpp14Test::SwizzleCpp14Test() {
addTests({&SwizzleCpp14Test::scatterIntoConstexpr});
}
constexpr Vector4i populate() {
Vector4i a{2, 4, 5, 7};
Math::scatterInto<'w', 'y'>(a, Vector2i{1, 3});
return a;
}
void SwizzleCpp14Test::scatterIntoConstexpr() {
constexpr Vector4i a = populate();
CORRADE_COMPARE(a, (Vector4i{2, 3, 5, 1}));
}
}}}}
CORRADE_TEST_MAIN(Magnum::Math::Test::SwizzleCpp14Test)

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

@ -43,6 +43,8 @@ struct SwizzleTest: TestSuite::Tester {
void scatterRepeatedComponents(); void scatterRepeatedComponents();
void scatterOverwriteAllComponents(); void scatterOverwriteAllComponents();
void scatterFarComponents(); void scatterFarComponents();
void scatterInto();
}; };
/* These differ from the typedefs in root Magnum namespace */ /* These differ from the typedefs in root Magnum namespace */
@ -60,7 +62,9 @@ SwizzleTest::SwizzleTest() {
&SwizzleTest::scatterOneComponent, &SwizzleTest::scatterOneComponent,
&SwizzleTest::scatterRepeatedComponents, &SwizzleTest::scatterRepeatedComponents,
&SwizzleTest::scatterOverwriteAllComponents, &SwizzleTest::scatterOverwriteAllComponents,
&SwizzleTest::scatterFarComponents}); &SwizzleTest::scatterFarComponents,
&SwizzleTest::scatterInto});
} }
void SwizzleTest::gather() { void SwizzleTest::gather() {
@ -138,6 +142,14 @@ void SwizzleTest::scatterFarComponents() {
CORRADE_COMPARE(a, (Vector<7, Int>{2, 4, 5, 7, 6, 1, 9})); CORRADE_COMPARE(a, (Vector<7, Int>{2, 4, 5, 7, 6, 1, 9}));
} }
void SwizzleTest::scatterInto() {
/* It calls into scatter() internally so just verify it works at all, the
whole functionality is sufficiently tested above */
Vector4i a{2, 4, 5, 7};
Math::scatterInto<'w', 'y'>(a, Vector2i{1, 3});
CORRADE_COMPARE(a, (Vector4i{2, 3, 5, 1}));
}
}}}} }}}}
CORRADE_TEST_MAIN(Magnum::Math::Test::SwizzleTest) CORRADE_TEST_MAIN(Magnum::Math::Test::SwizzleTest)

Loading…
Cancel
Save