Panda3D
doubleBitMask.I
1 // Filename: doubleBitMask.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 BMType>
16 TypeHandle DoubleBitMask<BMType>::_type_handle;
17 
18 ////////////////////////////////////////////////////////////////////
19 // Function: DoubleBitMask::Constructor
20 // Access: Published
21 // Description:
22 ////////////////////////////////////////////////////////////////////
23 template<class BMType>
25 DoubleBitMask() {
26 }
27 
28 ////////////////////////////////////////////////////////////////////
29 // Function: DoubleBitMask::Copy Constructor
30 // Access: Published
31 // Description:
32 ////////////////////////////////////////////////////////////////////
33 template<class BMType>
36  _lo(copy._lo),
37  _hi(copy._hi)
38 {
39 }
40 
41 ////////////////////////////////////////////////////////////////////
42 // Function: DoubleBitMask::Copy Assignment Operator
43 // Access: Published
44 // Description:
45 ////////////////////////////////////////////////////////////////////
46 template<class BMType>
49  _lo = copy._lo;
50  _hi = copy._hi;
51  return *this;
52 }
53 
54 ////////////////////////////////////////////////////////////////////
55 // Function: DoubleBitMask::Named all_on constructor
56 // Access: Published, Static
57 // Description: Returns a DoubleBitMask whose bits are all on.
58 ////////////////////////////////////////////////////////////////////
59 template<class BMType>
61 all_on() {
62  DoubleBitMask<BMType> result;
63  result._lo = BitMaskType::all_on();
64  result._hi = BitMaskType::all_on();
65  return result;
66 }
67 
68 ////////////////////////////////////////////////////////////////////
69 // Function: DoubleBitMask::Named all_on constructor
70 // Access: Published, Static
71 // Description: Returns a DoubleBitMask whose bits are all off.
72 ////////////////////////////////////////////////////////////////////
73 template<class BMType>
76  DoubleBitMask<BMType> result;
77  result._lo.clear();
78  result._hi.clear();
79  return result;
80 }
81 
82 ////////////////////////////////////////////////////////////////////
83 // Function: DoubleBitMask::Named lower_on constructor
84 // Access: Published, Static
85 // Description: Returns a DoubleBitMask whose lower on_bits bits are on.
86 ////////////////////////////////////////////////////////////////////
87 template<class BMType>
89 lower_on(int on_bits) {
90  if (on_bits <= 0) {
91  return all_off();
92  } else if (on_bits >= num_bits) {
93  return all_on();
94  }
95  DoubleBitMask<BMType> result;
96  if (on_bits <= half_bits) {
97  result._lo = BitMaskType::lower_on(on_bits);
98  } else {
99  result._lo = BitMaskType::all_on();
100  result._hi = BitMaskType::lower_on(on_bits - half_bits);
101  }
102  return result;
103 }
104 
105 ////////////////////////////////////////////////////////////////////
106 // Function: DoubleBitMask::Named bit constructor
107 // Access: Published, Static
108 // Description: Returns a DoubleBitMask with only the indicated bit on.
109 ////////////////////////////////////////////////////////////////////
110 template<class BMType>
112 bit(int index) {
113  DoubleBitMask<BMType> result;
114  result.set_bit(index);
115  return result;
116 }
117 
118 ////////////////////////////////////////////////////////////////////
119 // Function: DoubleBitMask::Named range constructor
120 // Access: Published, Static
121 // Description: Returns a DoubleBitMask whose size bits, beginning at
122 // low_bit, are on.
123 ////////////////////////////////////////////////////////////////////
124 template<class BMType>
126 range(int low_bit, int size) {
127  DoubleBitMask<BMType> result;
128  result.set_range(low_bit, size);
129  return result;
130 }
131 
132 ////////////////////////////////////////////////////////////////////
133 // Function: DoubleBitMask::Destructor
134 // Access: Published
135 // Description:
136 ////////////////////////////////////////////////////////////////////
137 template<class BMType>
139 ~DoubleBitMask() {
140 }
141 
142 ////////////////////////////////////////////////////////////////////
143 // Function: DoubleBitMask::has_max_num_bits
144 // Access: Published, Static
145 // Description: Returns true if there is a maximum number of bits
146 // that may be stored in this structure, false
147 // otherwise. If this returns true, the number may be
148 // queried in get_max_num_bits().
149 //
150 // This method always returns true. This method is
151 // defined so generic programming algorithms can use
152 // DoubleBitMask or BitArray interchangeably.
153 ////////////////////////////////////////////////////////////////////
154 template<class BMType>
155 CONSTEXPR bool DoubleBitMask<BMType>::
157  return true;
158 }
159 
160 ////////////////////////////////////////////////////////////////////
161 // Function: DoubleBitMask::get_max_num_bits
162 // Access: Published, Static
163 // Description: If get_max_num_bits() returned true, this method may
164 // be called to return the maximum number of bits that
165 // may be stored in this structure. It is an error to
166 // call this if get_max_num_bits() return false.
167 //
168 // It is never an error to call this method. This
169 // returns the same thing as get_num_bits(). This
170 // method is defined so generic programming algorithms
171 // can use DoubleBitMask or BitArray interchangeably.
172 ////////////////////////////////////////////////////////////////////
173 template<class BMType>
174 CONSTEXPR int DoubleBitMask<BMType>::
176  return num_bits;
177 }
178 
179 ////////////////////////////////////////////////////////////////////
180 // Function: DoubleBitMask::get_num_bits
181 // Access: Published, Static
182 // Description: Returns the number of bits available to set in the
183 // doubleBitMask.
184 ////////////////////////////////////////////////////////////////////
185 template<class BMType>
186 CONSTEXPR int DoubleBitMask<BMType>::
188  return num_bits;
189 }
190 
191 ////////////////////////////////////////////////////////////////////
192 // Function: DoubleBitMask::get_bit
193 // Access: Published
194 // Description: Returns true if the nth bit is set, false if it is
195 // cleared. index must be in the range [0,
196 // num_bits).
197 ////////////////////////////////////////////////////////////////////
198 template<class BMType>
199 INLINE bool DoubleBitMask<BMType>::
200 get_bit(int index) const {
201  if (index < half_bits) {
202  return _lo.get_bit(index);
203  } else {
204  return _hi.get_bit(index - half_bits);
205  }
206 }
207 
208 ////////////////////////////////////////////////////////////////////
209 // Function: DoubleBitMask::set_bit
210 // Access: Published
211 // Description: Sets the nth bit on. index must be in the range
212 // [0, num_bits).
213 ////////////////////////////////////////////////////////////////////
214 template<class BMType>
215 INLINE void DoubleBitMask<BMType>::
216 set_bit(int index) {
217  if (index < half_bits) {
218  _lo.set_bit(index);
219  } else {
220  _hi.set_bit(index - half_bits);
221  }
222 }
223 
224 ////////////////////////////////////////////////////////////////////
225 // Function: DoubleBitMask::clear_bit
226 // Access: Published
227 // Description: Sets the nth bit off. index must be in the range
228 // [0, num_bits).
229 ////////////////////////////////////////////////////////////////////
230 template<class BMType>
231 INLINE void DoubleBitMask<BMType>::
232 clear_bit(int index) {
233  if (index < half_bits) {
234  _lo.clear_bit(index);
235  } else {
236  _hi.clear_bit(index - half_bits);
237  }
238 }
239 
240 ////////////////////////////////////////////////////////////////////
241 // Function: DoubleBitMask::set_bit_to
242 // Access: Published
243 // Description: Sets the nth bit either on or off, according to the
244 // indicated bool value. index must be in the range [0,
245 // num_bits).
246 ////////////////////////////////////////////////////////////////////
247 template<class BMType>
248 INLINE void DoubleBitMask<BMType>::
249 set_bit_to(int index, bool value) {
250  if (index < half_bits) {
251  _lo.set_bit_to(index, value);
252  } else {
253  _hi.set_bit_to(index - half_bits, value);
254  }
255 }
256 
257 ////////////////////////////////////////////////////////////////////
258 // Function: DoubleBitMask::is_zero
259 // Access: Published
260 // Description: Returns true if the entire doubleBitMask is zero, false
261 // otherwise.
262 ////////////////////////////////////////////////////////////////////
263 template<class BMType>
264 INLINE bool DoubleBitMask<BMType>::
265 is_zero() const {
266  return (_lo.is_zero() && _hi.is_zero());
267 }
268 
269 ////////////////////////////////////////////////////////////////////
270 // Function: DoubleBitMask::is_all_on
271 // Access: Published
272 // Description: Returns true if the entire doubleBitMask is one, false
273 // otherwise.
274 ////////////////////////////////////////////////////////////////////
275 template<class BMType>
276 INLINE bool DoubleBitMask<BMType>::
277 is_all_on() const {
278  return (_lo.is_all_on() && _hi.is_all_on());
279 }
280 
281 ////////////////////////////////////////////////////////////////////
282 // Function: DoubleBitMask::extract
283 // Access: Published
284 // Description: Returns a word that represents only the indicated
285 // range of bits within this DoubleBitMask, shifted to the
286 // least-significant position.
287 ////////////////////////////////////////////////////////////////////
288 template<class BMType>
289 INLINE TYPENAME DoubleBitMask<BMType>::WordType DoubleBitMask<BMType>::
290 extract(int low_bit, int size) const {
291  if (low_bit >= half_bits) {
292  return _hi.extract(low_bit - half_bits, size);
293  } else if (low_bit + size < half_bits) {
294  return _lo.extract(low_bit, size);
295  } else {
296  int hi_portion = low_bit + size - half_bits;
297  int lo_portion = size - hi_portion;
298  return (_hi.extract(0, hi_portion) << lo_portion) |
299  _lo.extract(low_bit, lo_portion);
300  }
301 }
302 
303 ////////////////////////////////////////////////////////////////////
304 // Function: DoubleBitMask::store
305 // Access: Published
306 // Description: Stores the indicated word into the indicated range of
307 // bits with this DoubleBitMask.
308 ////////////////////////////////////////////////////////////////////
309 template<class BMType>
310 INLINE void DoubleBitMask<BMType>::
311 store(WordType value, int low_bit, int size) {
312  if (low_bit >= half_bits) {
313  _hi.store(value, low_bit - half_bits, size);
314  } else if (low_bit + size < half_bits) {
315  _lo.store(value, low_bit, size);
316  } else {
317  int hi_portion = low_bit + size - half_bits;
318  int lo_portion = size - hi_portion;
319 
320  _hi.store(value >> lo_portion, 0, hi_portion);
321  _lo.store(value, low_bit, lo_portion);
322  }
323 }
324 
325 ////////////////////////////////////////////////////////////////////
326 // Function: DoubleBitMask::has_any_of
327 // Access: Published
328 // Description: Returns true if any bit in the indicated range is
329 // set, false otherwise.
330 ////////////////////////////////////////////////////////////////////
331 template<class BMType>
332 INLINE bool DoubleBitMask<BMType>::
333 has_any_of(int low_bit, int size) const {
334  if (low_bit >= half_bits) {
335  return _hi.has_any_of(low_bit - half_bits, size);
336  } else if (low_bit + size < half_bits) {
337  return _lo.has_any_of(low_bit, size);
338  } else {
339  int hi_portion = low_bit + size - half_bits;
340  int lo_portion = size - hi_portion;
341  return (_hi.has_any_of(0, hi_portion) << lo_portion) ||
342  _lo.has_any_of(low_bit, lo_portion);
343  }
344 }
345 
346 ////////////////////////////////////////////////////////////////////
347 // Function: DoubleBitMask::has_all_of
348 // Access: Published
349 // Description: Returns true if all bits in the indicated range are
350 // set, false otherwise.
351 ////////////////////////////////////////////////////////////////////
352 template<class BMType>
353 INLINE bool DoubleBitMask<BMType>::
354 has_all_of(int low_bit, int size) const {
355  if (low_bit >= half_bits) {
356  return _hi.has_all_of(low_bit - half_bits, size);
357  } else if (low_bit + size < half_bits) {
358  return _lo.has_all_of(low_bit, size);
359  } else {
360  int hi_portion = low_bit + size - half_bits;
361  int lo_portion = size - hi_portion;
362  return (_hi.has_all_of(0, hi_portion) << lo_portion) &&
363  _lo.has_all_of(low_bit, lo_portion);
364  }
365 }
366 
367 ////////////////////////////////////////////////////////////////////
368 // Function: DoubleBitMask::set_range
369 // Access: Published
370 // Description: Sets the indicated range of bits on.
371 ////////////////////////////////////////////////////////////////////
372 template<class BMType>
373 INLINE void DoubleBitMask<BMType>::
374 set_range(int low_bit, int size) {
375  if (low_bit >= half_bits) {
376  _hi.set_range(low_bit - half_bits, size);
377  } else if (low_bit + size < half_bits) {
378  _lo.set_range(low_bit, size);
379  } else {
380  int hi_portion = low_bit + size - half_bits;
381  int lo_portion = size - hi_portion;
382 
383  _hi.set_range(0, hi_portion);
384  _lo.set_range(low_bit, lo_portion);
385  }
386 }
387 
388 ////////////////////////////////////////////////////////////////////
389 // Function: DoubleBitMask::clear_range
390 // Access: Published
391 // Description: Sets the indicated range of bits off.
392 ////////////////////////////////////////////////////////////////////
393 template<class BMType>
394 INLINE void DoubleBitMask<BMType>::
395 clear_range(int low_bit, int size) {
396  if (low_bit >= half_bits) {
397  _hi.clear_range(low_bit - half_bits, size);
398  } else if (low_bit + size < half_bits) {
399  _lo.clear_range(low_bit, size);
400  } else {
401  int hi_portion = low_bit + size - half_bits;
402  int lo_portion = size - hi_portion;
403 
404  _hi.clear_range(0, hi_portion);
405  _lo.clear_range(low_bit, lo_portion);
406  }
407 }
408 
409 ////////////////////////////////////////////////////////////////////
410 // Function: DoubleBitMask::set_range_to
411 // Access: Published
412 // Description: Sets the indicated range of bits to either on or off.
413 ////////////////////////////////////////////////////////////////////
414 template<class BMType>
415 INLINE void DoubleBitMask<BMType>::
416 set_range_to(bool value, int low_bit, int size) {
417  if (value) {
418  set_range(low_bit, size);
419  } else {
420  clear_range(low_bit, size);
421  }
422 }
423 
424 ////////////////////////////////////////////////////////////////////
425 // Function: DoubleBitMask::get_num_on_bits
426 // Access: Published
427 // Description: Returns the number of bits that are set to 1 in the
428 // mask.
429 ////////////////////////////////////////////////////////////////////
430 template<class BMType>
431 INLINE int DoubleBitMask<BMType>::
433  return _lo.get_num_on_bits() + _hi.get_num_on_bits();
434 }
435 
436 ////////////////////////////////////////////////////////////////////
437 // Function: DoubleBitMask::get_num_off_bits
438 // Access: Published
439 // Description: Returns the number of bits that are set to 0 in the
440 // mask.
441 ////////////////////////////////////////////////////////////////////
442 template<class BMType>
443 INLINE int DoubleBitMask<BMType>::
445  return _lo.get_num_off_bits() + _hi.get_num_off_bits();
446 }
447 
448 ////////////////////////////////////////////////////////////////////
449 // Function: DoubleBitMask::get_lowest_on_bit
450 // Access: Published
451 // Description: Returns the index of the lowest 1 bit in the mask.
452 // Returns -1 if there are no 1 bits.
453 ////////////////////////////////////////////////////////////////////
454 template<class BMType>
455 INLINE int DoubleBitMask<BMType>::
457  int result = _lo.get_lowest_on_bit();
458  if (result == -1) {
459  result = _hi.get_lowest_on_bit();
460  if (result != -1) {
461  result += half_bits;
462  }
463  }
464  return result;
465 }
466 
467 ////////////////////////////////////////////////////////////////////
468 // Function: DoubleBitMask::get_lowest_off_bit
469 // Access: Published
470 // Description: Returns the index of the lowest 0 bit in the mask.
471 // Returns -1 if there are no 0 bits.
472 ////////////////////////////////////////////////////////////////////
473 template<class BMType>
474 INLINE int DoubleBitMask<BMType>::
476  int result = _lo.get_lowest_off_bit();
477  if (result == -1) {
478  result = _hi.get_lowest_off_bit();
479  if (result != -1) {
480  result += half_bits;
481  }
482  }
483  return result;
484 }
485 
486 ////////////////////////////////////////////////////////////////////
487 // Function: DoubleBitMask::get_highest_on_bit
488 // Access: Published
489 // Description: Returns the index of the highest 1 bit in the mask.
490 // Returns -1 if there are no 1 bits.
491 ////////////////////////////////////////////////////////////////////
492 template<class BMType>
493 INLINE int DoubleBitMask<BMType>::
495  int result = _hi.get_highest_on_bit();
496  if (result == -1) {
497  result = _lo.get_highest_on_bit();
498  } else {
499  result += half_bits;
500  }
501  return result;
502 }
503 
504 ////////////////////////////////////////////////////////////////////
505 // Function: DoubleBitMask::get_highest_off_bit
506 // Access: Published
507 // Description: Returns the index of the highest 0 bit in the mask.
508 // Returns -1 if there are no 0 bits.
509 ////////////////////////////////////////////////////////////////////
510 template<class BMType>
511 INLINE int DoubleBitMask<BMType>::
513  int result = _hi.get_highest_off_bit();
514  if (result == -1) {
515  result = _lo.get_highest_off_bit();
516  } else {
517  result += half_bits;
518  }
519  return result;
520 }
521 
522 ////////////////////////////////////////////////////////////////////
523 // Function: DoubleBitMask::get_next_higher_different_bit
524 // Access: Published
525 // Description: Returns the index of the next bit in the mask, above
526 // low_bit, whose value is different that the value of
527 // low_bit. Returns low_bit again if all bits higher
528 // than low_bit have the same value.
529 //
530 // This can be used to quickly iterate through all of
531 // the bits in the mask.
532 ////////////////////////////////////////////////////////////////////
533 template<class BMType>
534 INLINE int DoubleBitMask<BMType>::
535 get_next_higher_different_bit(int low_bit) const {
536  if (low_bit > half_bits) {
537  return _hi.get_next_higher_different_bit(low_bit - half_bits) + half_bits;
538  }
539  int result = _lo.get_next_higher_different_bit(low_bit);
540  if (result != low_bit) {
541  return result;
542  }
543  if (_lo.get_bit(low_bit)) {
544  result = _hi.get_lowest_off_bit();
545  } else {
546  result = _hi.get_lowest_on_bit();
547  }
548  if (result == -1) {
549  return low_bit;
550  }
551  return result + half_bits;
552 }
553 
554 ////////////////////////////////////////////////////////////////////
555 // Function: DoubleBitMask::invert_in_place
556 // Access: Published
557 // Description: Inverts all the bits in the DoubleBitMask. This is
558 // equivalent to mask = ~mask.
559 ////////////////////////////////////////////////////////////////////
560 template<class BMType>
561 INLINE void DoubleBitMask<BMType>::
563  _lo.invert_in_place();
564  _hi.invert_in_place();
565 }
566 
567 ////////////////////////////////////////////////////////////////////
568 // Function: DoubleBitMask::has_bits_in_common
569 // Access: Published
570 // Description: Returns true if this DoubleBitMask has any "one" bits in
571 // common with the other one, false otherwise.
572 //
573 // This is equivalent to (mask & other) != 0, but may be
574 // faster. (Actually, it should only be faster in the
575 // BitArray case, but this method is provided for the
576 // benefit of generic programming algorithms).
577 ////////////////////////////////////////////////////////////////////
578 template<class BMType>
579 INLINE bool DoubleBitMask<BMType>::
581  return _lo.has_bits_in_common(other._lo) ||
582  _hi.has_bits_in_common(other._hi);
583 }
584 
585 ////////////////////////////////////////////////////////////////////
586 // Function: DoubleBitMask::clear
587 // Access: Published
588 // Description: Sets all the bits in the DoubleBitMask off.
589 ////////////////////////////////////////////////////////////////////
590 template<class BMType>
591 INLINE void DoubleBitMask<BMType>::
592 clear() {
593  _lo.clear();
594  _hi.clear();
595 }
596 
597 ////////////////////////////////////////////////////////////////////
598 // Function: DoubleBitMask::output
599 // Access: Published
600 // Description: Writes the DoubleBitMask out as a binary or a hex number,
601 // according to the number of bits.
602 ////////////////////////////////////////////////////////////////////
603 template<class BMType>
605 output(ostream &out) const {
606  output_hex(out);
607 }
608 
609 ////////////////////////////////////////////////////////////////////
610 // Function: DoubleBitMask::output_binary
611 // Access: Published
612 // Description: Writes the DoubleBitMask out as a binary number, with
613 // spaces every four bits.
614 ////////////////////////////////////////////////////////////////////
615 template<class BMType>
617 output_binary(ostream &out, int spaces_every) const {
618  _hi.output_binary(out);
619  out << ' ';
620  _lo.output_binary(out);
621 }
622 
623 ////////////////////////////////////////////////////////////////////
624 // Function: DoubleBitMask::output_hex
625 // Access: Published
626 // Description: Writes the DoubleBitMask out as a hexadecimal number, with
627 // spaces every four digits.
628 ////////////////////////////////////////////////////////////////////
629 template<class BMType>
631 output_hex(ostream &out, int spaces_every) const {
632  _hi.output_hex(out);
633  out << ' ';
634  _lo.output_hex(out);
635 }
636 
637 ////////////////////////////////////////////////////////////////////
638 // Function: DoubleBitMask::write
639 // Access: Published
640 // Description: Writes the DoubleBitMask out as a binary or a hex number,
641 // according to the number of bits.
642 ////////////////////////////////////////////////////////////////////
643 template<class BMType>
645 write(ostream &out, int indent_level) const {
646  indent(out, indent_level) << *this << "\n";
647 }
648 
649 ////////////////////////////////////////////////////////////////////
650 // Function: DoubleBitMask::operator ==
651 // Access: Published
652 // Description:
653 ////////////////////////////////////////////////////////////////////
654 template<class BMType>
655 INLINE bool DoubleBitMask<BMType>::
656 operator == (const DoubleBitMask<BMType> &other) const {
657  return _lo == other._lo && _hi == other._hi;
658 }
659 
660 ////////////////////////////////////////////////////////////////////
661 // Function: DoubleBitMask::operator !=
662 // Access: Published
663 // Description:
664 ////////////////////////////////////////////////////////////////////
665 template<class BMType>
666 INLINE bool DoubleBitMask<BMType>::
667 operator != (const DoubleBitMask<BMType> &other) const {
668  return _lo != other._lo && _hi != other._hi;
669 }
670 
671 ////////////////////////////////////////////////////////////////////
672 // Function: DoubleBitMask::operator <
673 // Access: Published
674 // Description: The ordering operator is of limited usefulness with a
675 // DoubleBitMask, however, it has a definition which places
676 // all unique DoubleBitMasks into a unique ordering. It may
677 // be useful when defining ordered STL containers of
678 // DoubleBitMasks, for instance; and it's required in order to
679 // export any STL container (ordered or unordered) of
680 // DoubleBitMask under Windows.
681 ////////////////////////////////////////////////////////////////////
682 template<class BMType>
683 INLINE bool DoubleBitMask<BMType>::
684 operator < (const DoubleBitMask<BMType> &other) const {
685  int cmp = _hi.compare_to(other._hi);
686  if (cmp != 0) {
687  return cmp < 0;
688  }
689  return _lo < other._lo;
690 }
691 
692 ////////////////////////////////////////////////////////////////////
693 // Function: DoubleBitMask::compare_to
694 // Access: Published
695 // Description: Returns a number less than zero if this DoubleBitMask sorts
696 // before the indicated other DoubleBitMask, greater than zero
697 // if it sorts after, or 0 if they are equivalent. This
698 // is based on the same ordering defined by operator <.
699 ////////////////////////////////////////////////////////////////////
700 template<class BMType>
701 INLINE int DoubleBitMask<BMType>::
702 compare_to(const DoubleBitMask<BMType> &other) const {
703  int cmp = _hi.compare_to(other._hi);
704  if (cmp != 0) {
705  return cmp;
706  }
707  return _lo.compare_to(other._lo);
708 }
709 
710 ////////////////////////////////////////////////////////////////////
711 // Function: DoubleBitMask::operator &
712 // Access: Published
713 // Description:
714 ////////////////////////////////////////////////////////////////////
715 template<class BMType>
717 operator & (const DoubleBitMask<BMType> &other) const {
718  DoubleBitMask<BMType> result(*this);
719  result &= other;
720  return result;
721 }
722 
723 ////////////////////////////////////////////////////////////////////
724 // Function: DoubleBitMask::operator |
725 // Access: Published
726 // Description:
727 ////////////////////////////////////////////////////////////////////
728 template<class BMType>
730 operator | (const DoubleBitMask<BMType> &other) const {
731  DoubleBitMask<BMType> result(*this);
732  result |= other;
733  return result;
734 }
735 
736 ////////////////////////////////////////////////////////////////////
737 // Function: DoubleBitMask::operator ^
738 // Access: Published
739 // Description:
740 ////////////////////////////////////////////////////////////////////
741 template<class BMType>
743 operator ^ (const DoubleBitMask<BMType> &other) const {
744  DoubleBitMask<BMType> result(*this);
745  result ^= other;
746  return result;
747 }
748 
749 ////////////////////////////////////////////////////////////////////
750 // Function: DoubleBitMask::operator ~
751 // Access: Published
752 // Description:
753 ////////////////////////////////////////////////////////////////////
754 template<class BMType>
756 operator ~ () const {
757  DoubleBitMask<BMType> result(*this);
758  result.invert_in_place();
759  return result;
760 }
761 
762 ////////////////////////////////////////////////////////////////////
763 // Function: DoubleBitMask::operator <<
764 // Access: Published
765 // Description:
766 ////////////////////////////////////////////////////////////////////
767 template<class BMType>
769 operator << (int shift) const {
770  DoubleBitMask<BMType> result(*this);
771  result <<= shift;
772  return result;
773 }
774 
775 ////////////////////////////////////////////////////////////////////
776 // Function: DoubleBitMask::operator >>
777 // Access: Published
778 // Description:
779 ////////////////////////////////////////////////////////////////////
780 template<class BMType>
782 operator >> (int shift) const {
783  DoubleBitMask<BMType> result(*this);
784  result >>= shift;
785  return result;
786 }
787 
788 ////////////////////////////////////////////////////////////////////
789 // Function: DoubleBitMask::operator &=
790 // Access: Published
791 // Description:
792 ////////////////////////////////////////////////////////////////////
793 template<class BMType>
794 INLINE void DoubleBitMask<BMType>::
795 operator &= (const DoubleBitMask<BMType> &other) {
796  _lo &= other._lo;
797  _hi &= other._hi;
798 }
799 
800 ////////////////////////////////////////////////////////////////////
801 // Function: DoubleBitMask::operator |=
802 // Access: Published
803 // Description:
804 ////////////////////////////////////////////////////////////////////
805 template<class BMType>
806 INLINE void DoubleBitMask<BMType>::
807 operator |= (const DoubleBitMask<BMType> &other) {
808  _lo |= other._lo;
809  _hi |= other._hi;
810 }
811 
812 ////////////////////////////////////////////////////////////////////
813 // Function: DoubleBitMask::operator ^=
814 // Access: Published
815 // Description:
816 ////////////////////////////////////////////////////////////////////
817 template<class BMType>
818 INLINE void DoubleBitMask<BMType>::
819 operator ^= (const DoubleBitMask<BMType> &other) {
820  _lo ^= other._lo;
821  _hi ^= other._hi;
822 }
823 
824 ////////////////////////////////////////////////////////////////////
825 // Function: DoubleBitMask::operator <<=
826 // Access: Published
827 // Description:
828 ////////////////////////////////////////////////////////////////////
829 template<class BMType>
830 INLINE void DoubleBitMask<BMType>::
831 operator <<= (int shift) {
832  _hi = (_hi << shift) | ((_lo >> half_bits - shift) & BitMaskType::lower_on(shift));
833  _lo <<= shift;
834 }
835 
836 ////////////////////////////////////////////////////////////////////
837 // Function: DoubleBitMask::operator >>=
838 // Access: Published
839 // Description:
840 ////////////////////////////////////////////////////////////////////
841 template<class BMType>
842 INLINE void DoubleBitMask<BMType>::
843 operator >>= (int shift) {
844  _lo = (_lo >> shift) | ((_hi & BitMaskType::lower_on(shift)) << half_bits - shift);
845  _hi >>= shift;
846 }
847 
848 ////////////////////////////////////////////////////////////////////
849 // Function: DoubleBitMask::generate_hash
850 // Access: Public
851 // Description: Adds the doubleBitMask to the indicated hash generator.
852 ////////////////////////////////////////////////////////////////////
853 template<class BMType>
854 INLINE void DoubleBitMask<BMType>::
856  _hi.generate_hash(hashgen);
857  _lo.generate_hash(hashgen);
858 }
859 
860 ////////////////////////////////////////////////////////////////////
861 // Function: DoubleBitMask::init_type
862 // Access: Public
863 // Description:
864 ////////////////////////////////////////////////////////////////////
865 template<class BMType>
867 init_type() {
868  ostringstream str;
869  str << "DoubleBitMask" << num_bits;
870  register_type(_type_handle, str.str());
871 }
bool is_all_on() const
Returns true if the entire doubleBitMask is one, false otherwise.
void write(ostream &out, int indent_level=0) const
Writes the DoubleBitMask out as a binary or a hex number, according to the number of bits...
This is a specific kind of HashGenerator that simply adds up all of the ints.
void clear_range(int low_bit, int size)
Sets the indicated range of bits off.
static DoubleBitMask< BMType > range(int low_bit, int size)
Returns a DoubleBitMask whose size bits, beginning at low_bit, are on.
void output(ostream &out) const
Writes the DoubleBitMask out as a binary or a hex number, according to the number of bits...
bool operator<(const DoubleBitMask< BMType > &other) const
The ordering operator is of limited usefulness with a DoubleBitMask, however, it has a definition whi...
int get_lowest_on_bit() const
Returns the index of the lowest 1 bit in the mask.
void set_range_to(bool value, int low_bit, int size)
Sets the indicated range of bits to either on or off.
void generate_hash(ChecksumHashGenerator &hashgen) const
Adds the doubleBitMask to the indicated hash generator.
int get_highest_on_bit() const
Returns the index of the highest 1 bit in the mask.
This is a special BitMask type that is implemented as a pair of lesser BitMask types, to present a double-wide bit mask.
Definition: doubleBitMask.h:32
void output_hex(ostream &out, int spaces_every=4) const
Writes the DoubleBitMask out as a hexadecimal number, with spaces every four digits.
void store(WordType value, int low_bit, int size)
Stores the indicated word into the indicated range of bits with this DoubleBitMask.
bool has_any_of(int low_bit, int size) const
Returns true if any bit in the indicated range is set, false otherwise.
void clear_bit(int index)
Sets the nth bit off.
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...
static DoubleBitMask< BMType > lower_on(int on_bits)
Returns a DoubleBitMask whose lower on_bits bits are on.
Definition: doubleBitMask.I:89
bool get_bit(int index) const
Returns true if the nth bit is set, false if it is cleared.
int get_lowest_off_bit() const
Returns the index of the lowest 0 bit in the mask.
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...
void output_binary(ostream &out, int spaces_every=4) const
Writes the DoubleBitMask out as a binary number, with spaces every four bits.
void set_range(int low_bit, int size)
Sets the indicated range of bits on.
WordType extract(int low_bit, int size) const
Returns a word that represents only the indicated range of bits within this DoubleBitMask, shifted to the least-significant position.
void clear()
Sets all the bits in the DoubleBitMask off.
void set_bit_to(int index, bool value)
Sets the nth bit either on or off, according to the indicated bool value.
int get_num_off_bits() const
Returns the number of bits that are set to 0 in the mask.
static CONSTEXPR int get_num_bits()
Returns the number of bits available to set in the doubleBitMask.
void set_bit(int index)
Sets the nth bit on.
static DoubleBitMask< BMType > all_on()
Returns a DoubleBitMask whose bits are all on.
Definition: doubleBitMask.I:61
bool is_zero() const
Returns true if the entire doubleBitMask is zero, false otherwise.
static DoubleBitMask< BMType > bit(int index)
Returns a DoubleBitMask with only the indicated bit on.
int get_num_on_bits() const
Returns the number of bits that are set to 1 in the mask.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
int compare_to(const DoubleBitMask< BMType > &other) const
Returns a number less than zero if this DoubleBitMask sorts before the indicated other DoubleBitMask...
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.
void invert_in_place()
Inverts all the bits in the DoubleBitMask.
int get_highest_off_bit() const
Returns the index of the highest 0 bit in the mask.
bool has_bits_in_common(const DoubleBitMask< BMType > &other) const
Returns true if this DoubleBitMask has any "one" bits in common with the other one, false otherwise.
static DoubleBitMask< BMType > all_off()
Returns a DoubleBitMask whose bits are all off.
Definition: doubleBitMask.I:75
bool has_all_of(int low_bit, int size) const
Returns true if all bits in the indicated range are set, false otherwise.