HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
mask.h
Go to the documentation of this file.
1 //
2 // Copyright 2025 Pixar
3 //
4 // Licensed under the terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 #ifndef PXR_EXEC_VDF_MASK_H
8 #define PXR_EXEC_VDF_MASK_H
9 
10 /// \file
11 
12 #include "pxr/pxr.h"
13 
14 #include "pxr/exec/vdf/api.h"
15 
18 #include "pxr/base/tf/diagnostic.h"
19 #include "pxr/base/tf/staticData.h"
20 
21 #include <atomic>
22 #include <functional>
23 #include <iosfwd>
24 #include <string>
25 #include <utility>
26 
28 
29 ////////////////////////////////////////////////////////////////////////////////
30 ///
31 /// \class VdfMask
32 ///
33 /// \brief A VdfMask is placed on connections to specify the data flowing
34 /// through them.
35 ///
36 class VdfMask
37 {
38  class _BitsImpl;
39 
40 public:
41  /// Typedef on the internal bitset implementation used.
42  ///
43  typedef TfCompressedBits Bits;
44 
45  /// Constructs an empty mask.
46  ///
47  VdfMask() {}
48 
49  /// Constructs a mask of size \p size.
50  ///
51  explicit VdfMask(size_t size) {
52  // If size == 0, we want to leave the optional _bits uninitialized.
53  // This is important, because we use the uninitialized optional as a
54  // sentinal for a zero size mask, and we need to be consistent about
55  // that.
56  if (size != 0) {
57  _bits = _FindOrInsert(VdfMask::Bits(size));
58  }
59  }
60 
61  /// Constructs a mask from VdfMask::Bits.
62  ///
63  explicit VdfMask(VdfMask::Bits const &bits) {
64  // If the bits denote a 1x1 mask, use the static 1x1 mask for
65  // initialization. This prevents a call to _FindOrInsert, which locks
66  // on the mask registry.
67  if (bits.GetSize() == 1 && bits.AreAllSet()) {
68  *this = _GetAllOnes1();
69  }
70 
71  // If size == 0, we want to leave the optional _bits uninitialized.
72  // This is important, because we use the uninitialized optional as a
73  // sentinal for a zero size mask, and we need to be consistent about
74  // that.
75  else if (bits.GetSize() != 0) {
76  _bits = _FindOrInsert(bits);
77  }
78  }
79 
80  /// Constructs a mask by *moving* the contents of \p bits into
81  /// the mask.
82  ///
83  /// \p *bits may not be used after passing it to this constructor.
84  ///
85  explicit VdfMask(VdfMask::Bits &&bits) {
86  if (bits.GetSize() != 0) {
87  _bits = _FindOrEmplace(std::move(bits));
88  }
89  }
90 
91  /// Swap this mask's bits with \p rhs.
92  ///
93  void Swap(VdfMask &rhs) noexcept {
94  _bits.swap(rhs._bits);
95  }
96 
97  /// Swap \p lhs's bits with \p rhs.
98  ///
99  friend void swap(VdfMask &lhs, VdfMask &rhs) noexcept {
100  lhs.Swap(rhs);
101  }
102 
103  /// Enables all the bits in the mask.
104  ///
105  void SetAll() {
106  if (!_bits) {
107  return;
108  }
109 
110  VdfMask::Bits bits(_bits->Get().GetSize());
111  bits.Complement();
112  _bits = _FindOrInsert(bits);
113  }
114 
115  /// Adds the given \p index to the mask.
116  ///
117  /// The corresponding element will be set after this call.
118  ///
119  void SetIndex(size_t index) {
120  if (!TF_VERIFY(_bits)) {
121  return;
122  }
123 
124  VdfMask::Bits copy(_bits->Get());
125  copy.Set(index);
126  _bits = _FindOrEmplace(std::move(copy));
127  }
128 
129  /// Returns true if mask at index is set
130  ///
131  bool IsSet(size_t index) const {
132  if (!TF_VERIFY(_bits)) {
133  return false;
134  }
135 
136  return _bits->Get().IsSet(index);
137  }
138 
139  /// Removes the given \p index from the mask.
140  ///
141  /// The corresponding element will be cleared after this call.
142  ///
143  void ClearIndex(size_t index) {
144  if (!TF_VERIFY(_bits)) {
145  return;
146  }
147 
148  VdfMask::Bits copy(_bits->Get());
149  copy.Clear(index);
150  _bits = _FindOrEmplace(std::move(copy));
151  }
152 
153  /// Returns the size of the mask.
154  ///
155  /// This is the number of elements that can be indexed in the mask,
156  /// not the number of elements set.
157  ///
158  size_t GetSize() const {
159  if (!_bits) {
160  return 0;
161  }
162 
163  return _bits->Get().GetSize();
164  }
165 
166  /// Returns \c true if this mask is empty, i.e. it is of size zero.
167  ///
168  bool IsEmpty() const {
169  return !_bits;
170  }
171 
172  /// Returns \c true if this mask and \p mask have any set entries in
173  /// common, and \c false otherwise.
174  ///
175  bool Overlaps(const VdfMask &mask) const {
176  if (_bits == mask._bits) {
177  return IsAnySet();
178  }
179 
180  return GetBits().HasNonEmptyIntersection(mask.GetBits());
181  }
182 
183  /// Returns \c true if \p mask is a subset-of or equal to this mask,
184  /// \c false otherwise.
185  ///
186  bool Contains(const VdfMask &mask) const {
187  if (_bits == mask._bits) {
188  return true;
189  }
190 
191  return !mask.GetBits().HasNonEmptyDifference(GetBits());
192  }
193 
194  /// Returns true if this mask has all entries set.
195  ///
196  bool IsAllOnes() const {
197  if (!_bits) {
198  return true;
199  }
200 
201  return _bits->Get().AreAllSet();
202  }
203 
204  /// Returns true if this mask has all entries unset.
205  ///
206  bool IsAllZeros() const {
207  if (!_bits) {
208  return true;
209  }
210 
211  return _bits->Get().AreAllUnset();
212  }
213 
214  /// Returns true, if there is at least a single set entry.
215  ///
216  bool IsAnySet() const {
217  if (!_bits) {
218  return false;
219  }
220 
221  return _bits->Get().IsAnySet();
222  }
223 
224  /// Returns the first set bit in the mask.
225  ///
226  size_t GetFirstSet() const {
227  if (!_bits) {
228  return 0;
229  }
230 
231  return _bits->Get().GetFirstSet();
232  }
233 
234  /// Returns the last set bit in the mask.
235  ///
236  size_t GetLastSet() const {
237  if (!_bits) {
238  return 0;
239  }
240 
241  return _bits->Get().GetLastSet();
242  }
243 
244  /// Returns the number of set bits in the mask.
245  ///
246  size_t GetNumSet() const {
247  if (!_bits) {
248  return 0;
249  }
250 
251  return _bits->Get().GetNumSet();
252  }
253 
254  /// Returns true if the set bits in the mask are contiguous.
255  ///
256  /// Note: This returns false if there are no set bits in the mask.
257  ///
258  bool IsContiguous() const {
259  if (!_bits) {
260  return false;
261  }
262 
263  return _bits->Get().AreContiguouslySet();
264  }
265 
266  /// \name Operators
267  /// @{
268 
269  /// Returns true if this and \p rhs are equal, false otherwise.
270  ///
271  bool operator==(const VdfMask &rhs) const {
272  return _bits == rhs._bits;
273  }
274 
275  bool operator!=(const VdfMask &rhs) const {
276  return !(*this == rhs);
277  }
278 
279  /// Arbitrary total ordering of masks. The order does not depend on the
280  /// actual mask values and may change from run to run.
281  ///
283  {
284  bool operator()(const VdfMask &lhs, const VdfMask &rhs) const
285  {
286  return lhs._bits < rhs._bits;
287  }
288  };
289 
290  /// Ands two masks together.
291  ///
292  /// The result is that an element is set iff it is set in both masks.
293  ///
294  VdfMask &operator&=(const VdfMask &rhs) {
295  if (_bits == rhs._bits) {
296  return *this;
297  }
298 
299  _bits = _FindOrEmplace(GetBits() & rhs.GetBits());
300  return *this;
301  }
302 
303  VdfMask operator&(const VdfMask &rhs) const {
304  VdfMask r(*this);
305  r &= rhs;
306  return r;
307  }
308 
309  /// Ors two masks together.
310  ///
311  /// The result is that an element is set iff it is set in either mask.
312  ///
313  VdfMask &operator|=(const VdfMask &rhs) {
314  if (_bits == rhs._bits) {
315  return *this;
316  }
317 
318  _bits = _FindOrEmplace(GetBits() | rhs.GetBits());
319  return *this;
320  }
321 
322  VdfMask operator|(const VdfMask &rhs) const {
323  VdfMask r(*this);
324  r |= rhs;
325  return r;
326  }
327 
328  /// Xors two masks together.
329  ///
330  /// The result is that an element is set iff it is set in exactly one
331  /// of the two masks.
332  ///
333  VdfMask &operator^=(const VdfMask &rhs) {
334  if (!_bits && TF_VERIFY(!rhs._bits)) {
335  return *this;
336  }
337 
338  _bits = _FindOrEmplace(GetBits() ^ rhs.GetBits());
339  return *this;
340  }
341 
342  VdfMask operator^(const VdfMask &rhs) const {
343  VdfMask r(*this);
344  r ^= rhs;
345  return r;
346  }
347 
348  /// Performs an asymmetric set difference.
349  ///
350  /// This method turns off the bits that are set in both \p this and
351  /// in \p rhs.
352  ///
353  VdfMask &operator-=(const VdfMask &rhs) {
354  if (!_bits && TF_VERIFY(!rhs._bits)) {
355  return *this;
356  }
357 
358  VdfMask::Bits copy = GetBits();
359  copy -= rhs.GetBits();
360  _bits = _FindOrEmplace(std::move(copy));
361  return *this;
362  }
363 
364  VdfMask operator-(const VdfMask &rhs) const {
365  VdfMask r(*this);
366  r -= rhs;
367  return r;
368  }
369 
370  /// Complement. Flips all the bits in the mask.
371  ///
373  if (!_bits) {
374  return *this;
375  }
376 
377  _bits = _FindOrEmplace(
379  return *this;
380  }
381 
382  /// Sets this mask to \p rhs if this mask is of zero size. Otherwise, will
383  /// or \p rhs to this mask.
384  ///
385  VdfMask &SetOrAppend(const VdfMask &rhs) {
386  if (!_bits) {
387  *this = rhs;
388  } else {
389  *this |= rhs;
390  }
391  return *this;
392  }
393 
394  /// @}
395 
396 
397  /// Iterator class used to iterate through the elements of the mask.
398  ///
399  class iterator {
400  using _BaseIterator = VdfMask::Bits::AllSetView::const_iterator;
401 
402  public:
404 
405  /// Constructs an null iterator that is already at end.
406  ///
407  iterator() {}
408 
409  /// Returns \c true if this iterator and rhs compare equal.
410  ///
411  bool operator==(const iterator &rhs) const {
412  return _it == rhs._it;
413  }
414 
415  /// Returns \c true if this iterator and rhs do not compare equal.
416  ///
417  bool operator!=(const iterator &rhs) const {
418  return !operator==(rhs);
419  }
420 
421  /// Returns the index of the current element.
422  ///
424  return *_it;
425  }
426 
427  /// Increment the iterator to the next element.
428  ///
430  ++_it;
431  return *this;
432  }
433 
434  /// Returns true if the iteration is finished.
435  ///
436  bool IsAtEnd() const {
437  return _it.IsAtEnd();
438  }
439 
440  /// Advance the iterator to the end.
441  ///
442  void AdvanceToEnd() {
443  _it = _BaseIterator();
444  }
445 
446  /// Advance the iterator to the first index that is set in the mask
447  /// located at or after \p index.
448  ///
450  if (_it.IsAtEnd()) {
451  return 0;
452  }
453 
454  // The index must be ahead of the current iterator position.
455  TF_DEV_AXIOM(index >= *_it);
456 
457  // We can simply increment the underlying VdfMask::Bits iterator
458  // until we reach (past) index.
459  while (!_it.IsAtEnd() && *_it < index) {
460  ++_it;
461  }
462  return *_it;
463  }
464 
465  private:
466 
467  // Only a mask is a allowed to create an iterator.
468  iterator(const VdfMask::Bits *bits) :
469  _it(bits->GetAllSetView().begin())
470  {}
471 
472  friend class VdfMask;
473 
474  // The wrapped VdfMask::Bits iterator
475  _BaseIterator _it;
476  };
477 
478 
479  /// Returns an iterator that can be used to iterate through the elements
480  /// of the mask.
481  ///
482  iterator begin() const {
483  if (!_bits) {
485  }
486 
487  return iterator(&_bits->Get());
488  }
489 
490 
491  /// Returns a mask of the requested size that will iterate over all
492  /// elements.
493  ///
494  static VdfMask AllOnes(size_t size) {
495  // special-case all-ones of size 1 and 0
496  if (size == 0) {
497  return VdfMask();
498  } else if (size == 1) {
499  return _GetAllOnes1();
500  }
501 
502  VdfMask::Bits bits(size);
503  bits.SetAll();
504  return VdfMask(bits);
505  }
506 
507  /// Returns a mask of the requested size where no element is set.
508  ///
509  static VdfMask AllZeros(size_t size) {
510  // special-case all-zeros of size 0
511  if (size == 0) {
512  return VdfMask();
513  }
514 
515  return VdfMask(size);
516  }
517 
518  /// \name Debugging API
519  /// @{
520  ///
521 
522  /// Returns the mask in an RLE format.
523  ///
524  /// This is useful for debugging large masks.
525  /// For example, the output of a mask that is 110001111 would be:
526  /// 1x2-0x3-1x4
527  ///
528  std::string GetRLEString() const {
529  if (!_bits) {
530  return std::string();
531  }
532 
533  return _bits->Get().GetAsRLEString();
534  }
535 
536  /// Returns the amount of memory in bytes used by this mask. Note that
537  /// masks are now shared, so this method is of dubious value.
538  ///
539  size_t GetMemoryUsage() const {
540  if (!_bits) {
541  return 0;
542  }
543 
544  return _bits->Get().GetAllocatedSize();
545  }
546 
547  /// @}
548 
549 
550  /// \name Performance Considerations
551  /// @{
552  ///
553 
554  /// Get this mask's content as CtCompressedfBits. This should not be used
555  /// except where performance is critical.
556  VdfMask::Bits const &GetBits() const {
557  if (!_bits) {
558  return VdfMask::Bits::GetEmpty();
559  }
560 
561  return _bits->Get();
562  }
563 
564  /// Returns a hash for the mask.
565  size_t GetHash() const {
566  return std::hash<_BitsImpl*>()(_bits.get());
567  }
568 
569  /// Hash Functor.
570  ///
571  struct HashFunctor {
572  size_t operator()(const VdfMask &mask) const {
573  return mask.GetHash();
574  }
575  };
576 
577  /// @}
578 
579 private:
580 
581  struct _AllOnes1Factory
582  {
583  static VdfMask * New()
584  {
585  return new VdfMask(_AllOnes1Factory());
586  }
587  };
588 
589  explicit VdfMask(const _AllOnes1Factory &) {
590  Bits allOnes1Bits(1);
591  allOnes1Bits.SetAll();
592  _bits = _FindOrInsert(allOnes1Bits);
593  }
594 
595  static VdfMask _GetAllOnes1() {
596  return *_allOnes1;
597  }
598 
599  // Befriend the stream operator so that VdfMasks support output streaming.
600  friend VDF_API std::ostream & operator<<(
601  std::ostream &os, const VdfMask &mask);
602 
603  // Refcounted hash table nodes for VdfMask::Bits.
604  //
605  class _BitsImpl
606  {
607  public:
608  // Non-copyable
609  _BitsImpl(const _BitsImpl &) = delete;
610  _BitsImpl& operator=(const _BitsImpl &) = delete;
611 
612  // Non-movable
613  _BitsImpl(_BitsImpl &&) = delete;
614  _BitsImpl& operator=(_BitsImpl &&) = delete;
615 
616  // Provide const access to the bits. Flyweighting requires that
617  // the value is never mutated.
618  //
619  const VdfMask::Bits &Get() const { return _bits; }
620 
621  // Return the pre-computed hash value for _bits.
622  //
623  // Implemented in MaskRegistry.h
624  //
625  size_t GetHash() const;
626 
627  private:
628  // next points to the next entry in the hash bucket (if any) for
629  // \p bits.
630  //
631  _BitsImpl(_BitsImpl *next, size_t hash, VdfMask::Bits &&bits);
632 
633  friend inline void TfDelegatedCountIncrement(_BitsImpl *p) noexcept;
634  friend inline void TfDelegatedCountDecrement(_BitsImpl *p) noexcept;
635 
636  friend class Vdf_MaskRegistry;
637 
638  _BitsImpl *_next;
639  size_t _hash;
640  VdfMask::Bits _bits;
641  std::atomic<int> _refCount;
642  // Note that the resurrection count is bounded by the number of threads
643  // concurrently accessing masks, thus a 16-bit integer is sufficient.
644  std::atomic<uint16_t> _resurrectionCount;
645  bool _isImmortal;
646  };
647 
648  friend inline void TfDelegatedCountIncrement(_BitsImpl *p) noexcept;
649  friend inline void TfDelegatedCountDecrement(_BitsImpl *p) noexcept;
650 
651  friend class Vdf_MaskRegistry;
652 
654 
655  // Return a ref ptr to the \c _BitsImpl corresponding to \p *bits. If an
656  // existing _BitsImpl for \p *bits is not found, create a new one by
657  // *moving* the contents out of \p *bits and into the new \c _BitsImpl.
658  //
659  // Do not use \p *bits after passing it to this function.
660  //
661  VDF_API
662  static _BitsImplRefPtr _FindOrEmplace(VdfMask::Bits &&bits);
663 
664  // Return a ref ptr to the \c _BitsImpl corresponding to \p bits. If an
665  // existing _BitsImpl for \p bits is not found, create a new one by
666  // copying \p bits.
667  //
668  VDF_API
669  static _BitsImplRefPtr _FindOrInsert(const VdfMask::Bits &bits);
670 
671  // Erase the _BitsImpl pointed to by \p bits.
672  //
673  VDF_API
674  static void _EraseBits(_BitsImpl *bits);
675 
676 private:
677  // Default constructed / empty masks are represented as null
678  // _BitsImplRefPtr.
679  _BitsImplRefPtr _bits;
680 
681  // AllOnes mask of size 1 optimization.
683 };
684 
685 // Specialize TfDelegatedCountPtr operations for VdfMask::_BitsImpl.
686 inline void TfDelegatedCountIncrement(VdfMask::_BitsImpl *p) noexcept
687 {
688  // For immortal masks there is no need to maintain the reference count.
689  if (p->_isImmortal) {
690  return;
691  }
692 
693  // There's no need for a stronger memory ordering here because we can only
694  // increase the ref count by way of an existing reference and sharing an
695  // existing VdfMask between threads requires external synchronization,
696  // just like any other non-atomic type.
697  //
698  // Note that Vdf_MaskRegistry manages reference counting and serialization
699  // for threads that are looking up the same bits concurrently rather than
700  // simply making copies of an existing VdfMask.
701  p->_refCount.fetch_add(1, std::memory_order_relaxed);
702 }
703 inline void TfDelegatedCountDecrement(VdfMask::_BitsImpl *p) noexcept
704 {
705  // For immortal masks there is no need to maintain the reference count.
706  if (p->_isImmortal) {
707  return;
708  }
709 
710  // Many threads may decrement the ref count but only one thread will be
711  // responsible for deleting it. However, we must ensure that all of the
712  // memory operations in all of the threads happen before the final thread
713  // performs the deletion. To establish this happens-before relationship,
714  // we need a release-acquire pair of atomic operations.
715  const int prevRC = p->_refCount.fetch_sub(1, std::memory_order_release);
716  if (prevRC == 1) {
717  // Use an acquire fence here because we only need to synchronize with
718  // the decrement accesses when we're about to perform the deletion.
719  std::atomic_thread_fence(std::memory_order_acquire);
720  VdfMask::_EraseBits(p);
721  }
722 }
723 
724 // Output stream operator
725 VDF_API
726 std::ostream &
727 operator<<(std::ostream &os, const VdfMask &mask);
728 
730 
731 #endif
bool AreAllSet() const
bool operator()(const VdfMask &lhs, const VdfMask &rhs) const
Definition: mask.h:284
VdfMask()
Definition: mask.h:47
bool IsContiguous() const
Definition: mask.h:258
VdfMask & operator-=(const VdfMask &rhs)
Definition: mask.h:353
size_t GetFirstSet() const
Definition: mask.h:226
bool IsEmpty() const
Definition: mask.h:168
void TfDelegatedCountIncrement(VdfMask::_BitsImpl *p) noexcept
Definition: mask.h:686
size_t GetHash() const
Returns a hash for the mask.
Definition: mask.h:565
_BaseIterator::value_type value_type
Definition: mask.h:403
#define PXR_NAMESPACE_OPEN_SCOPE
Definition: pxr.h:73
iterator & operator++()
Definition: mask.h:429
A VdfMask is placed on connections to specify the data flowing through them.
Definition: mask.h:36
static VdfMask AllOnes(size_t size)
Definition: mask.h:494
friend class Vdf_MaskRegistry
Definition: mask.h:651
bool IsAnySet() const
Definition: mask.h:216
bool HasNonEmptyDifference(const TfCompressedBits &rhs) const
#define VDF_API
Definition: api.h:25
VdfMask & Complement()
Definition: mask.h:372
uint64 value_type
Definition: GA_PrimCompat.h:29
VdfMask::Bits const & GetBits() const
Definition: mask.h:556
Fast, compressed bit array which is capable of performing logical operations without first decompress...
VdfMask operator-(const VdfMask &rhs) const
Definition: mask.h:364
bool operator!=(const iterator &rhs) const
Definition: mask.h:417
VdfMask & operator&=(const VdfMask &rhs)
Definition: mask.h:294
void SetIndex(size_t index)
Definition: mask.h:119
RawPtrType get() const noexcept
Return the underlying pointer.
bool Overlaps(const VdfMask &mask) const
Definition: mask.h:175
VdfMask(size_t size)
Definition: mask.h:51
#define TF_DEV_AXIOM(cond)
VdfMask(VdfMask::Bits &&bits)
Definition: mask.h:85
void ClearIndex(size_t index)
Definition: mask.h:143
VDF_API std::ostream & operator<<(std::ostream &os, const VdfMask &mask)
bool operator==(const VdfMask &rhs) const
Definition: mask.h:271
TfCompressedBits Bits
Definition: mask.h:38
GLint GLuint mask
Definition: glcorearb.h:124
bool IsAtEnd() const
Definition: mask.h:436
VdfMask operator^(const VdfMask &rhs) const
Definition: mask.h:342
VdfMask & operator|=(const VdfMask &rhs)
Definition: mask.h:313
bool Contains(const VdfMask &mask) const
Definition: mask.h:186
size_t GetLastSet() const
Definition: mask.h:236
friend void TfDelegatedCountIncrement(_BitsImpl *p) noexcept
Definition: mask.h:686
bool IsAllZeros() const
Definition: mask.h:206
friend VDF_API std::ostream & operator<<(std::ostream &os, const VdfMask &mask)
bool HasNonEmptyIntersection(const TfCompressedBits &rhs) const
size_t GetSize() const
Definition: mask.h:158
GLsizeiptr size
Definition: glcorearb.h:664
friend void TfDelegatedCountDecrement(_BitsImpl *p) noexcept
Definition: mask.h:703
size_t GetSize() const
VdfMask(VdfMask::Bits const &bits)
Definition: mask.h:63
VdfMask & SetOrAppend(const VdfMask &rhs)
Definition: mask.h:385
value_type operator*() const
Definition: mask.h:423
void Swap(VdfMask &rhs) noexcept
Definition: mask.h:93
static const TfCompressedBits & GetEmpty()
size_t GetMemoryUsage() const
Definition: mask.h:539
size_t GetNumSet() const
Definition: mask.h:246
LeafData & operator=(const LeafData &)=delete
GLuint index
Definition: glcorearb.h:786
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
static VdfMask AllZeros(size_t size)
Definition: mask.h:509
TfCompressedBits & Complement()
VdfMask & operator^=(const VdfMask &rhs)
Definition: mask.h:333
void SetAll()
Definition: mask.h:105
VdfMask operator&(const VdfMask &rhs) const
Definition: mask.h:303
bool operator!=(const VdfMask &rhs) const
Definition: mask.h:275
bool operator==(const iterator &rhs) const
Definition: mask.h:411
GLboolean r
Definition: glcorearb.h:1222
bool IsAllOnes() const
Definition: mask.h:196
std::string GetRLEString() const
Definition: mask.h:528
friend void swap(VdfMask &lhs, VdfMask &rhs) noexcept
Definition: mask.h:99
size_t operator()(const VdfMask &mask) const
Definition: mask.h:572
int AdvanceTo(value_type index)
Definition: mask.h:449
void AdvanceToEnd()
Definition: mask.h:442
VdfMask operator|(const VdfMask &rhs) const
Definition: mask.h:322
bool IsSet(size_t index) const
Definition: mask.h:131
void swap(TfDelegatedCountPtr &other) noexcept
Swap this object's held pointer with other's.
void TfDelegatedCountDecrement(VdfMask::_BitsImpl *p) noexcept
Definition: mask.h:703
iterator begin() const
Definition: mask.h:482