Documentation for Algorithm + constexpr
Former-commit-id: d77905d0ee9a2dde655f548bd175042aa3f5d22d
This commit is contained in:
parent
1d04ac8f13
commit
007b40b1b3
|
|
@ -30,32 +30,32 @@
|
|||
|
||||
namespace Nz
|
||||
{
|
||||
template<typename T> T Approach(T value, T objective, T increment);
|
||||
template<typename T> constexpr T Approach(T value, T objective, T increment);
|
||||
template<typename T> constexpr T Clamp(T value, T min, T max);
|
||||
template<typename T> T CountBits(T value);
|
||||
template<typename T> constexpr T CountBits(T value);
|
||||
template<typename T> constexpr T FromDegrees(T degrees);
|
||||
template<typename T> constexpr T FromRadians(T radians);
|
||||
template<typename T> constexpr T DegreeToRadian(T degrees);
|
||||
template<typename T> T GetNearestPowerOfTwo(T number);
|
||||
unsigned int GetNumberLength(signed char number);
|
||||
unsigned int GetNumberLength(unsigned char number);
|
||||
template<typename T> constexpr T GetNearestPowerOfTwo(T number);
|
||||
constexpr unsigned int GetNumberLength(signed char number);
|
||||
constexpr unsigned int GetNumberLength(unsigned char number);
|
||||
unsigned int GetNumberLength(int number);
|
||||
unsigned int GetNumberLength(unsigned int number);
|
||||
constexpr unsigned int GetNumberLength(unsigned int number);
|
||||
unsigned int GetNumberLength(long long number);
|
||||
unsigned int GetNumberLength(unsigned long long number);
|
||||
constexpr unsigned int GetNumberLength(unsigned long long number);
|
||||
unsigned int GetNumberLength(float number, UInt8 precision = NAZARA_CORE_DECIMAL_DIGITS);
|
||||
unsigned int GetNumberLength(double number, UInt8 precision = NAZARA_CORE_DECIMAL_DIGITS);
|
||||
unsigned int GetNumberLength(long double number, UInt8 precision = NAZARA_CORE_DECIMAL_DIGITS);
|
||||
template<typename T> unsigned int IntegralLog2(T number);
|
||||
template<typename T> unsigned int IntegralLog2Pot(T pot);
|
||||
unsigned int IntegralPow(unsigned int base, unsigned int exponent);
|
||||
template<typename T, typename T2> T Lerp(T from, T to, T2 interpolation);
|
||||
template<typename T> T MultiplyAdd(T x, T y, T z);
|
||||
template<typename T> T NormalizeAngle(T angle);
|
||||
template<typename T> bool NumberEquals(T a, T b);
|
||||
template<typename T> bool NumberEquals(T a, T b, T maxDifference);
|
||||
template<typename T> constexpr unsigned int IntegralLog2(T number);
|
||||
template<typename T> constexpr unsigned int IntegralLog2Pot(T pot);
|
||||
constexpr unsigned int IntegralPow(unsigned int base, unsigned int exponent);
|
||||
template<typename T, typename T2> constexpr T Lerp(const T& from, const T& to, const T2& interpolation);
|
||||
template<typename T> constexpr T MultiplyAdd(T x, T y, T z);
|
||||
template<typename T> constexpr T NormalizeAngle(T angle);
|
||||
template<typename T> constexpr bool NumberEquals(T a, T b);
|
||||
template<typename T> constexpr bool NumberEquals(T a, T b, T maxDifference);
|
||||
String NumberToString(long long number, UInt8 radix = 10);
|
||||
template<typename T> T RadianToDegree(T radians);
|
||||
template<typename T> constexpr T RadianToDegree(T radians);
|
||||
long long StringToNumber(String str, UInt8 radix = 10, bool* ok = nullptr);
|
||||
template<typename T> constexpr T ToDegrees(T angle);
|
||||
template<typename T> constexpr T ToRadians(T angle);
|
||||
|
|
|
|||
|
|
@ -98,10 +98,18 @@ namespace Nz
|
|||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Approaches the objective, beginning with value and with increment
|
||||
* \return The nearest value of the objective you can get with the value and the increment for one step
|
||||
*
|
||||
* \param value Initial value
|
||||
* \param objective Target value
|
||||
* \parma increment One step value
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T Approach(T value, T objective, T increment)
|
||||
constexpr T Approach(T value, T objective, T increment)
|
||||
{
|
||||
///TODO: Marquer comme constexpr en C++14
|
||||
if (value < objective)
|
||||
return std::min(value + increment, objective);
|
||||
else if (value > objective)
|
||||
|
|
@ -110,14 +118,30 @@ namespace Nz
|
|||
return value;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Clamps value between min and max and returns the expected value
|
||||
* \return If value is not in the interval of min..max, value obtained is the nearest limit of this interval
|
||||
*
|
||||
* \param value Value to clamp
|
||||
* \param min Minimum of the interval
|
||||
* \param max Maximum of the interval
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
constexpr T Clamp(T value, T min, T max)
|
||||
{
|
||||
return std::max(std::min(value, max), min);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets number of bits set in the number
|
||||
* \return The number of bits set to 1
|
||||
*
|
||||
* \param value The value to count bits
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T CountBits(T value)
|
||||
constexpr T CountBits(T value)
|
||||
{
|
||||
// https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan
|
||||
unsigned int count = 0;
|
||||
|
|
@ -130,12 +154,26 @@ namespace Nz
|
|||
return count;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Converts degree to radian
|
||||
* \return The representation in radian of the angle in degree (0..2*pi)
|
||||
*
|
||||
* \param degrees Angle in degree (this is expected between 0..360)
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
constexpr T DegreeToRadian(T degrees)
|
||||
{
|
||||
return degrees * T(M_PI/180.0);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the unit from degree and convert it according to NAZARA_MATH_ANGLE_RADIAN
|
||||
* \return Express the degrees
|
||||
*
|
||||
* \param degrees Convert degree to NAZARA_MATH_ANGLE_RADIAN unit
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
constexpr T FromDegrees(T degrees)
|
||||
{
|
||||
|
|
@ -146,6 +184,13 @@ namespace Nz
|
|||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the unit from radian and convert it according to NAZARA_MATH_ANGLE_RADIAN
|
||||
* \return Express the radians
|
||||
*
|
||||
* \param radians Convert radian to NAZARA_MATH_ANGLE_RADIAN unit
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
constexpr T FromRadians(T radians)
|
||||
{
|
||||
|
|
@ -156,22 +201,33 @@ namespace Nz
|
|||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the nearest power of two for the number
|
||||
* \return First power of two containing the number
|
||||
*
|
||||
* \param number Number to get nearest power
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T GetNearestPowerOfTwo(T number)
|
||||
constexpr T GetNearestPowerOfTwo(T number)
|
||||
{
|
||||
///TODO: Marquer comme constexpr en C++14
|
||||
T x = 1;
|
||||
// Tant que x est plus petit que n, on décale ses bits vers la gauche, ce qui revient à multiplier par deux
|
||||
while (x < number)
|
||||
x <<= 1;
|
||||
x <<= 1; // We multiply by 2
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
inline unsigned int GetNumberLength(signed char number)
|
||||
/*!
|
||||
* \brief Gets the number of digits to represent the number in base 10
|
||||
* \return Number of digits
|
||||
*
|
||||
* \param number Number to get number of digits
|
||||
*/
|
||||
|
||||
constexpr unsigned int GetNumberLength(signed char number)
|
||||
{
|
||||
///TODO: Marquer comme constexpr en C++14
|
||||
// Le standard définit le char comme étant codé sur un octet
|
||||
// Char is expected to be 1 byte
|
||||
static_assert(sizeof(number) == 1, "Signed char must be one byte-sized");
|
||||
|
||||
if (number >= 100)
|
||||
|
|
@ -188,10 +244,16 @@ namespace Nz
|
|||
return 4;
|
||||
}
|
||||
|
||||
inline unsigned int GetNumberLength(unsigned char number)
|
||||
/*!
|
||||
* \brief Gets the number of digits to represent the number in base 10
|
||||
* \return Number of digits
|
||||
*
|
||||
* \param number Number to get number of digits
|
||||
*/
|
||||
|
||||
constexpr unsigned int GetNumberLength(unsigned char number)
|
||||
{
|
||||
///TODO: Marquer comme constexpr en C++14
|
||||
// Le standard définit le char comme étant codé sur un octet
|
||||
// Char is expected to be 1 byte
|
||||
static_assert(sizeof(number) == 1, "Unsigned char must be one byte-sized");
|
||||
|
||||
if (number >= 100)
|
||||
|
|
@ -202,6 +264,13 @@ namespace Nz
|
|||
return 1;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the number of digits to represent the number in base 10
|
||||
* \return Number of digits
|
||||
*
|
||||
* \param number Number to get number of digits
|
||||
*/
|
||||
|
||||
inline unsigned int GetNumberLength(int number)
|
||||
{
|
||||
if (number == 0)
|
||||
|
|
@ -210,7 +279,14 @@ namespace Nz
|
|||
return static_cast<unsigned int>(std::log10(std::abs(number))) + (number < 0 ? 2 : 1);
|
||||
}
|
||||
|
||||
inline unsigned int GetNumberLength(unsigned int number)
|
||||
/*!
|
||||
* \brief Gets the number of digits to represent the number in base 10
|
||||
* \return Number of digits
|
||||
*
|
||||
* \param number Number to get number of digits
|
||||
*/
|
||||
|
||||
constexpr unsigned int GetNumberLength(unsigned int number)
|
||||
{
|
||||
if (number == 0)
|
||||
return 1;
|
||||
|
|
@ -218,6 +294,13 @@ namespace Nz
|
|||
return static_cast<unsigned int>(std::log10(number))+1;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the number of digits to represent the number in base 10
|
||||
* \return Number of digits
|
||||
*
|
||||
* \param number Number to get number of digits
|
||||
*/
|
||||
|
||||
inline unsigned int GetNumberLength(long long number)
|
||||
{
|
||||
if (number == 0)
|
||||
|
|
@ -226,7 +309,14 @@ namespace Nz
|
|||
return static_cast<unsigned int>(std::log10(std::abs(number))) + (number < 0 ? 2 : 1);
|
||||
}
|
||||
|
||||
inline unsigned int GetNumberLength(unsigned long long number)
|
||||
/*!
|
||||
* \brief Gets the number of digits to represent the number in base 10
|
||||
* \return Number of digits
|
||||
*
|
||||
* \param number Number to get number of digits
|
||||
*/
|
||||
|
||||
constexpr unsigned int GetNumberLength(unsigned long long number)
|
||||
{
|
||||
if (number == 0)
|
||||
return 1;
|
||||
|
|
@ -234,40 +324,90 @@ namespace Nz
|
|||
return static_cast<unsigned int>(std::log10(number)) + 1;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the number of digits to represent the number in base 10
|
||||
* \return Number of digits + 1 for the dot
|
||||
*
|
||||
* \param number Number to get number of digits
|
||||
* \param precision Number of digit after the dot
|
||||
*/
|
||||
|
||||
inline unsigned int GetNumberLength(float number, UInt8 precision)
|
||||
{
|
||||
// L'imprécision des flottants nécessite un cast (log10(9.99999) = 0.99999)
|
||||
return GetNumberLength(static_cast<long long>(number)) + precision + 1; // Plus un pour le point
|
||||
// The imprecision of floats need a cast (log10(9.99999) = 0.99999)
|
||||
return GetNumberLength(static_cast<long long>(number)) + precision + 1; // Plus one for the dot
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the number of digits to represent the number in base 10
|
||||
* \return Number of digits + 1 for the dot
|
||||
*
|
||||
* \param number Number to get number of digits
|
||||
* \param precision Number of digit after the dot
|
||||
*/
|
||||
|
||||
inline unsigned int GetNumberLength(double number, UInt8 precision)
|
||||
{
|
||||
// L'imprécision des flottants nécessite un cast (log10(9.99999) = 0.99999)
|
||||
return GetNumberLength(static_cast<long long>(number)) + precision + 1; // Plus un pour le point
|
||||
// The imprecision of floats need a cast (log10(9.99999) = 0.99999)
|
||||
return GetNumberLength(static_cast<long long>(number)) + precision + 1; // Plus one for the dot
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the number of digits to represent the number in base 10
|
||||
* \return Number of digits + 1 for the dot
|
||||
*
|
||||
* \param number Number to get number of digits
|
||||
* \param precision Number of digit after the dot
|
||||
*/
|
||||
|
||||
inline unsigned int GetNumberLength(long double number, UInt8 precision)
|
||||
{
|
||||
// L'imprécision des flottants nécessite un cast (log10(9.99999) = 0.99999)
|
||||
return GetNumberLength(static_cast<long long>(number)) + precision + 1; // Plus un pour le point
|
||||
// The imprecision of floats need a cast (log10(9.99999) = 0.99999)
|
||||
return GetNumberLength(static_cast<long long>(number)) + precision + 1; // Plus one for the dot
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the log in base 2 of integral number
|
||||
* \return Log of the number (floor)
|
||||
*
|
||||
* \param number To get log in base 2
|
||||
*
|
||||
* \remark If number is 0, 0 is returned
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
unsigned int IntegralLog2(T number)
|
||||
constexpr unsigned int IntegralLog2(T number)
|
||||
{
|
||||
// Proxy nécessaire pour éviter un problème de surcharge
|
||||
// Proxy needed to avoid an overload problem
|
||||
return Detail::IntegralLog2<T>(number);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the log in base 2 of integral number, only works for power of two !
|
||||
* \return Log of the number
|
||||
*
|
||||
* \param number To get log in base 2
|
||||
*
|
||||
* \remark Only works for power of two
|
||||
* \remark If number is 0, 0 is returned
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
unsigned int IntegralLog2Pot(T pot)
|
||||
constexpr unsigned int IntegralLog2Pot(T pot)
|
||||
{
|
||||
return Detail::IntegralLog2Pot<T>(pot);
|
||||
}
|
||||
|
||||
inline unsigned int IntegralPow(unsigned int base, unsigned int exponent)
|
||||
/*!
|
||||
* \brief Gets the power of integrals
|
||||
* \return base^exponent for integral
|
||||
*
|
||||
* \param base Base of the exponentation
|
||||
* \parma exponent Power for the base
|
||||
*/
|
||||
|
||||
constexpr unsigned int IntegralPow(unsigned int base, unsigned int exponent)
|
||||
{
|
||||
///TODO: Marquer comme constexpr en C++14
|
||||
unsigned int r = 1;
|
||||
for (unsigned int i = 0; i < exponent; ++i)
|
||||
r *= base;
|
||||
|
|
@ -275,8 +415,22 @@ namespace Nz
|
|||
return r;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Interpolates the value to other one with a factor of interpolation
|
||||
* \return A new value which is the interpolation of two values
|
||||
*
|
||||
* \param from Initial value
|
||||
* \param to Target value
|
||||
* \param interpolation Factor of interpolation
|
||||
*
|
||||
* \remark interpolation is meant to be between 0 and 1, other values are potentially undefined behavior
|
||||
* \remark With NAZARA_DEBUG, a NazaraWarning is produced
|
||||
*
|
||||
* \see Lerp
|
||||
*/
|
||||
|
||||
template<typename T, typename T2>
|
||||
T Lerp(T from, T to, T2 interpolation)
|
||||
constexpr T Lerp(const T& from, const T& to, const T2& interpolation)
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (interpolation < T2(0.0) || interpolation > T2(1.0))
|
||||
|
|
@ -286,15 +440,26 @@ namespace Nz
|
|||
return from + interpolation * (to - from);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Multiplies X and Y, then add Z
|
||||
* \return The result of X * Y + Z
|
||||
*
|
||||
* \param x is X
|
||||
* \param y is Y
|
||||
* \param z is Z
|
||||
*
|
||||
* \remark This function is meant to use a special instruction in CPU
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T MultiplyAdd(T x, T y, T z)
|
||||
constexpr T MultiplyAdd(T x, T y, T z)
|
||||
{
|
||||
return x*y + z;
|
||||
return x * y + z;
|
||||
}
|
||||
|
||||
#ifdef FP_FAST_FMAF
|
||||
template<>
|
||||
inline float MultiplyAdd(float x, float y, float z)
|
||||
constexpr float MultiplyAdd(float x, float y, float z)
|
||||
{
|
||||
return std::fmaf(x, y, z);
|
||||
}
|
||||
|
|
@ -302,7 +467,7 @@ namespace Nz
|
|||
|
||||
#ifdef FP_FAST_FMA
|
||||
template<>
|
||||
inline double MultiplyAdd(double x, double y, double z)
|
||||
constexpr double MultiplyAdd(double x, double y, double z)
|
||||
{
|
||||
return std::fma(x, y, z);
|
||||
}
|
||||
|
|
@ -310,14 +475,21 @@ namespace Nz
|
|||
|
||||
#ifdef FP_FAST_FMAL
|
||||
template<>
|
||||
inline long double MultiplyAdd(long double x, long double y, long double z)
|
||||
constexpr long double MultiplyAdd(long double x, long double y, long double z)
|
||||
{
|
||||
return std::fmal(x, y, z);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* \brief Normalizes the angle
|
||||
* \return Normalized value between 0..2*(pi if radian or 180 if degrees)
|
||||
*
|
||||
* \param angle Angle to normalize
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T NormalizeAngle(T angle)
|
||||
constexpr T NormalizeAngle(T angle)
|
||||
{
|
||||
#if NAZARA_MATH_ANGLE_RADIAN
|
||||
const T limit = T(M_PI);
|
||||
|
|
@ -333,14 +505,31 @@ namespace Nz
|
|||
return angle - limit;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether two numbers are equal
|
||||
* \return true if they are equal within a certain epsilon
|
||||
*
|
||||
* \param a First value
|
||||
* \param b Second value
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool NumberEquals(T a, T b)
|
||||
constexpr bool NumberEquals(T a, T b)
|
||||
{
|
||||
return NumberEquals(a, b, std::numeric_limits<T>::epsilon());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Checks whether two numbers are equal
|
||||
* \return true if they are equal within the max difference
|
||||
*
|
||||
* \param a First value
|
||||
* \param b Second value
|
||||
* \param maxDifference Epsilon of comparison (expected to be positive)
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
bool NumberEquals(T a, T b, T maxDifference)
|
||||
constexpr bool NumberEquals(T a, T b, T maxDifference)
|
||||
{
|
||||
if (b > a)
|
||||
std::swap(a, b);
|
||||
|
|
@ -349,6 +538,17 @@ namespace Nz
|
|||
return diff <= maxDifference;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Converts the number to String
|
||||
* \return String representation of the number
|
||||
*
|
||||
* \param number Number to represent
|
||||
* \param radix Base of the number
|
||||
*
|
||||
* \remark radix is meant to be between 2 and 36, other values are potentially undefined behavior
|
||||
* \remark With NAZARA_MATH_SAFE, a NazaraError is produced and String() is returned
|
||||
*/
|
||||
|
||||
inline String NumberToString(long long number, UInt8 radix)
|
||||
{
|
||||
#if NAZARA_MATH_SAFE
|
||||
|
|
@ -389,12 +589,31 @@ namespace Nz
|
|||
return str.Reverse();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Converts radian to degree
|
||||
* \return The representation in degree of the angle in radian (0..360)
|
||||
*
|
||||
* \param radians Angle in radian (this is expected between 0..2*pi)
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
T RadianToDegree(T radians)
|
||||
constexpr T RadianToDegree(T radians)
|
||||
{
|
||||
return radians * T(180.0/M_PI);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Converts the string to number
|
||||
* \return Number which is represented by the string
|
||||
*
|
||||
* \param str String representation
|
||||
* \param radix Base of the number
|
||||
* \param ok Optional argument to know if convertion is correct
|
||||
*
|
||||
* \remark radix is meant to be between 2 and 36, other values are potentially undefined behavior
|
||||
* \remark With NAZARA_MATH_SAFE, a NazaraError is produced and 0 is returned
|
||||
*/
|
||||
|
||||
inline long long StringToNumber(String str, UInt8 radix, bool* ok)
|
||||
{
|
||||
#if NAZARA_MATH_SAFE
|
||||
|
|
@ -444,6 +663,13 @@ namespace Nz
|
|||
return (negative) ? -static_cast<long long>(total) : total;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the degree from unit and convert it according to NAZARA_MATH_ANGLE_RADIAN
|
||||
* \return Express in degrees
|
||||
*
|
||||
* \param angle Convert degree from NAZARA_MATH_ANGLE_RADIAN unit to degrees
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
constexpr T ToDegrees(T angle)
|
||||
{
|
||||
|
|
@ -454,6 +680,13 @@ namespace Nz
|
|||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Gets the radian from unit and convert it according to NAZARA_MATH_ANGLE_RADIAN
|
||||
* \return Express in radians
|
||||
*
|
||||
* \param angle Convert degree from NAZARA_MATH_ANGLE_RADIAN unit to radians
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
constexpr T ToRadians(T angle)
|
||||
{
|
||||
|
|
@ -461,8 +694,8 @@ namespace Nz
|
|||
return angle;
|
||||
#else
|
||||
return DegreeToRadian(angle);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#include <Nazara/Core/DebugOff.hpp>
|
||||
|
|
|
|||
Loading…
Reference in New Issue