Panda3D

bitMask.I

00001 // Filename: bitMask.I
00002 // Created by:  drose (08Jun00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 template<class WType, int nbits>
00016 TypeHandle BitMask<WType, nbits>::_type_handle;
00017 
00018 ////////////////////////////////////////////////////////////////////
00019 //     Function: BitMask::Constructor
00020 //       Access: Published
00021 //  Description:
00022 ////////////////////////////////////////////////////////////////////
00023 template<class WType, int nbits>
00024 INLINE BitMask<WType, nbits>::
00025 BitMask() :
00026   _word(0)
00027 {
00028 }
00029 
00030 ////////////////////////////////////////////////////////////////////
00031 //     Function: BitMask::Constructor
00032 //       Access: Published
00033 //  Description:
00034 ////////////////////////////////////////////////////////////////////
00035 template<class WType, int nbits>
00036 INLINE BitMask<WType, nbits>::
00037 BitMask(WordType init_value) :
00038   _word(init_value)
00039 {
00040 }
00041 
00042 ////////////////////////////////////////////////////////////////////
00043 //     Function: BitMask::Copy Constructor
00044 //       Access: Published
00045 //  Description:
00046 ////////////////////////////////////////////////////////////////////
00047 template<class WType, int nbits>
00048 INLINE BitMask<WType, nbits>::
00049 BitMask(const BitMask<WType, nbits> &copy) :
00050   _word(copy._word)
00051 {
00052 }
00053 
00054 ////////////////////////////////////////////////////////////////////
00055 //     Function: BitMask::Copy Assignment Operator
00056 //       Access: Published
00057 //  Description:
00058 ////////////////////////////////////////////////////////////////////
00059 template<class WType, int nbits>
00060 INLINE BitMask<WType, nbits> &BitMask<WType, nbits>::
00061 operator = (const BitMask<WType, nbits> &copy) {
00062   _word = copy._word;
00063   return *this;
00064 }
00065 
00066 ////////////////////////////////////////////////////////////////////
00067 //     Function: BitMask::Named all_on constructor
00068 //       Access: Published, Static
00069 //  Description: Returns a BitMask whose bits are all on.
00070 ////////////////////////////////////////////////////////////////////
00071 template<class WType, int nbits>
00072 INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
00073 all_on() {
00074   BitMask result;
00075   result._word = (WordType)~0;
00076   return result;
00077 }
00078 
00079 ////////////////////////////////////////////////////////////////////
00080 //     Function: BitMask::Named all_on constructor
00081 //       Access: Published, Static
00082 //  Description: Returns a BitMask whose bits are all off.
00083 ////////////////////////////////////////////////////////////////////
00084 template<class WType, int nbits>
00085 INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
00086 all_off() {
00087   BitMask result;
00088   result._word = 0;
00089   return result;
00090 }
00091 
00092 ////////////////////////////////////////////////////////////////////
00093 //     Function: BitMask::Named lower_on constructor
00094 //       Access: Published, Static
00095 //  Description: Returns a BitMask whose lower on_bits bits are on.
00096 ////////////////////////////////////////////////////////////////////
00097 template<class WType, int nbits>
00098 INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
00099 lower_on(int on_bits) {
00100   if (on_bits <= 0) {
00101     return all_off();
00102   } else if (on_bits >= num_bits) {
00103     return all_on();
00104   }
00105   BitMask result;
00106   result._word = ((WordType)1 << on_bits) - 1;
00107   return result;
00108 }
00109 
00110 ////////////////////////////////////////////////////////////////////
00111 //     Function: BitMask::Named bit constructor
00112 //       Access: Published, Static
00113 //  Description: Returns a BitMask with only the indicated bit on.
00114 ////////////////////////////////////////////////////////////////////
00115 template<class WType, int nbits>
00116 INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
00117 bit(int index) {
00118   BitMask result;
00119   result.set_bit(index);
00120   return result;
00121 }
00122 
00123 ////////////////////////////////////////////////////////////////////
00124 //     Function: BitMask::Named range constructor
00125 //       Access: Published, Static
00126 //  Description: Returns a BitMask whose size bits, beginning at
00127 //               low_bit, are on.
00128 ////////////////////////////////////////////////////////////////////
00129 template<class WType, int nbits>
00130 INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
00131 range(int low_bit, int size) {
00132   BitMask result;
00133   if (size <= 0) {
00134     result._word = 0;
00135   } else if (size >= num_bits) {
00136     result._word = (WordType)~0;
00137   } else {
00138     result._word = ((WordType)1 << size) - 1;
00139   }
00140   result._word <<= low_bit;
00141   return result;
00142 }
00143 
00144 ////////////////////////////////////////////////////////////////////
00145 //     Function: BitMask::Destructor
00146 //       Access: Published
00147 //  Description:
00148 ////////////////////////////////////////////////////////////////////
00149 template<class WType, int nbits>
00150 INLINE BitMask<WType, nbits>::
00151 ~BitMask() {
00152 }
00153 
00154 ////////////////////////////////////////////////////////////////////
00155 //     Function: BitMask::has_max_num_bits
00156 //       Access: Published, Static
00157 //  Description: Returns true if there is a maximum number of bits
00158 //               that may be stored in this structure, false
00159 //               otherwise.  If this returns true, the number may be
00160 //               queried in get_max_num_bits().
00161 //
00162 //               This method always returns true.  This method is
00163 //               defined so generic programming algorithms can use
00164 //               BitMask or BitArray interchangeably.
00165 ////////////////////////////////////////////////////////////////////
00166 template<class WType, int nbits>
00167 INLINE bool BitMask<WType, nbits>::
00168 has_max_num_bits() {
00169   return true;
00170 }
00171 
00172 ////////////////////////////////////////////////////////////////////
00173 //     Function: BitMask::get_max_num_bits
00174 //       Access: Published, Static
00175 //  Description: If get_max_num_bits() returned true, this method may
00176 //               be called to return the maximum number of bits that
00177 //               may be stored in this structure.  It is an error to
00178 //               call this if get_max_num_bits() return false.
00179 //
00180 //               It is never an error to call this method.  This
00181 //               returns the same thing as get_num_bits().  This
00182 //               method is defined so generic programming algorithms
00183 //               can use BitMask or BitArray interchangeably.
00184 ////////////////////////////////////////////////////////////////////
00185 template<class WType, int nbits>
00186 INLINE int BitMask<WType, nbits>::
00187 get_max_num_bits() {
00188   return num_bits;
00189 }
00190 
00191 ////////////////////////////////////////////////////////////////////
00192 //     Function: BitMask::get_num_bits
00193 //       Access: Published, Static
00194 //  Description: Returns the number of bits available to set in the
00195 //               bitmask.
00196 ////////////////////////////////////////////////////////////////////
00197 template<class WType, int nbits>
00198 INLINE int BitMask<WType, nbits>::
00199 get_num_bits() {
00200   return num_bits;
00201 }
00202 
00203 ////////////////////////////////////////////////////////////////////
00204 //     Function: BitMask::get_bit
00205 //       Access: Published
00206 //  Description: Returns true if the nth bit is set, false if it is
00207 //               cleared.  index must be in the range [0,
00208 //               num_bits).
00209 ////////////////////////////////////////////////////////////////////
00210 template<class WType, int nbits>
00211 INLINE bool BitMask<WType, nbits>::
00212 get_bit(int index) const {
00213   nassertr(index >= 0 && index < num_bits, false);
00214   return (_word & ((WordType)1 << index)) != 0;
00215 }
00216 
00217 ////////////////////////////////////////////////////////////////////
00218 //     Function: BitMask::set_bit
00219 //       Access: Published
00220 //  Description: Sets the nth bit on.  index must be in the range
00221 //               [0, num_bits).
00222 ////////////////////////////////////////////////////////////////////
00223 template<class WType, int nbits>
00224 INLINE void BitMask<WType, nbits>::
00225 set_bit(int index) {
00226   nassertv(index >= 0 && index < num_bits);
00227   _word |= ((WordType)1 << index);
00228 }
00229 
00230 ////////////////////////////////////////////////////////////////////
00231 //     Function: BitMask::clear_bit
00232 //       Access: Published
00233 //  Description: Sets the nth bit off.  index must be in the range
00234 //               [0, num_bits).
00235 ////////////////////////////////////////////////////////////////////
00236 template<class WType, int nbits>
00237 INLINE void BitMask<WType, nbits>::
00238 clear_bit(int index) {
00239   nassertv(index >= 0 && index < num_bits);
00240   _word &= ~((WordType)1 << index);
00241 }
00242 
00243 ////////////////////////////////////////////////////////////////////
00244 //     Function: BitMask::set_bit_to
00245 //       Access: Published
00246 //  Description: Sets the nth bit either on or off, according to the
00247 //               indicated bool value.  index must be in the range [0,
00248 //               num_bits).
00249 ////////////////////////////////////////////////////////////////////
00250 template<class WType, int nbits>
00251 INLINE void BitMask<WType, nbits>::
00252 set_bit_to(int index, bool value) {
00253   if (value) {
00254     set_bit(index);
00255   } else {
00256     clear_bit(index);
00257   }
00258 }
00259 
00260 ////////////////////////////////////////////////////////////////////
00261 //     Function: BitMask::is_zero
00262 //       Access: Published
00263 //  Description: Returns true if the entire bitmask is zero, false
00264 //               otherwise.
00265 ////////////////////////////////////////////////////////////////////
00266 template<class WType, int nbits>
00267 INLINE bool BitMask<WType, nbits>::
00268 is_zero() const {
00269   return (_word == 0);
00270 }
00271 
00272 ////////////////////////////////////////////////////////////////////
00273 //     Function: BitMask::is_all_on
00274 //       Access: Published
00275 //  Description: Returns true if the entire bitmask is one, false
00276 //               otherwise.
00277 ////////////////////////////////////////////////////////////////////
00278 template<class WType, int nbits>
00279 INLINE bool BitMask<WType, nbits>::
00280 is_all_on() const {
00281   return (~_word == 0);
00282 }
00283 
00284 ////////////////////////////////////////////////////////////////////
00285 //     Function: BitMask::extract
00286 //       Access: Published
00287 //  Description: Returns a word that represents only the indicated
00288 //               range of bits within this BitMask, shifted to the
00289 //               least-significant position.
00290 ////////////////////////////////////////////////////////////////////
00291 template<class WType, int nbits>
00292 INLINE TYPENAME BitMask<WType, nbits>::WordType BitMask<WType, nbits>::
00293 extract(int low_bit, int size) const {
00294   return (_word >> low_bit) &
00295     BitMask<WType, nbits>::lower_on(size)._word;
00296 }
00297 
00298 ////////////////////////////////////////////////////////////////////
00299 //     Function: BitMask::store
00300 //       Access: Published
00301 //  Description: Stores the indicated word into the indicated range of
00302 //               bits with this BitMask.
00303 ////////////////////////////////////////////////////////////////////
00304 template<class WType, int nbits>
00305 INLINE void BitMask<WType, nbits>::
00306 store(WordType value, int low_bit, int size) {
00307   WordType mask = BitMask<WType, nbits>::range(low_bit, size)._word;
00308   _word = (_word & ~mask) | ((value << low_bit) & mask);
00309 }
00310 
00311 ////////////////////////////////////////////////////////////////////
00312 //     Function: BitMask::has_any_of
00313 //       Access: Published
00314 //  Description: Returns true if any bit in the indicated range is
00315 //               set, false otherwise.
00316 ////////////////////////////////////////////////////////////////////
00317 template<class WType, int nbits>
00318 INLINE bool BitMask<WType, nbits>::
00319 has_any_of(int low_bit, int size) const {
00320   WordType mask = BitMask<WType, nbits>::range(low_bit, size)._word;
00321   return (_word & mask) != 0;
00322 }
00323 
00324 ////////////////////////////////////////////////////////////////////
00325 //     Function: BitMask::has_all_of
00326 //       Access: Published
00327 //  Description: Returns true if all bits in the indicated range are
00328 //               set, false otherwise.
00329 ////////////////////////////////////////////////////////////////////
00330 template<class WType, int nbits>
00331 INLINE bool BitMask<WType, nbits>::
00332 has_all_of(int low_bit, int size) const {
00333   WordType mask = BitMask<WType, nbits>::range(low_bit, size)._word;
00334   return (_word & mask) == mask;
00335 }
00336 
00337 ////////////////////////////////////////////////////////////////////
00338 //     Function: BitMask::set_range
00339 //       Access: Published
00340 //  Description: Sets the indicated range of bits on.
00341 ////////////////////////////////////////////////////////////////////
00342 template<class WType, int nbits>
00343 INLINE void BitMask<WType, nbits>::
00344 set_range(int low_bit, int size) {
00345   WordType mask = BitMask<WType, nbits>::range(low_bit, size)._word;
00346   _word |= mask;
00347 }
00348 
00349 ////////////////////////////////////////////////////////////////////
00350 //     Function: BitMask::clear_range
00351 //       Access: Published
00352 //  Description: Sets the indicated range of bits off.
00353 ////////////////////////////////////////////////////////////////////
00354 template<class WType, int nbits>
00355 INLINE void BitMask<WType, nbits>::
00356 clear_range(int low_bit, int size) {
00357   WordType mask = BitMask<WType, nbits>::range(low_bit, size)._word;
00358   _word &= ~mask;
00359 }
00360 
00361 ////////////////////////////////////////////////////////////////////
00362 //     Function: BitMask::set_range_to
00363 //       Access: Published
00364 //  Description: Sets the indicated range of bits to either on or off.
00365 ////////////////////////////////////////////////////////////////////
00366 template<class WType, int nbits>
00367 INLINE void BitMask<WType, nbits>::
00368 set_range_to(bool value, int low_bit, int size) {
00369   if (value) {
00370     set_range(low_bit, size);
00371   } else {
00372     clear_range(low_bit, size);
00373   }
00374 }
00375 
00376 ////////////////////////////////////////////////////////////////////
00377 //     Function: BitMask::get_word
00378 //       Access: Published
00379 //  Description: Returns the entire BitMask as a single word.
00380 ////////////////////////////////////////////////////////////////////
00381 template<class WType, int nbits>
00382 INLINE TYPENAME BitMask<WType, nbits>::WordType BitMask<WType, nbits>::
00383 get_word() const {
00384   return _word;
00385 }
00386 
00387 ////////////////////////////////////////////////////////////////////
00388 //     Function: BitMask::set_word
00389 //       Access: Published
00390 //  Description: Sets the entire BitMask to the value indicated by the
00391 //               given word.
00392 ////////////////////////////////////////////////////////////////////
00393 template<class WType, int nbits>
00394 INLINE void BitMask<WType, nbits>::
00395 set_word(WordType value) {
00396   _word = value;
00397 }
00398 
00399 ////////////////////////////////////////////////////////////////////
00400 //     Function: BitMask::get_num_on_bits
00401 //       Access: Published
00402 //  Description: Returns the number of bits that are set to 1 in the
00403 //               mask.
00404 ////////////////////////////////////////////////////////////////////
00405 template<class WType, int nbits>
00406 INLINE int BitMask<WType, nbits>::
00407 get_num_on_bits() const {
00408   return count_bits_in_word((WType)_word);
00409 }
00410 
00411 ////////////////////////////////////////////////////////////////////
00412 //     Function: BitMask::get_num_off_bits
00413 //       Access: Published
00414 //  Description: Returns the number of bits that are set to 0 in the
00415 //               mask.
00416 ////////////////////////////////////////////////////////////////////
00417 template<class WType, int nbits>
00418 INLINE int BitMask<WType, nbits>::
00419 get_num_off_bits() const {
00420   return count_bits_in_word((WType)(~_word));
00421 }
00422 
00423 ////////////////////////////////////////////////////////////////////
00424 //     Function: BitMask::get_lowest_on_bit
00425 //       Access: Published
00426 //  Description: Returns the index of the lowest 1 bit in the mask.
00427 //               Returns -1 if there are no 1 bits.
00428 ////////////////////////////////////////////////////////////////////
00429 template<class WType, int nbits>
00430 INLINE int BitMask<WType, nbits>::
00431 get_lowest_on_bit() const {
00432   return ::get_lowest_on_bit(_word);
00433 }
00434 
00435 ////////////////////////////////////////////////////////////////////
00436 //     Function: BitMask::get_lowest_off_bit
00437 //       Access: Published
00438 //  Description: Returns the index of the lowest 0 bit in the mask.
00439 //               Returns -1 if there are no 0 bits.
00440 ////////////////////////////////////////////////////////////////////
00441 template<class WType, int nbits>
00442 INLINE int BitMask<WType, nbits>::
00443 get_lowest_off_bit() const {
00444   return (~(*this)).get_lowest_on_bit();
00445 }
00446 
00447 ////////////////////////////////////////////////////////////////////
00448 //     Function: BitMask::get_highest_on_bit
00449 //       Access: Published
00450 //  Description: Returns the index of the highest 1 bit in the mask.
00451 //               Returns -1 if there are no 1 bits.
00452 ////////////////////////////////////////////////////////////////////
00453 template<class WType, int nbits>
00454 INLINE int BitMask<WType, nbits>::
00455 get_highest_on_bit() const {
00456   return ::get_highest_on_bit(_word);
00457 }
00458 
00459 ////////////////////////////////////////////////////////////////////
00460 //     Function: BitMask::get_highest_off_bit
00461 //       Access: Published
00462 //  Description: Returns the index of the highest 0 bit in the mask.
00463 //               Returns -1 if there are no 0 bits.
00464 ////////////////////////////////////////////////////////////////////
00465 template<class WType, int nbits>
00466 INLINE int BitMask<WType, nbits>::
00467 get_highest_off_bit() const {
00468   return (~(*this)).get_highest_on_bit();
00469 }
00470 
00471 ////////////////////////////////////////////////////////////////////
00472 //     Function: BitMask::get_next_higher_different_bit
00473 //       Access: Published
00474 //  Description: Returns the index of the next bit in the mask, above
00475 //               low_bit, whose value is different that the value of
00476 //               low_bit.  Returns low_bit again if all bits higher
00477 //               than low_bit have the same value.
00478 //
00479 //               This can be used to quickly iterate through all of
00480 //               the bits in the mask.
00481 ////////////////////////////////////////////////////////////////////
00482 template<class WType, int nbits>
00483 INLINE int BitMask<WType, nbits>::
00484 get_next_higher_different_bit(int low_bit) const {
00485   // We are allowed to call this method with low_bit == num_bits,
00486   // which is the highest value this method will return.
00487   nassertr(low_bit >= 0, low_bit);
00488   if (low_bit >= num_bits) {
00489     return low_bit;
00490   }
00491 
00492   WordType is_on = (_word & ((WordType)1 << low_bit));
00493   WordType w;
00494   if (is_on) {
00495     // low_bit is 1.  Get the next higher 0 bit.  To do this, invert
00496     // the word and the get the next higher 1 bit.
00497     w = ~_word;
00498   } else {
00499     // low_bit is 0.  Get the next higher 1 bit.
00500     w = _word;
00501   }
00502 
00503   // Mask out all of the bits below low_bit.  Since we already know
00504   // that low_bit is 0, we can use (1 << low_bit) instead of (1 <<
00505   // (low_bit + 1)), which becomes undefined when (low_bit + 1) == 32.
00506   w &= ~((1 << low_bit) - 1);
00507 
00508   if (w == 0) {
00509     // All higher bits in the word have the same value.  Since every
00510     // bit after the topmost bit is 0, we either return the topmost
00511     // bit + 1 to indicate the next 0 bit, or low_bit to indicate we
00512     // have reached the end of the number of bits.
00513     return is_on ? num_bits : low_bit;
00514 
00515   } else {
00516     // Now determine the lowest 1 bit in the remaining word.  This
00517     // operation will clear out all bits except for the lowest 1 bit.
00518     w = (w & (~w + 1));
00519 
00520     // And the answer is the number of bits in (w - 1).
00521     return count_bits_in_word((WType)(w - 1));
00522   }
00523 }
00524 
00525 ////////////////////////////////////////////////////////////////////
00526 //     Function: BitMask::invert_in_place
00527 //       Access: Published
00528 //  Description: Inverts all the bits in the BitMask.  This is
00529 //               equivalent to mask = ~mask.
00530 ////////////////////////////////////////////////////////////////////
00531 template<class WType, int nbits>
00532 INLINE void BitMask<WType, nbits>::
00533 invert_in_place() {
00534   _word = ~_word;
00535 }
00536 
00537 ////////////////////////////////////////////////////////////////////
00538 //     Function: BitMask::has_bits_in_common
00539 //       Access: Published
00540 //  Description: Returns true if this BitMask has any "one" bits in
00541 //               common with the other one, false otherwise.
00542 //
00543 //               This is equivalent to (mask & other) != 0, but may be
00544 //               faster.  (Actually, it should only be faster in the
00545 //               BitArray case, but this method is provided for the
00546 //               benefit of generic programming algorithms).
00547 ////////////////////////////////////////////////////////////////////
00548 template<class WType, int nbits>
00549 INLINE bool BitMask<WType, nbits>::
00550 has_bits_in_common(const BitMask<WType, nbits> &other) const {
00551   return (_word & other._word) != 0;
00552 }
00553 
00554 ////////////////////////////////////////////////////////////////////
00555 //     Function: BitMask::clear
00556 //       Access: Published
00557 //  Description: Sets all the bits in the BitMask off.
00558 ////////////////////////////////////////////////////////////////////
00559 template<class WType, int nbits>
00560 INLINE void BitMask<WType, nbits>::
00561 clear() {
00562   _word = 0;
00563 }
00564 
00565 ////////////////////////////////////////////////////////////////////
00566 //     Function: BitMask::output
00567 //       Access: Published
00568 //  Description: Writes the BitMask out as a binary or a hex number,
00569 //               according to the number of bits.
00570 ////////////////////////////////////////////////////////////////////
00571 template<class WType, int nbits>
00572 void BitMask<WType, nbits>::
00573 output(ostream &out) const {
00574   if (num_bits >= 40) {
00575     output_hex(out);
00576   } else {
00577     output_binary(out);
00578   }
00579 }
00580 
00581 ////////////////////////////////////////////////////////////////////
00582 //     Function: BitMask::output_binary
00583 //       Access: Published
00584 //  Description: Writes the BitMask out as a binary number, with
00585 //               spaces every four bits.
00586 ////////////////////////////////////////////////////////////////////
00587 template<class WType, int nbits>
00588 void BitMask<WType, nbits>::
00589 output_binary(ostream &out, int spaces_every) const {
00590   for (int i = num_bits - 1; i >= 0; i--) {
00591     if (spaces_every != 0 && ((i % spaces_every) == spaces_every - 1)) {
00592       out << ' ';
00593     }
00594     out << (get_bit(i) ? '1' : '0');
00595   }
00596 }
00597 
00598 ////////////////////////////////////////////////////////////////////
00599 //     Function: BitMask::output_hex
00600 //       Access: Published
00601 //  Description: Writes the BitMask out as a hexadecimal number, with
00602 //               spaces every four digits.
00603 ////////////////////////////////////////////////////////////////////
00604 template<class WType, int nbits>
00605 void BitMask<WType, nbits>::
00606 output_hex(ostream &out, int spaces_every) const {
00607   int num_digits = (num_bits + 3) / 4;
00608 
00609   for (int i = num_digits - 1; i >= 0; i--) {
00610     WordType digit = extract(i * 4, 4);
00611     if (spaces_every != 0 && ((i % spaces_every) == spaces_every - 1)) {
00612       out << ' ';
00613     }
00614     if (digit > 9) {
00615       out << (char)(digit - 10 + 'a');
00616     } else {
00617       out << (char)(digit + '0');
00618     }
00619   }
00620 }
00621 
00622 ////////////////////////////////////////////////////////////////////
00623 //     Function: BitMask::write
00624 //       Access: Published
00625 //  Description: Writes the BitMask out as a binary or a hex number,
00626 //               according to the number of bits.
00627 ////////////////////////////////////////////////////////////////////
00628 template<class WType, int nbits>
00629 void BitMask<WType, nbits>::
00630 write(ostream &out, int indent_level) const {
00631   indent(out, indent_level) << *this << "\n";
00632 }
00633 
00634 ////////////////////////////////////////////////////////////////////
00635 //     Function: BitMask::operator ==
00636 //       Access: Published
00637 //  Description:
00638 ////////////////////////////////////////////////////////////////////
00639 template<class WType, int nbits>
00640 INLINE bool BitMask<WType, nbits>::
00641 operator == (const BitMask<WType, nbits> &other) const {
00642   return _word == other._word;
00643 }
00644 
00645 ////////////////////////////////////////////////////////////////////
00646 //     Function: BitMask::operator !=
00647 //       Access: Published
00648 //  Description:
00649 ////////////////////////////////////////////////////////////////////
00650 template<class WType, int nbits>
00651 INLINE bool BitMask<WType, nbits>::
00652 operator != (const BitMask<WType, nbits> &other) const {
00653   return _word != other._word;
00654 }
00655 
00656 ////////////////////////////////////////////////////////////////////
00657 //     Function: BitMask::operator <
00658 //       Access: Published
00659 //  Description: The ordering operator is of limited usefulness with a
00660 //               BitMask, however, it has a definition which places
00661 //               all unique BitMasks into a unique ordering.  It may
00662 //               be useful when defining ordered STL containers of
00663 //               BitMasks, for instance; and it's required in order to
00664 //               export any STL container (ordered or unordered) of
00665 //               BitMask under Windows.
00666 ////////////////////////////////////////////////////////////////////
00667 template<class WType, int nbits>
00668 INLINE bool BitMask<WType, nbits>::
00669 operator < (const BitMask<WType, nbits> &other) const {
00670   return _word < other._word;
00671 }
00672 
00673 ////////////////////////////////////////////////////////////////////
00674 //     Function: BitMask::compare_to
00675 //       Access: Published
00676 //  Description: Returns a number less than zero if this BitMask sorts
00677 //               before the indicated other BitMask, greater than zero
00678 //               if it sorts after, or 0 if they are equivalent.  This
00679 //               is based on the same ordering defined by operator <.
00680 ////////////////////////////////////////////////////////////////////
00681 template<class WType, int nbits>
00682 INLINE int BitMask<WType, nbits>::
00683 compare_to(const BitMask<WType, nbits> &other) const {
00684   if ((*this) < other) {
00685     return -1;
00686   } else if (other < (*this)) {
00687     return 1;
00688   } else {
00689     return 0;
00690   }
00691 }
00692 
00693 ////////////////////////////////////////////////////////////////////
00694 //     Function: BitMask::operator &
00695 //       Access: Published
00696 //  Description:
00697 ////////////////////////////////////////////////////////////////////
00698 template<class WType, int nbits>
00699 INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
00700 operator & (const BitMask<WType, nbits> &other) const {
00701   BitMask<WType, nbits> result(*this);
00702   result &= other;
00703   return result;
00704 }
00705 
00706 ////////////////////////////////////////////////////////////////////
00707 //     Function: BitMask::operator |
00708 //       Access: Published
00709 //  Description:
00710 ////////////////////////////////////////////////////////////////////
00711 template<class WType, int nbits>
00712 INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
00713 operator | (const BitMask<WType, nbits> &other) const {
00714   BitMask<WType, nbits> result(*this);
00715   result |= other;
00716   return result;
00717 }
00718 
00719 ////////////////////////////////////////////////////////////////////
00720 //     Function: BitMask::operator ^
00721 //       Access: Published
00722 //  Description:
00723 ////////////////////////////////////////////////////////////////////
00724 template<class WType, int nbits>
00725 INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
00726 operator ^ (const BitMask<WType, nbits> &other) const {
00727   BitMask<WType, nbits> result(*this);
00728   result ^= other;
00729   return result;
00730 }
00731 
00732 ////////////////////////////////////////////////////////////////////
00733 //     Function: BitMask::operator ~
00734 //       Access: Published
00735 //  Description:
00736 ////////////////////////////////////////////////////////////////////
00737 template<class WType, int nbits>
00738 INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
00739 operator ~ () const {
00740   return BitMask<WType, nbits>(~_word);
00741 }
00742 
00743 ////////////////////////////////////////////////////////////////////
00744 //     Function: BitMask::operator <<
00745 //       Access: Published
00746 //  Description:
00747 ////////////////////////////////////////////////////////////////////
00748 template<class WType, int nbits>
00749 INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
00750 operator << (int shift) const {
00751   BitMask<WType, nbits> result(*this);
00752   result <<= shift;
00753   return result;
00754 }
00755 
00756 ////////////////////////////////////////////////////////////////////
00757 //     Function: BitMask::operator >>
00758 //       Access: Published
00759 //  Description:
00760 ////////////////////////////////////////////////////////////////////
00761 template<class WType, int nbits>
00762 INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
00763 operator >> (int shift) const {
00764   BitMask<WType, nbits> result(*this);
00765   result >>= shift;
00766   return result;
00767 }
00768 
00769 ////////////////////////////////////////////////////////////////////
00770 //     Function: BitMask::operator &=
00771 //       Access: Published
00772 //  Description:
00773 ////////////////////////////////////////////////////////////////////
00774 template<class WType, int nbits>
00775 INLINE void BitMask<WType, nbits>::
00776 operator &= (const BitMask<WType, nbits> &other) {
00777   _word &= other._word;
00778 }
00779 
00780 ////////////////////////////////////////////////////////////////////
00781 //     Function: BitMask::operator |=
00782 //       Access: Published
00783 //  Description:
00784 ////////////////////////////////////////////////////////////////////
00785 template<class WType, int nbits>
00786 INLINE void BitMask<WType, nbits>::
00787 operator |= (const BitMask<WType, nbits> &other) {
00788   _word |= other._word;
00789 }
00790 
00791 ////////////////////////////////////////////////////////////////////
00792 //     Function: BitMask::operator ^=
00793 //       Access: Published
00794 //  Description:
00795 ////////////////////////////////////////////////////////////////////
00796 template<class WType, int nbits>
00797 INLINE void BitMask<WType, nbits>::
00798 operator ^= (const BitMask<WType, nbits> &other) {
00799   _word ^= other._word;
00800 }
00801 
00802 ////////////////////////////////////////////////////////////////////
00803 //     Function: BitMask::operator <<=
00804 //       Access: Published
00805 //  Description:
00806 ////////////////////////////////////////////////////////////////////
00807 template<class WType, int nbits>
00808 INLINE void BitMask<WType, nbits>::
00809 operator <<= (int shift) {
00810   _word <<= shift;
00811 }
00812 
00813 ////////////////////////////////////////////////////////////////////
00814 //     Function: BitMask::operator >>=
00815 //       Access: Published
00816 //  Description:
00817 ////////////////////////////////////////////////////////////////////
00818 template<class WType, int nbits>
00819 INLINE void BitMask<WType, nbits>::
00820 operator >>= (int shift) {
00821   _word >>= shift;
00822 }
00823 
00824 ////////////////////////////////////////////////////////////////////
00825 //     Function: BitMask::get_key
00826 //       Access: Published
00827 //  Description: Returns a mostly unique integer key per unique
00828 //               bitmask, suitable for using in a hash table.
00829 ////////////////////////////////////////////////////////////////////
00830 template<class WType, int nbits>
00831 INLINE int BitMask<WType, nbits>::
00832 get_key() const {
00833   return (int)_word;
00834 }
00835 
00836 ////////////////////////////////////////////////////////////////////
00837 //     Function: BitMask::generate_hash
00838 //       Access: Public
00839 //  Description: Adds the bitmask to the indicated hash generator.
00840 ////////////////////////////////////////////////////////////////////
00841 template<class WType, int nbits>
00842 INLINE void BitMask<WType, nbits>::
00843 generate_hash(ChecksumHashGenerator &hashgen) const {
00844   hashgen.add_int(_word);
00845 }
00846 
00847 ////////////////////////////////////////////////////////////////////
00848 //     Function: BitMask::init_type
00849 //       Access: Public
00850 //  Description:
00851 ////////////////////////////////////////////////////////////////////
00852 template<class WType, int nbits>
00853 void BitMask<WType, nbits>::
00854 init_type() {
00855   ostringstream str;
00856   str << "BitMask" << num_bits;
00857   register_type(_type_handle, str.str());
00858 }
00859 
00860 ////////////////////////////////////////////////////////////////////
00861 //     Function: BitMask::flood_up_in_place
00862 //       Access: Published
00863 //  Description: Floods this bitmask's bits upwards.
00864 ////////////////////////////////////////////////////////////////////
00865 template<class WType, int nbits>
00866 INLINE void BitMask<WType, nbits>::
00867 flood_up_in_place() {
00868   _word = ::flood_bits_up(_word);
00869 }
00870 
00871 ////////////////////////////////////////////////////////////////////
00872 //     Function: BitMask::flood_down_in_place
00873 //       Access: Published
00874 //  Description: Floods this bitmask's bits downwards.
00875 ////////////////////////////////////////////////////////////////////
00876 template<class WType, int nbits>
00877 INLINE void BitMask<WType, nbits>::
00878 flood_down_in_place() {
00879   _word = ::flood_bits_down(_word);
00880 }
00881 
00882 ////////////////////////////////////////////////////////////////////
00883 //     Function: BitMask::flood_bits_up
00884 //       Access: Published
00885 //  Description: Returns a BitMask with the bits flooded upwards.
00886 ////////////////////////////////////////////////////////////////////
00887 template<class WType, int nbits>
00888 INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
00889 flood_bits_up() const {
00890   BitMask<WType, nbits> result(::flood_bits_up(_word));
00891   return result;
00892 }
00893 
00894 ////////////////////////////////////////////////////////////////////
00895 //     Function: BitMask::flood_bits_down
00896 //       Access: Published
00897 //  Description: Returns a BitMask with the bits flooded down.
00898 ////////////////////////////////////////////////////////////////////
00899 template<class WType, int nbits>
00900 INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
00901 flood_bits_down() const {
00902   BitMask<WType, nbits> result(::flood_bits_down(_word));
00903   return result;
00904 }
00905 
00906 
00907 ////////////////////////////////////////////////////////////////////
00908 //     Function: BitMask::keep_next_highest_bit
00909 //       Access: Published
00910 //  Description: Returns a BitMask with only the next highest
00911 //               bit above the indicated bit on, or all_off.
00912 ////////////////////////////////////////////////////////////////////
00913 template<class WType, int nbits>
00914 INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
00915 keep_next_highest_bit() const {
00916   int low_bit = get_lowest_on_bit();
00917   if (low_bit >= 0) {
00918     return BitMask<WType, nbits>::bit(low_bit);
00919   } else {
00920     return BitMask<WType, nbits>::all_off();
00921   }
00922 }
00923 
00924 ////////////////////////////////////////////////////////////////////
00925 //     Function: BitMask::keep_next_lowest_bit
00926 //       Access: Published
00927 //  Description: Returns a BitMask with only the next lower
00928 //               bit below the indicated bit on, or all_off.
00929 ////////////////////////////////////////////////////////////////////
00930 template<class WType, int nbits>
00931 INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
00932 keep_next_lowest_bit() const {
00933   int high_bit = get_highest_on_bit();
00934   if (high_bit >= 0) {
00935     return BitMask<WType, nbits>::bit(high_bit);
00936   } else {
00937     return BitMask<WType, nbits>::all_off();
00938   }
00939 }
00940 
00941 ////////////////////////////////////////////////////////////////////
00942 //     Function: BitMask::keep_next_highest_bit
00943 //       Access: Published
00944 //  Description: Returns a BitMask with only the next highest
00945 //               bit above the indicated bit on, or all.
00946 ////////////////////////////////////////////////////////////////////
00947 template<class WType, int nbits>
00948 INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
00949 keep_next_highest_bit(int index) const {
00950   BitMask<WType, nbits> mask,temp;
00951   nassertr(index >= 0 && index < num_bits, mask);
00952   
00953   mask.set_bit(index); 
00954   mask.flood_down_in_place();
00955   mask.invert_in_place();
00956   mask &= *this;
00957   temp = mask;
00958 
00959   mask <<= 1;
00960   mask.flood_up_in_place();
00961   mask.invert_in_place();
00962   mask &= temp;
00963   
00964   return mask;
00965 }
00966 
00967 ////////////////////////////////////////////////////////////////////
00968 //     Function: BitMask::keep_next_lowest_bit
00969 //       Access: Published
00970 //  Description: Returns a BitMask with only the next lower
00971 //               bit below the indicated bit on, or all_off.
00972 ////////////////////////////////////////////////////////////////////
00973 template<class WType, int nbits>
00974 INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
00975 keep_next_lowest_bit(int index) const {
00976   BitMask<WType, nbits> mask, temp;
00977   nassertr(index >= 0 && index < num_bits, mask);
00978   
00979   mask.set_bit(index); 
00980   mask.flood_up_in_place();
00981   mask.invert_in_place();
00982   mask &= *this;
00983   temp = mask;
00984 
00985   mask >>= 1;
00986   mask.flood_down_in_place();
00987   mask.invert_in_place();
00988   mask &= temp;
00989   
00990   return mask;
00991 }
00992 
00993 ////////////////////////////////////////////////////////////////////
00994 //     Function: BitMask::keep_next_highest_bit
00995 //       Access: Published
00996 //  Description: Returns a BitMask with only the next highest "on"
00997 //               bit above all "on" bits in the passed in bitmask, or 
00998 //               all_off. If there are no "on" bits in the passed in 
00999 //               bitmask, it will return keep_next_highest_bit().
01000 ////////////////////////////////////////////////////////////////////
01001 template<class WType, int nbits>
01002 INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
01003 keep_next_highest_bit(const BitMask<WType, nbits> &other) const {
01004   int high_bit = other.get_highest_on_bit();
01005   if (high_bit >= 0) {
01006     return keep_next_highest_bit(high_bit);
01007   } else {
01008     return keep_next_highest_bit();
01009   }
01010 }
01011 
01012 ////////////////////////////////////////////////////////////////////
01013 //     Function: BitMask::keep_next_lowest_bit
01014 //       Access: Published
01015 //  Description: Returns a BitMask with only the next lowest "on"
01016 //               bit below all "on" bits in the passed in bitmask, or 
01017 //               all_off. If there are no "on" bits in the passed in 
01018 //               bitmask, it will return keep_next_lowest_bit().
01019 ////////////////////////////////////////////////////////////////////
01020 template<class WType, int nbits>
01021 INLINE BitMask<WType, nbits> BitMask<WType, nbits>::
01022 keep_next_lowest_bit(const BitMask<WType, nbits> &other) const {
01023   int low_bit = other.get_lowest_on_bit();
01024   if (low_bit >= 0) {
01025     return keep_next_lowest_bit(low_bit);
01026   } else {
01027     return keep_next_lowest_bit();
01028   }
01029 }
 All Classes Functions Variables Enumerations