mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-28 15:53:55 -04:00
putil: define pbitops in terms of fundamental types
This ensures there's always an overload matching a particular definition of size_t / uint64_t, etc.
This commit is contained in:
parent
2893d8cef8
commit
72b96f1afa
@ -15,7 +15,7 @@
|
||||
* Returns the number of 1 bits in the indicated word.
|
||||
*/
|
||||
INLINE int
|
||||
count_bits_in_word(uint16_t x) {
|
||||
count_bits_in_word(unsigned short x) {
|
||||
return (int)num_bits_on[x];
|
||||
}
|
||||
|
||||
@ -23,9 +23,9 @@ count_bits_in_word(uint16_t x) {
|
||||
* Returns the number of 1 bits in the indicated word.
|
||||
*/
|
||||
INLINE int
|
||||
count_bits_in_word(uint32_t x) {
|
||||
count_bits_in_word(unsigned int x) {
|
||||
#if defined(__GNUC__) && defined(__POPCNT__)
|
||||
return __builtin_popcount((unsigned int) x);
|
||||
return __builtin_popcount(x);
|
||||
#else
|
||||
return (int)num_bits_on[x & 0xffff] + (int)num_bits_on[(x >> 16) & 0xffff];
|
||||
#endif
|
||||
@ -35,19 +35,33 @@ count_bits_in_word(uint32_t x) {
|
||||
* Returns the number of 1 bits in the indicated word.
|
||||
*/
|
||||
INLINE int
|
||||
count_bits_in_word(uint64_t x) {
|
||||
count_bits_in_word(unsigned long x) {
|
||||
#if defined(__GNUC__) && defined(__POPCNT__)
|
||||
return __builtin_popcountll((unsigned long long) x);
|
||||
return __builtin_popcountl(x);
|
||||
#elif defined(_LP64)
|
||||
return count_bits_in_word((unsigned int)x) + count_bits_in_word((unsigned int)(x >> 32));
|
||||
#else
|
||||
return count_bits_in_word((uint32_t)x) + count_bits_in_word((uint32_t)(x >> 32));
|
||||
return count_bits_in_word((unsigned int)x);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of 1 bits in the indicated word.
|
||||
*/
|
||||
INLINE int
|
||||
count_bits_in_word(unsigned long long x) {
|
||||
#if defined(__GNUC__) && defined(__POPCNT__)
|
||||
return __builtin_popcountll(x);
|
||||
#else
|
||||
return count_bits_in_word((unsigned int)x) + count_bits_in_word((unsigned int)(x >> 32));
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a value such that every bit at or below the highest bit in x is 1.
|
||||
*/
|
||||
INLINE uint16_t
|
||||
flood_bits_down(uint16_t x) {
|
||||
INLINE unsigned short
|
||||
flood_bits_down(unsigned short x) {
|
||||
x |= (x >> 1);
|
||||
x |= (x >> 2);
|
||||
x |= (x >> 4);
|
||||
@ -58,8 +72,8 @@ flood_bits_down(uint16_t x) {
|
||||
/**
|
||||
* Returns a value such that every bit at or below the highest bit in x is 1.
|
||||
*/
|
||||
INLINE uint32_t
|
||||
flood_bits_down(uint32_t x) {
|
||||
INLINE unsigned int
|
||||
flood_bits_down(unsigned int x) {
|
||||
x |= (x >> 1);
|
||||
x |= (x >> 2);
|
||||
x |= (x >> 4);
|
||||
@ -71,8 +85,24 @@ flood_bits_down(uint32_t x) {
|
||||
/**
|
||||
* Returns a value such that every bit at or below the highest bit in x is 1.
|
||||
*/
|
||||
INLINE uint64_t
|
||||
flood_bits_down(uint64_t x) {
|
||||
INLINE unsigned long
|
||||
flood_bits_down(unsigned long x) {
|
||||
x |= (x >> 1);
|
||||
x |= (x >> 2);
|
||||
x |= (x >> 4);
|
||||
x |= (x >> 8);
|
||||
x |= (x >> 16);
|
||||
#if defined(_LP64) || defined(__LP64__)
|
||||
x |= (x >> 32);
|
||||
#endif
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a value such that every bit at or below the highest bit in x is 1.
|
||||
*/
|
||||
INLINE unsigned long long
|
||||
flood_bits_down(unsigned long long x) {
|
||||
x |= (x >> 1);
|
||||
x |= (x >> 2);
|
||||
x |= (x >> 4);
|
||||
@ -85,8 +115,8 @@ flood_bits_down(uint64_t x) {
|
||||
/**
|
||||
* Returns a value such that every bit at or above the highest bit in x is 1.
|
||||
*/
|
||||
INLINE uint16_t
|
||||
flood_bits_up(uint16_t x) {
|
||||
INLINE unsigned short
|
||||
flood_bits_up(unsigned short x) {
|
||||
x |= (x << 1);
|
||||
x |= (x << 2);
|
||||
x |= (x << 4);
|
||||
@ -97,8 +127,8 @@ flood_bits_up(uint16_t x) {
|
||||
/**
|
||||
* Returns a value such that every bit at or above the highest bit in x is 1.
|
||||
*/
|
||||
INLINE uint32_t
|
||||
flood_bits_up(uint32_t x) {
|
||||
INLINE unsigned int
|
||||
flood_bits_up(unsigned int x) {
|
||||
x |= (x << 1);
|
||||
x |= (x << 2);
|
||||
x |= (x << 4);
|
||||
@ -110,8 +140,24 @@ flood_bits_up(uint32_t x) {
|
||||
/**
|
||||
* Returns a value such that every bit at or above the highest bit in x is 1.
|
||||
*/
|
||||
INLINE uint64_t
|
||||
flood_bits_up(uint64_t x) {
|
||||
INLINE unsigned long
|
||||
flood_bits_up(unsigned long x) {
|
||||
x |= (x << 1);
|
||||
x |= (x << 2);
|
||||
x |= (x << 4);
|
||||
x |= (x << 8);
|
||||
x |= (x << 16);
|
||||
#if defined(_LP64) || defined(__LP64__)
|
||||
x |= (x << 32);
|
||||
#endif
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a value such that every bit at or above the highest bit in x is 1.
|
||||
*/
|
||||
INLINE unsigned long long
|
||||
flood_bits_up(unsigned long long x) {
|
||||
x |= (x << 1);
|
||||
x |= (x << 2);
|
||||
x |= (x << 4);
|
||||
@ -126,7 +172,7 @@ flood_bits_up(uint64_t x) {
|
||||
* no 1 bits.
|
||||
*/
|
||||
INLINE int
|
||||
get_lowest_on_bit(uint16_t x) {
|
||||
get_lowest_on_bit(unsigned short x) {
|
||||
#if defined(_MSC_VER)
|
||||
unsigned long result;
|
||||
return (_BitScanForward(&result, (unsigned long) x) == 0) ? -1 : result;
|
||||
@ -137,7 +183,7 @@ get_lowest_on_bit(uint16_t x) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint16_t w = (x & (~x + 1));
|
||||
unsigned short w = (x & (~x + 1));
|
||||
return (int)num_bits_on[w - 1];
|
||||
#endif
|
||||
}
|
||||
@ -147,7 +193,7 @@ get_lowest_on_bit(uint16_t x) {
|
||||
* no 1 bits.
|
||||
*/
|
||||
INLINE int
|
||||
get_lowest_on_bit(uint32_t x) {
|
||||
get_lowest_on_bit(unsigned int x) {
|
||||
#if defined(_MSC_VER)
|
||||
unsigned long result;
|
||||
return (_BitScanForward(&result, (unsigned long) x) == 0) ? -1 : result;
|
||||
@ -158,7 +204,7 @@ get_lowest_on_bit(uint32_t x) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t w = (x & (~x + 1));
|
||||
unsigned int w = (x & (~x + 1));
|
||||
return count_bits_in_word(w - 1);
|
||||
#endif
|
||||
}
|
||||
@ -168,7 +214,28 @@ get_lowest_on_bit(uint32_t x) {
|
||||
* no 1 bits.
|
||||
*/
|
||||
INLINE int
|
||||
get_lowest_on_bit(uint64_t x) {
|
||||
get_lowest_on_bit(unsigned long x) {
|
||||
#if defined(_MSC_VER) && defined(_M_X64)
|
||||
unsigned long result;
|
||||
return (_BitScanForward(&result, x) == 0) ? -1 : result;
|
||||
#elif defined(__GNUC__)
|
||||
return __builtin_ffsl((long) x) - 1;
|
||||
#else
|
||||
if (x == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned long w = (x & (~x + 1));
|
||||
return count_bits_in_word(w - 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the lowest 1 bit in the word. Returns -1 if there are
|
||||
* no 1 bits.
|
||||
*/
|
||||
INLINE int
|
||||
get_lowest_on_bit(unsigned long long x) {
|
||||
#if defined(_MSC_VER) && defined(_M_X64)
|
||||
unsigned long result;
|
||||
return (_BitScanForward64(&result, (unsigned __int64) x) == 0) ? -1 : result;
|
||||
@ -179,7 +246,7 @@ get_lowest_on_bit(uint64_t x) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint64_t w = (x & (~x + 1));
|
||||
unsigned long long w = (x & (~x + 1));
|
||||
return count_bits_in_word(w - 1);
|
||||
#endif
|
||||
}
|
||||
@ -189,14 +256,14 @@ get_lowest_on_bit(uint64_t x) {
|
||||
* are no 1 bits.
|
||||
*/
|
||||
INLINE int
|
||||
get_highest_on_bit(uint16_t x) {
|
||||
get_highest_on_bit(unsigned short x) {
|
||||
#if defined(_MSC_VER)
|
||||
unsigned long result;
|
||||
return (_BitScanReverse(&result, (unsigned long) x) == 0) ? -1 : result;
|
||||
#elif defined(__GNUC__)
|
||||
return (x == 0) ? -1 : 31 - __builtin_clz((unsigned int) x);
|
||||
#else
|
||||
uint16_t w = flood_bits_down(x);
|
||||
unsigned short w = flood_bits_down(x);
|
||||
return count_bits_in_word(w) - 1;
|
||||
#endif
|
||||
}
|
||||
@ -206,14 +273,14 @@ get_highest_on_bit(uint16_t x) {
|
||||
* are no 1 bits.
|
||||
*/
|
||||
INLINE int
|
||||
get_highest_on_bit(uint32_t x) {
|
||||
get_highest_on_bit(unsigned int x) {
|
||||
#if defined(_MSC_VER)
|
||||
unsigned long result;
|
||||
return (_BitScanReverse(&result, (unsigned long) x) == 0) ? -1 : result;
|
||||
#elif defined(__GNUC__)
|
||||
return (x == 0) ? -1 : 31 - __builtin_clz((unsigned int) x);
|
||||
return (x == 0) ? -1 : 31 - __builtin_clz(x);
|
||||
#else
|
||||
uint32_t w = flood_bits_down(x);
|
||||
unsigned int w = flood_bits_down(x);
|
||||
return count_bits_in_word(w) - 1;
|
||||
#endif
|
||||
}
|
||||
@ -223,14 +290,31 @@ get_highest_on_bit(uint32_t x) {
|
||||
* are no 1 bits.
|
||||
*/
|
||||
INLINE int
|
||||
get_highest_on_bit(uint64_t x) {
|
||||
get_highest_on_bit(unsigned long x) {
|
||||
#if defined(_MSC_VER) && defined(_M_X64)
|
||||
unsigned long result;
|
||||
return (_BitScanReverse(&result, (unsigned long) x) == 0) ? -1 : result;
|
||||
#elif defined(__GNUC__)
|
||||
return (x == 0) ? -1 : 63 - __builtin_clzl(x);
|
||||
#else
|
||||
unsigned long long w = flood_bits_down(x);
|
||||
return count_bits_in_word(w) - 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index of the highest 1 bit in the word. Returns -1 if there
|
||||
* are no 1 bits.
|
||||
*/
|
||||
INLINE int
|
||||
get_highest_on_bit(unsigned long long x) {
|
||||
#if defined(_MSC_VER) && defined(_M_X64)
|
||||
unsigned long result;
|
||||
return (_BitScanReverse64(&result, (unsigned __int64) x) == 0) ? -1 : result;
|
||||
#elif defined(__GNUC__)
|
||||
return (x == 0) ? -1 : 63 - __builtin_clzll((unsigned long long) x);
|
||||
return (x == 0) ? -1 : 63 - __builtin_clzll(x);
|
||||
#else
|
||||
uint64_t w = flood_bits_down(x);
|
||||
unsigned long long w = flood_bits_down(x);
|
||||
return count_bits_in_word(w) - 1;
|
||||
#endif
|
||||
}
|
||||
@ -241,7 +325,7 @@ get_highest_on_bit(uint64_t x) {
|
||||
* Returns the smallest number n such that (1 << n) is larger than x.
|
||||
*/
|
||||
INLINE int
|
||||
get_next_higher_bit(uint16_t x) {
|
||||
get_next_higher_bit(unsigned short x) {
|
||||
return get_highest_on_bit(x) + 1;
|
||||
}
|
||||
|
||||
@ -251,7 +335,7 @@ get_next_higher_bit(uint16_t x) {
|
||||
* Returns the smallest number n such that (1 << n) is larger than x.
|
||||
*/
|
||||
INLINE int
|
||||
get_next_higher_bit(uint32_t x) {
|
||||
get_next_higher_bit(unsigned int x) {
|
||||
return get_highest_on_bit(x) + 1;
|
||||
}
|
||||
|
||||
@ -261,6 +345,16 @@ get_next_higher_bit(uint32_t x) {
|
||||
* Returns the smallest number n such that (1 << n) is larger than x.
|
||||
*/
|
||||
INLINE int
|
||||
get_next_higher_bit(uint64_t x) {
|
||||
get_next_higher_bit(unsigned long x) {
|
||||
return get_highest_on_bit(x) + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the smallest power of 2 greater than x.
|
||||
*
|
||||
* Returns the smallest number n such that (1 << n) is larger than x.
|
||||
*/
|
||||
INLINE int
|
||||
get_next_higher_bit(unsigned long long x) {
|
||||
return get_highest_on_bit(x) + 1;
|
||||
}
|
||||
|
@ -24,27 +24,33 @@
|
||||
// This file defines a few low-level bit-operation routines, optimized all to
|
||||
// heck.
|
||||
|
||||
INLINE int count_bits_in_word(uint16_t x);
|
||||
INLINE int count_bits_in_word(uint32_t x);
|
||||
INLINE int count_bits_in_word(uint64_t x);
|
||||
INLINE int count_bits_in_word(unsigned short x);
|
||||
INLINE int count_bits_in_word(unsigned int x);
|
||||
INLINE int count_bits_in_word(unsigned long x);
|
||||
INLINE int count_bits_in_word(unsigned long long x);
|
||||
|
||||
INLINE uint16_t flood_bits_down(uint16_t x);
|
||||
INLINE uint32_t flood_bits_down(uint32_t x);
|
||||
INLINE uint64_t flood_bits_down(uint64_t x);
|
||||
INLINE uint16_t flood_bits_up(uint16_t x);
|
||||
INLINE uint32_t flood_bits_up(uint32_t x);
|
||||
INLINE uint64_t flood_bits_up(uint64_t x);
|
||||
INLINE unsigned short flood_bits_down(unsigned short x);
|
||||
INLINE unsigned int flood_bits_down(unsigned int x);
|
||||
INLINE unsigned long flood_bits_down(unsigned long x);
|
||||
INLINE unsigned long long flood_bits_down(unsigned long long x);
|
||||
INLINE unsigned short flood_bits_up(unsigned short x);
|
||||
INLINE unsigned int flood_bits_up(unsigned int x);
|
||||
INLINE unsigned long flood_bits_up(unsigned long x);
|
||||
INLINE unsigned long long flood_bits_up(unsigned long long x);
|
||||
|
||||
INLINE int get_lowest_on_bit(uint16_t x);
|
||||
INLINE int get_lowest_on_bit(uint32_t x);
|
||||
INLINE int get_lowest_on_bit(uint64_t x);
|
||||
INLINE int get_highest_on_bit(uint16_t x);
|
||||
INLINE int get_highest_on_bit(uint32_t x);
|
||||
INLINE int get_highest_on_bit(uint64_t x);
|
||||
INLINE int get_lowest_on_bit(unsigned short x);
|
||||
INLINE int get_lowest_on_bit(unsigned int x);
|
||||
INLINE int get_lowest_on_bit(unsigned long x);
|
||||
INLINE int get_lowest_on_bit(unsigned long long x);
|
||||
INLINE int get_highest_on_bit(unsigned short x);
|
||||
INLINE int get_highest_on_bit(unsigned int x);
|
||||
INLINE int get_highest_on_bit(unsigned long x);
|
||||
INLINE int get_highest_on_bit(unsigned long long x);
|
||||
|
||||
INLINE int get_next_higher_bit(uint16_t x);
|
||||
INLINE int get_next_higher_bit(uint32_t x);
|
||||
INLINE int get_next_higher_bit(uint64_t x);
|
||||
INLINE int get_next_higher_bit(unsigned short x);
|
||||
INLINE int get_next_higher_bit(unsigned int x);
|
||||
INLINE int get_next_higher_bit(unsigned long x);
|
||||
INLINE int get_next_higher_bit(unsigned long long x);
|
||||
|
||||
// This table precomputes the number of on bits in each 16-bit word.
|
||||
extern EXPCL_PANDA_PUTIL const unsigned char num_bits_on[65536];
|
||||
|
Loading…
x
Reference in New Issue
Block a user