Panda3D
bitMask.I
1 // Filename: bitMask.I
2 // Created by: drose (08Jun00)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 template<class WType, int nbits>
17 
18 ////////////////////////////////////////////////////////////////////
19 // Function: BitMask::Constructor
20 // Access: Published
21 // Description:
22 ////////////////////////////////////////////////////////////////////
23 template<class WType, int nbits>
25 BitMask() :
26  _word(0)
27 {
28 }
29 
30 ////////////////////////////////////////////////////////////////////
31 // Function: BitMask::Constructor
32 // Access: Published
33 // Description:
34 ////////////////////////////////////////////////////////////////////
35 template<class WType, int nbits>
37 BitMask(WordType init_value) :
38  _word(init_value)
39 {
40 }
41 
42 ////////////////////////////////////////////////////////////////////
43 // Function: BitMask::Copy Constructor
44 // Access: Published
45 // Description:
46 ////////////////////////////////////////////////////////////////////
47 template<class WType, int nbits>
49 BitMask(const BitMask<WType, nbits> &copy) :
50  _word(copy._word)
51 {
52 }
53 
54 ////////////////////////////////////////////////////////////////////
55 // Function: BitMask::Copy Assignment Operator
56 // Access: Published
57 // Description:
58 ////////////////////////////////////////////////////////////////////
59 template<class WType, int nbits>
62  _word = copy._word;
63  return *this;
64 }
65 
66 ////////////////////////////////////////////////////////////////////
67 // Function: BitMask::Named all_on constructor
68 // Access: Published, Static
69 // Description: Returns a BitMask whose bits are all on.
70 ////////////////////////////////////////////////////////////////////
71 template<class WType, int nbits>
73 all_on() {
74  BitMask result;
75  result._word = (WordType)~0;
76  return result;
77 }
78 
79 ////////////////////////////////////////////////////////////////////
80 // Function: BitMask::Named all_on constructor
81 // Access: Published, Static
82 // Description: Returns a BitMask whose bits are all off.
83 ////////////////////////////////////////////////////////////////////
84 template<class WType, int nbits>
87  BitMask result;
88  result._word = 0;
89  return result;
90 }
91 
92 ////////////////////////////////////////////////////////////////////
93 // Function: BitMask::Named lower_on constructor
94 // Access: Published, Static
95 // Description: Returns a BitMask whose lower on_bits bits are on.
96 ////////////////////////////////////////////////////////////////////
97 template<class WType, int nbits>
99 lower_on(int on_bits) {
100  if (on_bits <= 0) {
101  return all_off();
102  } else if (on_bits >= num_bits) {
103  return all_on();
104  }
105  BitMask result;
106  result._word = ((WordType)1 << on_bits) - 1;
107  return result;
108 }
109 
110 ////////////////////////////////////////////////////////////////////
111 // Function: BitMask::Named bit constructor
112 // Access: Published, Static
113 // Description: Returns a BitMask with only the indicated bit on.
114 ////////////////////////////////////////////////////////////////////
115 template<class WType, int nbits>
117 bit(int index) {
118  BitMask result;
119  result.set_bit(index);
120  return result;
121 }
122 
123 ////////////////////////////////////////////////////////////////////
124 // Function: BitMask::Named range constructor
125 // Access: Published, Static
126 // Description: Returns a BitMask whose size bits, beginning at
127 // low_bit, are on.
128 ////////////////////////////////////////////////////////////////////
129 template<class WType, int nbits>
131 range(int low_bit, int size) {
132  BitMask result;
133  if (size <= 0) {
134  result._word = 0;
135  } else if (size >= num_bits) {
136  result._word = (WordType)~0;
137  } else {
138  result._word = ((WordType)1 << size) - 1;
139  }
140  result._word <<= low_bit;
141  return result;
142 }
143 
144 ////////////////////////////////////////////////////////////////////
145 // Function: BitMask::Destructor
146 // Access: Published
147 // Description:
148 ////////////////////////////////////////////////////////////////////
149 template<class WType, int nbits>
151 ~BitMask() {
152 }
153 
154 ////////////////////////////////////////////////////////////////////
155 // Function: BitMask::has_max_num_bits
156 // Access: Published, Static
157 // Description: Returns true if there is a maximum number of bits
158 // that may be stored in this structure, false
159 // otherwise. If this returns true, the number may be
160 // queried in get_max_num_bits().
161 //
162 // This method always returns true. This method is
163 // defined so generic programming algorithms can use
164 // BitMask or BitArray interchangeably.
165 ////////////////////////////////////////////////////////////////////
166 template<class WType, int nbits>
167 CONSTEXPR bool BitMask<WType, nbits>::
169  return true;
170 }
171 
172 ////////////////////////////////////////////////////////////////////
173 // Function: BitMask::get_max_num_bits
174 // Access: Published, Static
175 // Description: If get_max_num_bits() returned true, this method may
176 // be called to return the maximum number of bits that
177 // may be stored in this structure. It is an error to
178 // call this if get_max_num_bits() return false.
179 //
180 // It is never an error to call this method. This
181 // returns the same thing as get_num_bits(). This
182 // method is defined so generic programming algorithms
183 // can use BitMask or BitArray interchangeably.
184 ////////////////////////////////////////////////////////////////////
185 template<class WType, int nbits>
186 CONSTEXPR int BitMask<WType, nbits>::
188  return num_bits;
189 }
190 
191 ////////////////////////////////////////////////////////////////////
192 // Function: BitMask::get_num_bits
193 // Access: Published, Static
194 // Description: Returns the number of bits available to set in the
195 // bitmask.
196 ////////////////////////////////////////////////////////////////////
197 template<class WType, int nbits>
198 CONSTEXPR int BitMask<WType, nbits>::
200  return num_bits;
201 }
202 
203 ////////////////////////////////////////////////////////////////////
204 // Function: BitMask::get_bit
205 // Access: Published
206 // Description: Returns true if the nth bit is set, false if it is
207 // cleared. index must be in the range [0,
208 // num_bits).
209 ////////////////////////////////////////////////////////////////////
210 template<class WType, int nbits>
211 INLINE bool BitMask<WType, nbits>::
212 get_bit(int index) const {
213  nassertr(index >= 0 && index < num_bits, false);
214  return (_word & ((WordType)1 << index)) != 0;
215 }
216 
217 ////////////////////////////////////////////////////////////////////
218 // Function: BitMask::set_bit
219 // Access: Published
220 // Description: Sets the nth bit on. index must be in the range
221 // [0, num_bits).
222 ////////////////////////////////////////////////////////////////////
223 template<class WType, int nbits>
224 INLINE void BitMask<WType, nbits>::
225 set_bit(int index) {
226  nassertv(index >= 0 && index < num_bits);
227  _word |= ((WordType)1 << index);
228 }
229 
230 ////////////////////////////////////////////////////////////////////
231 // Function: BitMask::clear_bit
232 // Access: Published
233 // Description: Sets the nth bit off. index must be in the range
234 // [0, num_bits).
235 ////////////////////////////////////////////////////////////////////
236 template<class WType, int nbits>
237 INLINE void BitMask<WType, nbits>::
238 clear_bit(int index) {
239  nassertv(index >= 0 && index < num_bits);
240  _word &= ~((WordType)1 << index);
241 }
242 
243 ////////////////////////////////////////////////////////////////////
244 // Function: BitMask::set_bit_to
245 // Access: Published
246 // Description: Sets the nth bit either on or off, according to the
247 // indicated bool value. index must be in the range [0,
248 // num_bits).
249 ////////////////////////////////////////////////////////////////////
250 template<class WType, int nbits>
251 INLINE void BitMask<WType, nbits>::
252 set_bit_to(int index, bool value) {
253  if (value) {
254  set_bit(index);
255  } else {
256  clear_bit(index);
257  }
258 }
259 
260 ////////////////////////////////////////////////////////////////////
261 // Function: BitMask::is_zero
262 // Access: Published
263 // Description: Returns true if the entire bitmask is zero, false
264 // otherwise.
265 ////////////////////////////////////////////////////////////////////
266 template<class WType, int nbits>
267 INLINE bool BitMask<WType, nbits>::
268 is_zero() const {
269  return (_word == 0);
270 }
271 
272 ////////////////////////////////////////////////////////////////////
273 // Function: BitMask::is_all_on
274 // Access: Published
275 // Description: Returns true if the entire bitmask is one, false
276 // otherwise.
277 ////////////////////////////////////////////////////////////////////
278 template<class WType, int nbits>
279 INLINE bool BitMask<WType, nbits>::
280 is_all_on() const {
281  return (~_word == 0);
282 }
283 
284 ////////////////////////////////////////////////////////////////////
285 // Function: BitMask::extract
286 // Access: Published
287 // Description: Returns a word that represents only the indicated
288 // range of bits within this BitMask, shifted to the
289 // least-significant position.
290 ////////////////////////////////////////////////////////////////////
291 template<class WType, int nbits>
292 INLINE TYPENAME BitMask<WType, nbits>::WordType BitMask<WType, nbits>::
293 extract(int low_bit, int size) const {
294  return (_word >> low_bit) &
296 }
297 
298 ////////////////////////////////////////////////////////////////////
299 // Function: BitMask::store
300 // Access: Published
301 // Description: Stores the indicated word into the indicated range of
302 // bits with this BitMask.
303 ////////////////////////////////////////////////////////////////////
304 template<class WType, int nbits>
305 INLINE void BitMask<WType, nbits>::
306 store(WordType value, int low_bit, int size) {
307  WordType mask = BitMask<WType, nbits>::range(low_bit, size)._word;
308  _word = (_word & ~mask) | ((value << low_bit) & mask);
309 }
310 
311 ////////////////////////////////////////////////////////////////////
312 // Function: BitMask::has_any_of
313 // Access: Published
314 // Description: Returns true if any bit in the indicated range is
315 // set, false otherwise.
316 ////////////////////////////////////////////////////////////////////
317 template<class WType, int nbits>
318 INLINE bool BitMask<WType, nbits>::
319 has_any_of(int low_bit, int size) const {
320  WordType mask = BitMask<WType, nbits>::range(low_bit, size)._word;
321  return (_word & mask) != 0;
322 }
323 
324 ////////////////////////////////////////////////////////////////////
325 // Function: BitMask::has_all_of
326 // Access: Published
327 // Description: Returns true if all bits in the indicated range are
328 // set, false otherwise.
329 ////////////////////////////////////////////////////////////////////
330 template<class WType, int nbits>
331 INLINE bool BitMask<WType, nbits>::
332 has_all_of(int low_bit, int size) const {
333  WordType mask = BitMask<WType, nbits>::range(low_bit, size)._word;
334  return (_word & mask) == mask;
335 }
336 
337 ////////////////////////////////////////////////////////////////////
338 // Function: BitMask::set_range
339 // Access: Published
340 // Description: Sets the indicated range of bits on.
341 ////////////////////////////////////////////////////////////////////
342 template<class WType, int nbits>
343 INLINE void BitMask<WType, nbits>::
344 set_range(int low_bit, int size) {
345  WordType mask = BitMask<WType, nbits>::range(low_bit, size)._word;
346  _word |= mask;
347 }
348 
349 ////////////////////////////////////////////////////////////////////
350 // Function: BitMask::clear_range
351 // Access: Published
352 // Description: Sets the indicated range of bits off.
353 ////////////////////////////////////////////////////////////////////
354 template<class WType, int nbits>
355 INLINE void BitMask<WType, nbits>::
356 clear_range(int low_bit, int size) {
357  WordType mask = BitMask<WType, nbits>::range(low_bit, size)._word;
358  _word &= ~mask;
359 }
360 
361 ////////////////////////////////////////////////////////////////////
362 // Function: BitMask::set_range_to
363 // Access: Published
364 // Description: Sets the indicated range of bits to either on or off.
365 ////////////////////////////////////////////////////////////////////
366 template<class WType, int nbits>
367 INLINE void BitMask<WType, nbits>::
368 set_range_to(bool value, int low_bit, int size) {
369  if (value) {
370  set_range(low_bit, size);
371  } else {
372  clear_range(low_bit, size);
373  }
374 }
375 
376 ////////////////////////////////////////////////////////////////////
377 // Function: BitMask::get_word
378 // Access: Published
379 // Description: Returns the entire BitMask as a single word.
380 ////////////////////////////////////////////////////////////////////
381 template<class WType, int nbits>
382 INLINE TYPENAME BitMask<WType, nbits>::WordType BitMask<WType, nbits>::
383 get_word() const {
384  return _word;
385 }
386 
387 ////////////////////////////////////////////////////////////////////
388 // Function: BitMask::set_word
389 // Access: Published
390 // Description: Sets the entire BitMask to the value indicated by the
391 // given word.
392 ////////////////////////////////////////////////////////////////////
393 template<class WType, int nbits>
394 INLINE void BitMask<WType, nbits>::
395 set_word(WordType value) {
396  _word = value;
397 }
398 
399 ////////////////////////////////////////////////////////////////////
400 // Function: BitMask::get_num_on_bits
401 // Access: Published
402 // Description: Returns the number of bits that are set to 1 in the
403 // mask.
404 ////////////////////////////////////////////////////////////////////
405 template<class WType, int nbits>
406 INLINE int BitMask<WType, nbits>::
408  return count_bits_in_word((WType)_word);
409 }
410 
411 ////////////////////////////////////////////////////////////////////
412 // Function: BitMask::get_num_off_bits
413 // Access: Published
414 // Description: Returns the number of bits that are set to 0 in the
415 // mask.
416 ////////////////////////////////////////////////////////////////////
417 template<class WType, int nbits>
418 INLINE int BitMask<WType, nbits>::
420  return count_bits_in_word((WType)(~_word));
421 }
422 
423 ////////////////////////////////////////////////////////////////////
424 // Function: BitMask::get_lowest_on_bit
425 // Access: Published
426 // Description: Returns the index of the lowest 1 bit in the mask.
427 // Returns -1 if there are no 1 bits.
428 ////////////////////////////////////////////////////////////////////
429 template<class WType, int nbits>
430 INLINE int BitMask<WType, nbits>::
432  return ::get_lowest_on_bit(_word);
433 }
434 
435 ////////////////////////////////////////////////////////////////////
436 // Function: BitMask::get_lowest_off_bit
437 // Access: Published
438 // Description: Returns the index of the lowest 0 bit in the mask.
439 // Returns -1 if there are no 0 bits.
440 ////////////////////////////////////////////////////////////////////
441 template<class WType, int nbits>
442 INLINE int BitMask<WType, nbits>::
444  return (~(*this)).get_lowest_on_bit();
445 }
446 
447 ////////////////////////////////////////////////////////////////////
448 // Function: BitMask::get_highest_on_bit
449 // Access: Published
450 // Description: Returns the index of the highest 1 bit in the mask.
451 // Returns -1 if there are no 1 bits.
452 ////////////////////////////////////////////////////////////////////
453 template<class WType, int nbits>
454 INLINE int BitMask<WType, nbits>::
456  return ::get_highest_on_bit(_word);
457 }
458 
459 ////////////////////////////////////////////////////////////////////
460 // Function: BitMask::get_highest_off_bit
461 // Access: Published
462 // Description: Returns the index of the highest 0 bit in the mask.
463 // Returns -1 if there are no 0 bits.
464 ////////////////////////////////////////////////////////////////////
465 template<class WType, int nbits>
466 INLINE int BitMask<WType, nbits>::
468  return (~(*this)).get_highest_on_bit();
469 }
470 
471 ////////////////////////////////////////////////////////////////////
472 // Function: BitMask::get_next_higher_different_bit
473 // Access: Published
474 // Description: Returns the index of the next bit in the mask, above
475 // low_bit, whose value is different that the value of
476 // low_bit. Returns low_bit again if all bits higher
477 // than low_bit have the same value.
478 //
479 // This can be used to quickly iterate through all of
480 // the bits in the mask.
481 ////////////////////////////////////////////////////////////////////
482 template<class WType, int nbits>
483 INLINE int BitMask<WType, nbits>::
484 get_next_higher_different_bit(int low_bit) const {
485  // We are allowed to call this method with low_bit == num_bits,
486  // which is the highest value this method will return.
487  nassertr(low_bit >= 0, low_bit);
488  if (low_bit >= num_bits) {
489  return low_bit;
490  }
491 
492  WordType is_on = (_word & ((WordType)1 << low_bit));
493  WordType w;
494  if (is_on) {
495  // low_bit is 1. Get the next higher 0 bit. To do this, invert
496  // the word and the get the next higher 1 bit.
497  w = ~_word;
498  } else {
499  // low_bit is 0. Get the next higher 1 bit.
500  w = _word;
501  }
502 
503  // Mask out all of the bits below low_bit. Since we already know
504  // that low_bit is 0, we can use (1 << low_bit) instead of (1 <<
505  // (low_bit + 1)), which becomes undefined when (low_bit + 1) == 32.
506  w &= ~(((WordType)1 << low_bit) - 1);
507 
508  if (w == 0) {
509  // All higher bits in the word have the same value. Since every
510  // bit after the topmost bit is 0, we either return the topmost
511  // bit + 1 to indicate the next 0 bit, or low_bit to indicate we
512  // have reached the end of the number of bits.
513  return is_on ? num_bits : low_bit;
514 
515  } else {
516  // Now determine the lowest 1 bit in the remaining word. This
517  // operation will clear out all bits except for the lowest 1 bit.
518  w = (w & (~w + 1));
519 
520  // And the answer is the number of bits in (w - 1).
521  return count_bits_in_word((WType)(w - 1));
522  }
523 }
524 
525 ////////////////////////////////////////////////////////////////////
526 // Function: BitMask::invert_in_place
527 // Access: Published
528 // Description: Inverts all the bits in the BitMask. This is
529 // equivalent to mask = ~mask.
530 ////////////////////////////////////////////////////////////////////
531 template<class WType, int nbits>
532 INLINE void BitMask<WType, nbits>::
534  _word = ~_word;
535 }
536 
537 ////////////////////////////////////////////////////////////////////
538 // Function: BitMask::has_bits_in_common
539 // Access: Published
540 // Description: Returns true if this BitMask has any "one" bits in
541 // common with the other one, false otherwise.
542 //
543 // This is equivalent to (mask & other) != 0, but may be
544 // faster. (Actually, it should only be faster in the
545 // BitArray case, but this method is provided for the
546 // benefit of generic programming algorithms).
547 ////////////////////////////////////////////////////////////////////
548 template<class WType, int nbits>
549 INLINE bool BitMask<WType, nbits>::
551  return (_word & other._word) != 0;
552 }
553 
554 ////////////////////////////////////////////////////////////////////
555 // Function: BitMask::clear
556 // Access: Published
557 // Description: Sets all the bits in the BitMask off.
558 ////////////////////////////////////////////////////////////////////
559 template<class WType, int nbits>
560 INLINE void BitMask<WType, nbits>::
561 clear() {
562  _word = 0;
563 }
564 
565 ////////////////////////////////////////////////////////////////////
566 // Function: BitMask::output
567 // Access: Published
568 // Description: Writes the BitMask out as a binary or a hex number,
569 // according to the number of bits.
570 ////////////////////////////////////////////////////////////////////
571 template<class WType, int nbits>
573 output(ostream &out) const {
574  if (num_bits >= 40) {
575  output_hex(out);
576  } else {
577  output_binary(out);
578  }
579 }
580 
581 ////////////////////////////////////////////////////////////////////
582 // Function: BitMask::output_binary
583 // Access: Published
584 // Description: Writes the BitMask out as a binary number, with
585 // spaces every four bits.
586 ////////////////////////////////////////////////////////////////////
587 template<class WType, int nbits>
589 output_binary(ostream &out, int spaces_every) const {
590  for (int i = num_bits - 1; i >= 0; i--) {
591  if (spaces_every != 0 && ((i % spaces_every) == spaces_every - 1)) {
592  out << ' ';
593  }
594  out << (get_bit(i) ? '1' : '0');
595  }
596 }
597 
598 ////////////////////////////////////////////////////////////////////
599 // Function: BitMask::output_hex
600 // Access: Published
601 // Description: Writes the BitMask out as a hexadecimal number, with
602 // spaces every four digits.
603 ////////////////////////////////////////////////////////////////////
604 template<class WType, int nbits>
606 output_hex(ostream &out, int spaces_every) const {
607  int num_digits = (num_bits + 3) / 4;
608 
609  for (int i = num_digits - 1; i >= 0; i--) {
610  WordType digit = extract(i * 4, 4);
611  if (spaces_every != 0 && ((i % spaces_every) == spaces_every - 1)) {
612  out << ' ';
613  }
614  if (digit > 9) {
615  out << (char)(digit - 10 + 'a');
616  } else {
617  out << (char)(digit + '0');
618  }
619  }
620 }
621 
622 ////////////////////////////////////////////////////////////////////
623 // Function: BitMask::write
624 // Access: Published
625 // Description: Writes the BitMask out as a binary or a hex number,
626 // according to the number of bits.
627 ////////////////////////////////////////////////////////////////////
628 template<class WType, int nbits>
630 write(ostream &out, int indent_level) const {
631  indent(out, indent_level) << *this << "\n";
632 }
633 
634 ////////////////////////////////////////////////////////////////////
635 // Function: BitMask::operator ==
636 // Access: Published
637 // Description:
638 ////////////////////////////////////////////////////////////////////
639 template<class WType, int nbits>
640 INLINE bool BitMask<WType, nbits>::
641 operator == (const BitMask<WType, nbits> &other) const {
642  return _word == other._word;
643 }
644 
645 ////////////////////////////////////////////////////////////////////
646 // Function: BitMask::operator !=
647 // Access: Published
648 // Description:
649 ////////////////////////////////////////////////////////////////////
650 template<class WType, int nbits>
651 INLINE bool BitMask<WType, nbits>::
652 operator != (const BitMask<WType, nbits> &other) const {
653  return _word != other._word;
654 }
655 
656 ////////////////////////////////////////////////////////////////////
657 // Function: BitMask::operator <
658 // Access: Published
659 // Description: The ordering operator is of limited usefulness with a
660 // BitMask, however, it has a definition which places
661 // all unique BitMasks into a unique ordering. It may
662 // be useful when defining ordered STL containers of
663 // BitMasks, for instance; and it's required in order to
664 // export any STL container (ordered or unordered) of
665 // BitMask under Windows.
666 ////////////////////////////////////////////////////////////////////
667 template<class WType, int nbits>
668 INLINE bool BitMask<WType, nbits>::
669 operator < (const BitMask<WType, nbits> &other) const {
670  return _word < other._word;
671 }
672 
673 ////////////////////////////////////////////////////////////////////
674 // Function: BitMask::compare_to
675 // Access: Published
676 // Description: Returns a number less than zero if this BitMask sorts
677 // before the indicated other BitMask, greater than zero
678 // if it sorts after, or 0 if they are equivalent. This
679 // is based on the same ordering defined by operator <.
680 ////////////////////////////////////////////////////////////////////
681 template<class WType, int nbits>
682 INLINE int BitMask<WType, nbits>::
683 compare_to(const BitMask<WType, nbits> &other) const {
684  if ((*this) < other) {
685  return -1;
686  } else if (other < (*this)) {
687  return 1;
688  } else {
689  return 0;
690  }
691 }
692 
693 ////////////////////////////////////////////////////////////////////
694 // Function: BitMask::operator &
695 // Access: Published
696 // Description:
697 ////////////////////////////////////////////////////////////////////
698 template<class WType, int nbits>
700 operator & (const BitMask<WType, nbits> &other) const {
701  BitMask<WType, nbits> result(*this);
702  result &= other;
703  return result;
704 }
705 
706 ////////////////////////////////////////////////////////////////////
707 // Function: BitMask::operator |
708 // Access: Published
709 // Description:
710 ////////////////////////////////////////////////////////////////////
711 template<class WType, int nbits>
713 operator | (const BitMask<WType, nbits> &other) const {
714  BitMask<WType, nbits> result(*this);
715  result |= other;
716  return result;
717 }
718 
719 ////////////////////////////////////////////////////////////////////
720 // Function: BitMask::operator ^
721 // Access: Published
722 // Description:
723 ////////////////////////////////////////////////////////////////////
724 template<class WType, int nbits>
726 operator ^ (const BitMask<WType, nbits> &other) const {
727  BitMask<WType, nbits> result(*this);
728  result ^= other;
729  return result;
730 }
731 
732 ////////////////////////////////////////////////////////////////////
733 // Function: BitMask::operator ~
734 // Access: Published
735 // Description:
736 ////////////////////////////////////////////////////////////////////
737 template<class WType, int nbits>
739 operator ~ () const {
740  return BitMask<WType, nbits>(~_word);
741 }
742 
743 ////////////////////////////////////////////////////////////////////
744 // Function: BitMask::operator <<
745 // Access: Published
746 // Description:
747 ////////////////////////////////////////////////////////////////////
748 template<class WType, int nbits>
750 operator << (int shift) const {
751  BitMask<WType, nbits> result(*this);
752  result <<= shift;
753  return result;
754 }
755 
756 ////////////////////////////////////////////////////////////////////
757 // Function: BitMask::operator >>
758 // Access: Published
759 // Description:
760 ////////////////////////////////////////////////////////////////////
761 template<class WType, int nbits>
763 operator >> (int shift) const {
764  BitMask<WType, nbits> result(*this);
765  result >>= shift;
766  return result;
767 }
768 
769 ////////////////////////////////////////////////////////////////////
770 // Function: BitMask::operator &=
771 // Access: Published
772 // Description:
773 ////////////////////////////////////////////////////////////////////
774 template<class WType, int nbits>
775 INLINE void BitMask<WType, nbits>::
776 operator &= (const BitMask<WType, nbits> &other) {
777  _word &= other._word;
778 }
779 
780 ////////////////////////////////////////////////////////////////////
781 // Function: BitMask::operator |=
782 // Access: Published
783 // Description:
784 ////////////////////////////////////////////////////////////////////
785 template<class WType, int nbits>
786 INLINE void BitMask<WType, nbits>::
787 operator |= (const BitMask<WType, nbits> &other) {
788  _word |= other._word;
789 }
790 
791 ////////////////////////////////////////////////////////////////////
792 // Function: BitMask::operator ^=
793 // Access: Published
794 // Description:
795 ////////////////////////////////////////////////////////////////////
796 template<class WType, int nbits>
797 INLINE void BitMask<WType, nbits>::
798 operator ^= (const BitMask<WType, nbits> &other) {
799  _word ^= other._word;
800 }
801 
802 ////////////////////////////////////////////////////////////////////
803 // Function: BitMask::operator <<=
804 // Access: Published
805 // Description:
806 ////////////////////////////////////////////////////////////////////
807 template<class WType, int nbits>
808 INLINE void BitMask<WType, nbits>::
809 operator <<= (int shift) {
810  _word <<= shift;
811 }
812 
813 ////////////////////////////////////////////////////////////////////
814 // Function: BitMask::operator >>=
815 // Access: Published
816 // Description:
817 ////////////////////////////////////////////////////////////////////
818 template<class WType, int nbits>
819 INLINE void BitMask<WType, nbits>::
820 operator >>= (int shift) {
821  _word >>= shift;
822 }
823 
824 ////////////////////////////////////////////////////////////////////
825 // Function: BitMask::get_key
826 // Access: Published
827 // Description: Returns a mostly unique integer key per unique
828 // bitmask, suitable for using in a hash table.
829 ////////////////////////////////////////////////////////////////////
830 template<class WType, int nbits>
831 INLINE int BitMask<WType, nbits>::
832 get_key() const {
833  return (int)_word;
834 }
835 
836 ////////////////////////////////////////////////////////////////////
837 // Function: BitMask::__nonzero__
838 // Access: Published
839 // Description: Returns true if the bitmask is not zero.
840 ////////////////////////////////////////////////////////////////////
841 template<class WType, int nbits>
842 INLINE bool BitMask<WType, nbits>::
843 __nonzero__() const {
844  return _word != 0;
845 }
846 
847 ////////////////////////////////////////////////////////////////////
848 // Function: BitMask::generate_hash
849 // Access: Public
850 // Description: Adds the bitmask to the indicated hash generator.
851 ////////////////////////////////////////////////////////////////////
852 template<class WType, int nbits>
853 INLINE void BitMask<WType, nbits>::
855  hashgen.add_int(_word);
856 }
857 
858 ////////////////////////////////////////////////////////////////////
859 // Function: BitMask::init_type
860 // Access: Public
861 // Description:
862 ////////////////////////////////////////////////////////////////////
863 template<class WType, int nbits>
865 init_type() {
866  ostringstream str;
867  str << "BitMask" << num_bits;
868  register_type(_type_handle, str.str());
869 }
870 
871 ////////////////////////////////////////////////////////////////////
872 // Function: BitMask::flood_up_in_place
873 // Access: Published
874 // Description: Floods this bitmask's bits upwards.
875 ////////////////////////////////////////////////////////////////////
876 template<class WType, int nbits>
877 INLINE void BitMask<WType, nbits>::
879  _word = ::flood_bits_up(_word);
880 }
881 
882 ////////////////////////////////////////////////////////////////////
883 // Function: BitMask::flood_down_in_place
884 // Access: Published
885 // Description: Floods this bitmask's bits downwards.
886 ////////////////////////////////////////////////////////////////////
887 template<class WType, int nbits>
888 INLINE void BitMask<WType, nbits>::
890  _word = ::flood_bits_down(_word);
891 }
892 
893 ////////////////////////////////////////////////////////////////////
894 // Function: BitMask::flood_bits_up
895 // Access: Published
896 // Description: Returns a BitMask with the bits flooded upwards.
897 ////////////////////////////////////////////////////////////////////
898 template<class WType, int nbits>
900 flood_bits_up() const {
901  BitMask<WType, nbits> result(::flood_bits_up(_word));
902  return result;
903 }
904 
905 ////////////////////////////////////////////////////////////////////
906 // Function: BitMask::flood_bits_down
907 // Access: Published
908 // Description: Returns a BitMask with the bits flooded down.
909 ////////////////////////////////////////////////////////////////////
910 template<class WType, int nbits>
913  BitMask<WType, nbits> result(::flood_bits_down(_word));
914  return result;
915 }
916 
917 
918 ////////////////////////////////////////////////////////////////////
919 // Function: BitMask::keep_next_highest_bit
920 // Access: Published
921 // Description: Returns a BitMask with only the next highest
922 // bit above the indicated bit on, or all_off.
923 ////////////////////////////////////////////////////////////////////
924 template<class WType, int nbits>
927  int low_bit = get_lowest_on_bit();
928  if (low_bit >= 0) {
929  return BitMask<WType, nbits>::bit(low_bit);
930  } else {
932  }
933 }
934 
935 ////////////////////////////////////////////////////////////////////
936 // Function: BitMask::keep_next_lowest_bit
937 // Access: Published
938 // Description: Returns a BitMask with only the next lower
939 // bit below the indicated bit on, or all_off.
940 ////////////////////////////////////////////////////////////////////
941 template<class WType, int nbits>
944  int high_bit = get_highest_on_bit();
945  if (high_bit >= 0) {
946  return BitMask<WType, nbits>::bit(high_bit);
947  } else {
949  }
950 }
951 
952 ////////////////////////////////////////////////////////////////////
953 // Function: BitMask::keep_next_highest_bit
954 // Access: Published
955 // Description: Returns a BitMask with only the next highest
956 // bit above the indicated bit on, or all.
957 ////////////////////////////////////////////////////////////////////
958 template<class WType, int nbits>
960 keep_next_highest_bit(int index) const {
961  BitMask<WType, nbits> mask,temp;
962  nassertr(index >= 0 && index < num_bits, mask);
963 
964  mask.set_bit(index);
965  mask.flood_down_in_place();
966  mask.invert_in_place();
967  mask &= *this;
968  temp = mask;
969 
970  mask <<= 1;
971  mask.flood_up_in_place();
972  mask.invert_in_place();
973  mask &= temp;
974 
975  return mask;
976 }
977 
978 ////////////////////////////////////////////////////////////////////
979 // Function: BitMask::keep_next_lowest_bit
980 // Access: Published
981 // Description: Returns a BitMask with only the next lower
982 // bit below the indicated bit on, or all_off.
983 ////////////////////////////////////////////////////////////////////
984 template<class WType, int nbits>
986 keep_next_lowest_bit(int index) const {
987  BitMask<WType, nbits> mask, temp;
988  nassertr(index >= 0 && index < num_bits, mask);
989 
990  mask.set_bit(index);
991  mask.flood_up_in_place();
992  mask.invert_in_place();
993  mask &= *this;
994  temp = mask;
995 
996  mask >>= 1;
997  mask.flood_down_in_place();
998  mask.invert_in_place();
999  mask &= temp;
1000 
1001  return mask;
1002 }
1003 
1004 ////////////////////////////////////////////////////////////////////
1005 // Function: BitMask::keep_next_highest_bit
1006 // Access: Published
1007 // Description: Returns a BitMask with only the next highest "on"
1008 // bit above all "on" bits in the passed in bitmask, or
1009 // all_off. If there are no "on" bits in the passed in
1010 // bitmask, it will return keep_next_highest_bit().
1011 ////////////////////////////////////////////////////////////////////
1012 template<class WType, int nbits>
1015  int high_bit = other.get_highest_on_bit();
1016  if (high_bit >= 0) {
1017  return keep_next_highest_bit(high_bit);
1018  } else {
1019  return keep_next_highest_bit();
1020  }
1021 }
1022 
1023 ////////////////////////////////////////////////////////////////////
1024 // Function: BitMask::keep_next_lowest_bit
1025 // Access: Published
1026 // Description: Returns a BitMask with only the next lowest "on"
1027 // bit below all "on" bits in the passed in bitmask, or
1028 // all_off. If there are no "on" bits in the passed in
1029 // bitmask, it will return keep_next_lowest_bit().
1030 ////////////////////////////////////////////////////////////////////
1031 template<class WType, int nbits>
1034  int low_bit = other.get_lowest_on_bit();
1035  if (low_bit >= 0) {
1036  return keep_next_lowest_bit(low_bit);
1037  } else {
1038  return keep_next_lowest_bit();
1039  }
1040 }
void clear_bit(int index)
Sets the nth bit off.
Definition: bitMask.I:238
static BitMask< WType, nbits > bit(int index)
Returns a BitMask with only the indicated bit on.
Definition: bitMask.I:117
void flood_down_in_place()
Floods this bitmask&#39;s bits downwards.
Definition: bitMask.I:889
int get_highest_off_bit() const
Returns the index of the highest 0 bit in the mask.
Definition: bitMask.I:467
bool has_any_of(int low_bit, int size) const
Returns true if any bit in the indicated range is set, false otherwise.
Definition: bitMask.I:319
This is a specific kind of HashGenerator that simply adds up all of the ints.
BitMask< WType, nbits > flood_bits_down() const
Returns a BitMask with the bits flooded down.
Definition: bitMask.I:912
void output_binary(ostream &out, int spaces_every=4) const
Writes the BitMask out as a binary number, with spaces every four bits.
Definition: bitMask.I:589
void invert_in_place()
Inverts all the bits in the BitMask.
Definition: bitMask.I:533
static BitMask< WType, nbits > all_on()
Returns a BitMask whose bits are all on.
Definition: bitMask.I:73
void output(ostream &out) const
Writes the BitMask out as a binary or a hex number, according to the number of bits.
Definition: bitMask.I:573
static CONSTEXPR int get_max_num_bits()
If get_max_num_bits() returned true, this method may be called to return the maximum number of bits t...
Definition: bitMask.I:187
void set_range(int low_bit, int size)
Sets the indicated range of bits on.
Definition: bitMask.I:344
void clear()
Sets all the bits in the BitMask off.
Definition: bitMask.I:561
void store(WordType value, int low_bit, int size)
Stores the indicated word into the indicated range of bits with this BitMask.
Definition: bitMask.I:306
int get_next_higher_different_bit(int low_bit) const
Returns the index of the next bit in the mask, above low_bit, whose value is different that the value...
Definition: bitMask.I:484
bool operator<(const BitMask< WType, nbits > &other) const
The ordering operator is of limited usefulness with a BitMask, however, it has a definition which pla...
Definition: bitMask.I:669
int get_lowest_off_bit() const
Returns the index of the lowest 0 bit in the mask.
Definition: bitMask.I:443
bool __nonzero__() const
Returns true if the bitmask is not zero.
Definition: bitMask.I:843
int compare_to(const BitMask< WType, nbits > &other) const
Returns a number less than zero if this BitMask sorts before the indicated other BitMask, greater than zero if it sorts after, or 0 if they are equivalent.
Definition: bitMask.I:683
BitMask< WType, nbits > keep_next_highest_bit() const
Returns a BitMask with only the next highest bit above the indicated bit on, or all_off.
Definition: bitMask.I:926
static BitMask< WType, nbits > all_off()
Returns a BitMask whose bits are all off.
Definition: bitMask.I:86
void output_hex(ostream &out, int spaces_every=4) const
Writes the BitMask out as a hexadecimal number, with spaces every four digits.
Definition: bitMask.I:606
void write(ostream &out, int indent_level=0) const
Writes the BitMask out as a binary or a hex number, according to the number of bits.
Definition: bitMask.I:630
int get_num_off_bits() const
Returns the number of bits that are set to 0 in the mask.
Definition: bitMask.I:419
void set_word(WordType value)
Sets the entire BitMask to the value indicated by the given word.
Definition: bitMask.I:395
static BitMask< WType, nbits > range(int low_bit, int size)
Returns a BitMask whose size bits, beginning at low_bit, are on.
Definition: bitMask.I:131
void flood_up_in_place()
Floods this bitmask&#39;s bits upwards.
Definition: bitMask.I:878
void clear_range(int low_bit, int size)
Sets the indicated range of bits off.
Definition: bitMask.I:356
bool is_all_on() const
Returns true if the entire bitmask is one, false otherwise.
Definition: bitMask.I:280
WordType get_word() const
Returns the entire BitMask as a single word.
Definition: bitMask.I:383
bool get_bit(int index) const
Returns true if the nth bit is set, false if it is cleared.
Definition: bitMask.I:212
static BitMask< WType, nbits > lower_on(int on_bits)
Returns a BitMask whose lower on_bits bits are on.
Definition: bitMask.I:99
void generate_hash(ChecksumHashGenerator &hashgen) const
Adds the bitmask to the indicated hash generator.
Definition: bitMask.I:854
int get_lowest_on_bit() const
Returns the index of the lowest 1 bit in the mask.
Definition: bitMask.I:431
void set_bit_to(int index, bool value)
Sets the nth bit either on or off, according to the indicated bool value.
Definition: bitMask.I:252
WordType extract(int low_bit, int size) const
Returns a word that represents only the indicated range of bits within this BitMask, shifted to the least-significant position.
Definition: bitMask.I:293
bool has_bits_in_common(const BitMask< WType, nbits > &other) const
Returns true if this BitMask has any "one" bits in common with the other one, false otherwise...
Definition: bitMask.I:550
BitMask< WType, nbits > flood_bits_up() const
Returns a BitMask with the bits flooded upwards.
Definition: bitMask.I:900
void set_range_to(bool value, int low_bit, int size)
Sets the indicated range of bits to either on or off.
Definition: bitMask.I:368
int get_highest_on_bit() const
Returns the index of the highest 1 bit in the mask.
Definition: bitMask.I:455
void add_int(long num)
Adds another integer to the hash so far.
void set_bit(int index)
Sets the nth bit on.
Definition: bitMask.I:225
bool has_all_of(int low_bit, int size) const
Returns true if all bits in the indicated range are set, false otherwise.
Definition: bitMask.I:332
static CONSTEXPR int get_num_bits()
Returns the number of bits available to set in the bitmask.
Definition: bitMask.I:199
int get_key() const
Returns a mostly unique integer key per unique bitmask, suitable for using in a hash table...
Definition: bitMask.I:832
int get_num_on_bits() const
Returns the number of bits that are set to 1 in the mask.
Definition: bitMask.I:407
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
A general bitmask class.
Definition: bitMask.h:35
static CONSTEXPR bool has_max_num_bits()
Returns true if there is a maximum number of bits that may be stored in this structure, false otherwise.
Definition: bitMask.I:168
bool is_zero() const
Returns true if the entire bitmask is zero, false otherwise.
Definition: bitMask.I:268
BitMask< WType, nbits > keep_next_lowest_bit() const
Returns a BitMask with only the next lower bit below the indicated bit on, or all_off.
Definition: bitMask.I:943