adding getNextHighestBit() and getNextLowestBit() functions

This commit is contained in:
Josh Wilson 2008-01-29 22:02:47 +00:00
parent 42df74595c
commit a4b51594b8
2 changed files with 218 additions and 1 deletions

View File

@ -466,7 +466,7 @@ get_highest_on_bit() const {
return -1;
}
WordType w = flood_bits_down(_word);
WordType w = ::flood_bits_down(_word);
return count_bits_in_word(w) - 1;
}
@ -919,3 +919,207 @@ flood_bits_down(PN_uint64 x) {
x |= (x >> 32);
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_uint32
flood_bits_up(PN_uint32 x) {
x |= (x << 1);
x |= (x << 2);
x |= (x << 4);
x |= (x << 8);
x |= (x << 16);
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_uint64
flood_bits_up(PN_uint64 x) {
x |= (x << 1);
x |= (x << 2);
x |= (x << 4);
x |= (x << 8);
x |= (x << 16);
x |= (x << 32);
return x;
}
////////////////////////////////////////////////////////////////////
// Function: BitMask::flood_up_in_place
// Access: Published
// Description: Floods this bitmask's bits upwards.
////////////////////////////////////////////////////////////////////
template<class WType, int nbits>
INLINE void BitMask<WType, nbits>::
flood_up_in_place() {
_word = ::flood_bits_up(_word);
}
////////////////////////////////////////////////////////////////////
// Function: BitMask::flood_down_in_place
// Access: Published
// Description: Floods this bitmask's bits downwards.
////////////////////////////////////////////////////////////////////
template<class WType, int nbits>
INLINE void BitMask<WType, nbits>::
flood_down_in_place() {
_word = ::flood_bits_down(_word);
}
////////////////////////////////////////////////////////////////////
// Function: BitMask::flood_bits_up
// Access: Published
// Description: Returns a BitMask with the bits flooded upwards.
////////////////////////////////////////////////////////////////////
template<class WType, int nbits>
INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
flood_bits_up() const {
BitMask<WType, nbits> result(::flood_bits_up(_word));
return result;
}
////////////////////////////////////////////////////////////////////
// Function: BitMask::flood_bits_down
// Access: Published
// Description: Returns a BitMask with the bits flooded down.
////////////////////////////////////////////////////////////////////
template<class WType, int nbits>
INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
flood_bits_down() const {
BitMask<WType, nbits> result(::flood_bits_down(_word));
return result;
}
////////////////////////////////////////////////////////////////////
// Function: BitMask::keep_next_highest_bit
// Access: Published
// Description: Returns a BitMask with only the next highest
// bit above the indicated bit on, or all_off.
////////////////////////////////////////////////////////////////////
template<class WType, int nbits>
INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
keep_next_highest_bit() const {
int low_bit = get_lowest_on_bit();
if (low_bit >= 0) {
return BitMask<WType, nbits>::bit(low_bit);
} else {
return BitMask<WType, nbits>::all_off();
}
}
////////////////////////////////////////////////////////////////////
// Function: BitMask::keep_next_lowest_bit
// Access: Published
// Description: Returns a BitMask with only the next lower
// bit below the indicated bit on, or all_off.
////////////////////////////////////////////////////////////////////
template<class WType, int nbits>
INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
keep_next_lowest_bit() const {
int high_bit = get_highest_on_bit();
if (high_bit >= 0) {
return BitMask<WType, nbits>::bit(high_bit);
} else {
return BitMask<WType, nbits>::all_off();
}
}
////////////////////////////////////////////////////////////////////
// Function: BitMask::keep_next_highest_bit
// Access: Published
// Description: Returns a BitMask with only the next highest
// bit above the indicated bit on, or all.
////////////////////////////////////////////////////////////////////
template<class WType, int nbits>
INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
keep_next_highest_bit(int index) const {
BitMask<WType, nbits> mask,temp;
nassertr(index >= 0 && index < num_bits, mask);
mask.set_bit(index);
mask.flood_down_in_place();
mask.invert_in_place();
mask &= *this;
temp = mask;
mask <<= 1;
mask.flood_up_in_place();
mask.invert_in_place();
mask &= temp;
return mask;
}
////////////////////////////////////////////////////////////////////
// Function: BitMask::keep_next_lowest_bit
// Access: Published
// Description: Returns a BitMask with only the next lower
// bit below the indicated bit on, or all_off.
////////////////////////////////////////////////////////////////////
template<class WType, int nbits>
INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
keep_next_lowest_bit(int index) const {
BitMask<WType, nbits> mask, temp;
nassertr(index >= 0 && index < num_bits, mask);
mask.set_bit(index);
mask.flood_up_in_place();
mask.invert_in_place();
mask &= *this;
temp = mask;
mask >>= 1;
mask.flood_down_in_place();
mask.invert_in_place();
mask &= temp;
return mask;
}
////////////////////////////////////////////////////////////////////
// Function: BitMask::keep_next_highest_bit
// Access: Published
// Description: Returns a BitMask with only the next highest "on"
// bit above all "on" bits in the passed in bitmask, or
// all_off. If there are no "on" bits in the passed in
// bitmask, it will return keep_next_highest_bit().
////////////////////////////////////////////////////////////////////
template<class WType, int nbits>
INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
keep_next_highest_bit(const BitMask<WType, nbits> &other) const {
int high_bit = other.get_highest_on_bit();
if (high_bit >= 0) {
return keep_next_highest_bit(high_bit);
} else {
return keep_next_highest_bit();
}
}
////////////////////////////////////////////////////////////////////
// Function: BitMask::keep_next_lowest_bit
// Access: Published
// Description: Returns a BitMask with only the next lowest "on"
// bit below all "on" bits in the passed in bitmask, or
// all_off. If there are no "on" bits in the passed in
// bitmask, it will return keep_next_lowest_bit().
////////////////////////////////////////////////////////////////////
template<class WType, int nbits>
INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
keep_next_lowest_bit(const BitMask<WType, nbits> &other) const {
int low_bit = other.get_lowest_on_bit();
if (low_bit >= 0) {
return keep_next_lowest_bit(low_bit);
} else {
return keep_next_lowest_bit();
}
}

View File

@ -122,6 +122,17 @@ PUBLISHED:
INLINE void operator <<= (int shift);
INLINE void operator >>= (int shift);
INLINE void flood_down_in_place();
INLINE void flood_up_in_place();
INLINE BitMask<WType, nbits> flood_bits_down() const;
INLINE BitMask<WType, nbits> flood_bits_up() const;
INLINE BitMask<WType, nbits> keep_next_highest_bit() const;
INLINE BitMask<WType, nbits> keep_next_lowest_bit() const;
INLINE BitMask<WType, nbits> keep_next_highest_bit(int index) const;
INLINE BitMask<WType, nbits> keep_next_lowest_bit(int index) const;
INLINE BitMask<WType, nbits> keep_next_highest_bit(const BitMask<WType, nbits> &other) const;
INLINE BitMask<WType, nbits> keep_next_lowest_bit(const BitMask<WType, nbits> &other) const;
INLINE int get_key() const;
public:
@ -144,6 +155,8 @@ INLINE int count_bits_in_word(PN_uint32 x);
INLINE int count_bits_in_word(PN_uint64 x);
INLINE PN_uint32 flood_bits_down(PN_uint32 x);
INLINE PN_uint64 flood_bits_down(PN_uint64 x);
INLINE PN_uint32 flood_bits_up(PN_uint32 x);
INLINE PN_uint64 flood_bits_up(PN_uint64 x);
// This table precomputes the number of on bits in each 16-bit word.
extern EXPCL_PANDA_PUTIL unsigned char num_bits_on[65536];