open_toontown_panda3d/panda/src/putil/sparseArray.I

575 lines
20 KiB
Plaintext

// Filename: sparseArray.I
// Created by: drose (14Feb07)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: SparseArray::Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE SparseArray::
SparseArray() : _inverse(false) {
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::Copy Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE SparseArray::
SparseArray(const SparseArray &copy) :
_subranges(copy._subranges),
_inverse(copy._inverse)
{
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::Copy Assignment Operator
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE SparseArray &SparseArray::
operator = (const SparseArray &copy) {
_subranges = copy._subranges;
_inverse = copy._inverse;
return *this;
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::Named all_on constructor
// Access: Published, Static
// Description: Returns a SparseArray with an infinite array of bits,
// all on.
////////////////////////////////////////////////////////////////////
INLINE SparseArray SparseArray::
all_on() {
SparseArray result;
result._inverse = true;
return result;
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::Named all_on constructor
// Access: Published, Static
// Description: Returns a SparseArray whose bits are all off.
////////////////////////////////////////////////////////////////////
INLINE SparseArray SparseArray::
all_off() {
return SparseArray();
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::Named lower_on constructor
// Access: Published, Static
// Description: Returns a SparseArray whose lower on_bits bits are on.
////////////////////////////////////////////////////////////////////
INLINE SparseArray SparseArray::
lower_on(int on_bits) {
SparseArray result;
result.set_range(0, on_bits);
return result;
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::Named bit constructor
// Access: Published, Static
// Description: Returns a SparseArray with only the indicated bit on.
////////////////////////////////////////////////////////////////////
INLINE SparseArray SparseArray::
bit(int index) {
SparseArray result;
result.set_bit(index);
return result;
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::Named range constructor
// Access: Published, Static
// Description: Returns a SparseArray whose size bits, beginning at
// low_bit, are on.
////////////////////////////////////////////////////////////////////
INLINE SparseArray SparseArray::
range(int low_bit, int size) {
SparseArray result;
result.set_range(low_bit, size);
return result;
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::Destructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE SparseArray::
~SparseArray() {
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::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 SparseArray has
// no maximum number of bits. This method is defined so
// generic programming algorithms can use BitMask or
// SparseArray interchangeably.
////////////////////////////////////////////////////////////////////
INLINE bool SparseArray::
has_max_num_bits() {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::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
// SparseArray has no maximum number of bits. This method
// is defined so generic programming algorithms can use
// BitMask or SparseArray interchangeably.
////////////////////////////////////////////////////////////////////
INLINE int SparseArray::
get_max_num_bits() {
nassertr(false, 0);
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::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 SparseArray::
get_num_bits() const {
if (_subranges.empty()) {
return 0;
} else {
Subranges::const_iterator si = _subranges.begin() + _subranges.size() - 1;
return (*si)._end;
}
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::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 SparseArray::
get_bit(int index) const {
return has_any_of(index, 1);
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::set_bit
// Access: Published
// Description: Sets the nth bit on. If n >= get_num_bits(), this
// automatically extends the array.
////////////////////////////////////////////////////////////////////
INLINE void SparseArray::
set_bit(int index) {
set_range(index, 1);
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::clear_bit
// Access: Published
// Description: Sets the nth bit off. If n >= get_num_bits(), this
// automatically extends the array.
////////////////////////////////////////////////////////////////////
INLINE void SparseArray::
clear_bit(int index) {
clear_range(index, 1);
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::set_bit_to
// Access: Published
// Description: Sets the nth bit either on or off, according to the
// indicated bool value.
////////////////////////////////////////////////////////////////////
INLINE void SparseArray::
set_bit_to(int index, bool value) {
if (value) {
set_bit(index);
} else {
clear_bit(index);
}
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::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 SparseArray::
get_highest_bits() const {
return _inverse;
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::is_zero
// Access: Published
// Description: Returns true if the entire bitmask is zero, false
// otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool SparseArray::
is_zero() const {
if (_inverse) {
return false;
} else {
return _subranges.empty();
}
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::is_all_on
// Access: Published
// Description: Returns true if the entire bitmask is one, false
// otherwise.
////////////////////////////////////////////////////////////////////
bool SparseArray::
is_all_on() const {
if (_inverse) {
return _subranges.empty();
} else {
return false;
}
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::has_any_of
// Access: Published
// Description: Returns true if any bit in the indicated range is
// set, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool SparseArray::
has_any_of(int low_bit, int size) const {
if (_inverse) {
return !do_has_all(low_bit, low_bit + size);
} else {
return do_has_any(low_bit, low_bit + size);
}
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::has_all_of
// Access: Published
// Description: Returns true if all bits in the indicated range are
// set, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool SparseArray::
has_all_of(int low_bit, int size) const {
if (_inverse) {
return !do_has_any(low_bit, low_bit + size);
} else {
return do_has_all(low_bit, low_bit + size);
}
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::set_range
// Access: Published
// Description: Sets the indicated range of bits on.
////////////////////////////////////////////////////////////////////
INLINE void SparseArray::
set_range(int low_bit, int size) {
if (_inverse) {
return do_remove_range(low_bit, low_bit + size);
} else {
return do_add_range(low_bit, low_bit + size);
}
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::clear_range
// Access: Published
// Description: Sets the indicated range of bits off.
////////////////////////////////////////////////////////////////////
INLINE void SparseArray::
clear_range(int low_bit, int size) {
if (_inverse) {
return do_add_range(low_bit, low_bit + size);
} else {
return do_remove_range(low_bit, low_bit + size);
}
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::set_range_to
// Access: Published
// Description: Sets the indicated range of bits to either on or off.
////////////////////////////////////////////////////////////////////
INLINE void SparseArray::
set_range_to(bool value, int low_bit, int size) {
if (value) {
set_range(low_bit, size);
} else {
clear_range(low_bit, size);
}
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::invert_in_place
// Access: Published
// Description: Inverts all the bits in the SparseArray. This is
// equivalent to array = ~array.
////////////////////////////////////////////////////////////////////
void SparseArray::
invert_in_place() {
_inverse = !_inverse;
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::clear
// Access: Published
// Description: Sets all the bits in the SparseArray off.
////////////////////////////////////////////////////////////////////
void SparseArray::
clear() {
_subranges.clear();
_inverse = false;
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::operator ==
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool SparseArray::
operator == (const SparseArray &other) const {
return compare_to(other) == 0;
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::operator !=
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool SparseArray::
operator != (const SparseArray &other) const {
return compare_to(other) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::operator <
// Access: Published
// Description: Returns true if the unsigned integer which is
// represented by this SparseArray is less than that of the
// other one, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool SparseArray::
operator < (const SparseArray &other) const {
return compare_to(other) < 0;
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::operator &
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE SparseArray SparseArray::
operator & (const SparseArray &other) const {
SparseArray result(*this);
result &= other;
return result;
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::operator |
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE SparseArray SparseArray::
operator | (const SparseArray &other) const {
SparseArray result(*this);
result |= other;
return result;
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::operator ^
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE SparseArray SparseArray::
operator ^ (const SparseArray &other) const {
SparseArray result(*this);
result ^= other;
return result;
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::operator ~
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE SparseArray SparseArray::
operator ~ () const {
SparseArray result(*this);
result.invert_in_place();
return result;
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::operator <<
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE SparseArray SparseArray::
operator << (int shift) const {
SparseArray result(*this);
result <<= shift;
return result;
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::operator >>
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE SparseArray SparseArray::
operator >> (int shift) const {
SparseArray result(*this);
result >>= shift;
return result;
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::operator <<=
// Access: Published
// Description: Logical left shift. Since negative bit positions
// have meaning in a SparseArray, real bit values are
// rotated in on the left (not necessarily zero).
////////////////////////////////////////////////////////////////////
void SparseArray::
operator <<= (int shift) {
do_shift(shift);
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::operator >>=
// Access: Published
// Description: Logical right shift. The rightmost bits become
// negative, but are not lost; they will reappear into
// the zero position if the array is later left-shifted.
////////////////////////////////////////////////////////////////////
void SparseArray::
operator >>= (int shift) {
do_shift(-shift);
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::is_inverse
// Access: Published
// Description: If this is true, the SparseArray is actually defined
// as a list of subranges of integers that are *not* in
// the set. If this is false (the default), then the
// subranges define the integers that *are* in the set.
// This affects the interpretation of the values
// returned by iterating through get_num_subranges().
////////////////////////////////////////////////////////////////////
INLINE bool SparseArray::
is_inverse() const {
return _inverse;
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::get_num_subranges
// Access: Published
// Description: Returns the number of separate subranges stored in
// the SparseArray. You can use this limit to iterate
// through the subranges, calling get_subrange_begin()
// and get_subrange_end() for each one.
//
// Also see is_inverse().
////////////////////////////////////////////////////////////////////
INLINE int SparseArray::
get_num_subranges() const {
return _subranges.size();
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::get_subrange_begin
// Access: Published
// Description: Returns the first numeric element in the nth
// subrange.
//
// Also see is_inverse().
////////////////////////////////////////////////////////////////////
INLINE int SparseArray::
get_subrange_begin(int n) const {
nassertr(n >= 0 && n < (int)_subranges.size(), 0);
return _subranges[n]._begin;
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::get_subrange_end
// Access: Published
// Description: Returns the last numeric element, plus one, in the
// nth subrange.
//
// Also see is_inverse().
////////////////////////////////////////////////////////////////////
INLINE int SparseArray::
get_subrange_end(int n) const {
nassertr(n >= 0 && n < (int)_subranges.size(), 0);
return _subranges[n]._end;
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::Subrange::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE SparseArray::Subrange::
Subrange(int begin, int end) :
_begin(begin),
_end(end)
{
}
////////////////////////////////////////////////////////////////////
// Function: SparseArray::Subrange::operator <
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool SparseArray::Subrange::
operator < (const SparseArray::Subrange &other) const {
// We compare the end values, rather than the begin values, to make
// lower_bound() sensibly return a possible intersection with the
// indicated Subrange.
return _end < other._end;
}