@@ -49,7 +49,7 @@ inline auto popcount(T x) -> std::size_t
4949// / @param N The size of the BitVector in bits.
5050template <std::size_t N>
5151struct BlockTypeHelper {
52- // Determine the smallest unsigned integer type that can store N bits.
52+ // / Determine the smallest unsigned integer type that can store N bits.
5353 using type = std::conditional_t <
5454 (N <= 8 ),
5555 std::uint8_t , // 8-bit
@@ -282,7 +282,13 @@ class BitVector
282282 if (pos >= N) {
283283 throw std::out_of_range (" Bit position out of range." );
284284 }
285- data[pos / BitsPerBlock] |= static_cast <BlockType>(BlockType (1 ) << (pos % BitsPerBlock));
285+ // Get the block index and bit position for the given position.
286+ std::size_t block = get_block_index (pos);
287+ std::size_t bit = get_bit_position (pos);
288+
289+ // Set the bit at the calculated position.
290+ data[block] |= static_cast <BlockType>(BlockType (1 ) << bit);
291+
286292 return *this ;
287293 }
288294
@@ -304,8 +310,12 @@ class BitVector
304310 if (pos >= N) {
305311 throw std::out_of_range (" Bit position out of range" );
306312 }
307- // Ensure same indexing as `set(pos)`
308- data[pos / BitsPerBlock] = static_cast <BlockType>(data[pos / BitsPerBlock] & ~(1U << (pos % BitsPerBlock)));
313+ // Get the block index and bit position for the given position.
314+ std::size_t block = get_block_index (pos);
315+ std::size_t bit = get_bit_position (pos);
316+
317+ // Reset the bit at the calculated position.
318+ data[block] = static_cast <BlockType>(data[block] & ~(1U << bit));
309319 return *this ;
310320 }
311321
@@ -341,7 +351,12 @@ class BitVector
341351 if (pos >= N) {
342352 throw std::out_of_range (" BitVector index out of range" );
343353 }
344- data[pos / BitsPerBlock] = static_cast <BlockType>(data[pos / BitsPerBlock] ^ (1 << (pos % BitsPerBlock)));
354+ // Get the block index and bit position for the given position.
355+ std::size_t block = get_block_index (pos);
356+ std::size_t bit = get_bit_position (pos);
357+
358+ // Flip the bit at the calculated position.
359+ data[block] = static_cast <BlockType>(data[block] ^ (1 << bit));
345360 return *this ;
346361 }
347362
@@ -505,7 +520,12 @@ class BitVector
505520 if (pos >= N) {
506521 throw std::out_of_range (" Accessing values outside bitvector" );
507522 }
508- return (data[pos / BitsPerBlock] & (BlockType (1 ) << (pos % BitsPerBlock))) != 0 ;
523+ // Get the block index and bit position for the given position.
524+ std::size_t block = get_block_index (pos);
525+ std::size_t bit = get_bit_position (pos);
526+
527+ // Return the bit at the calculated position.
528+ return (data[block] & (BlockType (1 ) << bit)) != 0 ;
509529 }
510530
511531 // / @brief Returns a modifiable reference-like proxy to a bit.
@@ -516,7 +536,12 @@ class BitVector
516536 if (pos >= N) {
517537 throw std::out_of_range (" Accessing values outside bitvector" );
518538 }
519- return detail::BitReference<BlockType>(data[pos / BitsPerBlock], pos % BitsPerBlock);
539+ // Get the block index and bit position for the given position.
540+ std::size_t block = get_block_index (pos);
541+ std::size_t bit = get_bit_position (pos);
542+
543+ // Return the bit reference at the calculated position.
544+ return detail::BitReference<BlockType>(data[block], bit);
520545 }
521546
522547 // / @brief Copies the contents of the provided BitVector into this BitVector.
@@ -617,6 +642,7 @@ class BitVector
617642 }
618643
619644 // / @brief Converts the BitVector to a string.
645+ // / @param split if true, it will add spaces between blocks based on BitsPerBlock.
620646 // / @return The binary string representing the bitvector.
621647 auto to_string (bool split = false ) const -> std::string
622648 {
@@ -629,6 +655,16 @@ class BitVector
629655 }
630656 return str;
631657 }
658+
659+ // / @brief Gets the block index for a given bit position.
660+ // / @param pos The bit position in the BitVector.
661+ // / @return The index of the block containing the bit.
662+ inline std::size_t get_block_index (std::size_t pos) const { return pos / BitsPerBlock; }
663+
664+ // / @brief Gets the bit position within a block for a given bit position.
665+ // / @param pos The bit position in the BitVector.
666+ // / @return The position of the bit within its block.
667+ inline std::size_t get_bit_position (std::size_t pos) const { return pos % BitsPerBlock; }
632668};
633669
634670} // namespace bvlib
0 commit comments