123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- #pragma once
- #include <Mathematics/Logger.h>
- #include <array>
- #include <cstdint>
- #define GTE_THROW_ON_BITHACKS_ERROR
- namespace WwiseGTE
- {
- class BitHacks
- {
- public:
- static bool IsPowerOfTwo(uint32_t value)
- {
- return (value > 0) && ((value & (value - 1)) == 0);
- }
- static bool IsPowerOfTwo(int32_t value)
- {
- #if defined(GTE_THROW_ON_BITHACKS_ERROR)
- LogAssert(value >= 0, "Invalid input.");
- #endif
- return IsPowerOfTwo(static_cast<int32_t>(value));
- }
- static uint32_t Log2OfPowerOfTwo(uint32_t powerOfTwo)
- {
- uint32_t log2 = (powerOfTwo & 0xAAAAAAAAu) != 0;
- log2 |= ((powerOfTwo & 0xFFFF0000u) != 0) << 4;
- log2 |= ((powerOfTwo & 0xFF00FF00u) != 0) << 3;
- log2 |= ((powerOfTwo & 0xF0F0F0F0u) != 0) << 2;
- log2 |= ((powerOfTwo & 0xCCCCCCCCu) != 0) << 1;
- return log2;
- }
- static int32_t Log2OfPowerOfTwo(int32_t powerOfTwo)
- {
- #if defined(GTE_THROW_ON_BITHACKS_ERROR)
- LogAssert(powerOfTwo >= 0, "Invalid input.");
- #endif
- return static_cast<int32_t>(Log2OfPowerOfTwo(static_cast<uint32_t>(powerOfTwo)));
- }
-
-
-
-
-
-
-
- static int32_t GetLeadingBit(uint32_t value)
- {
- static std::array<int32_t, 32> const leadingBitTable =
- {
- 0, 9, 1, 10, 13, 21, 2, 29,
- 11, 14, 16, 18, 22, 25, 3, 30,
- 8, 12, 20, 28, 15, 17, 24, 7,
- 19, 27, 23, 6, 26, 5, 4, 31
- };
- value |= value >> 1;
- value |= value >> 2;
- value |= value >> 4;
- value |= value >> 8;
- value |= value >> 16;
- uint32_t key = (value * 0x07C4ACDDu) >> 27;
- return leadingBitTable[key];
- }
- static int32_t GetLeadingBit(int32_t value)
- {
- #if defined(GTE_THROW_ON_BITHACKS_ERROR)
- LogAssert(value != 0, "Invalid input.");
- #endif
- return GetLeadingBit(static_cast<uint32_t>(value));
- }
- static int32_t GetLeadingBit(uint64_t value)
- {
- uint32_t v1 = static_cast<uint32_t>((value >> 32) & 0x00000000FFFFFFFFull);
- if (v1 != 0)
- {
- return GetLeadingBit(v1) + 32;
- }
- uint32_t v0 = static_cast<uint32_t>(value & 0x00000000FFFFFFFFull);
- return GetLeadingBit(v0);
- }
- static int32_t GetLeadingBit(int64_t value)
- {
- #if defined(GTE_THROW_ON_BITHACKS_ERROR)
- LogAssert(value != 0, "Invalid input.");
- #endif
- return GetLeadingBit(static_cast<uint64_t>(value));
- }
- static int32_t GetTrailingBit(int32_t value)
- {
- static std::array<int32_t, 32> const trailingBitTable =
- {
- 0, 1, 28, 2, 29, 14, 24, 3,
- 30, 22, 20, 15, 25, 17, 4, 8,
- 31, 27, 13, 23, 21, 19, 16, 7,
- 26, 12, 18, 6, 11, 5, 10, 9
- };
- #if defined(GTE_THROW_ON_BITHACKS_ERROR)
- LogAssert(value != 0, "Invalid input.");
- #endif
- uint32_t key = (static_cast<uint32_t>((value & -value) * 0x077CB531u)) >> 27;
- return trailingBitTable[key];
- }
- static int32_t GetTrailingBit(uint32_t value)
- {
-
-
-
-
-
- return GetTrailingBit(static_cast<int32_t>(value));
- }
- static int32_t GetTrailingBit(uint64_t value)
- {
- uint32_t v0 = static_cast<uint32_t>(value & 0x00000000FFFFFFFFull);
- if (v0 != 0)
- {
- return GetTrailingBit(v0);
- }
- uint32_t v1 = static_cast<uint32_t>((value >> 32) & 0x00000000FFFFFFFFull);
- if (v1 != 0)
- {
- return GetTrailingBit(v1) + 32;
- }
- return 0;
- }
- static int32_t GetTrailingBit(int64_t value)
- {
- #if defined(GTE_THROW_ON_BITHACKS_ERROR)
- LogAssert(value != 0, "Invalid input.");
- #endif
- return GetTrailingBit(static_cast<uint64_t>(value));
- }
-
-
- static uint64_t RoundUpToPowerOfTwo(uint32_t value)
- {
- if (value > 0)
- {
- int32_t leading = GetLeadingBit(value);
- uint32_t mask = (1 << leading);
- if ((value & ~mask) == 0)
- {
-
- return static_cast<uint64_t>(value);
- }
- else
- {
-
- return (static_cast<uint64_t>(mask) << 1);
- }
- }
- else
- {
- return 1ull;
- }
- }
-
- static uint32_t RoundDownToPowerOfTwo(uint32_t value)
- {
- if (value > 0)
- {
- int32_t leading = GetLeadingBit(value);
- uint32_t mask = (1 << leading);
- return mask;
- }
- else
- {
- return 0;
- }
- }
- };
- }
|