Browse Source

Math: fix batch min()/max()/minmax() to work with const input views.

Apart from returning const T instead of T it kinda worked, but in case
of floating-point vectors it tried to operate with
`std::pair<std::size_t, const T>` internally and failed miserably.
pull/592/head
Vladimír Vondruš 4 years ago
parent
commit
d1f283d962
  1. 6
      src/Magnum/Math/FunctionsBatch.h
  2. 21
      src/Magnum/Math/Test/FunctionsBatchTest.cpp

6
src/Magnum/Math/FunctionsBatch.h

@ -40,9 +40,9 @@ namespace Implementation {
/** @todo Utility/Algorithms.h has a similar (but different) variant of this,
maybe turn that into some public utility once we have one more use case? */
template<class T, class View = decltype(Corrade::Containers::Implementation::ErasedArrayViewConverter<typename std::remove_reference<T&&>::type>::from(std::declval<T&&>()))> static auto stridedArrayViewTypeFor(T&&) -> typename View::Type;
template<class T> static T stridedArrayViewTypeFor(const Corrade::Containers::ArrayView<T>&);
template<class T> static T stridedArrayViewTypeFor(const Corrade::Containers::StridedArrayView1D<T>&);
template<class T, class View = decltype(Corrade::Containers::Implementation::ErasedArrayViewConverter<typename std::remove_reference<T&&>::type>::from(std::declval<T&&>()))> static auto stridedArrayViewTypeFor(T&&) -> typename std::remove_const<typename View::Type>::type;
template<class T> static typename std::remove_const<T>::type stridedArrayViewTypeFor(const Corrade::Containers::ArrayView<T>&);
template<class T> static typename std::remove_const<T>::type stridedArrayViewTypeFor(const Corrade::Containers::StridedArrayView1D<T>&);
}

21
src/Magnum/Math/Test/FunctionsBatchTest.cpp

@ -24,6 +24,7 @@
*/
#include <vector>
#include <Corrade/Containers/Array.h>
#include <Corrade/Containers/ArrayViewStl.h>
#include <Corrade/TestSuite/Tester.h>
@ -44,6 +45,8 @@ struct FunctionsBatchTest: Corrade::TestSuite::Tester {
void nanIgnoring();
void nanIgnoringVector();
void constIterable();
};
using namespace Literals;
@ -62,7 +65,9 @@ FunctionsBatchTest::FunctionsBatchTest() {
&FunctionsBatchTest::minmax,
&FunctionsBatchTest::nanIgnoring,
&FunctionsBatchTest::nanIgnoringVector});
&FunctionsBatchTest::nanIgnoringVector,
&FunctionsBatchTest::constIterable});
}
void FunctionsBatchTest::isInf() {
@ -284,6 +289,20 @@ void FunctionsBatchTest::nanIgnoringVector() {
CORRADE_COMPARE(Math::minmax(allNan).second[1], Constants::nan());
}
void FunctionsBatchTest::constIterable() {
const Vector2 data[]{{5, -3}, {-2, 14}, {9, -5}};
/* It shouldn't try to operate with a const type (such as trying to to
assign to `std::pair<std::size_t, const Vector2>`) internally, instead
it should remove the const */
CORRADE_COMPARE(Math::min(Corrade::Containers::arrayView(data)),
(Vector2{-2, -5}));
CORRADE_COMPARE(Math::max(Corrade::Containers::stridedArrayView(data)),
(Vector2{9, 14}));
CORRADE_COMPARE(Math::minmax(Corrade::Containers::Array<const Vector2>{data, 3, [](const Vector2*, std::size_t){}}),
std::make_pair(Vector2{-2, -5}, Vector2{9, 14}));
}
}}}}
CORRADE_TEST_MAIN(Magnum::Math::Test::FunctionsBatchTest)

Loading…
Cancel
Save