68 mWordCount |= PX_SIGN_BITMASK;
83 if (mMap && !isInUserMemory())
84 mAllocator.deallocate(mMap);
93 mMap[index >> 5] |= 1 << (index & 31);
99 mMap[index >> 5] &= ~(1 << (index & 31));
102 PX_INLINE PxIntBool boundedTest(PxU32 index)
const
104 return PxIntBool(index >> 5 >= getWordCount() ? PxIntFalse : (mMap[index >> 5] & (1 << (index & 31))));
109 if((index >> 5) < getWordCount())
110 mMap[index >> 5] &= ~(1 << (index & 31));
116 PX_ASSERT(index<getWordCount() * 32);
117 mMap[index >> 5] |= 1 << (index & 31);
122 PX_ASSERT(index<getWordCount() * 32);
123 mMap[index >> 5] &= ~(1 << (index & 31));
126 PX_INLINE PxIntBool test(PxU32 index)
const
128 PX_ASSERT(index<getWordCount() * 32);
129 return PxIntBool(mMap[index >> 5] & (1 << (index & 31)));
133 PX_INLINE PxU32 getNibbleFast(PxU32 nibIndex)
const
135 const PxU32 bitIndex = nibIndex << 2;
136 PX_ASSERT(bitIndex < getWordCount() * 32);
137 return (mMap[bitIndex >> 5] >> (bitIndex & 31)) & 0xf;
140 PX_INLINE void andNibbleFast(PxU32 nibIndex, PxU32 mask)
143 const PxU32 bitIndex = nibIndex << 2;
144 const PxU32 shift = (bitIndex & 31);
145 const PxU32 nibMask = (0xfu << shift);
147 PX_ASSERT(bitIndex < getWordCount() * 32);
149 mMap[bitIndex >> 5] &= ((mask << shift) | ~nibMask);
152 PX_INLINE void orNibbleFast(PxU32 nibIndex, PxU32 mask)
154 PX_ASSERT(!(mask & ~0xfu));
156 const PxU32 bitIndex = nibIndex << 2;
157 const PxU32 shift = bitIndex & 31;
159 PX_ASSERT(bitIndex < getWordCount() * 32);
161 mMap[bitIndex >> 5] |= (mask << shift);
166 PxMemSet(mMap, 0, getWordCount() *
sizeof(PxU32));
169 void resizeAndClear(PxU32 newBitCount)
171 extendUninitialized(newBitCount);
172 PxMemSet(mMap, 0, getWordCount() *
sizeof(PxU32));
181 void setWords(PxU32* map, PxU32 wordCount)
184 mWordCount = wordCount;
185 mWordCount |= PX_SIGN_BITMASK;
189 void resize(PxU32 newBitCount,
bool value =
false)
196 PxU32 size()
const {
return getWordCount() * 32; }
200 extendUninitialized(a.getWordCount() << 5);
201 PxMemCopy(mMap, a.mMap, a.getWordCount() *
sizeof(PxU32));
202 if (getWordCount() > a.getWordCount())
203 PxMemSet(mMap + a.getWordCount(), 0, (getWordCount() - a.getWordCount()) *
sizeof(PxU32));
211 const PxU32 wordCount = getWordCount();
212 for (PxU32 i = 0; i<wordCount; i++)
213 count += PxBitCount(mMap[i]);
218 PX_INLINE PxU32 count(PxU32 start, PxU32 length)
const
220 const PxU32 end =
PxMin(getWordCount() << 5, start + length);
222 for (PxU32 i = start; i<end; i++)
223 count += (test(i) != 0);
230 const PxU32 wordCount = getWordCount();
231 for (PxU32 i = wordCount; i-- > 0;)
241 struct OR {
PX_INLINE PxU32 operator()(PxU32 a, PxU32 b) {
return a | b; } };
242 struct AND {
PX_INLINE PxU32 operator()(PxU32 a, PxU32 b) {
return a&b; } };
243 struct XOR {
PX_INLINE PxU32 operator()(PxU32 a, PxU32 b) {
return a^b; } };
248 template<
class Combiner,
class _>
251 combine1<Combiner>(b.mMap, b.getWordCount());
254 template<
class Combiner,
class _1,
class _2>
257 combine2<Combiner>(a.mMap, a.getWordCount(), b.mMap, b.getWordCount());
264 PX_FORCE_INLINE PxU32 getWordCount()
const {
return mWordCount & ~PX_SIGN_BITMASK; }
267 PX_FORCE_INLINE PxU32 isInUserMemory()
const {
return mWordCount & PX_SIGN_BITMASK; }
280 static const PxU32 DONE = 0xffffffff;
289 PX_ASSERT(&mBitMap == &other.mBitMap);
290 mBlock = other.mBlock;
291 mIndex = other.mIndex;
300 mBlock &= mBlock - 1;
301 PxU32 wordCount = mBitMap.getWordCount();
302 while (!mBlock && ++mIndex < wordCount)
303 mBlock = mBitMap.mMap[mIndex];
312 PxU32 wordCount = mBitMap.getWordCount();
313 while (mIndex < wordCount && ((mBlock = mBitMap.mMap[mIndex]) == 0))
317 PxU32 mBlock, mIndex;
331 PX_ASSERT(mIndex<mWordCount);
334 if (++mIndex == mWordCount)
336 mBlock = mMap[mIndex];
343 PX_ASSERT(mIndex<mWordCount && mBlock != 0);
345 mBlock &= (mBlock - 1);
350 const PxU32*
const mMap;
360 static const PxU32 DONE = 0xffffffff;
364 mIndex = mBlock = mStartIndex = 0;
365 const PxU32 wordCount = mBitMap.getWordCount();
366 if ((index << 5) < wordCount)
369 mStartIndex = mIndex;
372 if (mIndex < wordCount)
374 mBlock = mBitMap.mMap[mIndex];
377 mIndex = (mIndex + 1) % wordCount;
378 while (mIndex != mStartIndex && (mBlock = mBitMap.mMap[mIndex]) == 0)
379 mIndex = (mIndex + 1) % wordCount;
389 mBlock &= mBlock - 1;
390 PxU32 wordCount = mBitMap.getWordCount();
391 while (!mBlock && (mIndex = ((mIndex + 1) % wordCount)) != mStartIndex)
392 mBlock = mBitMap.mMap[mIndex];
399 PxU32 mBlock, mIndex;
412 void extend(PxU32 size)
414 const PxU32 newWordCount = (size + 31) >> 5;
415 if (newWordCount > getWordCount())
417 PxU32* newMap =
reinterpret_cast<PxU32*
>(mAllocator.allocate(newWordCount *
sizeof(PxU32), __FILE__, __LINE__));
420 PxMemCopy(newMap, mMap, getWordCount() *
sizeof(PxU32));
421 if (!isInUserMemory())
422 mAllocator.deallocate(mMap);
424 PxMemSet(newMap + getWordCount(), 0, (newWordCount - getWordCount()) *
sizeof(PxU32));
427 mWordCount = newWordCount;
431 void extendUninitialized(PxU32 size)
433 PxU32 newWordCount = (size + 31) >> 5;
434 if (newWordCount > getWordCount())
436 if (mMap && !isInUserMemory())
437 mAllocator.deallocate(mMap);
439 mWordCount = newWordCount;
440 mMap =
reinterpret_cast<PxU32*
>(mAllocator.allocate(mWordCount *
sizeof(PxU32), __FILE__, __LINE__));
444 template<
class Combiner>
445 void combine1(
const PxU32* words, PxU32 length)
448 PxU32 combineLength =
PxMin(getWordCount(), length);
449 for (PxU32 i = 0; i<combineLength; i++)
450 mMap[i] = Combiner()(mMap[i], words[i]);
453 template<
class Combiner>
454 void combine2(
const PxU32* words1, PxU32 length1,
455 const PxU32* words2, PxU32 length2)
457 extendUninitialized(
PxMax(length1, length2) << 5);
459 PxU32 commonSize =
PxMin(length1, length2);
461 for (PxU32 i = 0; i<commonSize; i++)
462 mMap[i] = Combiner()(words1[i], words2[i]);
464 for (PxU32 i = commonSize; i<length1; i++)
465 mMap[i] = Combiner()(words1[i], 0);
467 for (PxU32 i = commonSize; i<
length2; i++)
468 mMap[i] = Combiner()(0, words2[i]);
471 friend class Iterator;