From 571ba7b17f88dd283ce614a2cd121a354f637a4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 25 May 2019 00:44:24 +0200 Subject: [PATCH] Math: group the free functions to make them easier to look up. --- src/Magnum/Math/Functions.h | 268 +++++++++++++++++-------------- src/Magnum/Math/FunctionsBatch.h | 9 ++ src/Magnum/Math/Packing.h | 10 ++ 3 files changed, 164 insertions(+), 123 deletions(-) diff --git a/src/Magnum/Math/Functions.h b/src/Magnum/Math/Functions.h index 3330f308c..a6c70a7f6 100644 --- a/src/Magnum/Math/Functions.h +++ b/src/Magnum/Math/Functions.h @@ -58,38 +58,6 @@ namespace Implementation { template struct IsBoolVectorOrScalar>: std::true_type {}; } -/** -@brief Integral logarithm - -Returns integral logarithm of given number with given base. -@see @ref log2(), @ref log(T) -*/ -UnsignedInt MAGNUM_EXPORT log(UnsignedInt base, UnsignedInt number); - -/** -@brief Base-2 integral logarithm - -Returns integral logarithm of given number with base `2`. -@see @ref log(UnsignedInt, UnsignedInt), @ref log(T) -*/ -UnsignedInt MAGNUM_EXPORT log2(UnsignedInt number); - -/** -@brief Natural logarithm - -Returns natural (base @f$ e @f$) logarithm of given number. -@see @ref Constants::e(), @ref log(UnsignedInt, UnsignedInt), @ref log2() -*/ -template inline T log(T number) { return std::log(number); } - -/** -@brief Natural exponential - -Returns @f$ e^x @f$. -@see @ref Constants::e(), @ref pow(T, T) -*/ -template inline T exp(T exponent) { return std::exp(exponent); } - /** @brief Integer division with remainder @@ -109,39 +77,13 @@ template inline std::pair div(Integral x, In } /** -@brief If given number is a positive or negative infinity +@{ @name Trigonometric functions -@see @ref isNan(), @ref Constants::inf() +Unlike @ref std::sin() and friends, those take or return strongly-typed units +to prevent degrees being accidentally interpreted as radians and such. See +@ref Magnum::Math::Deg "Deg" and @ref Magnum::Math::Rad "Rad" for more +information. */ -template inline typename std::enable_if::value, bool>::type isInf(T value) { - return std::isinf(UnderlyingTypeOf(value)); -} - -/** @overload */ -template inline BoolVector isInf(const Vector& value) { - BoolVector out; - for(std::size_t i = 0; i != size; ++i) - out.set(i, Math::isInf(value[i])); - return out; -} - -/** -@brief If given number is a NaN - -Equivalent to @cpp value != value @ce. -@see @ref isInf(), @ref Constants::nan() -*/ -template inline typename std::enable_if::value, bool>::type isNan(T value) { - return std::isnan(UnderlyingTypeOf(value)); -} - -/** @overload */ -template inline BoolVector isNan(const Vector& value) { - BoolVector out; - for(std::size_t i = 0; i != size; ++i) - out.set(i, Math::isNan(value[i])); - return out; -} /** @todo Can't trigonometric functions be done with only one overload? */ @@ -204,58 +146,56 @@ template inline Rad acos(T value) { return Rad(std::acos(value)); /** @brief Arc tangent */ template inline Rad atan(T value) { return Rad(std::atan(value)); } +/*@}*/ + /** @{ @name Scalar/vector functions These functions are overloaded for both scalar and vector types, including -@ref Deg and @ref Rad. Scalar versions function exactly as their possible STL -equivalents, vector overloads perform the operations component-wise. +@ref Magnum::Math::Deg "Deg" and @ref Magnum::Math::Rad "Rad". Scalar versions +function exactly as their possible STL equivalents, vector overloads perform +the operations component-wise. */ /** -@brief Integral power +@brief If given number is a positive or negative infinity -Returns integral power of base to the exponent. Works only on types that -satisfy @ref IsUnitless. -@see @ref pow(T, T) +@see @ref isNan(), @ref Constants::inf() */ -template constexpr typename std::enable_if::value, T>::type pow(T base) { - static_assert(IsUnitless::value, "expected an unitless type"); - return Implementation::Pow::pow(base); +template inline typename std::enable_if::value, bool>::type isInf(T value) { + return std::isinf(UnderlyingTypeOf(value)); } /** @overload */ -template inline Vector pow(const Vector& base) { - Vector out{NoInit}; +template inline BoolVector isInf(const Vector& value) { + BoolVector out; for(std::size_t i = 0; i != size; ++i) - out[i] = Math::pow(base[i]); + out.set(i, Math::isInf(value[i])); return out; } /** -@brief Power +@brief If given number is a NaN -Returns power of @p base to the @p exponent. Works only on types that satisfy -@ref IsUnitless. -@see @ref pow(T), @ref exp() +Equivalent to @cpp value != value @ce. +@see @ref isInf(), @ref Constants::nan() */ -template inline typename std::enable_if::value, T>::type pow(T base, T exponent) { - static_assert(IsUnitless::value, "expected an unitless type"); - return std::pow(base, exponent); +template inline typename std::enable_if::value, bool>::type isNan(T value) { + return std::isnan(UnderlyingTypeOf(value)); } /** @overload */ -template inline Vector pow(const Vector& base, T exponent) { - Vector out{NoInit}; +template inline BoolVector isNan(const Vector& value) { + BoolVector out; for(std::size_t i = 0; i != size; ++i) - out[i] = Math::pow(base[i], exponent); + out.set(i, Math::isNan(value[i])); return out; } /** @brief Minimum -NaNs passed in @p value parameter are propagated. +NaNs passed in the @p value parameter are propagated. @see @ref max(), @ref minmax(), @ref clamp(), @ref min(Corrade::Containers::ArrayView), @ref Vector::min() */ @@ -281,7 +221,7 @@ template inline Vector min(const VectorNaNs passed in @p value parameter are propagated. +NaNs passed in the @p value parameter are propagated. @see @ref min(), @ref minmax(), @ref clamp(), @ref max(Corrade::Containers::ArrayView), @ref Vector::max() */ @@ -426,42 +366,6 @@ template inline Vector ceil(const Vector&) -*/ -template inline typename std::enable_if::value, T>::type sqrt(T a) { - static_assert(IsUnitless::value, "expecting an unitless type"); - return std::sqrt(a); -} - -/** @overload */ -template inline Vector sqrt(const Vector& a) { - Vector out{NoInit}; - for(std::size_t i = 0; i != size; ++i) - out[i] = Math::sqrt(a[i]); - return out; -} - -/** -@brief Inverse square root - -Works only on types that satisfy @ref IsUnitless. -@see @ref sqrt(), @ref Vector::lengthInverted() -@m_keyword{inversesqrt(),GLSL inversesqrt(),} -*/ -template inline typename std::enable_if::value, T>::type sqrtInverted(T a) { - static_assert(IsUnitless::value, "expecting an unitless type"); - return T(1)/std::sqrt(a); -} - -/** @overload */ -template inline Vector sqrtInverted(const Vector& a) { - return Vector(T(1))/Math::sqrt(a); -} - /** @brief Linear interpolation of two values @param a First value @@ -587,6 +491,124 @@ template inline Vector fma(const Vector inline T log(T number) { return std::log(number); } + +/** +@brief Natural exponential + +Returns @f$ e^x @f$. +@see @ref Constants::e(), @ref pow(T, T) +*/ +template inline T exp(T exponent) { return std::exp(exponent); } + +/** +@brief Integral power + +Returns integral power of base to the exponent. Works only on types that +satisfy @ref IsUnitless. +@see @ref pow(T, T) +*/ +template constexpr typename std::enable_if::value, T>::type pow(T base) { + static_assert(IsUnitless::value, "expected an unitless type"); + return Implementation::Pow::pow(base); +} + +/** @overload */ +template inline Vector pow(const Vector& base) { + Vector out{NoInit}; + for(std::size_t i = 0; i != size; ++i) + out[i] = Math::pow(base[i]); + return out; +} + +/** +@brief Power + +Returns power of @p base to the @p exponent. Works only on types that satisfy +@ref IsUnitless. +@see @ref pow(T), @ref exp() +*/ +template inline typename std::enable_if::value, T>::type pow(T base, T exponent) { + static_assert(IsUnitless::value, "expected an unitless type"); + return std::pow(base, exponent); +} + +/** @overload */ +template inline Vector pow(const Vector& base, T exponent) { + Vector out{NoInit}; + for(std::size_t i = 0; i != size; ++i) + out[i] = Math::pow(base[i], exponent); + return out; +} + +/** +@brief Square root + +Works only on types that satisfy @ref IsUnitless. +@see @ref sqrtInverted(), @ref Vector::length(), @ref sqrt(const Dual&) +*/ +template inline typename std::enable_if::value, T>::type sqrt(T a) { + static_assert(IsUnitless::value, "expecting an unitless type"); + return std::sqrt(a); +} + +/** @overload */ +template inline Vector sqrt(const Vector& a) { + Vector out{NoInit}; + for(std::size_t i = 0; i != size; ++i) + out[i] = Math::sqrt(a[i]); + return out; +} + +/** +@brief Inverse square root + +Works only on types that satisfy @ref IsUnitless. +@see @ref sqrt(), @ref Vector::lengthInverted() +@m_keyword{inversesqrt(),GLSL inversesqrt(),} +*/ +template inline typename std::enable_if::value, T>::type sqrtInverted(T a) { + static_assert(IsUnitless::value, "expecting an unitless type"); + return T(1)/std::sqrt(a); +} + +/** @overload */ +template inline Vector sqrtInverted(const Vector& a) { + return Vector(T(1))/Math::sqrt(a); +} + +/*@}*/ + }} #ifdef MAGNUM_BUILD_DEPRECATED diff --git a/src/Magnum/Math/FunctionsBatch.h b/src/Magnum/Math/FunctionsBatch.h index 18bda98ad..d094ce968 100644 --- a/src/Magnum/Math/FunctionsBatch.h +++ b/src/Magnum/Math/FunctionsBatch.h @@ -36,6 +36,13 @@ namespace Magnum { namespace Math { +/** +@{ @name Batch functions + +These functions process an ubounded range of values, as opposed to single +vectors or scalars. +*/ + /** @brief Minimum of a range @@ -124,6 +131,8 @@ template inline std::pair minmax(const T(&array return minmax(Corrade::Containers::arrayView(array)); } +/*@}*/ + }} #endif diff --git a/src/Magnum/Math/Packing.h b/src/Magnum/Math/Packing.h index c807fc760..61a2d0d27 100644 --- a/src/Magnum/Math/Packing.h +++ b/src/Magnum/Math/Packing.h @@ -33,6 +33,14 @@ namespace Magnum { namespace Math { +/** +@{ @name Packing and unpacking functions + +Similarly to @m_class{m-doc} [scalar/vector functions](#scalarvector-functions) +these work on both scalars and vectors, including @ref Magnum::Math::Deg "Deg" +and @ref Magnum::Math::Rad "Rad". +*/ + namespace Implementation { template inline constexpr T bitMax() { @@ -209,6 +217,8 @@ template Vector unpackHalf(const Vector