13#ifndef WPIUTIL_WPI_MATHEXTRAS_H
14#define WPIUTIL_WPI_MATHEXTRAS_H
26#include <android/api-level.h>
34unsigned char _BitScanForward(
unsigned long *_Index,
unsigned long _Mask);
35unsigned char _BitScanForward64(
unsigned long *_Index,
unsigned __int64 _Mask);
36unsigned char _BitScanReverse(
unsigned long *_Index,
unsigned long _Mask);
37unsigned char _BitScanReverse64(
unsigned long *_Index,
unsigned __int64 _Mask);
57 return std::numeric_limits<T>::digits;
62 unsigned ZeroBits = 0;
63 T Shift = std::numeric_limits<T>::digits >> 1;
66 if ((Val & Mask) == 0) {
77#if defined(__GNUC__) || defined(_MSC_VER)
78template <
typename T>
struct TrailingZerosCounter<T, 4> {
83#if __has_builtin(__builtin_ctz) || defined(__GNUC__)
84 return __builtin_ctz(Val);
85#elif defined(_MSC_VER)
87 _BitScanForward(&
Index, Val);
93#if !defined(_MSC_VER) || defined(_M_X64)
94template <
typename T>
struct TrailingZerosCounter<T, 8> {
99#if __has_builtin(__builtin_ctzll) || defined(__GNUC__)
100 return __builtin_ctzll(Val);
101#elif defined(_MSC_VER)
103 _BitScanForward64(&
Index, Val);
123 "Only unsigned integral types are allowed.");
131 return std::numeric_limits<T>::digits;
134 unsigned ZeroBits = 0;
135 for (T Shift = std::numeric_limits<T>::digits >> 1; Shift; Shift >>= 1) {
136 T Tmp = Val >> Shift;
146#if defined(__GNUC__) || defined(_MSC_VER)
147template <
typename T>
struct LeadingZerosCounter<T, 4> {
152#if __has_builtin(__builtin_clz) || defined(__GNUC__)
153 return __builtin_clz(Val);
154#elif defined(_MSC_VER)
156 _BitScanReverse(&
Index, Val);
162#if !defined(_MSC_VER) || defined(_M_X64)
163template <
typename T>
struct LeadingZerosCounter<T, 8> {
168#if __has_builtin(__builtin_clzll) || defined(__GNUC__)
169 return __builtin_clzll(Val);
170#elif defined(_MSC_VER)
172 _BitScanReverse64(&
Index, Val);
192 "Only unsigned integral types are allowed.");
204 if (ZB ==
ZB_Max && Val == 0)
213 static_assert(std::is_unsigned<T>::value,
"Invalid type!");
214 const unsigned Bits = CHAR_BIT *
sizeof(T);
215 assert(N <= Bits &&
"Invalid bit index");
216 return N == 0 ? 0 : (T(-1) >> (Bits - N));
222 return ~maskTrailingOnes<T>(CHAR_BIT *
sizeof(T) - N);
228 return maskLeadingOnes<T>(CHAR_BIT *
sizeof(T) - N);
234 return maskTrailingOnes<T>(CHAR_BIT *
sizeof(T) - N);
245 if (ZB ==
ZB_Max && Val == 0)
251 (std::numeric_limits<T>::digits - 1);
258#define R2(n) n, n + 2 * 64, n + 1 * 64, n + 3 * 64
259#define R4(n) R2(n), R2(n + 2 * 16), R2(n + 1 * 16), R2(n + 3 * 16)
260#define R6(n) R4(n), R4(n + 2 * 4), R4(n + 1 * 4), R4(n + 3 * 4)
270 unsigned char in[
sizeof(Val)];
271 unsigned char out[
sizeof(Val)];
272 std::memcpy(in, &Val,
sizeof(Val));
273 for (
unsigned i = 0; i <
sizeof(Val); ++i)
275 std::memcpy(&Val, out,
sizeof(Val));
279#if __has_builtin(__builtin_bitreverse8)
282 return __builtin_bitreverse8(Val);
286#if __has_builtin(__builtin_bitreverse16)
289 return __builtin_bitreverse16(Val);
293#if __has_builtin(__builtin_bitreverse32)
296 return __builtin_bitreverse32(Val);
300#if __has_builtin(__builtin_bitreverse64)
303 return __builtin_bitreverse64(Val);
313 return static_cast<uint32_t>(Value >> 32);
318 return static_cast<uint32_t>(Value);
328 return N >= 64 || (-(INT64_C(1)<<(N-1)) <= x && x < (INT64_C(1)<<(N-1)));
332 return static_cast<int8_t>(x) == x;
335 return static_cast<int16_t>(x) == x;
338 return static_cast<int32_t>(x) == x;
342template <
unsigned N,
unsigned S>
345 N > 0,
"isShiftedInt<0> doesn't make sense (refers to a 0-bit number.");
346 static_assert(N +
S <= 64,
"isShiftedInt<N, S> with N + S > 64 is too wide.");
347 return isInt<N + S>(x) && (x % (UINT64_C(1) <<
S) == 0);
360 static_assert(N > 0,
"isUInt<0> doesn't make sense");
361 return X < (UINT64_C(1) << (N));
370 return static_cast<uint8_t>(x) == x;
373 return static_cast<uint16_t>(x) == x;
376 return static_cast<uint32_t>(x) == x;
380template <
unsigned N,
unsigned S>
383 N > 0,
"isShiftedUInt<0> doesn't make sense (refers to a 0-bit number)");
384 static_assert(N +
S <= 64,
385 "isShiftedUInt<N, S> with N + S > 64 is too wide.");
388 return isUInt<N + S>(x) && (x % (UINT64_C(1) <<
S) == 0);
393 assert(N > 0 && N <= 64 &&
"integer width out of range");
399 return UINT64_MAX >> (64 - N);
404#pragma warning(disable : 4146)
409 assert(N > 0 && N <= 64 &&
"integer width out of range");
411 return UINT64_C(1) + ~(UINT64_C(1) << (N - 1));
420 assert(N > 0 && N <= 64 &&
"integer width out of range");
424 return (UINT64_C(1) << (N - 1)) - 1;
441 return Value && ((Value + 1) & Value) == 0;
447 return Value && ((Value + 1) & Value) == 0;
453 return Value &&
isMask_32((Value - 1) | Value);
459 return Value &&
isMask_64((Value - 1) | Value);
465 return Value && !(Value & (Value - 1));
470 return Value && !(Value & (Value - 1));
485 "Only unsigned integral types are allowed.");
486 return countLeadingZeros<T>(~Value, ZB);
501 "Only unsigned integral types are allowed.");
502 return countTrailingZeros<T>(~Value, ZB);
509 static_assert(SizeOfT <= 4,
"Not implemented!");
511 return __builtin_popcount(Value);
514 v = v - ((v >> 1) & 0x55555555);
515 v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
516 return ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
524 return __builtin_popcountll(Value);
527 v = v - ((v >> 1) & 0x5555555555555555ULL);
528 v = (v & 0x3333333333333333ULL) + ((v >> 2) & 0x3333333333333333ULL);
529 v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
530 return unsigned((
uint64_t)(v * 0x0101010101010101ULL) >> 56);
543 "Only unsigned integral types are allowed.");
549template <
size_t kValue>
constexpr inline size_t CTLog2() {
551 "Value is not a valid power of 2");
552 return 1 +
CTLog2<kValue / 2>();
555template <>
constexpr inline size_t CTLog2<1>() {
return 0; }
558inline double Log2(
double Value) {
559#if defined(__ANDROID_API__) && __ANDROID_API__ < 18
560 return __builtin_log(Value) / __builtin_log(2.0);
604 return greatestCommonDivisor<uint64_t>(A, B);
610 static_assert(
sizeof(
uint64_t) ==
sizeof(
double),
"Unexpected type sizes");
611 memcpy(&D, &Bits,
sizeof(Bits));
618 static_assert(
sizeof(
uint32_t) ==
sizeof(
float),
"Unexpected type sizes");
619 memcpy(&
F, &Bits,
sizeof(Bits));
628 static_assert(
sizeof(
uint64_t) ==
sizeof(
double),
"Unexpected type sizes");
629 memcpy(&Bits, &Double,
sizeof(Double));
638 static_assert(
sizeof(
uint32_t) ==
sizeof(
float),
"Unexpected type sizes");
639 memcpy(&Bits, &Float,
sizeof(Float));
651 return (A | B) & (1 + ~(A | B));
702 assert(Align != 0u &&
"Align can't be 0.");
704 return (Value + Align - 1 - Skew) / Align * Align + Skew;
710 static_assert(Align != 0u,
"Align must be non-zero");
711 return (Value + Align - 1) / Align * Align;
716 return alignTo(Numerator, Denominator) / Denominator;
721 return (Numerator + (Denominator / 2)) / Denominator;
727 assert(Align != 0u &&
"Align can't be 0.");
729 return (Value - Skew) / Align * Align + Skew;
735 static_assert(B > 0,
"Bit width can't be 0.");
736 static_assert(B <= 32,
"Bit width out of range.");
737 return int32_t(X << (32 - B)) >> (32 - B);
743 assert(B > 0 &&
"Bit width can't be 0.");
744 assert(B <= 32 &&
"Bit width out of range.");
745 return int32_t(X << (32 - B)) >> (32 - B);
751 static_assert(B > 0,
"Bit width can't be 0.");
752 static_assert(B <= 64,
"Bit width out of range.");
753 return int64_t(x << (64 - B)) >> (64 - B);
759 assert(B > 0 &&
"Bit width can't be 0.");
760 assert(B <= 64 &&
"Bit width out of range.");
761 return int64_t(X << (64 - B)) >> (64 - B);
768 return X > Y ? (X - Y) : (Y - X);
775std::enable_if_t<std::is_unsigned<T>::value, T>
778 bool &Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy;
781 Overflowed = (Z < X || Z < Y);
792std::enable_if_t<std::is_unsigned<T>::value, T>
795 bool &Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy;
810 if (Log2Z < Log2Max) {
813 if (Log2Z > Log2Max) {
822 if (Z & ~(Max >> 1)) {
838std::enable_if_t<std::is_unsigned<T>::value, T>
841 bool &Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy;
857std::enable_if_t<std::is_signed<T>::value, T>
AddOverflow(T X, T Y, T &Result) {
858#if __has_builtin(__builtin_add_overflow)
859 return __builtin_add_overflow(X, Y, &Result);
862 using U = std::make_unsigned_t<T>;
863 const U UX =
static_cast<U
>(X);
864 const U UY =
static_cast<U
>(Y);
865 const U UResult = UX + UY;
868 Result =
static_cast<T
>(UResult);
883std::enable_if_t<std::is_signed<T>::value, T>
SubOverflow(T X, T Y, T &Result) {
884#if __has_builtin(__builtin_sub_overflow)
885 return __builtin_sub_overflow(X, Y, &Result);
888 using U = std::make_unsigned_t<T>;
889 const U UX =
static_cast<U
>(X);
890 const U UY =
static_cast<U
>(Y);
891 const U UResult = UX - UY;
894 Result =
static_cast<T
>(UResult);
909std::enable_if_t<std::is_signed<T>::value, T>
MulOverflow(T X, T Y, T &Result) {
911 using U = std::make_unsigned_t<T>;
912 const U UX = X < 0 ? (0 -
static_cast<U
>(X)) :
static_cast<U
>(X);
913 const U UY = Y < 0 ? (0 -
static_cast<U
>(Y)) :
static_cast<U
>(Y);
914 const U UResult = UX * UY;
917 const bool IsNegative = (X < 0) ^ (Y < 0);
918 Result = IsNegative ? (0 - UResult) : UResult;
921 if (UX == 0 || UY == 0)
937 return (T(0) < val) - (val < T(0));
950constexpr T
Lerp(
const T& startValue,
const T& endValue,
double t) {
951 return startValue + (endValue - startValue) * t;
typename std::enable_if< B, T >::type enable_if_t
Definition: core.h:298
constexpr auto count() -> size_t
Definition: core.h:1204
dimensionless::scalar_t log2(const ScalarUnit x) noexcept
Compute binary logarithm.
Definition: math.h:453
constexpr common_t< T1, T2 > max(const T1 x, const T2 y) noexcept
Compile-time pairwise maximum function.
Definition: max.hpp:35
::uint64_t uint64_t
Definition: Meta.h:58
::int16_t int16_t
Definition: Meta.h:55
::uint16_t uint16_t
Definition: Meta.h:54
::uint32_t uint32_t
Definition: Meta.h:56
::int32_t int32_t
Definition: Meta.h:57
::int8_t int8_t
Definition: Meta.h:53
::int64_t int64_t
Definition: Meta.h:59
::uint8_t uint8_t
Definition: Meta.h:52
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:74
Definition: format-inl.h:32
static constexpr const unit_t< compound_unit< charge::coulomb, inverse< substance::mol > > > F(N_A *e)
Faraday constant.
Definition: AprilTagFieldLayout.h:18
int64_t maxIntN(int64_t N)
Gets the maximum value for a N-bit signed integer.
Definition: MathExtras.h:419
static const unsigned char BitReverseTable256[256]
Macro compressed bit reversal table for 256 bits.
Definition: MathExtras.h:257
T maskLeadingOnes(unsigned N)
Create a bitmask with the N left-most bits set to 1, and all other bits set to 0.
Definition: MathExtras.h:221
constexpr int sgn(T val)
Definition: MathExtras.h:936
unsigned countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the least significant bit to the most stopping at the first 1.
Definition: MathExtras.h:120
double Log2(double Value)
Return the log base 2 of the specified value.
Definition: MathExtras.h:558
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition: MathExtras.h:569
uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew=0)
Returns the next integer (mod 2**64) that is greater than or equal to Value and is a multiple of Alig...
Definition: MathExtras.h:701
unsigned Log2_32_Ceil(uint32_t Value)
Return the ceil log base 2 of the specified value, 32 if the value is zero.
Definition: MathExtras.h:582
constexpr bool isInt< 16 >(int64_t x)
Definition: MathExtras.h:334
uint64_t PowerOf2Ceil(uint64_t A)
Returns the power of two which is greater than or equal to the given value.
Definition: MathExtras.h:675
std::enable_if_t< std::is_unsigned< T >::value, T > SaturatingMultiply(T X, T Y, bool *ResultOverflowed=nullptr)
Multiply two unsigned integers, X and Y, of type T.
Definition: MathExtras.h:793
T findLastSet(T Val, ZeroBehavior ZB=ZB_Max)
Get the index of the last set bit starting from the least significant bit.
Definition: MathExtras.h:244
unsigned countLeadingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the most significant bit to the least stopping at the first 1.
Definition: MathExtras.h:189
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
Definition: MathExtras.h:317
T maskTrailingOnes(unsigned N)
Create a bitmask with the N right-most bits set to 1, and all other bits set to 0.
Definition: MathExtras.h:212
float BitsToFloat(uint32_t Bits)
This function takes a 32-bit integer and returns the bit equivalent float.
Definition: MathExtras.h:616
T findFirstSet(T Val, ZeroBehavior ZB=ZB_Max)
Get the index of the first set bit starting from the least significant bit.
Definition: MathExtras.h:203
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
Definition: MathExtras.h:343
std::enable_if_t< std::is_signed< T >::value, T > AddOverflow(T X, T Y, T &Result)
Add two signed integers, computing the two's complement truncated result, returning true if overflow ...
Definition: MathExtras.h:857
constexpr bool isShiftedMask_32(uint32_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (32 bit ver...
Definition: MathExtras.h:452
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
Definition: MathExtras.h:750
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition: MathExtras.h:464
constexpr std::enable_if_t<(N< 64), bool > isUInt(uint64_t X)
Checks if an unsigned integer fits into the given bit width.
Definition: MathExtras.h:359
T reverseBits(T Val)
Reverse the bits in Val.
Definition: MathExtras.h:269
constexpr size_t CTLog2()
Compile time Log2.
Definition: MathExtras.h:549
T greatestCommonDivisor(T A, T B)
Return the greatest common divisor of the values using Euclid's algorithm.
Definition: MathExtras.h:594
std::enable_if_t< std::is_unsigned< T >::value, T > AbsoluteDifference(T X, T Y)
Subtract two unsigned integers, X and Y, of type T and return the absolute value of the result.
Definition: MathExtras.h:767
const float huge_valf
Use this rather than HUGE_VALF; the latter causes warnings on MSVC.
std::enable_if_t< std::is_signed< T >::value, T > MulOverflow(T X, T Y, T &Result)
Multiply two signed integers, computing the two's complement truncated result, returning true if an o...
Definition: MathExtras.h:909
uint64_t NextPowerOf2(uint64_t A)
Returns the next power of two (in 64-bits) that is strictly greater than A.
Definition: MathExtras.h:656
constexpr size_t CTLog2< 1 >()
Definition: MathExtras.h:555
uint64_t divideNearest(uint64_t Numerator, uint64_t Denominator)
Returns the integer nearest(Numerator / Denominator).
Definition: MathExtras.h:720
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition: MathExtras.h:327
unsigned countLeadingOnes(T Value, ZeroBehavior ZB=ZB_Width)
Count the number of ones from the most significant bit to the first zero bit.
Definition: MathExtras.h:482
constexpr bool isUInt< 8 >(uint64_t x)
Definition: MathExtras.h:369
std::enable_if_t< std::is_signed< T >::value, T > SubOverflow(T X, T Y, T &Result)
Subtract two signed integers, computing the two's complement truncated result, returning true if an o...
Definition: MathExtras.h:883
uint64_t divideCeil(uint64_t Numerator, uint64_t Denominator)
Returns the integer ceil(Numerator / Denominator).
Definition: MathExtras.h:715
constexpr T Lerp(const T &startValue, const T &endValue, double t)
Linearly interpolates between two values.
Definition: MathExtras.h:950
unsigned countTrailingOnes(T Value, ZeroBehavior ZB=ZB_Width)
Count the number of ones from the least significant bit to the first zero bit.
Definition: MathExtras.h:498
uint64_t GreatestCommonDivisor64(uint64_t A, uint64_t B)
Definition: MathExtras.h:603
uint32_t FloatToBits(float Float)
This function takes a float and returns the bit equivalent 32-bit integer.
Definition: MathExtras.h:636
uint64_t PowerOf2Floor(uint64_t A)
Returns the power of two which is less than or equal to the given value.
Definition: MathExtras.h:668
constexpr uint64_t MinAlign(uint64_t A, uint64_t B)
A and B are either alignments or offsets.
Definition: MathExtras.h:645
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition: MathExtras.h:575
constexpr bool isUInt< 16 >(uint64_t x)
Definition: MathExtras.h:372
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Definition: MathExtras.h:469
constexpr bool isMask_64(uint64_t Value)
Return true if the argument is a non-empty sequence of ones starting at the least significant bit wit...
Definition: MathExtras.h:446
double BitsToDouble(uint64_t Bits)
This function takes a 64-bit integer and returns the bit equivalent double.
Definition: MathExtras.h:608
int64_t minIntN(int64_t N)
Gets the minimum value for a N-bit signed integer.
Definition: MathExtras.h:408
std::enable_if_t< std::is_unsigned< T >::value, T > SaturatingMultiplyAdd(T X, T Y, T A, bool *ResultOverflowed=nullptr)
Multiply two unsigned integers, X and Y, and add the unsigned integer, A to the product.
Definition: MathExtras.h:839
std::enable_if_t< std::is_unsigned< T >::value, T > SaturatingAdd(T X, T Y, bool *ResultOverflowed=nullptr)
Add two unsigned integers, X and Y, of type T.
Definition: MathExtras.h:776
constexpr uint64_t Make_64(uint32_t High, uint32_t Low)
Make a 64-bit integer from a high / low pair of 32-bit integers.
Definition: MathExtras.h:322
constexpr bool isInt< 8 >(int64_t x)
Definition: MathExtras.h:331
ZeroBehavior
The behavior an operation has on an input of 0.
Definition: MathExtras.h:44
@ ZB_Undefined
The returned value is undefined.
Definition: MathExtras.h:46
@ ZB_Max
The returned value is numeric_limits<T>::max()
Definition: MathExtras.h:48
@ ZB_Width
The returned value is numeric_limits<T>::digits.
Definition: MathExtras.h:50
T maskTrailingZeros(unsigned N)
Create a bitmask with the N right-most bits set to 0, and all other bits set to 1.
Definition: MathExtras.h:227
uint64_t maxUIntN(uint64_t N)
Gets the maximum value for a N-bit unsigned integer.
Definition: MathExtras.h:392
bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
Definition: MathExtras.h:428
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
Definition: MathExtras.h:381
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Definition: MathExtras.h:433
unsigned Log2_64_Ceil(uint64_t Value)
Return the ceil log base 2 of the specified value, 64 if the value is zero.
Definition: MathExtras.h:588
constexpr bool isShiftedMask_64(uint64_t Value)
Return true if the argument contains a non-empty sequence of ones with the remainder zero (64 bit ver...
Definition: MathExtras.h:458
constexpr int32_t SignExtend32(uint32_t X)
Sign-extend the number in the bottom B bits of X to a 32-bit integer.
Definition: MathExtras.h:734
constexpr bool isInt< 32 >(int64_t x)
Definition: MathExtras.h:337
unsigned countPopulation(T Value)
Count the number of set bits in a value.
Definition: MathExtras.h:540
T maskLeadingZeros(unsigned N)
Create a bitmask with the N left-most bits set to 0, and all other bits set to 1.
Definition: MathExtras.h:233
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
Definition: MathExtras.h:312
uint64_t DoubleToBits(double Double)
This function takes a double and returns the bit equivalent 64-bit integer.
Definition: MathExtras.h:626
constexpr bool isUInt< 32 >(uint64_t x)
Definition: MathExtras.h:375
constexpr bool isMask_32(uint32_t Value)
Return true if the argument is a non-empty sequence of ones starting at the least significant bit wit...
Definition: MathExtras.h:440
uint64_t alignDown(uint64_t Value, uint64_t Align, uint64_t Skew=0)
Returns the largest uint64_t less than or equal to Value and is Skew mod Align.
Definition: MathExtras.h:726
Definition: MathExtras.h:128
static unsigned count(T Val, ZeroBehavior)
Definition: MathExtras.h:129
static unsigned count(T Value)
Definition: MathExtras.h:522
Definition: MathExtras.h:506
static unsigned count(T Value)
Definition: MathExtras.h:507
Definition: MathExtras.h:54
static unsigned count(T Val, ZeroBehavior)
Definition: MathExtras.h:55
#define S(label, offset, message)
Definition: Errors.h:119