Browse Source

add double, quad BitMask objects

David Rose 18 years ago
parent
commit
ceace684a2

+ 3 - 0
panda/src/putil/Sources.pp

@@ -32,6 +32,7 @@
     datagramInputFile.I datagramInputFile.h \
     datagramOutputFile.I datagramOutputFile.h \
     deferredDeletor.h \
+    doubleBitMask.I doubleBitMask.h \
     drawMask.h \
     factoryBase.I factoryBase.h \
     factoryParam.I factoryParam.h factoryParams.I \
@@ -81,6 +82,7 @@
     config_util.cxx configurable.cxx \
     datagramInputFile.cxx datagramOutputFile.cxx \
     deferredDeletor.cxx \
+    doubleBitMask.cxx \
     factoryBase.cxx \
     factoryParam.cxx factoryParams.cxx \
     globalPointerRegistry.cxx \
@@ -126,6 +128,7 @@
     datagramInputFile.I datagramInputFile.h \
     datagramOutputFile.I datagramOutputFile.h \
     deferredDeletor.h \
+    doubleBitMask.I doubleBitMask.h \
     drawMask.h \
     factoryBase.I factoryBase.h factoryParam.I factoryParam.h \
     factoryParams.I factoryParams.h \

+ 0 - 5
panda/src/putil/bamReader.N

@@ -1,5 +0,0 @@
-ignoremember _factory
-ignoremember get_factory
-
-ignoretype FactoryBase
-ignoretype Factory<TypedWriteable>

+ 16 - 0
panda/src/putil/config_util.N

@@ -0,0 +1,16 @@
+ignoremember _factory
+ignoremember get_factory
+
+ignoretype FactoryBase
+ignoretype Factory<TypedWriteable>
+
+forcetype string
+ignoremember rbegin
+ignoremember rend
+
+ignoreinvolved __reserve_t
+
+forcetype DoubleBitMaskNative
+renametype DoubleBitMaskNative DoubleBitMaskNative
+forcetype QuadBitMaskNative
+renametype QuadBitMaskNative QuadBitMaskNative

+ 745 - 0
panda/src/putil/doubleBitMask.I

@@ -0,0 +1,745 @@
+// Filename: doubleBitMask.I
+// Created by:  drose (08Jun00)
+//
+////////////////////////////////////////////////////////////////////
+//
+// 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
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+template<class BMType>
+TypeHandle DoubleBitMask<BMType>::_type_handle;
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::Constructor
+//       Access: Published
+//  Description:
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE DoubleBitMask<BMType>::
+DoubleBitMask() {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::Copy Constructor
+//       Access: Published
+//  Description:
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE DoubleBitMask<BMType>::
+DoubleBitMask(const DoubleBitMask<BMType> &copy) :
+  _lo(copy._lo),
+  _hi(copy._hi)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::Copy Assignment Operator
+//       Access: Published
+//  Description:
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE DoubleBitMask<BMType> &DoubleBitMask<BMType>::
+operator = (const DoubleBitMask<BMType> &copy) {
+  _lo = copy._lo;
+  _hi = copy._hi;
+  return *this;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::Named all_on constructor
+//       Access: Published, Static
+//  Description: Returns a DoubleBitMask whose bits are all on.
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE DoubleBitMask<BMType> DoubleBitMask<BMType>::
+all_on() {
+  DoubleBitMask<BMType> result;
+  result._lo = BitMaskType::all_on();
+  result._hi = BitMaskType::all_on();
+  return result;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::Named all_on constructor
+//       Access: Published, Static
+//  Description: Returns a DoubleBitMask whose bits are all off.
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE DoubleBitMask<BMType> DoubleBitMask<BMType>::
+all_off() {
+  DoubleBitMask<BMType> result;
+  result._lo.clear();
+  result._hi.clear();
+  return result;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::Named lower_on constructor
+//       Access: Published, Static
+//  Description: Returns a DoubleBitMask whose lower on_bits bits are on.
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE DoubleBitMask<BMType> DoubleBitMask<BMType>::
+lower_on(int on_bits) {
+  if (on_bits <= 0) {
+    return all_off();
+  } else if (on_bits >= num_bits) {
+    return all_on();
+  }
+  DoubleBitMask<BMType> result;
+  if (on_bits <= half_bits) {
+    result._lo = BitMaskType::lower_on(on_bits);
+  } else {
+    result._lo = BitMaskType::all_on();
+    result._hi = BitMaskType::lower_on(on_bits - half_bits);
+  }
+  return result;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::Named bit constructor
+//       Access: Published, Static
+//  Description: Returns a DoubleBitMask with only the indicated bit on.
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE DoubleBitMask<BMType> DoubleBitMask<BMType>::
+bit(int index) {
+  DoubleBitMask<BMType> result;
+  result.set_bit(index);
+  return result;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::Named range constructor
+//       Access: Published, Static
+//  Description: Returns a DoubleBitMask whose size bits, beginning at
+//               low_bit, are on.
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE DoubleBitMask<BMType> DoubleBitMask<BMType>::
+range(int low_bit, int size) {
+  DoubleBitMask<BMType> result;
+  result.set_range(low_bit, size);
+  return result;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::Destructor
+//       Access: Published
+//  Description:
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE DoubleBitMask<BMType>::
+~DoubleBitMask() {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::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
+//               DoubleBitMask or BitArray interchangeably.
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE bool DoubleBitMask<BMType>::
+has_max_num_bits() {
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::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 DoubleBitMask or BitArray interchangeably.
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE int DoubleBitMask<BMType>::
+get_max_num_bits() {
+  return num_bits;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::get_num_bits
+//       Access: Published, Static
+//  Description: Returns the number of bits available to set in the
+//               doubleBitMask.
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE int DoubleBitMask<BMType>::
+get_num_bits() {
+  return num_bits;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::get_bit
+//       Access: Published
+//  Description: Returns true if the nth bit is set, false if it is
+//               cleared.  index must be in the range [0,
+//               num_bits).
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE bool DoubleBitMask<BMType>::
+get_bit(int index) const {
+  if (index < half_bits) {
+    return _lo.get_bit(index);
+  } else {
+    return _hi.get_bit(index - half_bits);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::set_bit
+//       Access: Published
+//  Description: Sets the nth bit on.  index must be in the range
+//               [0, num_bits).
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE void DoubleBitMask<BMType>::
+set_bit(int index) {
+  if (index < half_bits) {
+    _lo.set_bit(index);
+  } else {
+    _hi.set_bit(index - half_bits);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::clear_bit
+//       Access: Published
+//  Description: Sets the nth bit off.  index must be in the range
+//               [0, num_bits).
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE void DoubleBitMask<BMType>::
+clear_bit(int index) {
+  if (index < half_bits) {
+    _lo.clear_bit(index);
+  } else {
+    _hi.clear_bit(index - half_bits);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::set_bit_to
+//       Access: Published
+//  Description: Sets the nth bit either on or off, according to the
+//               indicated bool value.  index must be in the range [0,
+//               num_bits).
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE void DoubleBitMask<BMType>::
+set_bit_to(int index, bool value) {
+  if (index < half_bits) {
+    _lo.set_bit_to(index, value);
+  } else {
+    _hi.set_bit_to(index - half_bits, value);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::is_zero
+//       Access: Published
+//  Description: Returns true if the entire doubleBitMask is zero, false
+//               otherwise.
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE bool DoubleBitMask<BMType>::
+is_zero() const {
+  return (_lo.is_zero() && _hi.is_zero());
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::is_all_on
+//       Access: Published
+//  Description: Returns true if the entire doubleBitMask is one, false
+//               otherwise.
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE bool DoubleBitMask<BMType>::
+is_all_on() const {
+  return (_lo.is_all_on() && _hi.is_all_on());
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::extract
+//       Access: Published
+//  Description: Returns a word that represents only the indicated
+//               range of bits within this DoubleBitMask, shifted to the
+//               least-significant position.
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE TYPENAME DoubleBitMask<BMType>::WordType DoubleBitMask<BMType>::
+extract(int low_bit, int size) const {
+  if (low_bit >= half_bits) {
+    return _hi.extract(low_bit - half_bits, size);
+  } else if (low_bit + size < half_bits) {
+    return _lo.extract(low_bit, size);
+  } else {
+    int hi_portion = low_bit + size - half_bits;
+    int lo_portion = size - hi_portion;
+    return (_hi.extract(0, hi_portion) << lo_portion) |
+      _lo.extract(low_bit, lo_portion);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::store
+//       Access: Published
+//  Description: Stores the indicated word into the indicated range of
+//               bits with this DoubleBitMask.
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE void DoubleBitMask<BMType>::
+store(WordType value, int low_bit, int size) {
+  if (low_bit >= half_bits) {
+    _hi.store(value, low_bit - half_bits, size);
+  } else if (low_bit + size < half_bits) {
+    _lo.store(value, low_bit, size);
+  } else {
+    int hi_portion = low_bit + size - half_bits;
+    int lo_portion = size - hi_portion;
+
+    _hi.store(value >> lo_portion, 0, hi_portion);
+    _lo.store(value, low_bit, lo_portion);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::has_any_of
+//       Access: Published
+//  Description: Returns true if any bit in the indicated range is
+//               set, false otherwise.
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE bool DoubleBitMask<BMType>::
+has_any_of(int low_bit, int size) const {
+  if (low_bit >= half_bits) {
+    return _hi.has_any_of(low_bit - half_bits, size);
+  } else if (low_bit + size < half_bits) {
+    return _lo.has_any_of(low_bit, size);
+  } else {
+    int hi_portion = low_bit + size - half_bits;
+    int lo_portion = size - hi_portion;
+    return (_hi.has_any_of(0, hi_portion) << lo_portion) ||
+      _lo.has_any_of(low_bit, lo_portion);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::has_all_of
+//       Access: Published
+//  Description: Returns true if all bits in the indicated range are
+//               set, false otherwise.
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE bool DoubleBitMask<BMType>::
+has_all_of(int low_bit, int size) const {
+  if (low_bit >= half_bits) {
+    return _hi.has_all_of(low_bit - half_bits, size);
+  } else if (low_bit + size < half_bits) {
+    return _lo.has_all_of(low_bit, size);
+  } else {
+    int hi_portion = low_bit + size - half_bits;
+    int lo_portion = size - hi_portion;
+    return (_hi.has_all_of(0, hi_portion) << lo_portion) &&
+      _lo.has_all_of(low_bit, lo_portion);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::set_range
+//       Access: Published
+//  Description: Sets the indicated range of bits on.
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE void DoubleBitMask<BMType>::
+set_range(int low_bit, int size) {
+  if (low_bit >= half_bits) {
+    _hi.set_range(low_bit - half_bits, size);
+  } else if (low_bit + size < half_bits) {
+    _lo.set_range(low_bit, size);
+  } else {
+    int hi_portion = low_bit + size - half_bits;
+    int lo_portion = size - hi_portion;
+
+    _hi.set_range(0, hi_portion);
+    _lo.set_range(low_bit, lo_portion);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::clear_range
+//       Access: Published
+//  Description: Sets the indicated range of bits off.
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE void DoubleBitMask<BMType>::
+clear_range(int low_bit, int size) {
+  if (low_bit >= half_bits) {
+    _hi.clear_range(low_bit - half_bits, size);
+  } else if (low_bit + size < half_bits) {
+    _lo.clear_range(low_bit, size);
+  } else {
+    int hi_portion = low_bit + size - half_bits;
+    int lo_portion = size - hi_portion;
+
+    _hi.clear_range(0, hi_portion);
+    _lo.clear_range(low_bit, lo_portion);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::set_range_to
+//       Access: Published
+//  Description: Sets the indicated range of bits to either on or off.
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE void DoubleBitMask<BMType>::
+set_range_to(bool value, int low_bit, int size) {
+  if (value) {
+    set_range(low_bit, size);
+  } else {
+    clear_range(low_bit, size);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::invert_in_place
+//       Access: Published
+//  Description: Inverts all the bits in the DoubleBitMask.  This is
+//               equivalent to mask = ~mask.
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE void DoubleBitMask<BMType>::
+invert_in_place() {
+  _lo.invert_in_place();
+  _hi.invert_in_place();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::has_bits_in_common
+//       Access: Published
+//  Description: Returns true if this DoubleBitMask 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 BMType>
+INLINE bool DoubleBitMask<BMType>::
+has_bits_in_common(const DoubleBitMask<BMType> &other) const {
+  return _lo.has_bits_in_common(other._lo) || 
+    _hi.has_bits_in_common(other._hi);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::clear
+//       Access: Published
+//  Description: Sets all the bits in the DoubleBitMask off.
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE void DoubleBitMask<BMType>::
+clear() {
+  _lo.clear();
+  _hi.clear();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::output
+//       Access: Published
+//  Description: Writes the DoubleBitMask out as a binary or a hex number,
+//               according to the number of bits.
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+void DoubleBitMask<BMType>::
+output(ostream &out) const {
+  output_hex(out);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::output_binary
+//       Access: Published
+//  Description: Writes the DoubleBitMask out as a binary number, with
+//               spaces every four bits.
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+void DoubleBitMask<BMType>::
+output_binary(ostream &out, int spaces_every) const {
+  _hi.output_binary(out);
+  out << ' ';
+  _lo.output_binary(out);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::output_hex
+//       Access: Published
+//  Description: Writes the DoubleBitMask out as a hexadecimal number, with
+//               spaces every four digits.
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+void DoubleBitMask<BMType>::
+output_hex(ostream &out, int spaces_every) const {
+  _hi.output_hex(out);
+  out << ' ';
+  _lo.output_hex(out);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::write
+//       Access: Published
+//  Description: Writes the DoubleBitMask out as a binary or a hex number,
+//               according to the number of bits.
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+void DoubleBitMask<BMType>::
+write(ostream &out, int indent_level) const {
+  indent(out, indent_level) << *this << "\n";
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::operator ==
+//       Access: Published
+//  Description:
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE bool DoubleBitMask<BMType>::
+operator == (const DoubleBitMask<BMType> &other) const {
+  return _lo == other._lo && _hi == other._hi;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::operator !=
+//       Access: Published
+//  Description:
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE bool DoubleBitMask<BMType>::
+operator != (const DoubleBitMask<BMType> &other) const {
+  return _lo != other._lo && _hi != other._hi;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::operator <
+//       Access: Published
+//  Description: The ordering operator is of limited usefulness with a
+//               DoubleBitMask, however, it has a definition which places
+//               all unique DoubleBitMasks into a unique ordering.  It may
+//               be useful when defining ordered STL containers of
+//               DoubleBitMasks, for instance; and it's required in order to
+//               export any STL container (ordered or unordered) of
+//               DoubleBitMask under Windows.
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE bool DoubleBitMask<BMType>::
+operator < (const DoubleBitMask<BMType> &other) const {
+  int cmp = _hi.compare_to(other._hi);
+  if (cmp != 0) {
+    return cmp < 0;
+  }
+  return _lo < other._lo;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::compare_to
+//       Access: Published
+//  Description: Returns a number less than zero if this DoubleBitMask sorts
+//               before the indicated other DoubleBitMask, greater than zero
+//               if it sorts after, or 0 if they are equivalent.  This
+//               is based on the same ordering defined by operator <.
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE int DoubleBitMask<BMType>::
+compare_to(const DoubleBitMask<BMType> &other) const {
+  int cmp = _hi.compare_to(other._hi);
+  if (cmp != 0) {
+    return cmp;
+  }
+  return _lo.compare_to(other._lo);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::operator &
+//       Access: Published
+//  Description:
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE DoubleBitMask<BMType> DoubleBitMask<BMType>::
+operator & (const DoubleBitMask<BMType> &other) const {
+  DoubleBitMask<BMType> result(*this);
+  result &= other;
+  return result;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::operator |
+//       Access: Published
+//  Description:
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE DoubleBitMask<BMType> DoubleBitMask<BMType>::
+operator | (const DoubleBitMask<BMType> &other) const {
+  DoubleBitMask<BMType> result(*this);
+  result |= other;
+  return result;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::operator ^
+//       Access: Published
+//  Description:
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE DoubleBitMask<BMType> DoubleBitMask<BMType>::
+operator ^ (const DoubleBitMask<BMType> &other) const {
+  DoubleBitMask<BMType> result(*this);
+  result ^= other;
+  return result;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::operator ~
+//       Access: Published
+//  Description:
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE DoubleBitMask<BMType> DoubleBitMask<BMType>::
+operator ~ () const {
+  DoubleBitMask<BMType> result(*this);
+  result.invert_in_place();
+  return result;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::operator <<
+//       Access: Published
+//  Description:
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE DoubleBitMask<BMType> DoubleBitMask<BMType>::
+operator << (int shift) const {
+  DoubleBitMask<BMType> result(*this);
+  result <<= shift;
+  return result;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::operator >>
+//       Access: Published
+//  Description:
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE DoubleBitMask<BMType> DoubleBitMask<BMType>::
+operator >> (int shift) const {
+  DoubleBitMask<BMType> result(*this);
+  result >>= shift;
+  return result;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::operator &=
+//       Access: Published
+//  Description:
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE void DoubleBitMask<BMType>::
+operator &= (const DoubleBitMask<BMType> &other) {
+  _lo &= other._lo;
+  _hi &= other._hi;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::operator |=
+//       Access: Published
+//  Description:
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE void DoubleBitMask<BMType>::
+operator |= (const DoubleBitMask<BMType> &other) {
+  _lo |= other._lo;
+  _hi |= other._hi;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::operator ^=
+//       Access: Published
+//  Description:
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE void DoubleBitMask<BMType>::
+operator ^= (const DoubleBitMask<BMType> &other) {
+  _lo ^= other._lo;
+  _hi ^= other._hi;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::operator <<=
+//       Access: Published
+//  Description:
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE void DoubleBitMask<BMType>::
+operator <<= (int shift) {
+  _hi = (_hi << shift) | ((_lo >> half_bits - shift) & BitMaskType::lower_on(shift));
+  _lo <<= shift;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::operator >>=
+//       Access: Published
+//  Description:
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE void DoubleBitMask<BMType>::
+operator >>= (int shift) {
+  _lo = (_lo >> shift) | ((_hi & BitMaskType::lower_on(shift)) << half_bits - shift);
+  _hi >>= shift;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::generate_hash
+//       Access: Public
+//  Description: Adds the doubleBitMask to the indicated hash generator.
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+INLINE void DoubleBitMask<BMType>::
+generate_hash(ChecksumHashGenerator &hashgen) const {
+  _hi.generate_hash(hashgen);
+  _lo.generate_hash(hashgen);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DoubleBitMask::init_type
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+void DoubleBitMask<BMType>::
+init_type() {
+  ostringstream str;
+  str << "DoubleBitMask" << num_bits;
+  register_type(_type_handle, str.str());
+}

+ 25 - 0
panda/src/putil/doubleBitMask.cxx

@@ -0,0 +1,25 @@
+// Filename: doubleBitMask.cxx
+// Created by:  drose (08Jun00)
+//
+////////////////////////////////////////////////////////////////////
+//
+// 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
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "doubleBitMask.h"
+
+// Tell GCC that we'll take care of the instantiation explicitly here.
+#ifdef __GNUC__
+#pragma implementation
+#endif
+

+ 149 - 0
panda/src/putil/doubleBitMask.h

@@ -0,0 +1,149 @@
+// Filename: doubleBitMask.h
+// Created by:  drose (08Jun00)
+//
+////////////////////////////////////////////////////////////////////
+//
+// 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
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef DOUBLEBITMASK_H
+#define DOUBLEBITMASK_H
+
+#include "pandabase.h"
+
+#include "bitMask.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : DoubleBitMask
+// Description : This is a special BitMask type that is implemented as
+//               a pair of lesser BitMask types, to present a
+//               double-wide bit mask.  For instance, on a 32-bit
+//               system, this can be used to make a single 64-bit bit
+//               mask.  More of these can be ganged up together to
+//               make a 128-bit mask, and so on.
+////////////////////////////////////////////////////////////////////
+template<class BMType>
+class DoubleBitMask {
+public:
+  typedef BMType BitMaskType;
+  typedef TYPENAME BMType::WordType WordType;
+#ifndef CPPPARSER  // interrogate has a problem with these lines.
+  enum { 
+    half_bits = BitMaskType::num_bits,
+    num_bits = BitMaskType::num_bits * 2,
+  };
+#endif  // CPPPARSER
+
+PUBLISHED:
+  INLINE DoubleBitMask();
+  INLINE DoubleBitMask(const DoubleBitMask<BMType> &copy);
+  INLINE DoubleBitMask<BMType> &operator = (const DoubleBitMask<BMType> &copy);
+
+  INLINE static DoubleBitMask<BMType> all_on();
+  INLINE static DoubleBitMask<BMType> all_off();
+  INLINE static DoubleBitMask<BMType> lower_on(int on_bits);
+  INLINE static DoubleBitMask<BMType> bit(int index);
+  INLINE static DoubleBitMask<BMType> range(int low_bit, int size);
+
+  INLINE ~DoubleBitMask();
+
+  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);
+  INLINE void clear_bit(int index);
+  INLINE void set_bit_to(int index, bool value);
+  INLINE bool is_zero() const;
+  INLINE bool is_all_on() const;
+
+  INLINE WordType extract(int low_bit, int size) const;
+  INLINE void store(WordType value, int low_bit, int size);
+  INLINE bool has_any_of(int low_bit, int size) const;
+  INLINE bool has_all_of(int low_bit, int size) const;
+  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 void invert_in_place();
+  INLINE bool has_bits_in_common(const DoubleBitMask<BMType> &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 DoubleBitMask<BMType> &other) const;
+  INLINE bool operator != (const DoubleBitMask<BMType> &other) const;
+  INLINE bool operator < (const DoubleBitMask<BMType> &other) const;
+  INLINE int compare_to(const DoubleBitMask<BMType> &other) const;
+
+  INLINE DoubleBitMask<BMType>
+  operator & (const DoubleBitMask<BMType> &other) const;
+
+  INLINE DoubleBitMask<BMType>
+  operator | (const DoubleBitMask<BMType> &other) const;
+
+  INLINE DoubleBitMask<BMType>
+  operator ^ (const DoubleBitMask<BMType> &other) const;
+
+  INLINE DoubleBitMask<BMType>
+  operator ~ () const;
+
+  INLINE DoubleBitMask<BMType>
+  operator << (int shift) const;
+
+  INLINE DoubleBitMask<BMType>
+  operator >> (int shift) const;
+
+  INLINE void operator &= (const DoubleBitMask<BMType> &other);
+  INLINE void operator |= (const DoubleBitMask<BMType> &other);
+  INLINE void operator ^= (const DoubleBitMask<BMType> &other);
+  INLINE void operator <<= (int shift);
+  INLINE void operator >>= (int shift);
+
+public:
+  INLINE void generate_hash(ChecksumHashGenerator &hashgen) const;
+
+private:
+  BitMaskType _hi, _lo;
+
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type();
+
+private:
+  static TypeHandle _type_handle;
+};
+
+#include "doubleBitMask.I"
+
+template<class BMType>
+INLINE ostream &operator << (ostream &out, const DoubleBitMask<BMType> &doubleBitMask) {
+  doubleBitMask.output(out);
+  return out;
+}
+
+typedef DoubleBitMask<BitMaskNative> DoubleBitMaskNative;
+typedef DoubleBitMask<DoubleBitMaskNative> QuadBitMaskNative;
+
+// Tell GCC that we'll take care of the instantiation explicitly here.
+#ifdef __GNUC__
+#pragma interface
+#endif
+
+#endif

+ 1 - 0
panda/src/putil/putil_composite1.cxx

@@ -18,6 +18,7 @@
 #include "datagramInputFile.cxx"
 #include "datagramOutputFile.cxx"
 #include "deferredDeletor.cxx"
+#include "doubleBitMask.cxx"
 #include "factoryBase.cxx"
 #include "factoryParam.cxx"
 #include "factoryParams.cxx"

+ 0 - 5
panda/src/putil/string_utils.N

@@ -1,5 +0,0 @@
-forcetype string
-ignoremember rbegin
-ignoremember rend
-
-ignoreinvolved __reserve_t