diff --git a/doc/changelog.dox b/doc/changelog.dox index 4a1860f3f..08b3ef852 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -216,12 +216,15 @@ See also: special types such as @ref Deg or @ref Rad --- the only exception is power functions such as @ref Math::sqrt() or @ref Math::log(), as the resulting unit can't be represented. Those accept only unitless types. -- Batch @ref Math::min(Containers::ArrayView), - @ref Math::max(Containers::ArrayView) and - @ref Math::minmax(Containers::ArrayView) functions now ignore NaNs - in the data, if possible. Use the batch - @ref Math::isNan(Containers::ArrayView) to detect presence of NaN - values if needed. +- All batch functions in @ref Magnum/Math/FunctionsBatch.h now accept + @ref Corrade::Containers::StridedArrayView instead of a dense array view to + make them usable in more contexts +- Batch @ref Math::min(Containers::StridedArrayView1D), + @ref Math::max(Containers::StridedArrayView1D) and + @ref Math::minmax(Containers::StridedArrayView1D) functions now + ignore NaNs in the data, if possible. Use the batch + @ref Math::isNan(Containers::StridedArrayView1D) to detect + presence of NaN values if needed. - Changed the way @ref Math::operator<<(Corrade::Utility::Debug&, const BoolVector&) works --- the output now has the same bit order as when constructing it using binary literals @@ -373,10 +376,10 @@ See also: - @cpp Math::Frustum::planes() @ce are deprecated due to redundancy, use either @ref Math::Frustum::operator[](), @ref Math::Frustum::data() or range access using @ref Math::Frustum::begin() / @ref Math::Frustum::end() -- Batch @ref Math::min(Containers::ArrayView), - @ref Math::max(Containers::ArrayView) and - @ref Math::minmax(Containers::ArrayView) are moved to a new - @ref Magnum/Math/FunctionsBatch.h header in order to speed up compile +- Batch @ref Math::min(Containers::StridedArrayView1D), + @ref Math::max(Containers::StridedArrayView1D) and + @ref Math::minmax(Containers::StridedArrayView1D) are moved to a + new @ref Magnum/Math/FunctionsBatch.h header in order to speed up compile times. This header is included from @ref Magnum/Math/FunctionsBatch.h when building with @ref MAGNUM_BUILD_DEPRECATED enabled, include it explicitly to ensure forward compatibility diff --git a/src/Magnum/Math/Functions.h b/src/Magnum/Math/Functions.h index 8bc286dbb..24de6763e 100644 --- a/src/Magnum/Math/Functions.h +++ b/src/Magnum/Math/Functions.h @@ -161,7 +161,7 @@ the operations component-wise. @brief If given number is a positive or negative infinity @see @ref isNan(), @ref Constants::inf(), - @ref isInf(Corrade::Containers::ArrayView) + @ref isInf(Corrade::Containers::StridedArrayView1D) */ template inline typename std::enable_if::value, bool>::type isInf(T value) { return std::isinf(UnderlyingTypeOf(value)); @@ -180,7 +180,7 @@ template inline BoolVector isInf(const Vector) + @ref isNan(Corrade::Containers::StridedArrayView1D) */ template inline typename std::enable_if::value, bool>::type isNan(T value) { return std::isnan(UnderlyingTypeOf(value)); @@ -199,7 +199,8 @@ template inline BoolVector isNan(const VectorNaNs passed in the @p value parameter are propagated. @see @ref max(), @ref minmax(), @ref clamp(), - @ref min(Corrade::Containers::ArrayView), @ref Vector::min() + @ref min(Corrade::Containers::StridedArrayView1D), + @ref Vector::min() */ /* defined in Vector.h */ template constexpr typename std::enable_if::value, T>::type min(T value, T min); @@ -225,7 +226,8 @@ template inline Vector min(const VectorNaNs passed in the @p value parameter are propagated. @see @ref min(), @ref minmax(), @ref clamp(), - @ref max(Corrade::Containers::ArrayView), @ref Vector::max() + @ref max(Corrade::Containers::StridedArrayView1D), + @ref Vector::max() */ /* defined in Vector.h */ template constexpr typename std::enable_if::value, T>::type max(T a, T b); @@ -250,7 +252,8 @@ template inline Vector max(const Vector), @ref Vector::minmax(), + @ref minmax(Corrade::Containers::StridedArrayView1D), + @ref Vector::minmax(), @ref Range::Range(const std::pair&) */ template inline typename std::enable_if::value, std::pair>::type minmax(T a, T b) { diff --git a/src/Magnum/Math/FunctionsBatch.h b/src/Magnum/Math/FunctionsBatch.h index 1c62287ef..03546dd90 100644 --- a/src/Magnum/Math/FunctionsBatch.h +++ b/src/Magnum/Math/FunctionsBatch.h @@ -30,7 +30,7 @@ */ #include -#include +#include #include "Magnum/Math/Functions.h" @@ -52,7 +52,7 @@ set to @cpp 1 @ce if any value has that component infinite. If the range is empty, returns @cpp false @ce or a @ref BoolVector with no bits set. @see @ref isInf(T), @ref Constants::inf() */ -template auto isInf(Corrade::Containers::ArrayView range) -> decltype(isInf(std::declval())) { +template auto isInf(Corrade::Containers::StridedArrayView1D range) -> decltype(isInf(std::declval())) { if(range.empty()) return {}; /* For scalars, this loop exits once any value is infinity. For vectors @@ -69,12 +69,12 @@ template auto isInf(Corrade::Containers::ArrayView range) -> d /** @overload */ template inline auto isInf(std::initializer_list list) -> decltype(isInf(std::declval())) { - return isInf(Corrade::Containers::arrayView(list.begin(), list.size())); + return isInf(Corrade::Containers::arrayView(list.begin(), list.size())); } /** @overload */ template inline auto isInf(const T(&array)[size]) -> decltype(isInf(std::declval())) { - return isInf(Corrade::Containers::arrayView(array)); + return isInf(Corrade::Containers::arrayView(array)); } /** @@ -86,7 +86,7 @@ set to @cpp 1 @ce if any value has that component NaN. If the range is empty, returns @cpp false @ce or a @ref BoolVector with no bits set. @see @ref isNan(T), @ref Constants::nan() */ -template inline auto isNan(Corrade::Containers::ArrayView range) -> decltype(isNan(std::declval())) { +template inline auto isNan(Corrade::Containers::StridedArrayView1D range) -> decltype(isNan(std::declval())) { if(range.empty()) return {}; /* For scalars, this loop exits once any value is infinity. For vectors @@ -103,21 +103,21 @@ template inline auto isNan(Corrade::Containers::ArrayView rang /** @overload */ template inline auto isNan(std::initializer_list list) -> decltype(isInf(std::declval())) { - return isNan(Corrade::Containers::arrayView(list.begin(), list.size())); + return isNan(Corrade::Containers::arrayView(list.begin(), list.size())); } /** @overload */ template inline bool isNan(const T(&array)[size]) { - return isNan(Corrade::Containers::arrayView(array)); + return isNan(Corrade::Containers::arrayView(array)); } namespace Implementation { /* Non-floating-point types, the first is a non-NaN for sure */ - template constexpr std::pair firstNonNan(Corrade::Containers::ArrayView range, std::false_type, std::integral_constant) { + template constexpr std::pair firstNonNan(Corrade::Containers::StridedArrayView1D range, std::false_type, std::integral_constant) { return {0, range.front()}; } /* Floating-point scalars, return the first that's not NaN */ - template inline std::pair firstNonNan(Corrade::Containers::ArrayView range, std::true_type, std::false_type) { + template inline std::pair firstNonNan(Corrade::Containers::StridedArrayView1D range, std::true_type, std::false_type) { /* Find the first non-NaN value to compare against. If all are NaN, return the last value so the following loop in min/max/minmax() doesn't even execute. */ @@ -132,7 +132,7 @@ namespace Implementation { apply the min/max/minmax operation. I expect the cases of heavily NaN-filled vectors (and thus the need to loop twice through most of the range) to be very rare, so this shouldn't be a problem. */ - template inline std::pair firstNonNan(Corrade::Containers::ArrayView range, std::true_type, std::true_type) { + template inline std::pair firstNonNan(Corrade::Containers::StridedArrayView1D range, std::true_type, std::true_type) { T out = range[0]; std::size_t firstValid = 0; for(std::size_t i = 1; i != range.size(); ++i) { @@ -150,9 +150,9 @@ namespace Implementation { If the range is empty, returns default-constructed value. NaNs are ignored, unless the range is all NaNs. -@see @ref min(T, T), @ref isNan(Corrade::Containers::ArrayView) +@see @ref min(T, T), @ref isNan(Corrade::Containers::StridedArrayView1D) */ -template inline T min(Corrade::Containers::ArrayView range) { +template inline T min(Corrade::Containers::StridedArrayView1D range) { if(range.empty()) return {}; std::pair iOut = Implementation::firstNonNan(range, IsFloatingPoint{}, IsVector{}); @@ -164,12 +164,12 @@ template inline T min(Corrade::Containers::ArrayView range) { /** @overload */ template inline T min(std::initializer_list list) { - return min(Corrade::Containers::arrayView(list.begin(), list.size())); + return min(Corrade::Containers::arrayView(list.begin(), list.size())); } /** @overload */ template inline T min(const T(&array)[size]) { - return min(Corrade::Containers::arrayView(array)); + return min(Corrade::Containers::arrayView(array)); } /** @@ -177,9 +177,9 @@ template inline T min(const T(&array)[size]) { If the range is empty, returns default-constructed value. NaNs are ignored, unless the range is all NaNs. -@see @ref max(T, T), @ref isNan(Corrade::Containers::ArrayView) +@see @ref max(T, T), @ref isNan(Corrade::Containers::StridedArrayView1D) */ -template inline T max(Corrade::Containers::ArrayView range) { +template inline T max(Corrade::Containers::StridedArrayView1D range) { if(range.empty()) return {}; std::pair iOut = Implementation::firstNonNan(range, IsFloatingPoint{}, IsVector{}); @@ -191,12 +191,12 @@ template inline T max(Corrade::Containers::ArrayView range) { /** @overload */ template inline T max(std::initializer_list list) { - return max(Corrade::Containers::arrayView(list.begin(), list.size())); + return max(Corrade::Containers::arrayView(list.begin(), list.size())); } /** @overload */ template inline T max(const T(&array)[size]) { - return max(Corrade::Containers::arrayView(array)); + return max(Corrade::Containers::arrayView(array)); } namespace Implementation { @@ -219,9 +219,9 @@ If the range is empty, returns default-constructed values. NaNs are ignored, unless the range is all NaNs. @see @ref minmax(T, T), @ref Range::Range(const std::pair&), - @ref isNan(Corrade::Containers::ArrayView) + @ref isNan(Corrade::Containers::StridedArrayView1D) */ -template inline std::pair minmax(Corrade::Containers::ArrayView range) { +template inline std::pair minmax(Corrade::Containers::StridedArrayView1D range) { if(range.empty()) return {}; std::pair iOut = Implementation::firstNonNan(range, IsFloatingPoint{}, IsVector{}); @@ -234,12 +234,12 @@ template inline std::pair minmax(Corrade::Containers::ArrayView inline std::pair minmax(std::initializer_list list) { - return minmax(Corrade::Containers::arrayView(list.begin(), list.size())); + return minmax(Corrade::Containers::arrayView(list.begin(), list.size())); } /** @overload */ template inline std::pair minmax(const T(&array)[size]) { - return minmax(Corrade::Containers::arrayView(array)); + return minmax(Corrade::Containers::arrayView(array)); } /*@}*/