Browse Source

Math: provide our own min() / max().

The one from std:: needs to #include <algorithm> to be used portably.
That's insane, so it's a big nope. Also, the standard implementation
takes the value always by reference, making it unnecessarily slow for
small types. We do better here.
pull/331/head
Vladimír Vondruš 7 years ago
parent
commit
563dee0436
  1. 18
      src/Magnum/Math/Functions.h
  2. 18
      src/Magnum/Math/Vector.h

18
src/Magnum/Math/Functions.h

@ -272,13 +272,11 @@ template<std::size_t size, class T> inline Vector<size, T> pow(const Vector<size
#ifdef DOXYGEN_GENERATING_OUTPUT
template<class T> inline T min(T value, T min);
#else
template<class T> inline typename std::enable_if<std::is_arithmetic<T>::value, T>::type min(T value, T min) {
return std::min(value, min);
}
/* min() for scalars defined in Vector.h */
template<std::size_t size, class T> inline Vector<size, T> min(const Vector<size, T>& value, const Vector<size, T>& min) {
Vector<size, T> out{NoInit};
for(std::size_t i = 0; i != size; ++i)
out[i] = std::min(value[i], min[i]);
out[i] = Math::min(value[i], min[i]);
return out;
}
#endif
@ -287,7 +285,7 @@ template<std::size_t size, class T> inline Vector<size, T> min(const Vector<size
template<std::size_t size, class T> inline Vector<size, T> min(const Vector<size, T>& value, T min) {
Vector<size, T> out{NoInit};
for(std::size_t i = 0; i != size; ++i)
out[i] = std::min(value[i], min);
out[i] = Math::min(value[i], min);
return out;
}
@ -324,13 +322,11 @@ template<class T, std::size_t size> inline T min(const T(&array)[size]) {
#ifdef DOXYGEN_GENERATING_OUTPUT
template<class T> inline T max(T value, T max);
#else
template<class T> inline typename std::enable_if<std::is_arithmetic<T>::value, T>::type max(T value, T max) {
return std::max(value, max);
}
/* max() for scalars defined in Vector.h */
template<std::size_t size, class T> Vector<size, T> max(const Vector<size, T>& value, const Vector<size, T>& max) {
Vector<size, T> out{NoInit};
for(std::size_t i = 0; i != size; ++i)
out[i] = std::max(value[i], max[i]);
out[i] = Math::max(value[i], max[i]);
return out;
}
#endif
@ -339,7 +335,7 @@ template<std::size_t size, class T> Vector<size, T> max(const Vector<size, T>& v
template<std::size_t size, class T> inline Vector<size, T> max(const Vector<size, T>& value, T max) {
Vector<size, T> out{NoInit};
for(std::size_t i = 0; i != size; ++i)
out[i] = std::max(value[i], max);
out[i] = Math::max(value[i], max);
return out;
}
@ -442,7 +438,7 @@ set to @p max. Equivalent to:
template<class T, class U> inline T clamp(const T& value, const T& min, const T& max);
#else
template<class T> inline typename std::enable_if<std::is_arithmetic<T>::value, T>::type clamp(T value, T min, T max) {
return std::min(std::max(value, min), max);
return Math::min(Math::max(value, min), max);
}
template<std::size_t size, class T> inline Vector<size, T> clamp(const Vector<size, T>& value, const Vector<size, T>& min, const Vector<size, T>& max) {
Vector<size, T> out{NoInit};

18
src/Magnum/Math/Vector.h

@ -30,9 +30,6 @@
*/
#include <cmath>
#ifdef _MSC_VER
#include <algorithm> /* std::max() */
#endif
#include <Corrade/Utility/Assert.h>
#ifndef CORRADE_NO_DEBUG
#include <Corrade/Utility/Debug.h>
@ -45,6 +42,17 @@
namespace Magnum { namespace Math {
#ifndef DOXYGEN_GENERATING_OUTPUT
/* Documented in Functions.h, defined here because Vector needs them */
template<class T> constexpr typename std::enable_if<std::is_arithmetic<T>::value, T>::type min(T a, T b) {
return b < a ? b : a;
}
template<class T> constexpr typename std::enable_if<std::is_arithmetic<T>::value, T>::type max(T a, T b) {
return a < b ? b : a;
}
#endif
namespace Implementation {
template<std::size_t, class, class> struct VectorConverter;
/* Needed by DualQuaternion and Functions.h (to avoid dependency between them) */
@ -1383,7 +1391,7 @@ template<std::size_t size, class T> inline T Vector<size, T>::min() const {
T out(_data[0]);
for(std::size_t i = 1; i != size; ++i)
out = std::min(out, _data[i]);
out = Math::min(out, _data[i]);
return out;
}
@ -1392,7 +1400,7 @@ template<std::size_t size, class T> inline T Vector<size, T>::max() const {
T out(_data[0]);
for(std::size_t i = 1; i != size; ++i)
out = std::max(out, _data[i]);
out = Math::max(out, _data[i]);
return out;
}

Loading…
Cancel
Save