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> ©) : 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> ©) { 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 }