1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
|
// File: lzham_math.h
// See Copyright Notice and license at the end of include/lzham.h
#pragma once
#if defined(LZHAM_USE_MSVC_INTRINSICS) && !defined(__MINGW32__)
#include <intrin.h>
#if defined(_MSC_VER)
#pragma intrinsic(_BitScanReverse)
#endif
#endif
namespace lzham
{
namespace math
{
// Yes I know these should probably be pass by ref, not val:
// http://www.stepanovpapers.com/notes.pdf
// Just don't use them on non-simple (non built-in) types!
template<typename T> inline T minimum(T a, T b) { return (a < b) ? a : b; }
template<typename T> inline T minimum(T a, T b, T c) { return minimum(minimum(a, b), c); }
template<typename T> inline T maximum(T a, T b) { return (a > b) ? a : b; }
template<typename T> inline T maximum(T a, T b, T c) { return maximum(maximum(a, b), c); }
template<typename T> inline T clamp(T value, T low, T high) { return (value < low) ? low : ((value > high) ? high : value); }
inline bool is_power_of_2(uint32 x) { return x && ((x & (x - 1U)) == 0U); }
inline bool is_power_of_2(uint64 x) { return x && ((x & (x - 1U)) == 0U); }
template<typename T> inline T align_up_pointer(T p, uint alignment)
{
LZHAM_ASSERT(is_power_of_2(alignment));
ptr_bits_t q = reinterpret_cast<ptr_bits_t>(p);
q = (q + alignment - 1) & (~((uint_ptr)alignment - 1));
return reinterpret_cast<T>(q);
}
// From "Hackers Delight"
// val remains unchanged if it is already a power of 2.
inline uint32 next_pow2(uint32 val)
{
val--;
val |= val >> 16;
val |= val >> 8;
val |= val >> 4;
val |= val >> 2;
val |= val >> 1;
return val + 1;
}
// val remains unchanged if it is already a power of 2.
inline uint64 next_pow2(uint64 val)
{
val--;
val |= val >> 32;
val |= val >> 16;
val |= val >> 8;
val |= val >> 4;
val |= val >> 2;
val |= val >> 1;
return val + 1;
}
inline uint floor_log2i(uint v)
{
uint l = 0;
while (v > 1U)
{
v >>= 1;
l++;
}
return l;
}
inline uint ceil_log2i(uint v)
{
uint l = floor_log2i(v);
if ((l != cIntBits) && (v > (1U << l)))
l++;
return l;
}
// Returns the total number of bits needed to encode v.
inline uint total_bits(uint v)
{
unsigned long l = 0;
#if defined(__MINGW32__)
if (v)
{
l = 32 -__builtin_clz(v);
}
#elif defined(LZHAM_USE_MSVC_INTRINSICS)
if (_BitScanReverse(&l, v))
{
l++;
}
else
{
l = 0;
}
#else
while (v > 0U)
{
v >>= 1;
l++;
}
#endif
return static_cast<uint>(l);
}
inline uint compute_mask_size(uint x)
{
uint l = 0;
while (x)
{
x &= (x - 1);
l++;
}
return l;
}
inline uint compute_mask_shift(uint x)
{
if (!x)
return 0;
uint l = 0;
while ((x & 1) == 0)
{
x >>= 1;
l++;
}
return l;
}
}
} // namespace lzham
|