mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
BitArray (first pass)
This commit is contained in:
parent
4b35c0715d
commit
ecec0779f0
@ -11,8 +11,9 @@
|
||||
animInterface.h animInterface.I \
|
||||
bam.h bamEndian.h \
|
||||
bamReader.I bamReader.N bamReader.h bamReaderParam.I \
|
||||
bamReaderParam.h bamWriter.I bamWriter.h bitMask.I \
|
||||
bitMask.h \
|
||||
bamReaderParam.h bamWriter.I bamWriter.h \
|
||||
bitArray.I bitArray.h \
|
||||
bitMask.I bitMask.h \
|
||||
buttonHandle.I \
|
||||
buttonHandle.h buttonRegistry.I buttonRegistry.h \
|
||||
cachedTypedWritableReferenceCount.h cachedTypedWritableReferenceCount.I \
|
||||
@ -62,7 +63,9 @@
|
||||
#define INCLUDED_SOURCES \
|
||||
animInterface.cxx \
|
||||
bamEndian.cxx \
|
||||
bamReader.cxx bamReaderParam.cxx bamWriter.cxx bitMask.cxx \
|
||||
bamReader.cxx bamReaderParam.cxx bamWriter.cxx \
|
||||
bitArray.cxx \
|
||||
bitMask.cxx \
|
||||
buttonHandle.cxx buttonRegistry.cxx \
|
||||
cachedTypedWritableReferenceCount.cxx \
|
||||
config_util.cxx configurable.cxx \
|
||||
@ -99,7 +102,9 @@
|
||||
animInterface.h animInterface.I \
|
||||
bam.h bamEndian.h \
|
||||
bamReader.I bamReader.h bamReaderParam.I bamReaderParam.h \
|
||||
bamWriter.I bamWriter.h bitMask.I bitMask.h \
|
||||
bamWriter.I bamWriter.h \
|
||||
bitArray.I bitArray.h \
|
||||
bitMask.I bitMask.h \
|
||||
buttonHandle.I buttonHandle.h buttonRegistry.I \
|
||||
buttonRegistry.h \
|
||||
cachedTypedWritableReferenceCount.h cachedTypedWritableReferenceCount.I \
|
||||
|
||||
518
panda/src/putil/bitArray.I
Executable file
518
panda/src/putil/bitArray.I
Executable file
@ -0,0 +1,518 @@
|
||||
// Filename: bitArray.I
|
||||
// Created by: drose (20Jan06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE BitArray::
|
||||
BitArray() {
|
||||
_highest_bits = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE BitArray::
|
||||
BitArray(WordType init_value) {
|
||||
if (init_value != 0) {
|
||||
_array.push_back(MaskType(init_value));
|
||||
}
|
||||
_highest_bits = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::Copy Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE BitArray::
|
||||
BitArray(const BitArray ©) :
|
||||
_array(copy._array),
|
||||
_highest_bits(copy._highest_bits)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::Copy Assignment Operator
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void BitArray::
|
||||
operator = (const BitArray ©) {
|
||||
_array = copy._array;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::Named all_on constructor
|
||||
// Access: Published, Static
|
||||
// Description: Returns a BitArray with an infinite array of bits,
|
||||
// all on.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE BitArray BitArray::
|
||||
all_on() {
|
||||
BitArray result;
|
||||
result._highest_bits = 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::Named all_on constructor
|
||||
// Access: Published, Static
|
||||
// Description: Returns a BitArray whose bits are all off.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE BitArray BitArray::
|
||||
all_off() {
|
||||
return BitArray();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::Named lower_on constructor
|
||||
// Access: Published, Static
|
||||
// Description: Returns a BitArray whose lower on_bits bits are on.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE BitArray BitArray::
|
||||
lower_on(int on_bits) {
|
||||
BitArray result;
|
||||
result.set_range(0, on_bits);
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::Named bit constructor
|
||||
// Access: Published, Static
|
||||
// Description: Returns a BitArray with only the indicated bit on.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE BitArray BitArray::
|
||||
bit(int index) {
|
||||
BitArray result;
|
||||
result.set_bit(index);
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::Named range constructor
|
||||
// Access: Published, Static
|
||||
// Description: Returns a BitArray whose size bits, beginning at
|
||||
// low_bit, are on.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE BitArray BitArray::
|
||||
range(int low_bit, int size) {
|
||||
BitArray result;
|
||||
result.set_range(low_bit, size);
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::Destructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE BitArray::
|
||||
~BitArray() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::has_max_num_bits
|
||||
// Access: Published, Static
|
||||
// Description: Returns true if there is a maximum number of bits
|
||||
// that may be stored in this structure, false
|
||||
// otherwise. If this returns true, the number may be
|
||||
// queried in get_max_num_bits().
|
||||
//
|
||||
// This method always returns false. The BitArray has
|
||||
// no maximum number of bits. This method is defined so
|
||||
// generic programming algorithms can use BitMask or
|
||||
// BitArray interchangeably.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool BitArray::
|
||||
has_max_num_bits() {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::get_max_num_bits
|
||||
// Access: Published, Static
|
||||
// Description: If get_max_num_bits() returned true, this method may
|
||||
// be called to return the maximum number of bits that
|
||||
// may be stored in this structure. It is an error to
|
||||
// call this if get_max_num_bits() return false.
|
||||
//
|
||||
// It is always an error to call this method. The
|
||||
// BitArray has no maximum number of bits. This method
|
||||
// is defined so generic programming algorithms can use
|
||||
// BitMask or BitArray interchangeably.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int BitArray::
|
||||
get_max_num_bits() {
|
||||
nassertr(false, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::get_num_bits_per_word
|
||||
// Access: Published, Static
|
||||
// Description: Returns the number of bits stored per word
|
||||
// internally. This is of interest only in that it
|
||||
// limits the maximum number of bits that may be queried
|
||||
// or set at once by extract() and store().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int BitArray::
|
||||
get_num_bits_per_word() {
|
||||
return num_bits_per_word;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::get_num_bits
|
||||
// Access: Published
|
||||
// Description: Returns the current number of possibly different bits
|
||||
// in this array. There are actually an infinite number
|
||||
// of bits, but every bit higher than this bit will have
|
||||
// the same value, either 0 or 1 (see
|
||||
// get_highest_bits()).
|
||||
//
|
||||
// This number may grow and/or shrink automatically as
|
||||
// needed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int BitArray::
|
||||
get_num_bits() const {
|
||||
return get_num_words() * num_bits_per_word;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::get_bit
|
||||
// Access: Published
|
||||
// Description: Returns true if the nth bit is set, false if it is
|
||||
// cleared. It is valid for n to increase beyond
|
||||
// get_num_bits(), but the return value get_num_bits()
|
||||
// will always be the same.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool BitArray::
|
||||
get_bit(int index) const {
|
||||
nassertr(index >= 0, false);
|
||||
int w = index / num_bits_per_word;
|
||||
int b = index % num_bits_per_word;
|
||||
if (w >= get_num_words()) {
|
||||
return get_highest_bits();
|
||||
} else {
|
||||
return (_array[w].get_bit(b));
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::set_bit
|
||||
// Access: Published
|
||||
// Description: Sets the nth bit on. If n >= get_num_bits(), this
|
||||
// automatically extends the array.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void BitArray::
|
||||
set_bit(int index) {
|
||||
nassertv(index >= 0);
|
||||
int w = index / num_bits_per_word;
|
||||
int b = index % num_bits_per_word;
|
||||
if (w >= get_num_words() && _highest_bits) {
|
||||
// All the highest bits are already on.
|
||||
return;
|
||||
}
|
||||
ensure_has_word(w);
|
||||
_array[w].set_bit(b);
|
||||
normalize();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::clear_bit
|
||||
// Access: Published
|
||||
// Description: Sets the nth bit off. If n >= get_num_bits(), this
|
||||
// automatically extends the array.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void BitArray::
|
||||
clear_bit(int index) {
|
||||
nassertv(index >= 0);
|
||||
int w = index / num_bits_per_word;
|
||||
int b = index % num_bits_per_word;
|
||||
if (w >= get_num_words() && !_highest_bits) {
|
||||
// All the highest bits are already off.
|
||||
return;
|
||||
}
|
||||
ensure_has_word(w);
|
||||
_array[w].clear_bit(b);
|
||||
normalize();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::set_bit_to
|
||||
// Access: Published
|
||||
// Description: Sets the nth bit either on or off, according to the
|
||||
// indicated bool value.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void BitArray::
|
||||
set_bit_to(int index, bool value) {
|
||||
if (value) {
|
||||
set_bit(index);
|
||||
} else {
|
||||
clear_bit(index);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::get_highest_bits
|
||||
// Access: Published
|
||||
// Description: Returns true if the infinite set of bits beyond
|
||||
// get_num_bits() are all on, or false of they are all
|
||||
// off.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool BitArray::
|
||||
get_highest_bits() const {
|
||||
return (_highest_bits != 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::extract
|
||||
// Access: Published
|
||||
// Description: Returns a word that represents only the indicated
|
||||
// range of bits within this BitArray, shifted to the
|
||||
// least-significant position. size must be <=
|
||||
// get_num_bits_per_word().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE BitArray::WordType BitArray::
|
||||
extract(int low_bit, int size) const {
|
||||
nassertr(size >= 0 && size <= num_bits_per_word, 0);
|
||||
int w = low_bit / num_bits_per_word;
|
||||
int b = low_bit % num_bits_per_word;
|
||||
|
||||
if (b + size < num_bits_per_word) {
|
||||
// The whole thing fits within one word of the array.
|
||||
return get_word(w).extract(b, size);
|
||||
|
||||
} else {
|
||||
// We have to split it across two words.
|
||||
int num_lower_bits = num_bits_per_word - b;
|
||||
int num_higher_bits = size - num_lower_bits;
|
||||
|
||||
return get_word(w).extract(b, num_lower_bits) |
|
||||
(get_word(w + 1).extract(0, num_higher_bits) << num_lower_bits);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::store
|
||||
// Access: Published
|
||||
// Description: Stores the indicated word into the indicated range of
|
||||
// bits with this BitArray.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void BitArray::
|
||||
store(WordType value, int low_bit, int size) {
|
||||
nassertv(size >= 0);
|
||||
int w = low_bit / num_bits_per_word;
|
||||
int b = low_bit % num_bits_per_word;
|
||||
|
||||
if (b + size < num_bits_per_word) {
|
||||
// The whole thing fits within one word of the array.
|
||||
ensure_has_word(w);
|
||||
_array[w].store(value, b, size);
|
||||
|
||||
} else {
|
||||
// We have to split it across two words.
|
||||
int num_lower_bits = num_bits_per_word - b;
|
||||
int num_higher_bits = size - num_lower_bits;
|
||||
|
||||
ensure_has_word(w + 1);
|
||||
_array[w].store(value, b, num_lower_bits);
|
||||
_array[w + 1].store(value >> num_lower_bits, 0, num_higher_bits);
|
||||
}
|
||||
normalize();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::set_range_to
|
||||
// Access: Published
|
||||
// Description: Sets the indicated range of bits to either on or off.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void BitArray::
|
||||
set_range_to(bool value, int low_bit, int size) {
|
||||
if (value) {
|
||||
set_range(low_bit, size);
|
||||
} else {
|
||||
clear_range(low_bit, size);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::get_num_words
|
||||
// Access: Published
|
||||
// Description: Returns the number of possibly-unique words stored in
|
||||
// the array.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int BitArray::
|
||||
get_num_words() const {
|
||||
return _array.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::get_word
|
||||
// Access: Published
|
||||
// Description: Returns the nth word in the array. It is valid for n
|
||||
// to be greater than get_num_words(), but the return
|
||||
// value beyond get_num_words() will always be the same.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE BitArray::MaskType BitArray::
|
||||
get_word(int n) const {
|
||||
nassertr(n >= 0, MaskType::all_off());
|
||||
if (n < get_num_words()) {
|
||||
return _array[n];
|
||||
}
|
||||
if (_highest_bits) {
|
||||
return MaskType::all_on();
|
||||
} else {
|
||||
return MaskType::all_off();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::set_word
|
||||
// Access: Published
|
||||
// Description: Replaces the nth word in the array. If n >=
|
||||
// get_num_words(), this automatically extends the
|
||||
// array.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void BitArray::
|
||||
set_word(int n, MaskType value) {
|
||||
nassertv(n >= 0);
|
||||
ensure_has_word(n);
|
||||
_array[n] = value;
|
||||
normalize();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::clear
|
||||
// Access: Published
|
||||
// Description: Sets all the bits in the BitArray off.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BitArray::
|
||||
clear() {
|
||||
_array.clear();
|
||||
_highest_bits = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::operator ==
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool BitArray::
|
||||
operator == (const BitArray &other) const {
|
||||
return compare_to(other) == 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::operator !=
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool BitArray::
|
||||
operator != (const BitArray &other) const {
|
||||
return compare_to(other) != 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::operator <
|
||||
// Access: Published
|
||||
// Description: Returns true if the unsigned integer which is
|
||||
// represented by this BitArray is less than that of the
|
||||
// other one, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool BitArray::
|
||||
operator < (const BitArray &other) const {
|
||||
return compare_to(other) < 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::operator &
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE BitArray BitArray::
|
||||
operator & (const BitArray &other) const {
|
||||
BitArray result(*this);
|
||||
result &= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::operator |
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE BitArray BitArray::
|
||||
operator | (const BitArray &other) const {
|
||||
BitArray result(*this);
|
||||
result |= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::operator ^
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE BitArray BitArray::
|
||||
operator ^ (const BitArray &other) const {
|
||||
BitArray result(*this);
|
||||
result ^= other;
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::operator ~
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE BitArray BitArray::
|
||||
operator ~ () const {
|
||||
BitArray result(*this);
|
||||
result.invert_in_place();
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::operator <<
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE BitArray BitArray::
|
||||
operator << (int shift) const {
|
||||
BitArray result(*this);
|
||||
result <<= shift;
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::operator >>
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE BitArray BitArray::
|
||||
operator >> (int shift) const {
|
||||
BitArray result(*this);
|
||||
result >>= shift;
|
||||
return result;
|
||||
}
|
||||
626
panda/src/putil/bitArray.cxx
Executable file
626
panda/src/putil/bitArray.cxx
Executable file
@ -0,0 +1,626 @@
|
||||
// Filename: bitArray.cxx
|
||||
// Created by: drose (20Jan06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "bitArray.h"
|
||||
|
||||
TypeHandle BitArray::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::is_zero
|
||||
// Access: Published
|
||||
// Description: Returns true if the entire bitmask is zero, false
|
||||
// otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool BitArray::
|
||||
is_zero() const {
|
||||
if (_highest_bits) {
|
||||
// If all the infinite highest bits are set, certainly the bitmask
|
||||
// is nonzero.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Start from the high end, since that's more likely to be nonzero.
|
||||
Array::const_reverse_iterator ai;
|
||||
for (ai = _array.rbegin(); ai != _array.rend(); ++ai) {
|
||||
if ((*ai) != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::set_range
|
||||
// Access: Published
|
||||
// Description: Sets the indicated range of bits on.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BitArray::
|
||||
set_range(int low_bit, int size) {
|
||||
int w = low_bit / num_bits_per_word;
|
||||
int b = low_bit % num_bits_per_word;
|
||||
|
||||
if (w >= get_num_words() && _highest_bits) {
|
||||
// All the highest bits are already on.
|
||||
return;
|
||||
}
|
||||
if (b + size <= num_bits_per_word) {
|
||||
// The whole thing fits within one word of the array.
|
||||
ensure_has_word(w);
|
||||
_array[w].set_range(b, size);
|
||||
normalize();
|
||||
return;
|
||||
}
|
||||
|
||||
while (size > 0) {
|
||||
if (size <= num_bits_per_word) {
|
||||
// The remainder fits within one word of the array.
|
||||
ensure_has_word(w);
|
||||
_array[w].set_range(0, size);
|
||||
normalize();
|
||||
return;
|
||||
}
|
||||
|
||||
// Keep going.
|
||||
ensure_has_word(w);
|
||||
_array[w] = MaskType::all_on();
|
||||
size -= num_bits_per_word;
|
||||
++w;
|
||||
|
||||
if (w >= get_num_words() && _highest_bits) {
|
||||
// All the highest bits are already on.
|
||||
normalize();
|
||||
return;
|
||||
}
|
||||
}
|
||||
normalize();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::clear_range
|
||||
// Access: Published
|
||||
// Description: Sets the indicated range of bits off.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BitArray::
|
||||
clear_range(int low_bit, int size) {
|
||||
int w = low_bit / num_bits_per_word;
|
||||
int b = low_bit % num_bits_per_word;
|
||||
|
||||
if (w >= get_num_words() && !_highest_bits) {
|
||||
// All the highest bits are already off.
|
||||
return;
|
||||
}
|
||||
if (b + size <= num_bits_per_word) {
|
||||
// The whole thing fits within one word of the array.
|
||||
ensure_has_word(w);
|
||||
_array[w].clear_range(b, size);
|
||||
normalize();
|
||||
return;
|
||||
}
|
||||
|
||||
while (size > 0) {
|
||||
if (size <= num_bits_per_word) {
|
||||
// The remainder fits within one word of the array.
|
||||
ensure_has_word(w);
|
||||
_array[w].clear_range(0, size);
|
||||
normalize();
|
||||
return;
|
||||
}
|
||||
|
||||
// Keep going.
|
||||
ensure_has_word(w);
|
||||
_array[w] = MaskType::all_on();
|
||||
size -= num_bits_per_word;
|
||||
++w;
|
||||
|
||||
if (w >= get_num_words() && !_highest_bits) {
|
||||
// All the highest bits are already off.
|
||||
normalize();
|
||||
return;
|
||||
}
|
||||
}
|
||||
normalize();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::invert_in_place
|
||||
// Access: Published
|
||||
// Description: Inverts all the bits in the BitArray. This is
|
||||
// equivalent to array = ~array.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BitArray::
|
||||
invert_in_place() {
|
||||
_highest_bits = !_highest_bits;
|
||||
Array::iterator ai;
|
||||
for (ai = _array.begin(); ai != _array.end(); ++ai) {
|
||||
(*ai) = ~(*ai);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::has_bits_in_common
|
||||
// Access: Published
|
||||
// Description: Returns true if this BitArray has any "one" bits in
|
||||
// common with the other one, false otherwise.
|
||||
//
|
||||
// This is equivalent to (array & other) != 0, but may
|
||||
// be faster.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool BitArray::
|
||||
has_bits_in_common(const BitArray &other) const {
|
||||
if (_highest_bits && other._highest_bits) {
|
||||
// Yup, in fact we have an infinite number of bits in common.
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t num_common_words = min(_array.size(), other._array.size());
|
||||
|
||||
// Consider the words that are on top of either array.
|
||||
if (other._array.size() < _array.size() && other._highest_bits) {
|
||||
// The other array has fewer actual words, and the top n words of
|
||||
// the other array are all ones. We have bits in common if any of
|
||||
// our top n words are nonzero.
|
||||
Array::const_iterator ai;
|
||||
for (ai = _array.begin() + other._array.size();
|
||||
ai != _array.end();
|
||||
++ai) {
|
||||
if (!(*ai).is_zero()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (_array.size() < other._array.size() && _highest_bits) {
|
||||
// This array has fewer actual words, and the top n words of this
|
||||
// array are all ones. We have bits in common if any of the the
|
||||
// other's top n words are nonzero.
|
||||
Array::const_iterator ai;
|
||||
for (ai = other._array.begin() + _array.size();
|
||||
ai != other._array.end();
|
||||
++ai) {
|
||||
if (!(*ai).is_zero()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Consider the words that both arrays have in common.
|
||||
for (size_t i = 0; i < num_common_words; ++i) {
|
||||
if (!(_array[i] & other._array[i]).is_zero()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Nope, nothing.
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::output
|
||||
// Access: Published
|
||||
// Description: Writes the BitArray out as a binary or a hex number,
|
||||
// according to the number of bits.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BitArray::
|
||||
output(ostream &out) const {
|
||||
if (get_num_bits() >= 40) {
|
||||
output_hex(out);
|
||||
} else {
|
||||
output_binary(out);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::output_binary
|
||||
// Access: Published
|
||||
// Description: Writes the BitArray out as a binary number, with
|
||||
// spaces every four bits.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BitArray::
|
||||
output_binary(ostream &out, int spaces_every) const {
|
||||
if (_highest_bits) {
|
||||
out << "...1 ";
|
||||
}
|
||||
int num_bits = max(get_num_bits(), spaces_every);
|
||||
for (int i = num_bits - 1; i >= 0; i--) {
|
||||
if (spaces_every != 0 && ((i % spaces_every) == spaces_every - 1)) {
|
||||
out << ' ';
|
||||
}
|
||||
out << (get_bit(i) ? '1' : '0');
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::output_hex
|
||||
// Access: Published
|
||||
// Description: Writes the BitArray out as a hexadecimal number, with
|
||||
// spaces every four digits.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BitArray::
|
||||
output_hex(ostream &out, int spaces_every) const {
|
||||
int num_bits = get_num_bits();
|
||||
int num_digits = max((num_bits + 3) / 4, spaces_every);
|
||||
|
||||
if (_highest_bits) {
|
||||
out << "...f ";
|
||||
}
|
||||
|
||||
for (int i = num_digits - 1; i >= 0; i--) {
|
||||
WordType digit = extract(i * 4, 4);
|
||||
if (spaces_every != 0 && ((i % spaces_every) == spaces_every - 1)) {
|
||||
out << ' ';
|
||||
}
|
||||
if (digit > 9) {
|
||||
out << (char)(digit - 10 + 'a');
|
||||
} else {
|
||||
out << (char)(digit + '0');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::write
|
||||
// Access: Published
|
||||
// Description: Writes the BitArray out as a binary or a hex number,
|
||||
// according to the number of bits.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BitArray::
|
||||
write(ostream &out, int indent_level) const {
|
||||
indent(out, indent_level) << *this << "\n";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::compare_to
|
||||
// Access: Published
|
||||
// Description: Returns a number less than zero if this BitArray sorts
|
||||
// before the indicated other BitArray, greater than zero
|
||||
// if it sorts after, or 0 if they are equivalent. This
|
||||
// is based on the same ordering defined by operator <.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int BitArray::
|
||||
compare_to(const BitArray &other) const {
|
||||
if (_highest_bits != other._highest_bits) {
|
||||
return _highest_bits ? 1 : -1;
|
||||
}
|
||||
|
||||
int num_words = max(get_num_words(), other.get_num_words());
|
||||
|
||||
// Compare from highest-order to lowest-order word.
|
||||
for (int i = num_words - 1; i >= 0; --i) {
|
||||
int compare = get_word(i).compare_to(other.get_word(i));
|
||||
if (compare != 0) {
|
||||
return compare;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::operator &=
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BitArray::
|
||||
operator &= (const BitArray &other) {
|
||||
size_t num_common_words = min(_array.size(), other._array.size());
|
||||
|
||||
// Consider the words that are on top of either array.
|
||||
if (other._array.size() < _array.size() && !other._highest_bits) {
|
||||
// The other array has fewer actual words, and the top n words of
|
||||
// the other array are all zeroes. "mask off" the top n words of
|
||||
// this array.
|
||||
_array.erase(_array.begin() + other._array.size(), _array.end());
|
||||
|
||||
} else if (_array.size() < other._array.size() && _highest_bits) {
|
||||
// This array has fewer actual words, and the top n words of this
|
||||
// array are all ones. "mask on" the top n words of the other
|
||||
// array.
|
||||
Array::const_iterator ai;
|
||||
for (ai = other._array.begin() + _array.size();
|
||||
ai != other._array.end();
|
||||
++ai) {
|
||||
_array.push_back(*ai);
|
||||
}
|
||||
}
|
||||
|
||||
// Consider the words that both arrays have in common.
|
||||
for (size_t i = 0; i < num_common_words; ++i) {
|
||||
_array[i] &= other._array[i];
|
||||
}
|
||||
|
||||
_highest_bits &= other._highest_bits;
|
||||
normalize();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::operator |=
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BitArray::
|
||||
operator |= (const BitArray &other) {
|
||||
size_t num_common_words = min(_array.size(), other._array.size());
|
||||
|
||||
// Consider the words that are on top of either array.
|
||||
if (other._array.size() < _array.size() && other._highest_bits) {
|
||||
// The other array has fewer actual words, and the top n words of
|
||||
// the other array are all ones. The top n words of this array
|
||||
// become ones too (which means we can drop them out).
|
||||
_array.erase(_array.begin() + other._array.size(), _array.end());
|
||||
|
||||
} else if (_array.size() < other._array.size() && !_highest_bits) {
|
||||
// This array has fewer actual words, and the top n words of this
|
||||
// array are all zeros. Copy in the top n words of the other
|
||||
// array.
|
||||
Array::const_iterator ai;
|
||||
for (ai = other._array.begin() + _array.size();
|
||||
ai != other._array.end();
|
||||
++ai) {
|
||||
_array.push_back(*ai);
|
||||
}
|
||||
}
|
||||
|
||||
// Consider the words that both arrays have in common.
|
||||
for (size_t i = 0; i < num_common_words; ++i) {
|
||||
_array[i] |= other._array[i];
|
||||
}
|
||||
|
||||
_highest_bits |= other._highest_bits;
|
||||
normalize();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::operator ^=
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BitArray::
|
||||
operator ^= (const BitArray &other) {
|
||||
size_t num_common_words = min(_array.size(), other._array.size());
|
||||
|
||||
// Consider the words that are on top of either array.
|
||||
if (other._array.size() < _array.size() && other._highest_bits) {
|
||||
// The other array has fewer actual words, and the top n words of
|
||||
// the other array are all ones. The top n words of this array
|
||||
// get inverted.
|
||||
Array::iterator ai;
|
||||
for (ai = _array.begin() + other._array.size();
|
||||
ai != _array.end();
|
||||
++ai) {
|
||||
(*ai).invert_in_place();
|
||||
}
|
||||
|
||||
} else if (_array.size() < other._array.size()) {
|
||||
if (!_highest_bits) {
|
||||
// This array has fewer actual words, and the top n words of this
|
||||
// array are all zeros. Copy in the top n words of the other
|
||||
// array.
|
||||
Array::const_iterator ai;
|
||||
for (ai = other._array.begin() + _array.size();
|
||||
ai != other._array.end();
|
||||
++ai) {
|
||||
_array.push_back(*ai);
|
||||
}
|
||||
} else {
|
||||
// This array has fewer actual words, and the top n words of this
|
||||
// array are all ones. Copy in the top n words of the other
|
||||
// array, inverted.
|
||||
Array::const_iterator ai;
|
||||
for (ai = other._array.begin() + _array.size();
|
||||
ai != other._array.end();
|
||||
++ai) {
|
||||
_array.push_back(~(*ai));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Consider the words that both arrays have in common.
|
||||
for (size_t i = 0; i < num_common_words; ++i) {
|
||||
_array[i] ^= other._array[i];
|
||||
}
|
||||
|
||||
_highest_bits ^= other._highest_bits;
|
||||
normalize();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::operator <<=
|
||||
// Access: Published
|
||||
// Description: Logical left shift. The rightmost bits are filled in
|
||||
// with zeroes. Since this is an infinite bit array,
|
||||
// none of the bits on the left are lost.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BitArray::
|
||||
operator <<= (int shift) {
|
||||
if (shift == 0 || _array.empty()) {
|
||||
return;
|
||||
}
|
||||
if (shift < 0) {
|
||||
operator >>= (-shift);
|
||||
return;
|
||||
}
|
||||
|
||||
int w = shift / num_bits_per_word;
|
||||
int b = shift % num_bits_per_word;
|
||||
|
||||
if (b == 0) {
|
||||
// Easy case--word-at-a-time.
|
||||
Array new_array;
|
||||
new_array.reserve(_array.size() + w);
|
||||
for (int i = 0; i < w; ++i) {
|
||||
new_array.push_back(MaskType::all_off());
|
||||
}
|
||||
Array::const_iterator ai;
|
||||
for (ai = _array.begin(); ai != _array.end(); ++ai) {
|
||||
new_array.push_back(*ai);
|
||||
}
|
||||
_array.swap(new_array);
|
||||
|
||||
} else {
|
||||
// Harder case--we have to shuffle bits between words.
|
||||
Array new_array;
|
||||
new_array.reserve(_array.size() + w + 1);
|
||||
for (int i = 0; i < w; ++i) {
|
||||
new_array.push_back(MaskType::all_off());
|
||||
}
|
||||
|
||||
int downshift_count = num_bits_per_word - b;
|
||||
MaskType lower_mask = MaskType::lower_on(downshift_count);
|
||||
MaskType upper_mask = ~lower_mask;
|
||||
|
||||
Array::const_iterator ai = _array.begin();
|
||||
nassertv(ai != _array.end());
|
||||
MaskType next_bits = ((*ai) & upper_mask) >> downshift_count;
|
||||
new_array.push_back(((*ai) & lower_mask) << b);
|
||||
++ai;
|
||||
while (ai != _array.end()) {
|
||||
new_array.push_back((((*ai) & lower_mask) << b) | next_bits);
|
||||
next_bits = ((*ai) & upper_mask) >> downshift_count;
|
||||
++ai;
|
||||
}
|
||||
|
||||
// Finally, the top n bits.
|
||||
if (_highest_bits) {
|
||||
next_bits |= upper_mask;
|
||||
}
|
||||
new_array.push_back(next_bits);
|
||||
_array.swap(new_array);
|
||||
}
|
||||
|
||||
normalize();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::operator >>=
|
||||
// Access: Published
|
||||
// Description: Logical right shift. The rightmost bits are lost.
|
||||
// Since this is an infinite bit array, there is no
|
||||
// question of sign extension; there is no need to
|
||||
// synthesize bits on the left.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BitArray::
|
||||
operator >>= (int shift) {
|
||||
if (shift == 0 || _array.empty()) {
|
||||
return;
|
||||
}
|
||||
if (shift < 0) {
|
||||
operator <<= (-shift);
|
||||
return;
|
||||
}
|
||||
|
||||
int w = shift / num_bits_per_word;
|
||||
int b = shift % num_bits_per_word;
|
||||
|
||||
if (w >= (int)_array.size()) {
|
||||
// Trivial case--shift to nothing.
|
||||
_array.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
if (b == 0) {
|
||||
// Easy case--word-at-a-time.
|
||||
Array new_array;
|
||||
new_array.reserve(_array.size() - w);
|
||||
Array::const_iterator ai;
|
||||
for (ai = _array.begin() + w; ai != _array.end(); ++ai) {
|
||||
new_array.push_back(*ai);
|
||||
}
|
||||
_array.swap(new_array);
|
||||
|
||||
} else {
|
||||
// Harder case--we have to shuffle bits between words.
|
||||
Array new_array;
|
||||
new_array.reserve(_array.size() - w);
|
||||
|
||||
int upshift_count = num_bits_per_word - b;
|
||||
MaskType lower_mask = MaskType::lower_on(b);
|
||||
MaskType upper_mask = ~lower_mask;
|
||||
|
||||
Array::const_iterator ai = _array.begin() + w;
|
||||
nassertv(ai < _array.end());
|
||||
MaskType next_bits = ((*ai) & upper_mask) >> b;
|
||||
|
||||
++ai;
|
||||
while (ai != _array.end()) {
|
||||
new_array.push_back((((*ai) & lower_mask) << upshift_count) | next_bits);
|
||||
next_bits = ((*ai) & upper_mask) >> b;
|
||||
++ai;
|
||||
}
|
||||
|
||||
// Finally, the top n bits.
|
||||
if (_highest_bits) {
|
||||
next_bits |= upper_mask;
|
||||
}
|
||||
new_array.push_back(next_bits);
|
||||
_array.swap(new_array);
|
||||
}
|
||||
|
||||
normalize();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::generate_hash
|
||||
// Access: Public
|
||||
// Description: Adds the bitmask to the indicated hash generator.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BitArray::
|
||||
generate_hash(ChecksumHashGenerator &hashgen) const {
|
||||
hashgen.add_int(_highest_bits);
|
||||
Array::const_iterator ai;
|
||||
for (ai = _array.begin(); ai != _array.end(); ++ai) {
|
||||
hashgen.add_int((*ai).get_word());
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::ensure_has_word
|
||||
// Access: Private
|
||||
// Description: Ensures that at least word n has been allocated into
|
||||
// the array.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BitArray::
|
||||
ensure_has_word(int n) {
|
||||
if (_highest_bits) {
|
||||
while (n >= (int)_array.size()) {
|
||||
_array.push_back(MaskType::all_on());
|
||||
}
|
||||
} else {
|
||||
while (n >= (int)_array.size()) {
|
||||
_array.push_back(MaskType::all_off());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitArray::normalize
|
||||
// Access: Private
|
||||
// Description: Ensures that the array is the smallest array that
|
||||
// represents this same value, by removing the topmost
|
||||
// words that are all bits off (or on).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void BitArray::
|
||||
normalize() {
|
||||
if (_highest_bits) {
|
||||
while (!_array.empty() && _array.back() == MaskType::all_on()) {
|
||||
_array.pop_back();
|
||||
}
|
||||
} else {
|
||||
while (!_array.empty() && _array.back().is_zero()) {
|
||||
_array.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
152
panda/src/putil/bitArray.h
Executable file
152
panda/src/putil/bitArray.h
Executable file
@ -0,0 +1,152 @@
|
||||
// Filename: bitArray.h
|
||||
// Created by: drose (20Jan06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BITARRAY_H
|
||||
#define BITARRAY_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "bitMask.h"
|
||||
#include "numeric_types.h"
|
||||
#include "typedObject.h"
|
||||
#include "indent.h"
|
||||
|
||||
#include "checksumHashGenerator.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : BitArray
|
||||
// Description : A dynamic array with an unlimited number of bits.
|
||||
//
|
||||
// This is similar to a BitMask, except it appears to
|
||||
// contain an infinite number of bits. You can use it
|
||||
// very much as you would use a BitMask.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA BitArray {
|
||||
public:
|
||||
typedef BitMask32 MaskType;
|
||||
typedef MaskType::WordType WordType;
|
||||
enum { num_bits_per_word = MaskType::num_bits };
|
||||
|
||||
PUBLISHED:
|
||||
|
||||
INLINE BitArray();
|
||||
INLINE BitArray(WordType init_value);
|
||||
INLINE BitArray(const BitArray ©);
|
||||
INLINE void operator = (const BitArray ©);
|
||||
|
||||
INLINE static BitArray all_on();
|
||||
INLINE static BitArray all_off();
|
||||
INLINE static BitArray lower_on(int on_bits);
|
||||
INLINE static BitArray bit(int index);
|
||||
INLINE static BitArray range(int low_bit, int size);
|
||||
|
||||
INLINE ~BitArray();
|
||||
|
||||
INLINE static bool has_max_num_bits();
|
||||
INLINE static int get_max_num_bits();
|
||||
|
||||
INLINE static int get_num_bits_per_word();
|
||||
INLINE int get_num_bits() const;
|
||||
INLINE bool get_bit(int index) const;
|
||||
INLINE void set_bit(int index);
|
||||
INLINE void clear_bit(int index);
|
||||
INLINE void set_bit_to(int index, bool value);
|
||||
INLINE bool get_highest_bits() const;
|
||||
bool is_zero() const;
|
||||
|
||||
INLINE WordType extract(int low_bit, int size) const;
|
||||
INLINE void store(WordType value, int low_bit, int size);
|
||||
void set_range(int low_bit, int size);
|
||||
void clear_range(int low_bit, int size);
|
||||
INLINE void set_range_to(bool value, int low_bit, int size);
|
||||
|
||||
INLINE int get_num_words() const;
|
||||
INLINE MaskType get_word(int n) const;
|
||||
INLINE void set_word(int n, MaskType value);
|
||||
|
||||
void invert_in_place();
|
||||
bool has_bits_in_common(const BitArray &other) const;
|
||||
INLINE void clear();
|
||||
|
||||
void output(ostream &out) const;
|
||||
void output_binary(ostream &out, int spaces_every = 4) const;
|
||||
void output_hex(ostream &out, int spaces_every = 4) const;
|
||||
void write(ostream &out, int indent_level = 0) const;
|
||||
|
||||
INLINE bool operator == (const BitArray &other) const;
|
||||
INLINE bool operator != (const BitArray &other) const;
|
||||
INLINE bool operator < (const BitArray &other) const;
|
||||
int compare_to(const BitArray &other) const;
|
||||
|
||||
INLINE BitArray
|
||||
operator & (const BitArray &other) const;
|
||||
|
||||
INLINE BitArray
|
||||
operator | (const BitArray &other) const;
|
||||
|
||||
INLINE BitArray
|
||||
operator ^ (const BitArray &other) const;
|
||||
|
||||
INLINE BitArray
|
||||
operator ~ () const;
|
||||
|
||||
INLINE BitArray
|
||||
operator << (int shift) const;
|
||||
|
||||
INLINE BitArray
|
||||
operator >> (int shift) const;
|
||||
|
||||
void operator &= (const BitArray &other);
|
||||
void operator |= (const BitArray &other);
|
||||
void operator ^= (const BitArray &other);
|
||||
void operator <<= (int shift);
|
||||
void operator >>= (int shift);
|
||||
|
||||
public:
|
||||
void generate_hash(ChecksumHashGenerator &hashgen) const;
|
||||
|
||||
private:
|
||||
void ensure_has_word(int n);
|
||||
void normalize();
|
||||
|
||||
private:
|
||||
typedef pvector<MaskType> Array;
|
||||
Array _array;
|
||||
int _highest_bits; // Either 0 or 1.
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
register_type(_type_handle, "BitArray");
|
||||
}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#include "bitArray.I"
|
||||
|
||||
INLINE ostream &
|
||||
operator << (ostream &out, const BitArray &array) {
|
||||
array.output(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -16,16 +16,16 @@
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class WordType, int num_bits>
|
||||
TypeHandle BitMask<WordType, num_bits>::_type_handle;
|
||||
template<class WType, int nbits>
|
||||
TypeHandle BitMask<WType, nbits>::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitMask::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE BitMask<WordType, num_bits>::
|
||||
template<class WType, int nbits>
|
||||
INLINE BitMask<WType, nbits>::
|
||||
BitMask() :
|
||||
_word(0)
|
||||
{
|
||||
@ -36,8 +36,8 @@ BitMask() :
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE BitMask<WordType, num_bits>::
|
||||
template<class WType, int nbits>
|
||||
INLINE BitMask<WType, nbits>::
|
||||
BitMask(WordType init_value) :
|
||||
_word(init_value)
|
||||
{
|
||||
@ -48,9 +48,9 @@ BitMask(WordType init_value) :
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE BitMask<WordType, num_bits>::
|
||||
BitMask(const BitMask<WordType, num_bits> ©) :
|
||||
template<class WType, int nbits>
|
||||
INLINE BitMask<WType, nbits>::
|
||||
BitMask(const BitMask<WType, nbits> ©) :
|
||||
_word(copy._word)
|
||||
{
|
||||
}
|
||||
@ -60,9 +60,9 @@ BitMask(const BitMask<WordType, num_bits> ©) :
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE void BitMask<WordType, num_bits>::
|
||||
operator = (const BitMask<WordType, num_bits> ©) {
|
||||
template<class WType, int nbits>
|
||||
INLINE void BitMask<WType, nbits>::
|
||||
operator = (const BitMask<WType, nbits> ©) {
|
||||
_word = copy._word;
|
||||
}
|
||||
|
||||
@ -71,8 +71,8 @@ operator = (const BitMask<WordType, num_bits> ©) {
|
||||
// Access: Published, Static
|
||||
// Description: Returns a BitMask whose bits are all on.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE BitMask<WordType, num_bits> BitMask<WordType, num_bits>::
|
||||
template<class WType, int nbits>
|
||||
INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
|
||||
all_on() {
|
||||
BitMask result;
|
||||
result._word = ~0;
|
||||
@ -84,8 +84,8 @@ all_on() {
|
||||
// Access: Published, Static
|
||||
// Description: Returns a BitMask whose bits are all off.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE BitMask<WordType, num_bits> BitMask<WordType, num_bits>::
|
||||
template<class WType, int nbits>
|
||||
INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
|
||||
all_off() {
|
||||
BitMask result;
|
||||
result._word = 0;
|
||||
@ -95,10 +95,10 @@ all_off() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitMask::Named lower_on constructor
|
||||
// Access: Published, Static
|
||||
// Description: Returns a BitMask whose lower num_bits bits are on.
|
||||
// Description: Returns a BitMask whose lower on_bits bits are on.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE BitMask<WordType, num_bits> BitMask<WordType, num_bits>::
|
||||
template<class WType, int nbits>
|
||||
INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
|
||||
lower_on(int on_bits) {
|
||||
if (on_bits <= 0) {
|
||||
return all_off();
|
||||
@ -115,8 +115,8 @@ lower_on(int on_bits) {
|
||||
// Access: Published, Static
|
||||
// Description: Returns a BitMask with only the indicated bit on.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE BitMask<WordType, num_bits> BitMask<WordType, num_bits>::
|
||||
template<class WType, int nbits>
|
||||
INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
|
||||
bit(int index) {
|
||||
BitMask result;
|
||||
result.set_bit(index);
|
||||
@ -129,8 +129,8 @@ bit(int index) {
|
||||
// Description: Returns a BitMask whose size bits, beginning at
|
||||
// low_bit, are on.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE BitMask<WordType, num_bits> BitMask<WordType, num_bits>::
|
||||
template<class WType, int nbits>
|
||||
INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
|
||||
range(int low_bit, int size) {
|
||||
BitMask result;
|
||||
if (size <= 0) {
|
||||
@ -149,19 +149,56 @@ range(int low_bit, int size) {
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE BitMask<WordType, num_bits>::
|
||||
template<class WType, int nbits>
|
||||
INLINE BitMask<WType, nbits>::
|
||||
~BitMask() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitMask::has_max_num_bits
|
||||
// Access: Published, Static
|
||||
// Description: Returns true if there is a maximum number of bits
|
||||
// that may be stored in this structure, false
|
||||
// otherwise. If this returns true, the number may be
|
||||
// queried in get_max_num_bits().
|
||||
//
|
||||
// This method always returns true. This method is
|
||||
// defined so generic programming algorithms can use
|
||||
// BitMask or BitArray interchangeably.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WType, int nbits>
|
||||
INLINE bool BitMask<WType, nbits>::
|
||||
has_max_num_bits() {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitMask::get_max_num_bits
|
||||
// Access: Published, Static
|
||||
// Description: If get_max_num_bits() returned true, this method may
|
||||
// be called to return the maximum number of bits that
|
||||
// may be stored in this structure. It is an error to
|
||||
// call this if get_max_num_bits() return false.
|
||||
//
|
||||
// It is never an error to call this method. This
|
||||
// returns the same thing as get_num_bits(). This
|
||||
// method is defined so generic programming algorithms
|
||||
// can use BitMask or BitArray interchangeably.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WType, int nbits>
|
||||
INLINE int BitMask<WType, nbits>::
|
||||
get_max_num_bits() {
|
||||
return num_bits;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitMask::get_num_bits
|
||||
// Access: Published, Static
|
||||
// Description: Returns the number of bits available to set in the
|
||||
// bitmask.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE int BitMask<WordType, num_bits>::
|
||||
template<class WType, int nbits>
|
||||
INLINE int BitMask<WType, nbits>::
|
||||
get_num_bits() {
|
||||
return num_bits;
|
||||
}
|
||||
@ -171,10 +208,10 @@ get_num_bits() {
|
||||
// Access: Published
|
||||
// Description: Returns true if the nth bit is set, false if it is
|
||||
// cleared. index must be in the range [0,
|
||||
// get_num_bits).
|
||||
// num_bits).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE bool BitMask<WordType, num_bits>::
|
||||
template<class WType, int nbits>
|
||||
INLINE bool BitMask<WType, nbits>::
|
||||
get_bit(int index) const {
|
||||
nassertr(index >= 0 && index < num_bits, false);
|
||||
return (_word & ((WordType)1 << index)) != 0;
|
||||
@ -184,10 +221,10 @@ get_bit(int index) const {
|
||||
// Function: BitMask::set_bit
|
||||
// Access: Published
|
||||
// Description: Sets the nth bit on. index must be in the range
|
||||
// [0, get_num_bits).
|
||||
// [0, num_bits).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE void BitMask<WordType, num_bits>::
|
||||
template<class WType, int nbits>
|
||||
INLINE void BitMask<WType, nbits>::
|
||||
set_bit(int index) {
|
||||
nassertv(index >= 0 && index < num_bits);
|
||||
_word |= ((WordType)1 << index);
|
||||
@ -197,10 +234,10 @@ set_bit(int index) {
|
||||
// Function: BitMask::clear_bit
|
||||
// Access: Published
|
||||
// Description: Sets the nth bit off. index must be in the range
|
||||
// [0, get_num_bits).
|
||||
// [0, num_bits).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE void BitMask<WordType, num_bits>::
|
||||
template<class WType, int nbits>
|
||||
INLINE void BitMask<WType, nbits>::
|
||||
clear_bit(int index) {
|
||||
nassertv(index >= 0 && index < num_bits);
|
||||
_word &= ~((WordType)1 << index);
|
||||
@ -211,10 +248,10 @@ clear_bit(int index) {
|
||||
// Access: Published
|
||||
// Description: Sets the nth bit either on or off, according to the
|
||||
// indicated bool value. index must be in the range [0,
|
||||
// get_num_bits).
|
||||
// num_bits).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE void BitMask<WordType, num_bits>::
|
||||
template<class WType, int nbits>
|
||||
INLINE void BitMask<WType, nbits>::
|
||||
set_bit_to(int index, bool value) {
|
||||
if (value) {
|
||||
set_bit(index);
|
||||
@ -229,8 +266,8 @@ set_bit_to(int index, bool value) {
|
||||
// Description: Returns true if the entire bitmask is zero, false
|
||||
// otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE bool BitMask<WordType, num_bits>::
|
||||
template<class WType, int nbits>
|
||||
INLINE bool BitMask<WType, nbits>::
|
||||
is_zero() const {
|
||||
return (_word == 0);
|
||||
}
|
||||
@ -242,11 +279,11 @@ is_zero() const {
|
||||
// range of bits within this BitMask, shifted to the
|
||||
// least-significant position.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE WordType BitMask<WordType, num_bits>::
|
||||
template<class WType, int nbits>
|
||||
INLINE TYPENAME BitMask<WType, nbits>::WordType BitMask<WType, nbits>::
|
||||
extract(int low_bit, int size) const {
|
||||
return (_word >> low_bit) &
|
||||
BitMask<WordType, num_bits>::lower_on(size)._word;
|
||||
BitMask<WType, nbits>::lower_on(size)._word;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -255,21 +292,59 @@ extract(int low_bit, int size) const {
|
||||
// Description: Stores the indicated word into the indicated range of
|
||||
// bits with this BitMask.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE void BitMask<WordType, num_bits>::
|
||||
template<class WType, int nbits>
|
||||
INLINE void BitMask<WType, nbits>::
|
||||
store(WordType value, int low_bit, int size) {
|
||||
WordType mask =
|
||||
BitMask<WordType, num_bits>::lower_on(size)._word << low_bit;
|
||||
WordType mask = BitMask<WType, nbits>::range(low_bit, size)._word;
|
||||
_word = (_word & ~mask) | ((value << low_bit) & mask);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitMask::set_range
|
||||
// Access: Published
|
||||
// Description: Sets the indicated range of bits on.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WType, int nbits>
|
||||
INLINE void BitMask<WType, nbits>::
|
||||
set_range(int low_bit, int size) {
|
||||
WordType mask = BitMask<WType, nbits>::range(low_bit, size)._word;
|
||||
_word |= mask;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitMask::clear_range
|
||||
// Access: Published
|
||||
// Description: Sets the indicated range of bits off.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WType, int nbits>
|
||||
INLINE void BitMask<WType, nbits>::
|
||||
clear_range(int low_bit, int size) {
|
||||
WordType mask = BitMask<WType, nbits>::range(low_bit, size)._word;
|
||||
_word &= ~mask;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitMask::set_range_to
|
||||
// Access: Published
|
||||
// Description: Sets the indicated range of bits to either on or off.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WType, int nbits>
|
||||
INLINE void BitMask<WType, nbits>::
|
||||
set_range_to(bool value, int low_bit, int size) {
|
||||
if (value) {
|
||||
set_range(low_bit, size);
|
||||
} else {
|
||||
clear_range(low_bit, size);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitMask::get_word
|
||||
// Access: Published
|
||||
// Description: Returns the entire BitMask as a single word.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE WordType BitMask<WordType, num_bits>::
|
||||
template<class WType, int nbits>
|
||||
INLINE TYPENAME BitMask<WType, nbits>::WordType BitMask<WType, nbits>::
|
||||
get_word() const {
|
||||
return _word;
|
||||
}
|
||||
@ -280,8 +355,8 @@ get_word() const {
|
||||
// Description: Sets the entire BitMask to the value indicated by the
|
||||
// given word.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE void BitMask<WordType, num_bits>::
|
||||
template<class WType, int nbits>
|
||||
INLINE void BitMask<WType, nbits>::
|
||||
set_word(WordType value) {
|
||||
_word = value;
|
||||
}
|
||||
@ -289,21 +364,39 @@ set_word(WordType value) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitMask::invert_in_place
|
||||
// Access: Published
|
||||
// Description: Inverts all the bits in the BitMask.
|
||||
// Description: Inverts all the bits in the BitMask. This is
|
||||
// equivalent to mask = ~mask.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE void BitMask<WordType, num_bits>::
|
||||
template<class WType, int nbits>
|
||||
INLINE void BitMask<WType, nbits>::
|
||||
invert_in_place() {
|
||||
_word = ~_word;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitMask::has_bits_in_common
|
||||
// Access: Published
|
||||
// Description: Returns true if this BitMask has any "one" bits in
|
||||
// common with the other one, false otherwise.
|
||||
//
|
||||
// This is equivalent to (mask & other) != 0, but may be
|
||||
// faster. (Actually, it should only be faster in the
|
||||
// BitArray case, but this method is provided for the
|
||||
// benefit of generic programming algorithms).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WType, int nbits>
|
||||
INLINE bool BitMask<WType, nbits>::
|
||||
has_bits_in_common(const BitMask<WType, nbits> &other) const {
|
||||
return (_word & other._word) != 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BitMask::clear
|
||||
// Access: Published
|
||||
// Description: Sets all the bits in the BitMask off.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE void BitMask<WordType, num_bits>::
|
||||
template<class WType, int nbits>
|
||||
INLINE void BitMask<WType, nbits>::
|
||||
clear() {
|
||||
_word = 0;
|
||||
}
|
||||
@ -314,8 +407,8 @@ clear() {
|
||||
// Description: Writes the BitMask out as a binary or a hex number,
|
||||
// according to the number of bits.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
void BitMask<WordType, num_bits>::
|
||||
template<class WType, int nbits>
|
||||
void BitMask<WType, nbits>::
|
||||
output(ostream &out) const {
|
||||
if (num_bits >= 40) {
|
||||
output_hex(out);
|
||||
@ -330,8 +423,8 @@ output(ostream &out) const {
|
||||
// Description: Writes the BitMask out as a binary number, with
|
||||
// spaces every four bits.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
void BitMask<WordType, num_bits>::
|
||||
template<class WType, int nbits>
|
||||
void BitMask<WType, nbits>::
|
||||
output_binary(ostream &out, int spaces_every) const {
|
||||
for (int i = num_bits - 1; i >= 0; i--) {
|
||||
if (spaces_every != 0 && ((i % spaces_every) == spaces_every - 1)) {
|
||||
@ -347,8 +440,8 @@ output_binary(ostream &out, int spaces_every) const {
|
||||
// Description: Writes the BitMask out as a hexadecimal number, with
|
||||
// spaces every four digits.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
void BitMask<WordType, num_bits>::
|
||||
template<class WType, int nbits>
|
||||
void BitMask<WType, nbits>::
|
||||
output_hex(ostream &out, int spaces_every) const {
|
||||
int num_digits = (num_bits + 3) / 4;
|
||||
|
||||
@ -371,8 +464,8 @@ output_hex(ostream &out, int spaces_every) const {
|
||||
// Description: Writes the BitMask out as a binary or a hex number,
|
||||
// according to the number of bits.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
void BitMask<WordType, num_bits>::
|
||||
template<class WType, int nbits>
|
||||
void BitMask<WType, nbits>::
|
||||
write(ostream &out, int indent_level) const {
|
||||
indent(out, indent_level) << *this << "\n";
|
||||
}
|
||||
@ -382,9 +475,9 @@ write(ostream &out, int indent_level) const {
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE bool BitMask<WordType, num_bits>::
|
||||
operator == (const BitMask<WordType, num_bits> &other) const {
|
||||
template<class WType, int nbits>
|
||||
INLINE bool BitMask<WType, nbits>::
|
||||
operator == (const BitMask<WType, nbits> &other) const {
|
||||
return _word == other._word;
|
||||
}
|
||||
|
||||
@ -393,9 +486,9 @@ operator == (const BitMask<WordType, num_bits> &other) const {
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE bool BitMask<WordType, num_bits>::
|
||||
operator != (const BitMask<WordType, num_bits> &other) const {
|
||||
template<class WType, int nbits>
|
||||
INLINE bool BitMask<WType, nbits>::
|
||||
operator != (const BitMask<WType, nbits> &other) const {
|
||||
return _word != other._word;
|
||||
}
|
||||
|
||||
@ -410,9 +503,9 @@ operator != (const BitMask<WordType, num_bits> &other) const {
|
||||
// export any STL container (ordered or unordered) of
|
||||
// BitMask under Windows.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE bool BitMask<WordType, num_bits>::
|
||||
operator < (const BitMask<WordType, num_bits> &other) const {
|
||||
template<class WType, int nbits>
|
||||
INLINE bool BitMask<WType, nbits>::
|
||||
operator < (const BitMask<WType, nbits> &other) const {
|
||||
return _word < other._word;
|
||||
}
|
||||
|
||||
@ -424,9 +517,9 @@ operator < (const BitMask<WordType, num_bits> &other) const {
|
||||
// if it sorts after, or 0 if they are equivalent. This
|
||||
// is based on the same ordering defined by operator <.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE int BitMask<WordType, num_bits>::
|
||||
compare_to(const BitMask<WordType, num_bits> &other) const {
|
||||
template<class WType, int nbits>
|
||||
INLINE int BitMask<WType, nbits>::
|
||||
compare_to(const BitMask<WType, nbits> &other) const {
|
||||
if ((*this) < other) {
|
||||
return -1;
|
||||
} else if (other < (*this)) {
|
||||
@ -441,10 +534,10 @@ compare_to(const BitMask<WordType, num_bits> &other) const {
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE BitMask<WordType, num_bits> BitMask<WordType, num_bits>::
|
||||
operator & (const BitMask<WordType, num_bits> &other) const {
|
||||
BitMask<WordType, num_bits> result(*this);
|
||||
template<class WType, int nbits>
|
||||
INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
|
||||
operator & (const BitMask<WType, nbits> &other) const {
|
||||
BitMask<WType, nbits> result(*this);
|
||||
result &= other;
|
||||
return result;
|
||||
}
|
||||
@ -454,10 +547,10 @@ operator & (const BitMask<WordType, num_bits> &other) const {
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE BitMask<WordType, num_bits> BitMask<WordType, num_bits>::
|
||||
operator | (const BitMask<WordType, num_bits> &other) const {
|
||||
BitMask<WordType, num_bits> result(*this);
|
||||
template<class WType, int nbits>
|
||||
INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
|
||||
operator | (const BitMask<WType, nbits> &other) const {
|
||||
BitMask<WType, nbits> result(*this);
|
||||
result |= other;
|
||||
return result;
|
||||
}
|
||||
@ -467,10 +560,10 @@ operator | (const BitMask<WordType, num_bits> &other) const {
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE BitMask<WordType, num_bits> BitMask<WordType, num_bits>::
|
||||
operator ^ (const BitMask<WordType, num_bits> &other) const {
|
||||
BitMask<WordType, num_bits> result(*this);
|
||||
template<class WType, int nbits>
|
||||
INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
|
||||
operator ^ (const BitMask<WType, nbits> &other) const {
|
||||
BitMask<WType, nbits> result(*this);
|
||||
result ^= other;
|
||||
return result;
|
||||
}
|
||||
@ -480,12 +573,10 @@ operator ^ (const BitMask<WordType, num_bits> &other) const {
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE BitMask<WordType, num_bits> BitMask<WordType, num_bits>::
|
||||
template<class WType, int nbits>
|
||||
INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
|
||||
operator ~ () const {
|
||||
BitMask<WordType, num_bits> result(*this);
|
||||
result._word = ~result._word;
|
||||
return result;
|
||||
return BitMask<WType, nbits>(~_word);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -493,10 +584,10 @@ operator ~ () const {
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE BitMask<WordType, num_bits> BitMask<WordType, num_bits>::
|
||||
template<class WType, int nbits>
|
||||
INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
|
||||
operator << (int shift) const {
|
||||
BitMask<WordType, num_bits> result(*this);
|
||||
BitMask<WType, nbits> result(*this);
|
||||
result <<= shift;
|
||||
return result;
|
||||
}
|
||||
@ -506,10 +597,10 @@ operator << (int shift) const {
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE BitMask<WordType, num_bits> BitMask<WordType, num_bits>::
|
||||
template<class WType, int nbits>
|
||||
INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
|
||||
operator >> (int shift) const {
|
||||
BitMask<WordType, num_bits> result(*this);
|
||||
BitMask<WType, nbits> result(*this);
|
||||
result >>= shift;
|
||||
return result;
|
||||
}
|
||||
@ -519,9 +610,9 @@ operator >> (int shift) const {
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE void BitMask<WordType, num_bits>::
|
||||
operator &= (const BitMask<WordType, num_bits> &other) {
|
||||
template<class WType, int nbits>
|
||||
INLINE void BitMask<WType, nbits>::
|
||||
operator &= (const BitMask<WType, nbits> &other) {
|
||||
_word &= other._word;
|
||||
}
|
||||
|
||||
@ -530,9 +621,9 @@ operator &= (const BitMask<WordType, num_bits> &other) {
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE void BitMask<WordType, num_bits>::
|
||||
operator |= (const BitMask<WordType, num_bits> &other) {
|
||||
template<class WType, int nbits>
|
||||
INLINE void BitMask<WType, nbits>::
|
||||
operator |= (const BitMask<WType, nbits> &other) {
|
||||
_word |= other._word;
|
||||
}
|
||||
|
||||
@ -541,9 +632,9 @@ operator |= (const BitMask<WordType, num_bits> &other) {
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE void BitMask<WordType, num_bits>::
|
||||
operator ^= (const BitMask<WordType, num_bits> &other) {
|
||||
template<class WType, int nbits>
|
||||
INLINE void BitMask<WType, nbits>::
|
||||
operator ^= (const BitMask<WType, nbits> &other) {
|
||||
_word ^= other._word;
|
||||
}
|
||||
|
||||
@ -552,8 +643,8 @@ operator ^= (const BitMask<WordType, num_bits> &other) {
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE void BitMask<WordType, num_bits>::
|
||||
template<class WType, int nbits>
|
||||
INLINE void BitMask<WType, nbits>::
|
||||
operator <<= (int shift) {
|
||||
_word <<= shift;
|
||||
}
|
||||
@ -563,8 +654,8 @@ operator <<= (int shift) {
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE void BitMask<WordType, num_bits>::
|
||||
template<class WType, int nbits>
|
||||
INLINE void BitMask<WType, nbits>::
|
||||
operator >>= (int shift) {
|
||||
_word >>= shift;
|
||||
}
|
||||
@ -574,8 +665,8 @@ operator >>= (int shift) {
|
||||
// Access: Public
|
||||
// Description: Adds the bitmask to the indicated hash generator.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
INLINE void BitMask<WordType, num_bits>::
|
||||
template<class WType, int nbits>
|
||||
INLINE void BitMask<WType, nbits>::
|
||||
generate_hash(ChecksumHashGenerator &hashgen) const {
|
||||
hashgen.add_int(_word);
|
||||
}
|
||||
@ -585,8 +676,8 @@ generate_hash(ChecksumHashGenerator &hashgen) const {
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
void BitMask<WordType, num_bits>::
|
||||
template<class WType, int nbits>
|
||||
void BitMask<WType, nbits>::
|
||||
init_type() {
|
||||
ostringstream str;
|
||||
str << "BitMask" << num_bits;
|
||||
|
||||
@ -34,22 +34,29 @@
|
||||
// bits of some length that must fit within a given word
|
||||
// of the indicated type. See also BitArray.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class WordType, int num_bits>
|
||||
template<class WType, int nbits>
|
||||
class BitMask {
|
||||
public:
|
||||
typedef WType WordType;
|
||||
enum { num_bits = nbits };
|
||||
|
||||
PUBLISHED:
|
||||
INLINE BitMask();
|
||||
INLINE BitMask(WordType init_value);
|
||||
INLINE BitMask(const BitMask<WordType, num_bits> ©);
|
||||
INLINE void operator = (const BitMask<WordType, num_bits> ©);
|
||||
INLINE BitMask(const BitMask<WType, nbits> ©);
|
||||
INLINE void operator = (const BitMask<WType, nbits> ©);
|
||||
|
||||
INLINE static BitMask<WordType, num_bits> all_on();
|
||||
INLINE static BitMask<WordType, num_bits> all_off();
|
||||
INLINE static BitMask<WordType, num_bits> lower_on(int on_bits);
|
||||
INLINE static BitMask<WordType, num_bits> bit(int index);
|
||||
INLINE static BitMask<WordType, num_bits> range(int low_bit, int size);
|
||||
INLINE static BitMask<WType, nbits> all_on();
|
||||
INLINE static BitMask<WType, nbits> all_off();
|
||||
INLINE static BitMask<WType, nbits> lower_on(int on_bits);
|
||||
INLINE static BitMask<WType, nbits> bit(int index);
|
||||
INLINE static BitMask<WType, nbits> range(int low_bit, int size);
|
||||
|
||||
INLINE ~BitMask();
|
||||
|
||||
INLINE static bool has_max_num_bits();
|
||||
INLINE static int get_max_num_bits();
|
||||
|
||||
INLINE static int get_num_bits();
|
||||
INLINE bool get_bit(int index) const;
|
||||
INLINE void set_bit(int index);
|
||||
@ -59,10 +66,14 @@ PUBLISHED:
|
||||
|
||||
INLINE WordType extract(int low_bit, int size) const;
|
||||
INLINE void store(WordType value, int low_bit, int size);
|
||||
INLINE void set_range(int low_bit, int size);
|
||||
INLINE void clear_range(int low_bit, int size);
|
||||
INLINE void set_range_to(bool value, int low_bit, int size);
|
||||
INLINE WordType get_word() const;
|
||||
INLINE void set_word(WordType value);
|
||||
|
||||
INLINE void invert_in_place();
|
||||
INLINE bool has_bits_in_common(const BitMask<WType, nbits> &other) const;
|
||||
INLINE void clear();
|
||||
|
||||
void output(ostream &out) const;
|
||||
@ -70,32 +81,32 @@ PUBLISHED:
|
||||
void output_hex(ostream &out, int spaces_every = 4) const;
|
||||
void write(ostream &out, int indent_level = 0) const;
|
||||
|
||||
INLINE bool operator == (const BitMask<WordType, num_bits> &other) const;
|
||||
INLINE bool operator != (const BitMask<WordType, num_bits> &other) const;
|
||||
INLINE bool operator < (const BitMask<WordType, num_bits> &other) const;
|
||||
INLINE int compare_to(const BitMask<WordType, num_bits> &other) const;
|
||||
INLINE bool operator == (const BitMask<WType, nbits> &other) const;
|
||||
INLINE bool operator != (const BitMask<WType, nbits> &other) const;
|
||||
INLINE bool operator < (const BitMask<WType, nbits> &other) const;
|
||||
INLINE int compare_to(const BitMask<WType, nbits> &other) const;
|
||||
|
||||
INLINE BitMask<WordType, num_bits>
|
||||
operator & (const BitMask<WordType, num_bits> &other) const;
|
||||
INLINE BitMask<WType, nbits>
|
||||
operator & (const BitMask<WType, nbits> &other) const;
|
||||
|
||||
INLINE BitMask<WordType, num_bits>
|
||||
operator | (const BitMask<WordType, num_bits> &other) const;
|
||||
INLINE BitMask<WType, nbits>
|
||||
operator | (const BitMask<WType, nbits> &other) const;
|
||||
|
||||
INLINE BitMask<WordType, num_bits>
|
||||
operator ^ (const BitMask<WordType, num_bits> &other) const;
|
||||
INLINE BitMask<WType, nbits>
|
||||
operator ^ (const BitMask<WType, nbits> &other) const;
|
||||
|
||||
INLINE BitMask<WordType, num_bits>
|
||||
INLINE BitMask<WType, nbits>
|
||||
operator ~ () const;
|
||||
|
||||
INLINE BitMask<WordType, num_bits>
|
||||
INLINE BitMask<WType, nbits>
|
||||
operator << (int shift) const;
|
||||
|
||||
INLINE BitMask<WordType, num_bits>
|
||||
INLINE BitMask<WType, nbits>
|
||||
operator >> (int shift) const;
|
||||
|
||||
INLINE void operator &= (const BitMask<WordType, num_bits> &other);
|
||||
INLINE void operator |= (const BitMask<WordType, num_bits> &other);
|
||||
INLINE void operator ^= (const BitMask<WordType, num_bits> &other);
|
||||
INLINE void operator &= (const BitMask<WType, nbits> &other);
|
||||
INLINE void operator |= (const BitMask<WType, nbits> &other);
|
||||
INLINE void operator ^= (const BitMask<WType, nbits> &other);
|
||||
INLINE void operator <<= (int shift);
|
||||
INLINE void operator >>= (int shift);
|
||||
|
||||
@ -117,8 +128,8 @@ private:
|
||||
|
||||
#include "bitMask.I"
|
||||
|
||||
template<class WordType, int num_bits>
|
||||
INLINE ostream &operator << (ostream &out, const BitMask<WordType, num_bits> &bitmask) {
|
||||
template<class WType, int nbits>
|
||||
INLINE ostream &operator << (ostream &out, const BitMask<WType, nbits> &bitmask) {
|
||||
bitmask.output(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
@ -19,6 +19,8 @@
|
||||
#include "config_util.h"
|
||||
#include "animInterface.h"
|
||||
#include "bamReaderParam.h"
|
||||
#include "bitArray.h"
|
||||
#include "bitMask.h"
|
||||
#include "cachedTypedWritableReferenceCount.h"
|
||||
#include "clockObject.h"
|
||||
#include "configurable.h"
|
||||
@ -70,6 +72,8 @@ ConfigVariableSearchPath sound_path
|
||||
ConfigureFn(config_util) {
|
||||
AnimInterface::init_type();
|
||||
BamReaderParam::init_type();
|
||||
BitArray::init_type();
|
||||
BitMask32::init_type();
|
||||
CachedTypedWritableReferenceCount::init_type();
|
||||
Configurable::init_type();
|
||||
Datagram::init_type();
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include "bamReader.cxx"
|
||||
#include "bamReaderParam.cxx"
|
||||
#include "bamWriter.cxx"
|
||||
#include "bitArray.cxx"
|
||||
#include "bitMask.cxx"
|
||||
#include "buttonHandle.cxx"
|
||||
#include "buttonRegistry.cxx"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user