diff --git a/panda/src/putil/bitMask.I b/panda/src/putil/bitMask.I index ffaf45052d..9c7de08321 100644 --- a/panda/src/putil/bitMask.I +++ b/panda/src/putil/bitMask.I @@ -405,7 +405,7 @@ set_word(WordType value) { template INLINE int BitMask:: get_num_on_bits() const { - return count_bits_in_word(_word); + return count_bits_in_word((WType)_word); } //////////////////////////////////////////////////////////////////// @@ -417,7 +417,7 @@ get_num_on_bits() const { template INLINE int BitMask:: get_num_off_bits() const { - return count_bits_in_word(~_word); + return count_bits_in_word((WType)(~_word)); } //////////////////////////////////////////////////////////////////// @@ -518,7 +518,7 @@ get_next_higher_different_bit(int low_bit) const { w = (w & (~w + 1)); // And the answer is the number of bits in (w - 1). - return count_bits_in_word(w - 1); + return count_bits_in_word((WType)(w - 1)); } } diff --git a/panda/src/putil/bitMask.h b/panda/src/putil/bitMask.h index 2a3e494236..fdc3b58fc1 100644 --- a/panda/src/putil/bitMask.h +++ b/panda/src/putil/bitMask.h @@ -160,6 +160,7 @@ INLINE ostream &operator << (ostream &out, const BitMask &bitmask) #define BITMASK32_DEF BitMask EXPORT_TEMPLATE_CLASS(EXPCL_PANDA_PUTIL, EXPTP_PANDA_PUTIL, BITMASK32_DEF); +typedef BitMask BitMask16; typedef BitMask BitMask32; typedef BitMask BitMask64; diff --git a/panda/src/putil/pbitops.I b/panda/src/putil/pbitops.I index 36487ba082..e6a1457fc9 100644 --- a/panda/src/putil/pbitops.I +++ b/panda/src/putil/pbitops.I @@ -13,6 +13,15 @@ //////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////// +// Function: count_bits_in_word +// Description: Returns the number of 1 bits in the indicated word. +//////////////////////////////////////////////////////////////////// +INLINE int +count_bits_in_word(PN_uint16 x) { + return (int)num_bits_on[x]; +} + //////////////////////////////////////////////////////////////////// // Function: count_bits_in_word // Description: Returns the number of 1 bits in the indicated word. @@ -31,6 +40,20 @@ count_bits_in_word(PN_uint64 x) { return count_bits_in_word((PN_uint32)x) + count_bits_in_word((PN_uint32)(x >> 32)); } +//////////////////////////////////////////////////////////////////// +// Function: flood_bits_down +// Description: Returns a value such that every bit at or below the +// highest bit in x is 1. +//////////////////////////////////////////////////////////////////// +INLINE PN_uint16 +flood_bits_down(PN_uint16 x) { + x |= (x >> 1); + x |= (x >> 2); + x |= (x >> 4); + x |= (x >> 8); + return x; +} + //////////////////////////////////////////////////////////////////// // Function: flood_bits_down // Description: Returns a value such that every bit at or below the @@ -62,6 +85,20 @@ flood_bits_down(PN_uint64 x) { return x; } +//////////////////////////////////////////////////////////////////// +// Function: flood_bits_up +// Description: Returns a value such that every bit at or above the +// highest bit in x is 1. +//////////////////////////////////////////////////////////////////// +INLINE PN_uint16 +flood_bits_up(PN_uint16 x) { + x |= (x << 1); + x |= (x << 2); + x |= (x << 4); + x |= (x << 8); + return x; +} + //////////////////////////////////////////////////////////////////// // Function: flood_bits_up // Description: Returns a value such that every bit at or above the @@ -93,6 +130,21 @@ flood_bits_up(PN_uint64 x) { return x; } +//////////////////////////////////////////////////////////////////// +// Function: get_lowest_on_bit +// Description: 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(PN_uint16 x) { + if (x == 0) { + return -1; + } + + PN_uint16 w = (x & (~x + 1)); + return (int)num_bits_on[w - 1]; +} + //////////////////////////////////////////////////////////////////// // Function: get_lowest_on_bit // Description: Returns the index of the lowest 1 bit in the word. @@ -123,6 +175,17 @@ get_lowest_on_bit(PN_uint64 x) { return count_bits_in_word(w - 1); } +//////////////////////////////////////////////////////////////////// +// Function: get_highest_on_bit +// Description: 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(PN_uint16 x) { + PN_uint16 w = flood_bits_down(x); + return count_bits_in_word(w) - 1; +} + //////////////////////////////////////////////////////////////////// // Function: get_highest_on_bit // Description: Returns the index of the highest 1 bit in the word. @@ -145,6 +208,19 @@ get_highest_on_bit(PN_uint64 x) { return count_bits_in_word(w) - 1; } +//////////////////////////////////////////////////////////////////// +// Function: get_next_higher_bit +// Description: 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(PN_uint16 x) { + PN_uint16 w = flood_bits_down(x); + return count_bits_in_word(w); +} + //////////////////////////////////////////////////////////////////// // Function: get_next_higher_bit // Description: Returns the smallest power of 2 greater than x. diff --git a/panda/src/putil/pbitops.h b/panda/src/putil/pbitops.h index d85a68f3f9..ff6adca171 100644 --- a/panda/src/putil/pbitops.h +++ b/panda/src/putil/pbitops.h @@ -23,19 +23,25 @@ // all to heck. //////////////////////////////////////////////////////////////////// +INLINE int count_bits_in_word(PN_uint16 x); INLINE int count_bits_in_word(PN_uint32 x); INLINE int count_bits_in_word(PN_uint64 x); +INLINE PN_uint16 flood_bits_down(PN_uint16 x); INLINE PN_uint32 flood_bits_down(PN_uint32 x); INLINE PN_uint64 flood_bits_down(PN_uint64 x); +INLINE PN_uint16 flood_bits_up(PN_uint16 x); INLINE PN_uint32 flood_bits_up(PN_uint32 x); INLINE PN_uint64 flood_bits_up(PN_uint64 x); +INLINE int get_lowest_on_bit(PN_uint16 x); INLINE int get_lowest_on_bit(PN_uint32 x); INLINE int get_lowest_on_bit(PN_uint64 x); +INLINE int get_highest_on_bit(PN_uint16 x); INLINE int get_highest_on_bit(PN_uint32 x); INLINE int get_highest_on_bit(PN_uint64 x); +INLINE int get_next_higher_bit(PN_uint16 x); INLINE int get_next_higher_bit(PN_uint32 x); INLINE int get_next_higher_bit(PN_uint64 x);