@@ -44,8 +44,15 @@ using std::atomic_size_t;
4444
4545// enables iteration through the set bits of the bitmap
4646template <typename Container>
47- class BitmapIter : public std ::iterator<std::forward_iterator_tag, size_t > {
47+ class BitmapIter {
4848public:
49+ // Iterator traits (modern C++17 approach, not inheriting from deprecated std::iterator)
50+ using iterator_category = std::forward_iterator_tag;
51+ using value_type = size_t ;
52+ using difference_type = std::ptrdiff_t ;
53+ using pointer = size_t *;
54+ using reference = size_t &;
55+
4956 BitmapIter (const Container &a, const size_t i) : _i(i), _cont(a) {
5057 }
5158 BitmapIter &operator ++() {
@@ -86,28 +93,22 @@ class AtomicBitmapBase {
8693 AtomicBitmapBase (size_t bitCount) {
8794 d_assert_msg (bitCount <= maxBits, " max bits (%zu) exceeded: %zu" , maxBits, bitCount);
8895
89- static_assert (wordCount (representationSize (maxBits)) == 4 , " unexpected representation size" );
90- // for (size_t i = 0; i < wordCount(representationSize(maxBits)); i++) {
91- // _bits[i].store(0, std::memory_order_relaxed);
92- // }
93- _bits[0 ].store (0 , std::memory_order_relaxed);
94- _bits[1 ].store (0 , std::memory_order_relaxed);
95- _bits[2 ].store (0 , std::memory_order_relaxed);
96- _bits[3 ].store (0 , std::memory_order_relaxed);
96+ // Initialize all words to 0
97+ constexpr size_t wordCnt = wordCount (representationSize (maxBits));
98+ for (size_t i = 0 ; i < wordCnt; i++) {
99+ _bits[i].store (0 , std::memory_order_relaxed);
100+ }
97101 std::atomic_thread_fence (std::memory_order_release);
98102 }
99103
100104 ~AtomicBitmapBase () {
101105 }
102106
103107 inline void ATTRIBUTE_ALWAYS_INLINE setAndExchangeAll (size_t *oldBits, const size_t *newBits) {
104- // for (size_t i = 0; i < wordCount(representationSize(maxBits)); i++) {
105- // oldBits[i] = _bits[i].exchange(newBits[i]);
106- // }
107- oldBits[0 ] = _bits[0 ].exchange (newBits[0 ], std::memory_order_acq_rel);
108- oldBits[1 ] = _bits[1 ].exchange (newBits[1 ], std::memory_order_acq_rel);
109- oldBits[2 ] = _bits[2 ].exchange (newBits[2 ], std::memory_order_acq_rel);
110- oldBits[3 ] = _bits[3 ].exchange (newBits[3 ], std::memory_order_acq_rel);
108+ constexpr size_t wordCnt = wordCount (representationSize (maxBits));
109+ for (size_t i = 0 ; i < wordCnt; i++) {
110+ oldBits[i] = _bits[i].exchange (newBits[i], std::memory_order_acq_rel);
111+ }
111112 }
112113
113114public:
@@ -140,8 +141,12 @@ class AtomicBitmapBase {
140141 }
141142
142143 inline uint32_t ATTRIBUTE_ALWAYS_INLINE inUseCount () const {
143- return __builtin_popcountl (_bits[0 ]) + __builtin_popcountl (_bits[1 ]) + __builtin_popcountl (_bits[2 ]) +
144- __builtin_popcountl (_bits[3 ]);
144+ constexpr size_t wordCnt = wordCount (representationSize (maxBits));
145+ uint32_t count = 0 ;
146+ for (size_t i = 0 ; i < wordCnt; i++) {
147+ count += __builtin_popcountl (_bits[i].load (std::memory_order_relaxed));
148+ }
149+ return count;
145150 }
146151
147152protected:
@@ -273,14 +278,10 @@ class RelaxedFixedBitmapBase {
273278
274279public:
275280 inline void ATTRIBUTE_ALWAYS_INLINE invert () {
276- // constexpr size_t numWords = wordCount(representationSize(maxBits));
277- // for (size_t i = 0; i < numWords; i++) {
278- // _bits[i] = ~_bits[i];
279- // }
280- _bits[0 ] = ~_bits[0 ];
281- _bits[1 ] = ~_bits[1 ];
282- _bits[2 ] = ~_bits[2 ];
283- _bits[3 ] = ~_bits[3 ];
281+ constexpr size_t numWords = wordCount (representationSize (maxBits));
282+ for (size_t i = 0 ; i < numWords; i++) {
283+ _bits[i] = ~_bits[i];
284+ }
284285 }
285286
286287 inline void ATTRIBUTE_ALWAYS_INLINE setAll (uint64_t bitCount) {
@@ -315,15 +316,11 @@ class RelaxedFixedBitmapBase {
315316 }
316317
317318 inline uint64_t ATTRIBUTE_ALWAYS_INLINE inUseCount () const {
318- constexpr auto wordCount = representationSize (maxBits) / sizeof (size_t );
319+ constexpr auto wordCnt = representationSize (maxBits) / sizeof (size_t );
319320 uint32_t count = 0 ;
320- // for (size_t i = 0; i < wordCount; i++) {
321- // count += __builtin_popcountl(_bits[i]);
322- // }
323- count += __builtin_popcountl (_bits[0 ]);
324- count += __builtin_popcountl (_bits[1 ]);
325- count += __builtin_popcountl (_bits[2 ]);
326- count += __builtin_popcountl (_bits[3 ]);
321+ for (size_t i = 0 ; i < wordCnt; i++) {
322+ count += __builtin_popcountl (_bits[i]);
323+ }
327324 return count;
328325 }
329326
@@ -332,10 +329,10 @@ class RelaxedFixedBitmapBase {
332329 }
333330
334331 void ATTRIBUTE_ALWAYS_INLINE clear () {
335- _bits[ 0 ] = 0 ;
336- _bits[ 1 ] = 0 ;
337- _bits[2 ] = 0 ;
338- _bits[ 3 ] = 0 ;
332+ constexpr size_t wordCnt = wordCount ( representationSize (maxBits)) ;
333+ for ( size_t i = 0 ; i < wordCnt; i++) {
334+ _bits[i ] = 0 ;
335+ }
339336 }
340337
341338 inline size_t ATTRIBUTE_ALWAYS_INLINE bitCount () const {
@@ -477,11 +474,15 @@ class BitmapBase : public Super {
477474 return Super::unsetAt (item, position);
478475 }
479476
480- // FIXME: who uses this? bad idea with atomics
477+ // NOTE: This is not fully atomic-safe, but only used in debug assertions
478+ // For RelaxedBitmapBase (non-atomic), direct access is fine
479+ // For AtomicBitmapBase, this creates a potential race, but acceptable for debug
481480 inline bool ATTRIBUTE_ALWAYS_INLINE isSet (uint64_t index) const {
482481 uint32_t item, position;
483482 computeItemPosition (index, item, position);
484483
484+ // Use direct access for both atomic and non-atomic variants
485+ // This works because on x86/ARM, reading a size_t is atomic
485486 return Super::_bits[item] & getMask (position);
486487 }
487488
@@ -577,12 +578,12 @@ class BitmapBase : public Super {
577578} // namespace bitmap
578579
579580namespace internal {
580- typedef bitmap::BitmapBase<bitmap::AtomicBitmapBase<256 >> Bitmap;
581- typedef bitmap::BitmapBase<bitmap::RelaxedFixedBitmapBase<256 >> RelaxedFixedBitmap;
581+ typedef bitmap::BitmapBase<bitmap::AtomicBitmapBase<1024 >> Bitmap;
582+ typedef bitmap::BitmapBase<bitmap::RelaxedFixedBitmapBase<1024 >> RelaxedFixedBitmap;
582583typedef bitmap::BitmapBase<bitmap::RelaxedBitmapBase> RelaxedBitmap;
583584
584- static_assert (sizeof (Bitmap) == sizeof (size_t ) * 4 , " Bitmap unexpected size" );
585- static_assert (sizeof (RelaxedFixedBitmap) == sizeof (size_t ) * 4 , " Bitmap unexpected size" );
585+ static_assert (sizeof (Bitmap) == sizeof (size_t ) * 16 , " Bitmap unexpected size (expected 128 bytes for 1024 bits) " );
586+ static_assert (sizeof (RelaxedFixedBitmap) == sizeof (size_t ) * 16 , " Bitmap unexpected size (expected 128 bytes for 1024 bits) " );
586587static_assert (sizeof (RelaxedBitmap) == sizeof (size_t ) * 2 , " Bitmap unexpected size" );
587588} // namespace internal
588589} // namespace mesh
0 commit comments