11 #include <type_traits>
16 #if !defined(WS_GCC_FAMILY) && !(defined(WS_MSC) && defined(WS_64BITS))
21 #define WS_UNUSED(x) (void)x
36 template<
typename SignedResult,
unsigned NbBits,
typename InputType>
37 inline SignedResult signExtend(
const InputType value)
39 static_assert(std::is_integral<SignedResult>::value && std::is_integral<InputType>::value,
"");
40 static_assert(NbBits > 0,
"Can not represent a signed value on 0 bit.");
41 static_assert(NbBits <=
sizeof(SignedResult) * CHAR_BIT,
42 "Result type is not big enough to hold the values.");
43 static_assert(std::is_signed<SignedResult>::value,
"Result type must be signed");
46 SignedResult x : NbBits;
48 return s.x =
static_cast<SignedResult
>(value);
53 template <
typename SignedResult,
unsigned NbBits,
typename InputType>
54 inline SignedResult signExtendS(InputType value)
56 static_assert(std::is_integral<SignedResult>::value && std::is_integral<InputType>::value,
"");
57 static_assert(NbBits > 1,
"Can not represent a signed value on 1 bit.");
58 static_assert(NbBits <=
sizeof(SignedResult) * CHAR_BIT,
"Result type is not big enough to hold the values.");
59 static_assert(std::is_signed<SignedResult>::value,
"Result type must be signed");
61 const InputType signBitMask = (InputType(1) << (NbBits - 1) );
62 const bool signBit = value & signBitMask;
63 const InputType valWithoutSignBit = value & (signBitMask - 1);
67 return valWithoutSignBit - signBit * signBitMask;
76 inline T reverseBits(T bits)
78 constexpr
size_t nbBits =
sizeof(T) * CHAR_BIT;
82 #if __has_builtin(__builtin_bitreverse8)
83 case 8:
return __builtin_bitreverse8(bits);
85 #if __has_builtin(__builtin_bitreverse16)
86 case 16:
return __builtin_bitreverse16(bits);
88 #if __has_builtin(__builtin_bitreverse32)
89 case 32:
return __builtin_bitreverse32(bits);
91 #if __has_builtin(__builtin_bitreverse64)
92 case 64:
return __builtin_bitreverse64(bits);
98 for (
size_t bitIndex = 0; bitIndex < nbBits; bitIndex++)
111 inline uint16_t popCount(uint16_t value)
113 #if defined(WS_GCC_FAMILY)
114 return uint16_t(__builtin_popcount(value));
115 #elif defined(WS_MSC)
116 return __popcnt16(value);
118 std::bitset<16> bset = value;
119 return uint16_t(bset.count());
124 inline uint32_t popCount(uint32_t value)
126 #if defined(WS_GCC_FAMILY)
127 return uint32_t(__builtin_popcount(value));
128 #elif defined(WS_MSC)
129 return __popcnt(value);
131 std::bitset<32> bset = value;
132 return uint32_t(bset.count());
137 inline uint64_t popCount(uint64_t value)
139 #if defined(WS_GCC_FAMILY)
140 return uint64_t(__builtin_popcountll(value));
141 #elif defined(WS_MSC) && defined(WS_64BITS)
142 return __popcnt64(value);
144 std::bitset<64> bset = value;
145 return uint64_t(bset.count());
149 template<
class T, std::
size_t N>
150 constexpr
size_t Size(
const T (&array)[N]) noexcept
168 template<
class T,
int ExpectedSize,
int TSize = sizeof(T)>
169 static constexpr
bool StaticCheckSize()
171 static_assert(ExpectedSize == TSize,
"T has a bad size(see "
172 "StaticCheckEnsureSizeOf<T,ExpectedSize,ActualSize> in "
#define WS_UNUSED(x)
Mark a variable as unused to shut warnings when it is unused on purpose.