Skip to content

BitVecLen

Description

Number of bits currently held by the bitvector.

Usage example (Cross-references)

Usage examples (Cross-references)
    
        if (fmt_info->flags & FMT_FLAG_HEX) {
            if (BitVecLen(bv) == 0) {
                // Render "0x0" / "0o0" placeholders for the zero-length
                // edge case so the prefix is visible even with no bits.
            }
        } else if (fmt_info->flags & FMT_FLAG_OCTAL) {
            if (BitVecLen(bv) == 0) {
                if (!StrPushBackMany(o, "0o0")) {
                    return false;
            // No flag -> render the raw 0/1 bit string (the BitVec's
            // native textual form).
            if (BitVecLen(bv) == 0) {
                // A zero-length BitVec renders empty; padding handles any
                // requested width below.
        ValidateInt(value);
    
        for (u64 i = BitVecLen(INT_BITS(value)); i > 0; i--) {
            if (BitVecGet(INT_BITS(value), i - 1)) {
                return i;
    static bool int_is_odd(const Int *value) {
        ValidateInt(value);
        return BitVecLen(INT_BITS(value)) > 0 && BitVecGet(INT_BITS(value), 0);
    }
        ValidateInt(value);
    
        for (u64 i = 0; i < BitVecLen(INT_BITS(value)); i++) {
            if (BitVecGet(INT_BITS(value), i)) {
                return i;
                u64 bit_idx = i * 8 + bit;
    
                if (bit_idx < BitVecLen(INT_BITS(value)) && BitVecGet(INT_BITS(value), bit_idx)) {
                    byte |= (u8)(1u << bit);
                }
                u64 bit_idx = i * 8 + bit;
    
                if (bit_idx < BitVecLen(INT_BITS(value)) && BitVecGet(INT_BITS(value), bit_idx)) {
                    byte |= (u8)(1u << bit);
                }
        // Check that capacity is larger than length
        u64  initial_capacity = BitVecCapacity(&bv);
        bool result           = (initial_capacity >= 100) && (BitVecLen(&bv) == 3);
    
        // Shrink to fit
        // Check that capacity is now closer to length
        result = result && (BitVecCapacity(&bv) < initial_capacity);
        result = result && (BitVecCapacity(&bv) >= BitVecLen(&bv));
    
        // Check that data is still intact
    
        // Check that data is still intact
        result = result && (BitVecLen(&bv) == 3);
        result = result && (BitVecGet(&bv, 0) == true);
        result = result && (BitVecGet(&bv, 1) == false);
    
        // Check that capacity was set correctly
        bool result = (BitVecCapacity(&bv) >= 50) && (BitVecLen(&bv) == 2);
    
        // Check that data is still intact
    
        // Capacity should still accommodate at least the current length
        result = result && (BitVecCapacity(&bv) >= BitVecLen(&bv));
        result = result && (BitVecLen(&bv) == 2);
        // Capacity should still accommodate at least the current length
        result = result && (BitVecCapacity(&bv) >= BitVecLen(&bv));
        result = result && (BitVecLen(&bv) == 2);
    
        // Data should still be intact
    
        // Store original states
        u64 bv1_orig_length = BitVecLen(&bv1);
        u64 bv2_orig_length = BitVecLen(&bv2);
        // Store original states
        u64 bv1_orig_length = BitVecLen(&bv1);
        u64 bv2_orig_length = BitVecLen(&bv2);
    
        // Swap the bitvectors
    
        // Check that they swapped
        bool result = (BitVecLen(&bv1) == bv2_orig_length) && (BitVecLen(&bv2) == bv1_orig_length);
    
        // Check bv1 (should now have bv2's original content)
    
        // Check bv1 (should now have bv2's original content)
        result = result && (BitVecLen(&bv1) == 2);
        result = result && (BitVecGet(&bv1, 0) == false);
        result = result && (BitVecGet(&bv1, 1) == false);
    
        // Check bv2 (should now have bv1's original content)
        result = result && (BitVecLen(&bv2) == 3);
        result = result && (BitVecGet(&bv2, 0) == true);
        result = result && (BitVecGet(&bv2, 1) == false);
    
        // Check that clone has same content as original
        bool result = (BitVecLen(&clone) == BitVecLen(&original));
    
        for (u64 i = 0; i < BitVecLen(&original); i++) {
        bool result = (BitVecLen(&clone) == BitVecLen(&original));
    
        for (u64 i = 0; i < BitVecLen(&original); i++) {
            result = result && (BitVecGet(&clone, i) == BitVecGet(&original, i));
        }
    
        // Clone should remain unchanged
        result = result && (BitVecLen(&clone) == 4) && (BitVecLen(&original) == 5);
        result = result && (BitVecGet(&clone, 0) == true);
        result = result && (BitVecGet(&clone, 1) == false);
        // Clone should share the same Allocator* and therefore see identical
        // configuration fields on the base allocator.
        bool result = BitVecLen(&clone) == BitVecLen(&original) && BitVecCapacity(&clone) >= BitVecLen(&original) &&
                      BitVecAllocator(&clone) == BitVecAllocator(&original) &&
                      BitVecAllocator(&clone)->allocate == BitVecAllocator(&original)->allocate &&
        // Test shrink on empty bitvec
        BitVecShrinkToFit(&bv);
        result = result && (BitVecLen(&bv) == 0) && (BitVecCapacity(&bv) >= 0);
    
        // Test shrink on single element
        BitVecPush(&bv, true);
        BitVecShrinkToFit(&bv);
        result = result && (BitVecLen(&bv) == 1) && (BitVecCapacity(&bv) >= 1);
        result = result && (BitVecGet(&bv, 0) == true);
        BitVecShrinkToFit(&bv);
        BitVecShrinkToFit(&bv);
        result = result && (BitVecLen(&bv) == 1);
    
        // Test shrink after reserve and clear
        BitVecClear(&bv);
        BitVecShrinkToFit(&bv);
        result = result && (BitVecLen(&bv) == 0);
    
        BitVecDeinit(&bv);
        // Test set capacity on empty bitvec
        BitVecReserve(&bv, 100);
        result = result && (BitVecCapacity(&bv) >= 100) && (BitVecLen(&bv) == 0);
    
        // BitVecReserve is grow-only; use BitVecClear to drop length to 0.
        // BitVecReserve is grow-only; use BitVecClear to drop length to 0.
        BitVecClear(&bv);
        result = result && (BitVecLen(&bv) == 0);
    
        for (int i = 0; i < 10; i++) {
            BitVecPush(&bv, i % 2 == 0);
        }
        u64 original_length = BitVecLen(&bv);
    
        result = result && (BitVecLen(&bv) == original_length);
        u64 original_length = BitVecLen(&bv);
    
        result = result && (BitVecLen(&bv) == original_length);
        for (u64 i = 0; i < BitVecLen(&bv); i++) {
            result = result && (BitVecGet(&bv, i) == (i % 2 == 0));
    
        result = result && (BitVecLen(&bv) == original_length);
        for (u64 i = 0; i < BitVecLen(&bv); i++) {
            result = result && (BitVecGet(&bv, i) == (i % 2 == 0));
        }
        // Test swap with both empty
        BitVecSwap(&bv1, &bv2);
        result = result && (BitVecLen(&bv1) == 0) && (BitVecLen(&bv2) == 0);
    
        // Test swap with one empty, one non-empty
        BitVecSwap(&bv1, &bv2);
    
        result = result && (BitVecLen(&bv1) == 0);
        result = result && (BitVecLen(&bv2) == 2);
        result = result && (BitVecGet(&bv2, 0) == true);
    
        result = result && (BitVecLen(&bv1) == 0);
        result = result && (BitVecLen(&bv2) == 2);
        result = result && (BitVecGet(&bv2, 0) == true);
        result = result && (BitVecGet(&bv2, 1) == false);
    
        BitVecSwap(&bv1, &bv2);
        result = result && (BitVecLen(&bv1) == 2) && (BitVecLen(&bv2) == 1000);
        result = result && (BitVecGet(&bv2, 0) == true); // 0 % 3 == 0
        result = result && (BitVecGet(&bv2, 999) == (999 % 3 == 0));
        // Test swapping with itself (should be safe)
        BitVecSwap(&bv1, &bv1);
        result = result && (BitVecLen(&bv1) == 2);
    
        BitVecDeinit(&bv1);
        // Test clone empty bitvec
        BitVec clone1 = BitVecClone(&bv);
        result        = result && (BitVecLen(&clone1) == 0);
        BitVecDeinit(&clone1);
        BitVecPush(&bv, true);
        BitVec clone2 = BitVecClone(&bv);
        result        = result && (BitVecLen(&clone2) == 1);
        result        = result && (BitVecGet(&clone2, 0) == true);
        BitVecDeinit(&clone2);
    
        BitVec clone3 = BitVecClone(&bv);
        result        = result && (BitVecLen(&clone3) == 1000);
    
        // Verify all bits match
    
            // Verify data integrity
            result = result && (BitVecLen(&clone) == cycle * 10);
            if (cycle > 0) {
                result = result && (BitVecGet(&clone, 0) == true); // 0 % 2 == 0
    
        // Expected result: 1000 (1101 AND 1010)
        bool test_result = (BitVecLen(&result) == 4);
        test_result      = test_result && (BitVecGet(&result, 0) == true);
        test_result      = test_result && (BitVecGet(&result, 1) == false);
    
        // Expected result: 1110 (1100 OR 1010)
        bool test_result = (BitVecLen(&result) == 4);
        test_result      = test_result && (BitVecGet(&result, 0) == true);
        test_result      = test_result && (BitVecGet(&result, 1) == true);
    
        // Expected result: 0110 (1100 XOR 1010)
        bool test_result = (BitVecLen(&result) == 4);
        test_result      = test_result && (BitVecGet(&result, 0) == false);
        test_result      = test_result && (BitVecGet(&result, 1) == true);
    
        // Expected result: 0101 (NOT 1010)
        bool test_result = (BitVecLen(&result) == 4);
        test_result      = test_result && (BitVecGet(&result, 0) == false);
        test_result      = test_result && (BitVecGet(&result, 1) == true);
        // After shift left by 2, implementation should clear bits that shift out
        // and fill lower positions with 0
        bool test_result = (BitVecLen(&bv) == 4);
    
        // Let me trace through the implementation:
        BitVecShiftRight(&bv, 2);
    
        bool test_result = (BitVecLen(&bv) == 4);
        test_result      = test_result && (BitVecGet(&bv, 0) == true);
        test_result      = test_result && (BitVecGet(&bv, 1) == true);
    
        // Expected result: 1110 (1011 rotated left by 2)
        bool test_result = (BitVecLen(&bv) == 4);
        test_result      = test_result && (BitVecGet(&bv, 0) == true);
        test_result      = test_result && (BitVecGet(&bv, 1) == true);
    
        // Expected result: 1101 (1011 rotated right by 1)
        bool test_result = (BitVecLen(&bv) == 4);
        test_result      = test_result && (BitVecGet(&bv, 0) == true);
        test_result      = test_result && (BitVecGet(&bv, 1) == true);
    
        // Expected result: 1101 (1011 reversed)
        bool test_result = (BitVecLen(&bv) == 4);
        test_result      = test_result && (BitVecGet(&bv, 0) == true);
        test_result      = test_result && (BitVecGet(&bv, 1) == true);
        // Test shift empty bitvec
        BitVecShiftLeft(&bv, 5);
        result = result && (BitVecLen(&bv) == 0);
    
        BitVecShiftRight(&bv, 3);
    
        BitVecShiftRight(&bv, 3);
        result = result && (BitVecLen(&bv) == 0);
    
        // Test shift by 0 (should be no-op)
        BitVecPush(&bv, false);
        BitVecShiftLeft(&bv, 0);
        result = result && (BitVecLen(&bv) == 2);
        result = result && (BitVecGet(&bv, 0) == true);
        // Test shift larger than length (should clear all bits)
        BitVecShiftLeft(&bv, 10);
        result = result && (BitVecLen(&bv) == 0); // Should clear when shifting everything out
    
        // Test large data shift
        }
        BitVecShiftLeft(&bv, 1);
        result = result && (BitVecLen(&bv) == 1000);
    
        BitVecDeinit(&bv);
        // Test rotate empty bitvec
        BitVecRotateLeft(&bv, 5);
        result = result && (BitVecLen(&bv) == 0);
    
        // Test rotate by 0
        BitVecPush(&bv, false);
        BitVecRotateLeft(&bv, 2);
        result = result && (BitVecLen(&bv) == 2);
    
        // Test large rotate amount
        // Test large rotate amount
        BitVecRotateRight(&bv, 1000);
        result = result && (BitVecLen(&bv) == 2);
    
        BitVecDeinit(&bv);
        BitVec result_bv = BitVecInit(ALLOCATOR_OF(&alloc));
        BitVecAnd(&result_bv, &bv1, &bv2);
        result = result && (BitVecLen(&result_bv) == 0);
    
        BitVecOr(&result_bv, &bv1, &bv2);
    
        BitVecOr(&result_bv, &bv1, &bv2);
        result = result && (BitVecLen(&result_bv) == 0);
    
        // Test operations with different lengths
    
        BitVecAnd(&result_bv, &bv1, &bv2);
        result = result && (BitVecLen(&result_bv) >= 1); // Should handle gracefully
    
        // Test NOT on various sizes
        BitVecClear(&bv1);
        BitVecNot(&result_bv, &bv1);
        result = result && (BitVecLen(&result_bv) == 0);
    
        BitVecPush(&bv1, true);
        // Test reverse empty bitvec
        BitVecReverse(&bv);
        result = result && (BitVecLen(&bv) == 0);
    
        // Test reverse single bit
        BitVecPush(&bv, true);
        BitVecReverse(&bv);
        result = result && (BitVecLen(&bv) == 1);
        result = result && (BitVecGet(&bv, 0) == true);
        // Test AND with different lengths (result should be min length)
        BitVecAnd(&result, &bv1, &bv2);
        test_result = test_result && (BitVecLen(&result) == 4);
    
        // Test OR with different lengths (result should be max length)
        // Test OR with different lengths (result should be max length)
        BitVecOr(&result, &bv1, &bv2);
        test_result = test_result && (BitVecLen(&result) == 8);
    
        // Test XOR with different lengths
        // Test XOR with different lengths
        BitVecXor(&result, &bv1, &bv2);
        test_result = test_result && (BitVecLen(&result) == 8);
    
        // Test with single bit operands
    
        BitVecAnd(&result, &bv1, &bv2);
        test_result = test_result && (BitVecLen(&result) == 1);
        test_result = test_result && (BitVecGet(&result, 0) == false);
    
        BitVecNot(&result, &bv1);
        test_result = test_result && (BitVecLen(&result) == 100);
    
        // Verify NOT correctness
        // Should be different from original (lost MSB, gained LSB zero)
        bool changed = false;
        for (int i = 0; i < (int)BitVecLen(&original); i++) {
            if (BitVecGet(&bv, i) != BitVecGet(&original, i)) {
                changed = true;
    
        BitVecShiftLeft(&bv, 8);
        result = result && (BitVecLen(&bv) == 0);
    
        // Test shifting by more than length
    
        BitVecShiftRight(&bv, 10);
        result = result && (BitVecLen(&bv) == 0);
    
        // Test boundary conditions - shift by length-1
    
        BitVecShiftLeft(&bv, 2);
        result = result && (BitVecLen(&bv) == 3);
        result = result && (BitVecGet(&bv, 0) == false); // filled with 0
        result = result && (BitVecGet(&bv, 1) == false); // filled with 0
        // Test A XOR A = 0
        BitVecXor(&result, &bv1, &bv1);
        test_result = test_result && (BitVecLen(&result) == 16);
        for (int i = 0; i < 16; i++) {
            test_result = test_result && (BitVecGet(&result, i) == false);
        // Test AND on large data
        BitVecAnd(&result, &bv1, &bv2);
        test_result = test_result && (BitVecLen(&result) == 1000);
    
        // Verify result integrity - spot check a few positions
        // Test XOR on large data
        BitVecXor(&result, &bv1, &bv2);
        test_result = test_result && (BitVecLen(&result) == 1000);
    
        // Test NOT on large data
        // Test NOT on large data
        BitVecNot(&result, &bv1);
        test_result = test_result && (BitVecLen(&result) == 1000);
    
        // Verify NOT correctness on sample
    
        BitVecShiftLeft(&result, 100);
        test_result = test_result && (BitVecLen(&result) == 1000);
    
        // First 100 bits should be 0
    
        bool result =
            BitVecLen(&clone.bits) == BitVecLen(&original.bits) && IntAllocator(&clone) == IntAllocator(&original) &&
            IntAllocator(&clone)->allocate == IntAllocator(&original)->allocate &&
            IntAllocator(&clone)->remap == IntAllocator(&original)->remap &&
    
        // Check length
        bool result = (BitVecLen(&bv) == 5);
    
        // Check each bit
    
        // Check first bit
        bool result = (BitVecLen(&bv) == 1 && BitVecGet(&bv, 0) == true);
    
        // Insert at the end
    
        // Check bits
        result = result && (BitVecLen(&bv) == 2);
        result = result && (BitVecGet(&bv, 0) == true);
        result = result && (BitVecGet(&bv, 1) == false);
    
        // Check all bits
        result = result && (BitVecLen(&bv) == 3);
        result = result && (BitVecGet(&bv, 0) == true);
        result = result && (BitVecGet(&bv, 1) == true);
    
        // Check result: false, true, true, true, false
        bool result = (BitVecLen(&bv) == 5);
        result      = result && (BitVecGet(&bv, 0) == false);
        result      = result && (BitVecGet(&bv, 1) == true);
    
        // Check result: true, true, true, true, false
        bool result = (BitVecLen(&bv) == 5);
        result      = result && (BitVecGet(&bv, 0) == true);
        result      = result && (BitVecGet(&bv, 1) == true);
        // Check result: false, true, false, true, true, false
        // Pattern 1011 gets inserted as individual bits
        bool result = (BitVecLen(&bv) == 6);
        result      = result && (BitVecGet(&bv, 0) == false); // original
        result      = result && (BitVecGet(&bv, 1) == true);  // bit 0 of pattern (LSB)
    
        // Check result: true, false, true, true (3 bits: 101)
        result = result && (BitVecLen(&bv2) == 4);
        result = result && (BitVecGet(&bv2, 0) == true);  // bit 0 of pattern (LSB)
        result = result && (BitVecGet(&bv2, 1) == false); // bit 1 of pattern
        // Test inserting 0 bits (should be no-op)
        BitVecInsertRange(&bv, 0, 0, true);
        result = result && (BitVecLen(&bv) == 0);
    
        // Test inserting at end
        BitVecPush(&bv, true);
        BitVecInsertRange(&bv, 1, 2, false);
        result = result && (BitVecLen(&bv) == 3);
        result = result && (BitVecGet(&bv, 1) == false);
        result = result && (BitVecGet(&bv, 2) == false);
        BitVecClear(&bv);
        BitVecInsertRange(&bv, 0, 1000, true);
        result = result && (BitVecLen(&bv) == 1000);
        result = result && (BitVecGet(&bv, 0) == true);
        result = result && (BitVecGet(&bv, 999) == true);
        // Test inserting empty bitvec
        BitVecInsertMultiple(&bv, 0, &empty);
        result = result && (BitVecLen(&bv) == 0);
    
        // Test inserting single bit bitvec
        BitVecPush(&source, true);
        BitVecInsertMultiple(&bv, 0, &source);
        result = result && (BitVecLen(&bv) == 1) && (BitVecGet(&bv, 0) == true);
    
        // Test inserting large bitvec
        }
        BitVecInsertMultiple(&bv, 1, &source);
        result = result && (BitVecLen(&bv) == 501);
        result = result && (BitVecGet(&bv, 1) == false);
        result = result && (BitVecGet(&bv, 500) == false);
        // Test inserting empty pattern (should be no-op)
        BitVecInsertPattern(&bv, 0, 0x00, 0);
        result = result && (BitVecLen(&bv) == 0);
    
        // Test inserting single bit pattern
        // Test inserting single bit pattern
        BitVecInsertPattern(&bv, 0, 0x01, 1); // 1 bit pattern
        result = result && (BitVecLen(&bv) == 1);
    
        // Test inserting 8-bit pattern
        BitVecClear(&bv);
        BitVecInsertPattern(&bv, 0, 0xAA, 8);            // 10101010 pattern
        result = result && (BitVecLen(&bv) == 8);
        result = result && (BitVecGet(&bv, 0) == false); // First bit of 0xAA
        result = result && (BitVecGet(&bv, 1) == true);  // Second bit
        // Check initial state
        bool result =
            (BitVecLen(&bitvec) == 0 && BitVecCapacity(&bitvec) == 0 && BitVecData(&bitvec) == NULL &&
             BitVecByteSize(&bitvec) == 0);
    
        // Check result should be: 101110
        result = result && (BitVecLen(&source) == 6);
        result = result && (BitVecGet(&source, 0) == true);
        result = result && (BitVecGet(&source, 1) == false);
    
        // Check final length
        result = result && (BitVecLen(&source) == 6); // 3 * 2 = 6
    
        BitVecDeinit(&source);
    
        // Initially empty
        bool result = (BitVecLen(&bv) == 0);
    
        // Push some bits
        BitVecPush(&bv, true);
    
        result = result && (BitVecLen(&bv) == 3);
        result = result && (BitVecCapacity(&bv) >= 3);
        // Reserve more space
        BitVecReserve(&bv, 100);
        result = result && (BitVecLen(&bv) == 3);
        result = result && (BitVecCapacity(&bv) >= 100);
    
        // Test length and capacity macros if they exist
        result = result && (BitVecLen(&bv) == 2);
        result = result && (BitVecCapacity(&bv) >= 2);
    
        // Check initial state
        bool result = (BitVecLen(&bv) == 0);
        result      = result && (BitVecCapacity(&bv) == 0);
        result      = result && (BitVecData(&bv) == NULL);
    
        // Check that data was allocated
        bool result = (BitVecLen(&bv) == 3) && (BitVecData(&bv) != NULL);
    
        // Deinitialize
        // Note: We can't easily test that memory was freed without causing issues,
        // but we can check that the structure is reset to safe values
        result = result && (BitVecLen(&bv) == 0);
        result = result && (BitVecCapacity(&bv) == 0);
        result = result && (BitVecData(&bv) == NULL);
        // Check that capacity was increased
        bool result = (BitVecCapacity(&bv) >= 50);
        result      = result && (BitVecLen(&bv) == 0);     // Length should still be 0
        result      = result && (BitVecData(&bv) != NULL); // Memory should be allocated
        }
    
        result = result && (BitVecLen(&bv) == 10);
        result = result && (BitVecCapacity(&bv) >= 50); // Should still have the reserved capacity
    
        // Check initial state
        bool result            = (BitVecLen(&bv) == 4) && (BitVecData(&bv) != NULL);
        u64  original_capacity = BitVecCapacity(&bv);
    
        // Check that length is 0 but capacity and memory allocation remain
        result = result && (BitVecLen(&bv) == 0);
        result = result && (BitVecCapacity(&bv) == original_capacity);
        result = result && (BitVecData(&bv) != NULL); // Memory should still be allocated
        // Test that we can still add data after clearing
        BitVecPush(&bv, true);
        result = result && (BitVecLen(&bv) == 1);
        result = result && (BitVecGet(&bv, 0) == true);
    
        // Check that length was increased and new bits have the default value
        bool result = (BitVecLen(&bv) == 6);
        result      = result && (BitVecGet(&bv, 0) == true);  // Original data
        result      = result && (BitVecGet(&bv, 1) == false); // Original data
    
        // Check that length was decreased and data was truncated
        result = result && (BitVecLen(&bv) == 2);
        result = result && (BitVecGet(&bv, 0) == true);  // Original data preserved
        result = result && (BitVecGet(&bv, 1) == false); // Original data preserved
        // Test resizing to same size (should be no-op)
        BitVecResize(&bv, 2);
        result = result && (BitVecLen(&bv) == 2);
    
        // Clean up
        BitVec bv3 = BitVecInit(ALLOCATOR_OF(&alloc));
    
        bool result = (BitVecLen(&bv1) == 0) && (BitVecLen(&bv2) == 0) && (BitVecLen(&bv3) == 0);
        result      = result && (BitVecData(&bv1) == NULL) && (BitVecData(&bv2) == NULL) && (BitVecData(&bv3) == NULL);
        BitVecPush(&bv, false);
        BitVecResize(&bv, 0);
        result = result && (BitVecLen(&bv) == 0);
    
        // Test reu64 from 0 to non-zero
        // Test reu64 from 0 to non-zero
        BitVecResize(&bv, 5);
        result = result && (BitVecLen(&bv) == 5);
        // New bits should be false
        for (u64 i = 0; i < 5; i++) {
        // Test reu64 to same size
        BitVecResize(&bv, 5);
        result = result && (BitVecLen(&bv) == 5);
    
        // Test large resize
        // Test large resize
        BitVecResize(&bv, 1000);
        result = result && (BitVecLen(&bv) == 1000);
    
        // Test shrinking from large size
        // Test shrinking from large size
        BitVecResize(&bv, 10);
        result = result && (BitVecLen(&bv) == 10);
    
        BitVecDeinit(&bv);
        // Test clear on empty bitvec
        BitVecClear(&bv);
        result = result && (BitVecLen(&bv) == 0);
    
        // Test clear after single bit
        BitVecPush(&bv, true);
        BitVecClear(&bv);
        result = result && (BitVecLen(&bv) == 0);
    
        // Test multiple clears
        BitVecClear(&bv);
        BitVecClear(&bv);
        result = result && (BitVecLen(&bv) == 0);
    
        // Test clear after large data
        }
        BitVecClear(&bv);
        result = result && (BitVecLen(&bv) == 0);
    
        BitVecDeinit(&bv);
            }
    
            result = result && (BitVecLen(&bv) == (size)(cycle % 10));
            BitVecDeinit(&bv);
        }
    
        // Check result
        bool result = (popped == true) && (BitVecLen(&bv) == 2);
        result      = result && (BitVecGet(&bv, 0) == true);
        result      = result && (BitVecGet(&bv, 1) == false);
        // Pop another bit
        popped = BitVecPop(&bv);
        result = result && (popped == false) && (BitVecLen(&bv) == 1);
        result = result && (BitVecGet(&bv, 0) == true);
        // Pop the last bit
        popped = BitVecPop(&bv);
        result = result && (popped == true) && (BitVecLen(&bv) == 0);
    
        // Clean up
    
        // Check result: true, false, false, true
        bool result = (removed == true) && (BitVecLen(&bv) == 4);
        result      = result && (BitVecGet(&bv, 0) == true);
        result      = result && (BitVecGet(&bv, 1) == false);
        // Remove bit at index 0 (first bit)
        removed = BitVecRemove(&bv, 0);
        result  = result && (removed == true) && (BitVecLen(&bv) == 3);
        result  = result && (BitVecGet(&bv, 0) == false);
        result  = result && (BitVecGet(&bv, 1) == false);
    
        // Check result: true, false, true (removed false, true, true)
        bool result = (BitVecLen(&bv) == 3);
        result      = result && (BitVecGet(&bv, 0) == true);
        result      = result && (BitVecGet(&bv, 1) == false);
    
        // Check result: true, true, false, true (removed first false at index 1)
        bool result = (found == true) && (BitVecLen(&bv) == 4);
        result      = result && (BitVecGet(&bv, 0) == true);
        result      = result && (BitVecGet(&bv, 1) == true);
        // Now try to remove false from a bitvector with only trues
        found  = BitVecRemoveFirst(&bv, false);
        result = result && (found == false) && (BitVecLen(&bv) == 3);
    
        // Clean up
    
        // Check result: true, false, true, true (removed last false at index 3)
        bool result = (found == true) && (BitVecLen(&bv) == 4);
        result      = result && (BitVecGet(&bv, 0) == true);
        result      = result && (BitVecGet(&bv, 1) == false);
    
        // Check result: true, false, true (removed last true at index 3)
        result = result && (found == true) && (BitVecLen(&bv) == 3);
        result = result && (BitVecGet(&bv, 0) == true);
        result = result && (BitVecGet(&bv, 1) == false);
    
        // Check result: true, true, true (all false bits removed)
        bool result = (removed_count == 3) && (BitVecLen(&bv) == 3);
        result      = result && (BitVecGet(&bv, 0) == true);
        result      = result && (BitVecGet(&bv, 1) == true);
        // Try to remove all false bits again (should return 0)
        removed_count = BitVecRemoveAll(&bv, false);
        result        = result && (removed_count == 0) && (BitVecLen(&bv) == 3);
    
        // Remove all true bits
        // Remove all true bits
        removed_count = BitVecRemoveAll(&bv, true);
        result        = result && (removed_count == 3) && (BitVecLen(&bv) == 0);
    
        // Clean up
        BitVecPush(&bv, true);
        bool popped = BitVecPop(&bv);
        result      = result && (popped == true) && (BitVecLen(&bv) == 0);
    
        // Test multiple pops in sequence
            popped = BitVecPop(&bv);
            result = result && (popped == (i % 2 == 0));
            result = result && (BitVecLen(&bv) == (size)i);
        }
        BitVecPush(&bv, true);
        bool removed = BitVecRemove(&bv, 0);
        result       = result && (removed == true) && (BitVecLen(&bv) == 0);
    
        // Test remove from large bitvec
        removed = BitVecRemove(&bv, 500);
        result  = result && (removed == (500 % 3 == 0)); // Should return the value of the removed bit
        result  = result && (BitVecLen(&bv) == 999);
    
        BitVecDeinit(&bv);
        BitVecPush(&bv, true);
        BitVecRemoveRange(&bv, 0, 0);
        result = result && (BitVecLen(&bv) == 1);
    
        // Test remove entire bitvec
        }
        BitVecRemoveRange(&bv, 0, 10);
        result = result && (BitVecLen(&bv) == 0);
    
        // Test remove partial range
        }
        BitVecRemoveRange(&bv, 1, 5);             // Remove 5 elements starting at index 1
        result = result && (BitVecLen(&bv) == 5); // Should have 5 elements left
    
        BitVecDeinit(&bv);
        // Test remove from empty bitvec
        bool found = BitVecRemoveFirst(&bv, true);
        result     = result && (found == false) && (BitVecLen(&bv) == 0);
    
        found  = BitVecRemoveLast(&bv, false);
    
        found  = BitVecRemoveLast(&bv, false);
        result = result && (found == false) && (BitVecLen(&bv) == 0);
    
        // Test remove when value doesn't exist
        BitVecPush(&bv, true);
        found  = BitVecRemoveFirst(&bv, false);
        result = result && (found == false) && (BitVecLen(&bv) == 2);
    
        // Test remove single occurrence
        BitVecPush(&bv, false);
        found  = BitVecRemoveFirst(&bv, false);
        result = result && (found == true) && (BitVecLen(&bv) == 0);
    
        // Test remove from large uniform data
        }
        found  = BitVecRemoveFirst(&bv, true);
        result = result && (found == true) && (BitVecLen(&bv) == 999);
    
        BitVecDeinit(&bv);
        // Test remove all from empty bitvec
        u64 count = BitVecRemoveAll(&bv, true);
        result    = result && (count == 0) && (BitVecLen(&bv) == 0);
    
        // Test remove all when value doesn't exist
        BitVecPush(&bv, true);
        count  = BitVecRemoveAll(&bv, false);
        result = result && (count == 0) && (BitVecLen(&bv) == 2);
    
        // Test remove all of uniform data
        }
        count  = BitVecRemoveAll(&bv, true);
        result = result && (count == 100) && (BitVecLen(&bv) == 0);
    
        // Test remove all mixed data
        }
        count  = BitVecRemoveAll(&bv, false); // Remove odds
        result = result && (count == 500) && (BitVecLen(&bv) == 500);
    
        BitVecDeinit(&bv);
    
        // Expected result: 1000 (1101 AND 1010)
        bool test_result = (BitVecLen(&result) == 4);
        test_result      = test_result && (BitVecGet(&result, 0) == true);
        test_result      = test_result && (BitVecGet(&result, 1) == false);
    
        // Expected result: 1110 (1100 OR 1010)
        bool test_result = (BitVecLen(&result) == 4);
        test_result      = test_result && (BitVecGet(&result, 0) == true);
        test_result      = test_result && (BitVecGet(&result, 1) == true);
    
        // Expected result: 0110 (1100 XOR 1010)
        bool test_result = (BitVecLen(&result) == 4);
        test_result      = test_result && (BitVecGet(&result, 0) == false);
        test_result      = test_result && (BitVecGet(&result, 1) == true);
    
        // Expected result: 0101 (NOT 1010)
        bool test_result = (BitVecLen(&result) == 4);
        test_result      = test_result && (BitVecGet(&result, 0) == false);
        test_result      = test_result && (BitVecGet(&result, 1) == true);
        // After shift left by 2, implementation should clear bits that shift out
        // and fill lower positions with 0
        bool test_result = (BitVecLen(&bv) == 4);
    
        // Let me trace through the implementation:
        BitVecShiftRight(&bv, 2);
    
        bool test_result = (BitVecLen(&bv) == 4);
        test_result      = test_result && (BitVecGet(&bv, 0) == true);
        test_result      = test_result && (BitVecGet(&bv, 1) == true);
    
        // Expected result: 1110 (1011 rotated left by 2)
        bool test_result = (BitVecLen(&bv) == 4);
        test_result      = test_result && (BitVecGet(&bv, 0) == true);
        test_result      = test_result && (BitVecGet(&bv, 1) == true);
    
        // Expected result: 1101 (1011 rotated right by 1)
        bool test_result = (BitVecLen(&bv) == 4);
        test_result      = test_result && (BitVecGet(&bv, 0) == true);
        test_result      = test_result && (BitVecGet(&bv, 1) == true);
    
        // Expected result: 1101 (1011 reversed)
        bool test_result = (BitVecLen(&bv) == 4);
        test_result      = test_result && (BitVecGet(&bv, 0) == true);
        test_result      = test_result && (BitVecGet(&bv, 1) == true);
        // Test shift empty bitvec
        BitVecShiftLeft(&bv, 5);
        result = result && (BitVecLen(&bv) == 0);
    
        BitVecShiftRight(&bv, 3);
    
        BitVecShiftRight(&bv, 3);
        result = result && (BitVecLen(&bv) == 0);
    
        // Test shift by 0 (should be no-op)
        BitVecPush(&bv, false);
        BitVecShiftLeft(&bv, 0);
        result = result && (BitVecLen(&bv) == 2);
        result = result && (BitVecGet(&bv, 0) == true);
        // Test shift larger than length (should clear all bits)
        BitVecShiftLeft(&bv, 10);
        result = result && (BitVecLen(&bv) == 0); // Should clear when shifting everything out
    
        // Test large data shift
        }
        BitVecShiftLeft(&bv, 1);
        result = result && (BitVecLen(&bv) == 1000);
    
        BitVecDeinit(&bv);
        // Test rotate empty bitvec
        BitVecRotateLeft(&bv, 5);
        result = result && (BitVecLen(&bv) == 0);
    
        // Test rotate by 0
        BitVecPush(&bv, false);
        BitVecRotateLeft(&bv, 2);
        result = result && (BitVecLen(&bv) == 2);
    
        // Test large rotate amount
        // Test large rotate amount
        BitVecRotateRight(&bv, 1000);
        result = result && (BitVecLen(&bv) == 2);
    
        BitVecDeinit(&bv);
        BitVec result_bv = BitVecInit(ALLOCATOR_OF(&alloc));
        BitVecAnd(&result_bv, &bv1, &bv2);
        result = result && (BitVecLen(&result_bv) == 0);
    
        BitVecOr(&result_bv, &bv1, &bv2);
    
        BitVecOr(&result_bv, &bv1, &bv2);
        result = result && (BitVecLen(&result_bv) == 0);
    
        // Test operations with different lengths
    
        BitVecAnd(&result_bv, &bv1, &bv2);
        result = result && (BitVecLen(&result_bv) >= 1); // Should handle gracefully
    
        // Test NOT on various sizes
        BitVecClear(&bv1);
        BitVecNot(&result_bv, &bv1);
        result = result && (BitVecLen(&result_bv) == 0);
    
        BitVecPush(&bv1, true);
        // Test reverse empty bitvec
        BitVecReverse(&bv);
        result = result && (BitVecLen(&bv) == 0);
    
        // Test reverse single bit
        BitVecPush(&bv, true);
        BitVecReverse(&bv);
        result = result && (BitVecLen(&bv) == 1);
        result = result && (BitVecGet(&bv, 0) == true);
        // Test AND with different lengths (result should be min length)
        BitVecAnd(&result, &bv1, &bv2);
        test_result = test_result && (BitVecLen(&result) == 4);
    
        // Test OR with different lengths (result should be max length)
        // Test OR with different lengths (result should be max length)
        BitVecOr(&result, &bv1, &bv2);
        test_result = test_result && (BitVecLen(&result) == 8);
    
        // Test XOR with different lengths
        // Test XOR with different lengths
        BitVecXor(&result, &bv1, &bv2);
        test_result = test_result && (BitVecLen(&result) == 8);
    
        // Test with single bit operands
    
        BitVecAnd(&result, &bv1, &bv2);
        test_result = test_result && (BitVecLen(&result) == 1);
        test_result = test_result && (BitVecGet(&result, 0) == false);
    
        BitVecNot(&result, &bv1);
        test_result = test_result && (BitVecLen(&result) == 100);
    
        // Verify NOT correctness
        // Should be different from original (lost MSB, gained LSB zero)
        bool changed = false;
        for (int i = 0; i < (int)BitVecLen(&original); i++) {
            if (BitVecGet(&bv, i) != BitVecGet(&original, i)) {
                changed = true;
    
        BitVecShiftLeft(&bv, 8);
        result = result && (BitVecLen(&bv) == 0);
    
        // Test shifting by more than length
    
        BitVecShiftRight(&bv, 10);
        result = result && (BitVecLen(&bv) == 0);
    
        // Test boundary conditions - shift by length-1
    
        BitVecShiftLeft(&bv, 2);
        result = result && (BitVecLen(&bv) == 3);
        result = result && (BitVecGet(&bv, 0) == false); // filled with 0
        result = result && (BitVecGet(&bv, 1) == false); // filled with 0
        // Test A XOR A = 0
        BitVecXor(&result, &bv1, &bv1);
        test_result = test_result && (BitVecLen(&result) == 16);
        for (int i = 0; i < 16; i++) {
            test_result = test_result && (BitVecGet(&result, i) == false);
        // Test AND on large data
        BitVecAnd(&result, &bv1, &bv2);
        test_result = test_result && (BitVecLen(&result) == 1000);
    
        // Verify result integrity - spot check a few positions
        // Test XOR on large data
        BitVecXor(&result, &bv1, &bv2);
        test_result = test_result && (BitVecLen(&result) == 1000);
    
        // Test NOT on large data
        // Test NOT on large data
        BitVecNot(&result, &bv1);
        test_result = test_result && (BitVecLen(&result) == 1000);
    
        // Verify NOT correctness on sample
    
        BitVecShiftLeft(&result, 100);
        test_result = test_result && (BitVecLen(&result) == 1000);
    
        // First 100 bits should be 0
    
        // Check result
        bool result = ok && (BitVecLen(&bv) == 4);
        result      = result && (BitVecGet(&bv, 0) == true);
        result      = result && (BitVecGet(&bv, 1) == false);
        // Test with empty string
        BitVec empty_bv = BitVecFromStr("", ALLOCATOR_OF(&alloc));
        result          = result && (BitVecLen(&empty_bv) == 0);
    
        // Clean up
    
        // Check result (8 bits from 1 byte)
        bool result = ok && (BitVecLen(&bv) == 8);
    
        // The exact bit order depends on implementation
        u64 false_count = 0;
    
        for (u64 i = 0; i < BitVecLen(&bv); i++) {
            if (BitVecGet(&bv, i)) {
                true_count++;
    
        // Check result
        bool result = ok && (BitVecLen(&bv) == 4);
    
        // Count ones and zeros
        u64 false_count = 0;
    
        for (u64 i = 0; i < BitVecLen(&bv); i++) {
            if (BitVecGet(&bv, i)) {
                true_count++;
        BitVec zero_bv;
        result = result && BitVecTryFromInteger(&zero_bv, 0, 8, ALLOCATOR_OF(&alloc));
        result = result && (BitVecLen(&zero_bv) == 8);
    
        // All bits should be false
        // All bits should be false
        bool all_false = true;
        for (u64 i = 0; i < BitVecLen(&zero_bv); i++) {
            if (BitVecGet(&zero_bv, i)) {
                all_false = false;
        // Test empty string
        BitVec bv1 = BitVecFromStr("", ALLOCATOR_OF(&alloc));
        result     = result && (BitVecLen(&bv1) == 0);
        BitVecDeinit(&bv1);
        // Test single character
        BitVec bv2 = BitVecFromStr("1", ALLOCATOR_OF(&alloc));
        result     = result && (BitVecLen(&bv2) == 1);
        result     = result && (BitVecGet(&bv2, 0) == true);
        BitVecDeinit(&bv2);
    
        BitVec bv3 = BitVecFromStr(long_str, ALLOCATOR_OF(&alloc));
        result     = result && (BitVecLen(&bv3) == 1000);
        result     = result && (BitVecGet(&bv3, 0) == true);
        result     = result && (BitVecGet(&bv3, 1) == false);
        u8     empty_bytes[1] = {0x05};
        BitVec bv2            = BitVecFromBytes(empty_bytes, 0, ALLOCATOR_OF(&alloc)); // 0 bits
        result                = result && (BitVecLen(&bv2) == 0);
        BitVecDeinit(&bv2);
        u8     single_byte[1] = {0xFF};
        BitVec bv3            = BitVecFromBytes(single_byte, 8, ALLOCATOR_OF(&alloc)); // 8 bits from 1 byte
        result                = result && (BitVecLen(&bv3) == 8);
        BitVecDeinit(&bv3);
        // Test integer to bitvec with 0
        BitVec bv2 = BitVecFromInteger(0, 8, ALLOCATOR_OF(&alloc)); // 8 bits for zero
        result     = result && (BitVecLen(&bv2) == 8);              // Should be 8 bits
        BitVecDeinit(&bv2);
        // Test large integer
        BitVec bv3 = BitVecFromInteger(UINT64_MAX, 64, ALLOCATOR_OF(&alloc)); // 64 bits for max value
        result     = result && (BitVecLen(&bv3) == 64);
        BitVecDeinit(&bv3);
        // Test large integer conversion (should cap at 64 bits)
        BitVec large_bv = BitVecFromInteger(0xFFFFFFFFFFFFFFFF, 64, ALLOCATOR_OF(&alloc));
        result          = result && (BitVecLen(&large_bv) == 64);
    
        u64 large_value = BitVecToInteger(&large_bv);
        // Test round-trip from bytes
        BitVec recovered_bv = BitVecFromBytes(large_bytes, 1000, ALLOCATOR_OF(&alloc));
        result              = result && (BitVecLen(&recovered_bv) == 1000);
    
        // Verify recovered pattern
        // Verify recovered pattern
        bool recovered_pattern_correct = true;
        for (u64 i = 0; i < BitVecLen(&recovered_bv); i++) {
            bool expected = (i % 3) == 0;
            bool actual   = BitVecGet(&recovered_bv, i);
    
        BitVec large_from_str = BitVecFromStr(large_pattern, ALLOCATOR_OF(&alloc));
        result                = result && (BitVecLen(&large_from_str) == 2000);
    
        // Verify pattern
        // Verify pattern
        bool large_pattern_correct = true;
        for (u64 i = 0; i < BitVecLen(&large_from_str); i++) {
            bool expected = (i % 7) == 0;
            bool actual   = BitVecGet(&large_from_str, i);
        u8     dummy_bytes[1] = {0xFF};
        BitVec empty_bv       = BitVecFromBytes(dummy_bytes, 0, ALLOCATOR_OF(&alloc));
        bool   result         = (BitVecLen(&empty_bv) == 0);
        BitVecDeinit(&empty_bv);
    
        // Initially should be empty
        bool result = (BitVecLen(&bv) == 0) && (BitVecCapacity(&bv) == 0);
    
        // Add some bits
        BitVecPush(&bv, true);
    
        result = result && (BitVecLen(&bv) == 3);
        result = result && (BitVecCapacity(&bv) >= 3);
        BitVecClear(&bv);
        result = result && BitVecEmpty(&bv);
        result = result && (BitVecLen(&bv) == 0);
    
        // Clean up
            if (cycle > 0) {
                result = result && (BitVecGet(&bv, 0) == true);
                result = result && (BitVecLen(&bv) == (size)(cycle + 1));
            }
        for (int check = 0; check < 50; check++) {
            u64 base_idx = check * 80; // Check every 80 bits
            if (base_idx + 7 < BitVecLen(&bv)) {
                for (int bit = 0; bit < 8; bit++) {
                    bool expected = (pattern & (1u << bit)) != 0;
        result = result && (BitVecGet(&bv, 0) == false);                 // First bit of pattern
        result = result && (BitVecGet(&bv, 2) == true);                  // Third bit of pattern
        result = result && (BitVecGet(&bv, BitVecLen(&bv) - 1) == true); // Last bit
    
        BitVecDeinit(&bv);
    
        // Test all macros on empty bitvector
        result = result && (BitVecLen(&bv) == 0);
        result = result && (BitVecCapacity(&bv) == 0);
        result = result && BitVecEmpty(&bv);
        }
    
        result = result && (BitVecLen(&bv) == 65);
        result = result && (BitVecCapacity(&bv) >= 65);
        result = result && !BitVecEmpty(&bv);
        }
    
        result = result && (BitVecLen(&bv) == 64);
        result = result && (BitVecByteSize(&bv) >= 8); // At least 8 bytes for 64 bits
    /// TAGS: BitVec, Empty, Check
    ///
    #define BitVecEmpty(bv) (BitVecLen(bv) == 0)
    
    ///
Last updated on