7 #ifndef PXR_BASE_TF_BITS_H
8 #define PXR_BASE_TF_BITS_H
22 #include <type_traits>
103 }
else if (first == 0 && last >= (num - 1)) {
107 for (
size_t i = first; i <=
last; ++i)
117 _numSet .Store(rhs._numSet.Load());
118 _firstSet .Store(rhs._firstSet.Load());
119 _lastSet .Store(rhs._lastSet.Load());
120 _numWords = rhs._numWords;
121 _bits = _Alloc(_numWords);
124 for (
size_t i = 0; i < _numWords; ++i)
125 _bits[i] = rhs._bits[i];
139 _Free(_bits, _numWords);
152 if (_numWords != rhs._numWords) {
153 _Free(_bits, _numWords);
154 _bits = _Alloc(rhs._numWords);
158 _numSet .Store(rhs._numSet.Load());
159 _firstSet .Store(rhs._firstSet.Load());
160 _lastSet .Store(rhs._lastSet.Load());
161 _numWords = rhs._numWords;
164 for (
size_t i = 0; i < _numWords; ++i)
165 _bits[i] = rhs._bits[i];
187 if (_bits && _num == num)
190 _Free(_bits, _numWords);
194 _firstSet .Store(-1);
196 _numWords = (num + 63) >> 6;
197 _bits = _Alloc(_numWords);
203 _bits[_numWords - 1] = 0;
217 size_t numWordsToCopy = TfMin(temp._numWords, _numWords);
219 for(
size_t i=0; i<numWordsToCopy; ++i)
220 temp._bits[i] = _bits[i];
227 temp._ClearTrailingBits();
231 temp._numSet.Store(-1);
232 temp._firstSet.Store(-1);
233 temp._lastSet.Store(-1);
240 temp._numSet.Store(_numSet.Load());
241 const size_t firstSet = _firstSet.Load();
242 temp._firstSet.Store(firstSet < _num ? firstSet : num);
243 const size_t lastSet = _lastSet.Load();
244 temp._lastSet.Store(lastSet < _num ? lastSet : num);
270 _numSet.NonAtomicSwap(rhs._numSet);
271 _firstSet.NonAtomicSwap(rhs._firstSet);
272 _lastSet.NonAtomicSwap(rhs._lastSet);
274 if (_numWords == 1 && rhs._numWords == 1) {
283 }
else if (_numWords == 1) {
292 rhs._inlineData = _inlineData;
293 rhs._bits = &rhs._inlineData;
295 }
else if (rhs._numWords == 1) {
304 _inlineData = rhs._inlineData;
305 _bits = &_inlineData;
332 memset(_bits, 0x00, _numWords << 3);
334 _firstSet.Store(_num);
335 _lastSet.Store(_num);
342 memset(_bits, 0xff, _numWords << 3);
345 _lastSet.Store(_num > 0 ? _num-1 : 0);
348 _ClearTrailingBits();
357 uint64_t
mask = UINT64_C(1) << (index & 63);
359 if (_bits[index >> 6] & mask)
361 const size_t numSet = _numSet.Load();
362 TF_AXIOM(numSet ==
size_t(-1) || numSet > 0);
364 if (numSet !=
size_t(-1))
366 if (index == _firstSet.Load())
368 if (index == _lastSet.Load())
371 _bits[index >> 6] ^=
mask;
381 uint64_t
mask = UINT64_C(1) << (index & 63);
383 if (!(_bits[index >> 6] & mask))
385 const size_t numSet = _numSet.Load();
386 TF_AXIOM(numSet ==
size_t(-1) || numSet < _num);
388 if (numSet !=
size_t(-1))
390 if (index < _firstSet.Load())
391 _firstSet.Store(index);
392 const size_t lastSet = _lastSet.Load();
393 if (index > lastSet || lastSet == _num)
394 _lastSet.Store(index);
396 _bits[index >> 6] |=
mask;
416 return _bits[index >> 6] & (UINT64_C(1) << (index & 63));
428 size_t startBit = index & 63;
431 if (_bits[index >> 6] & (UINT64_C(1) << startBit))
434 return _FindNextSet(index, startBit);
446 size_t startBit = index & 63;
449 if (_bits[index >> 6] & (UINT64_C(1) << startBit))
452 return _FindPrevSet(index, startBit);
464 size_t startBit = index & 63;
467 if (!(_bits[index >> 6] & (UINT64_C(1) << startBit)))
470 return _FindNextUnset(index, startBit);
493 size_t firstSet = _firstSet.Load();
494 if (firstSet ==
size_t(-1)) {
496 _firstSet.Store(firstSet);
508 size_t lastSet = _lastSet.Load();
509 if (lastSet ==
size_t(-1)) {
512 _lastSet.Store(lastSet);
523 size_t numSet = _numSet.Load();
524 if (numSet ==
size_t(-1)) {
525 numSet = _CountNumSet();
526 _numSet.Store(numSet);
575 size_t memUsed =
sizeof(
TfBits);
579 memUsed += _numWords << 3;
613 return !(*
this == rhs);
706 if (firstSet < _num && rhsFirstSet < _num)
708 firstSet = TfMax(firstSet, rhsFirstSet);
711 if (firstSet <= lastSet)
713 size_t offset = firstSet >> 6;
714 size_t numWords = (lastSet >> 6) + 1 - offset;
717 uint64_t *p0 = _bits +
offset;
718 uint64_t *p1 = rhs._bits +
offset;
720 for(
size_t n=numWords;
n>0;
n--)
723 if (uint64_t word = *p0)
756 if (firstSet < rhsFirstSet || lastSet > rhsLastSet ||
757 firstSet > rhsLastSet || lastSet < rhsFirstSet ||
761 size_t offset = firstSet >> 6;
762 size_t numWords = (lastSet >> 6) + 1 - offset;
765 uint64_t *p0 = _bits +
offset;
766 uint64_t *p1 = rhs._bits +
offset;
768 for(
size_t n=numWords;
n>0;
n--)
771 if (uint64_t word = *p0)
808 : _bits(NULL), _index(0) {}
839 : _bits(bits), _index(index) {}
842 return _bits == rhs._bits && _index == rhs._index;
854 const size_t &dereference()
const {
930 size_t _CountNumSet()
const;
936 size_t _FindNextSet(
size_t index,
size_t startBit)
const;
942 size_t _FindPrevSet(
size_t index,
size_t startBit)
const;
948 size_t _FindNextUnset(
size_t index,
size_t startBit)
const;
953 void _ClearTrailingBits();
958 void _Or(
const TfBits &rhs);
965 uint64_t *_Alloc(
size_t numWords)
973 return new uint64_t[numWords];
977 static void _Free(uint64_t *
data,
size_t numWords)
993 class _RelaxedAtomicSize_t
996 _RelaxedAtomicSize_t()
1000 explicit _RelaxedAtomicSize_t(
size_t n)
1005 _n.fetch_add(1, std::memory_order_relaxed);
1009 _n.fetch_sub(1, std::memory_order_relaxed);
1012 size_t Load()
const {
1013 return _n.load(std::memory_order_relaxed);
1016 void Store(
size_t n) {
1017 _n.store(n, std::memory_order_relaxed);
1023 void NonAtomicSwap(_RelaxedAtomicSize_t &other) {
1024 const size_t n = _n.load(std::memory_order_relaxed);
1025 const size_t o = other._n.load(std::memory_order_relaxed);
1026 _n.store(o, std::memory_order_relaxed);
1027 other._n.store(n, std::memory_order_relaxed);
1031 std::atomic<size_t> _n;
1038 mutable _RelaxedAtomicSize_t _numSet;
1041 mutable _RelaxedAtomicSize_t _firstSet;
1042 mutable _RelaxedAtomicSize_t _lastSet;
1051 uint64_t _inlineData;
TF_API void OrSubset(const TfBits &rhs)
AllUnsetView GetAllUnsetView() const
size_t operator()(TfBits const &bits) const
TfBits & operator=(TfBits &&rhs)
bool HasNonEmptyDifference(const TfBits &rhs) const
void swap(UT::ArraySet< Key, MULTI, MAX_LOAD_FACTOR_256, Clearer, Hash, KeyEqual > &a, UT::ArraySet< Key, MULTI, MAX_LOAD_FACTOR_256, Clearer, Hash, KeyEqual > &b)
bool operator!=(const const_iterator &rhs) const
const_iterator end() const
TfBits(size_t num, size_t first, size_t last)
IMATH_HOSTDEVICE constexpr bool equal(T1 a, T2 b, T3 t) IMATH_NOEXCEPT
bool HasNonEmptyIntersection(const TfBits &rhs) const
size_t GetFirstSet() const
TF_API std::string GetAsStringLeftToRight() const
friend void swap(TfBits &lhs, TfBits &rhs)
size_t operator()(TfBits const &bits) const
TF_API TfBits & Complement()
const_iterator operator++(int)
TF_API std::ostream & operator<<(std::ostream &out, const TfBits &bits)
Output a TfBits, as a stream of 0s and 1s.
size_t GetLastSet() const
size_t GetAllocatedSize() const
Fast bit array that keeps track of the number of bits set and can find the next set in a timely manne...
TfBits & operator=(const TfBits &rhs)
size_t FindPrevSet(size_t index) const
bool operator==(const const_iterator &rhs) const
TF_API TfBits & operator&=(const TfBits &rhs)
View< AllUnset > AllUnsetView
bool operator[](size_t index) const
pointer operator->() const
void ResizeKeepContent(size_t num)
std::forward_iterator_tag iterator_category
const_iterator begin() const
TF_API bool operator==(const TfBits &rhs) const
TF_API TfBits & operator|=(const TfBits &rhs)
__hostdev__ uint64_t last(uint32_t i) const
TfBits(const TfBits &rhs)
TF_API std::string GetAsStringRightToLeft() const
const size_t difference_type
static size_t Combine(Args &&...args)
Produce a hash code by combining the hash codes of several objects.
TF_API size_t GetHash() const
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
TfBits operator|(const TfBits &rhs) const
reference operator*() const
AllSetView GetAllSetView() const
#define PXR_NAMESPACE_CLOSE_SCOPE
TfBits operator^(const TfBits &rhs) const
TfBits operator&(const TfBits &rhs) const
AllView GetAllView() const
void Assign(size_t index, bool val)
size_t FindNextSet(size_t index) const
const_iterator & operator++()
View< AllSet > AllSetView
bool operator!=(const TfBits &rhs) const
size_t FindNextUnset(size_t index) const
bool IsSet(size_t index) const
TF_API TfBits & operator^=(const TfBits &rhs)
bool AreContiguouslySet() const
TF_API TfBits & operator-=(const TfBits &rhs)
bool Contains(const TfBits &rhs) const