Skip to content
ValidateBitVec

ValidateBitVec

Description

Validate whether a given BitVec object is valid. Not foolproof but will work most of the time. Aborts if provided BitVec is not valid.

Parameters

Name Direction Description
bv in Pointer to BitVec object to validate.

Success

Continue execution, meaning given BitVec object is most probably valid.

Failure

abort

Usage example (Cross-references)

Usage examples (Cross-references)
    
        ValidateStr(o);
        ValidateBitVec(bv);
    
        // Snapshot the pre-render length so post-render padding sees the
        }
    
        ValidateBitVec(bv);
    
        StrIter si = StrIterFromZstr(i);
    
    void BitVecDeinit(BitVec *bitvec) {
        ValidateBitVec(bitvec);
        if (bitvec->data) {
            AllocatorFree(bitvec->allocator, bitvec->data);
    
    void BitVecClear(BitVec *bitvec) {
        ValidateBitVec(bitvec);
        bitvec->length = 0;
        if (bitvec->data && bitvec->byte_size > 0) {
    
    bool BitVecResize(BitVec *bitvec, u64 new_size) {
        ValidateBitVec(bitvec);
        if (new_size > bitvec->capacity) {
            if (!BitVecReserve(bitvec, new_size)) {
    
    bool BitVecReserve(BitVec *bitvec, u64 n) {
        ValidateBitVec(bitvec);
        if (n <= bitvec->capacity)
            return true;
    
    void BitVecShrinkToFit(BitVec *bv) {
        ValidateBitVec(bv);
        if (bv->length == 0) {
            AllocatorFree(bv->allocator, bv->data);
    
    void BitVecSwap(BitVec *bv1, BitVec *bv2) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
    void BitVecSwap(BitVec *bv1, BitVec *bv2) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
    
        u8 *temp_data = bv1->data;
    
    bool BitVecTryClone(BitVec *out, BitVec *bv) {
        ValidateBitVec(bv);
        if (!out) {
            LOG_FATAL("Invalid arguments");
        BitVec clone;
    
        ValidateBitVec(bv);
        clone = BitVecInit(bv->allocator);
        (void)BitVecTryClone(&clone, bv);
    
    bool BitVecGet(const BitVec *bitvec, u64 idx) {
        ValidateBitVec(bitvec);
        if (idx >= bitvec->length) {
            LOG_FATAL("Index {} exceeds bitvector length {}", idx, bitvec->length);
    
    void BitVecSet(BitVec *bitvec, u64 idx, bool value) {
        ValidateBitVec(bitvec);
        if (idx >= bitvec->length) {
            LOG_FATAL("Index {} exceeds bitvector length {}", idx, bitvec->length);
    
    void BitVecFlip(BitVec *bitvec, u64 idx) {
        ValidateBitVec(bitvec);
        if (idx >= bitvec->length) {
            LOG_FATAL("Index {} exceeds bitvector length {}", idx, bitvec->length);
    
    bool BitVecPush(BitVec *bitvec, bool value) {
        ValidateBitVec(bitvec);
        if (bitvec->length >= bitvec->capacity) {
            u64 new_capacity = bitvec->capacity == 0 ? 8 : bitvec->capacity * 2;
    
    bool BitVecPop(BitVec *bitvec) {
        ValidateBitVec(bitvec);
        if (bitvec->length == 0) {
            LOG_FATAL("Cannot pop from empty bitvector");
    
    bool BitVecInsert(BitVec *bitvec, u64 idx, bool value) {
        ValidateBitVec(bitvec);
        if (idx > bitvec->length) {
            LOG_FATAL("Index {} exceeds bitvector length {}", idx, bitvec->length);
    
    bool BitVecInsertRange(BitVec *bv, u64 idx, u64 count, bool value) {
        ValidateBitVec(bv);
        if (idx > bv->length) {
            LOG_FATAL("Index {} exceeds bitvector length {}", idx, bv->length);
    
    bool BitVecInsertMultiple(BitVec *bv, u64 idx, BitVec *other) {
        ValidateBitVec(bv);
        ValidateBitVec(other);
        if (idx > bv->length) {
    bool BitVecInsertMultiple(BitVec *bv, u64 idx, BitVec *other) {
        ValidateBitVec(bv);
        ValidateBitVec(other);
        if (idx > bv->length) {
            LOG_FATAL("Index {} exceeds bitvector length {}", idx, bv->length);
    
    bool BitVecInsertPattern(BitVec *bv, u64 idx, u8 pattern, u64 pattern_bits) {
        ValidateBitVec(bv);
        if (idx > bv->length) {
            LOG_FATAL("Index {} exceeds bitvector length {}", idx, bv->length);
    
    bool BitVecRemove(BitVec *bv, u64 idx) {
        ValidateBitVec(bv);
        if (idx >= bv->length) {
            LOG_FATAL("Index {} exceeds bitvector length {}", idx, bv->length);
    
    void BitVecRemoveRange(BitVec *bv, u64 idx, u64 count) {
        ValidateBitVec(bv);
        if (idx >= bv->length) {
            LOG_FATAL("Index {} exceeds bitvector length {}", idx, bv->length);
    
    bool BitVecRemoveFirst(BitVec *bv, bool value) {
        ValidateBitVec(bv);
    
        u64 pos = BitVecFind(bv, value);
    
    bool BitVecRemoveLast(BitVec *bv, bool value) {
        ValidateBitVec(bv);
    
        u64 pos = BitVecFindLast(bv, value);
    
    u64 BitVecRemoveAll(BitVec *bv, bool value) {
        ValidateBitVec(bv);
    
        u64 removed_count = 0;
    
    u64 BitVecCountOnes(const BitVec *bitvec) {
        ValidateBitVec(bitvec);
        if (!bitvec->data)
            return 0;
    
    u64 BitVecCountZeros(const BitVec *bitvec) {
        ValidateBitVec(bitvec);
        return bitvec->length - BitVecCountOnes(bitvec);
    }
    
    void BitVecAnd(BitVec *result, BitVec *a, BitVec *b) {
        ValidateBitVec(result);
        ValidateBitVec(a);
        ValidateBitVec(b);
    void BitVecAnd(BitVec *result, BitVec *a, BitVec *b) {
        ValidateBitVec(result);
        ValidateBitVec(a);
        ValidateBitVec(b);
        ValidateBitVec(result);
        ValidateBitVec(a);
        ValidateBitVec(b);
    
        u64 min_len = MIN2(a->length, b->length);
    
    void BitVecOr(BitVec *result, BitVec *a, BitVec *b) {
        ValidateBitVec(result);
        ValidateBitVec(a);
        ValidateBitVec(b);
    void BitVecOr(BitVec *result, BitVec *a, BitVec *b) {
        ValidateBitVec(result);
        ValidateBitVec(a);
        ValidateBitVec(b);
        ValidateBitVec(result);
        ValidateBitVec(a);
        ValidateBitVec(b);
    
        u64 max_len = MAX2(a->length, b->length);
    
    void BitVecXor(BitVec *result, BitVec *a, BitVec *b) {
        ValidateBitVec(result);
        ValidateBitVec(a);
        ValidateBitVec(b);
    void BitVecXor(BitVec *result, BitVec *a, BitVec *b) {
        ValidateBitVec(result);
        ValidateBitVec(a);
        ValidateBitVec(b);
        ValidateBitVec(result);
        ValidateBitVec(a);
        ValidateBitVec(b);
    
        u64 max_len = MAX2(a->length, b->length);
    
    void BitVecNot(BitVec *result, BitVec *bitvec) {
        ValidateBitVec(result);
        ValidateBitVec(bitvec);
    void BitVecNot(BitVec *result, BitVec *bitvec) {
        ValidateBitVec(result);
        ValidateBitVec(bitvec);
    
        if (!BitVecResize(result, bitvec->length)) {
    
    bool BitVecEquals(const BitVec *bv1, const BitVec *bv2) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
    bool BitVecEquals(const BitVec *bv1, const BitVec *bv2) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
    
        if (bv1->length != bv2->length) {
    
    bool BitVecEqualsRange(const BitVec *bv1, u64 start1, const BitVec *bv2, u64 start2, u64 len) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
    bool BitVecEqualsRange(const BitVec *bv1, u64 start1, const BitVec *bv2, u64 start2, u64 len) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
    
        if (start1 + len > bv1->length) {
    
        (void)size;
        ValidateBitVec(bv);
    
        u64       bit_count  = bv->length;
    
    int BitVecCompare(const BitVec *bv1, const BitVec *bv2) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
    int BitVecCompare(const BitVec *bv1, const BitVec *bv2) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
    
        u64 min_len = MIN2(bv1->length, bv2->length);
    
    int BitVecCompareRange(const BitVec *bv1, u64 start1, const BitVec *bv2, u64 start2, u64 len) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
    int BitVecCompareRange(const BitVec *bv1, u64 start1, const BitVec *bv2, u64 start2, u64 len) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
    
        if (start1 + len > bv1->length) {
    
    int BitVecNumericalCompare(const BitVec *bv1, const BitVec *bv2) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
    int BitVecNumericalCompare(const BitVec *bv1, const BitVec *bv2) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
    
        // LSB-first storage means the most significant magnitude bit lives
    
    int BitVecWeightCompare(const BitVec *bv1, const BitVec *bv2) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
    int BitVecWeightCompare(const BitVec *bv1, const BitVec *bv2) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
    
        u64 weight1 = BitVecCountOnes(bv1);
    
    int BitVecSignedCompare(const BitVec *bv1, const BitVec *bv2) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
    int BitVecSignedCompare(const BitVec *bv1, const BitVec *bv2) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
    
        if (bv1->length == 0 && bv2->length == 0) {
    
    bool BitVecIsSubset(const BitVec *bv1, const BitVec *bv2) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
    bool BitVecIsSubset(const BitVec *bv1, const BitVec *bv2) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
    
        // Subset = every 1-bit position in bv1 also has a 1 in bv2. Out-of-
    
    bool BitVecDisjoint(const BitVec *bv1, const BitVec *bv2) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
    bool BitVecDisjoint(const BitVec *bv1, const BitVec *bv2) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
    
        u64 min_len = MIN2(bv1->length, bv2->length);
    
    bool BitVecIsSorted(const BitVec *bv) {
        ValidateBitVec(bv);
    
        bool found_one = false;
    
    bool bitvec_try_to_str(Str *out, BitVec *bv, Allocator *alloc) {
        ValidateBitVec(bv);
        if (!out) {
            LOG_FATAL("out is NULL");
    
    u64 BitVecToBytes(BitVec *bv, u8 *bytes, u64 max_len) {
        ValidateBitVec(bv);
        if (!bytes) {
            LOG_FATAL("bytes is NULL");
    
    u64 BitVecToInteger(const BitVec *bv) {
        ValidateBitVec(bv);
        if (bv->length == 0) {
            return 0;
    
    void BitVecShiftLeft(BitVec *bv, u64 positions) {
        ValidateBitVec(bv);
        if (positions == 0 || bv->length == 0) {
            return;
    
    void BitVecShiftRight(BitVec *bv, u64 positions) {
        ValidateBitVec(bv);
        if (positions == 0 || bv->length == 0) {
            return;
    
    void BitVecRotateLeft(BitVec *bv, u64 positions) {
        ValidateBitVec(bv);
        if (positions == 0 || bv->length == 0) {
            return;
    
    void BitVecRotateRight(BitVec *bv, u64 positions) {
        ValidateBitVec(bv);
        if (positions == 0 || bv->length == 0) {
            return;
    
    void BitVecReverse(BitVec *bv) {
        ValidateBitVec(bv);
        if (bv->length <= 1) {
            return;
    
    u64 BitVecFind(const BitVec *bv, bool value) {
        ValidateBitVec(bv);
    
        for (u64 i = 0; i < bv->length; i++) {
    
    u64 BitVecFindLast(const BitVec *bv, bool value) {
        ValidateBitVec(bv);
    
        if (bv->length == 0) {
    
    bool BitVecAll(const BitVec *bv, bool value) {
        ValidateBitVec(bv);
    
        for (u64 i = 0; i < bv->length; i++) {
    
    bool BitVecAny(const BitVec *bv, bool value) {
        ValidateBitVec(bv);
        return BitVecFind(bv, value) != SIZE_MAX;
    }
    
    u64 BitVecLongestRun(const BitVec *bv, bool value) {
        ValidateBitVec(bv);
    
        if (bv->length == 0) {
    
    u64 BitVecFindPattern(BitVec *bv, BitVec *pattern) {
        ValidateBitVec(bv);
        ValidateBitVec(pattern);
    u64 BitVecFindPattern(BitVec *bv, BitVec *pattern) {
        ValidateBitVec(bv);
        ValidateBitVec(pattern);
    
        if (pattern->length == 0 || pattern->length > bv->length) {
    
    u64 BitVecFindLastPattern(BitVec *bv, BitVec *pattern) {
        ValidateBitVec(bv);
        ValidateBitVec(pattern);
    u64 BitVecFindLastPattern(BitVec *bv, BitVec *pattern) {
        ValidateBitVec(bv);
        ValidateBitVec(pattern);
    
        if (pattern->length == 0 || pattern->length > bv->length) {
    
    u64 bitvec_find_all_pattern_raw(BitVec *bv, BitVec *pattern, size *results, u64 max_results) {
        ValidateBitVec(bv);
        ValidateBitVec(pattern);
    u64 bitvec_find_all_pattern_raw(BitVec *bv, BitVec *pattern, size *results, u64 max_results) {
        ValidateBitVec(bv);
        ValidateBitVec(pattern);
    
        if (!results || max_results == 0) {
    
    bool bitvec_find_all_pattern_vec(BitVec *bv, BitVec *pattern, BitVecMatchIndices *out) {
        ValidateBitVec(bv);
        ValidateBitVec(pattern);
    bool bitvec_find_all_pattern_vec(BitVec *bv, BitVec *pattern, BitVecMatchIndices *out) {
        ValidateBitVec(bv);
        ValidateBitVec(pattern);
    
        if (!out || !out->allocator) {
    
    u64 bitvec_run_lengths_raw(BitVec *bv, u64 *runs, bool *values, u64 max_runs) {
        ValidateBitVec(bv);
        if (!runs || !values || max_runs == 0) {
            LOG_FATAL("invalid arguments");
    
    bool bitvec_run_lengths_vec(BitVec *bv, BitVecRuns *out) {
        ValidateBitVec(bv);
        if (!out || !out->allocator) {
            LOG_FATAL("output BitVecRuns is NULL or uninitialized");
    
    u64 BitVecHammingDistance(BitVec *bv1, BitVec *bv2) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
    u64 BitVecHammingDistance(BitVec *bv1, BitVec *bv2) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
    
        u64 min_length = MIN2(bv1->length, bv2->length);
    
    double BitVecJaccardSimilarity(BitVec *bv1, BitVec *bv2) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
    double BitVecJaccardSimilarity(BitVec *bv1, BitVec *bv2) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
    
        if (bv1->length == 0 && bv2->length == 0) {
    
    double BitVecCosineSimilarity(BitVec *bv1, BitVec *bv2) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
    double BitVecCosineSimilarity(BitVec *bv1, BitVec *bv2) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
    
        u64 dot_product = BitVecDotProduct(bv1, bv2);
    
    u64 BitVecDotProduct(BitVec *bv1, BitVec *bv2) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
    u64 BitVecDotProduct(BitVec *bv1, BitVec *bv2) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
    
        u64 min_length = MIN2(bv1->length, bv2->length);
    
    bool BitVecTryEditDistance(BitVec *bv1, BitVec *bv2, u64 *out) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
        if (!out) {
    bool BitVecTryEditDistance(BitVec *bv1, BitVec *bv2, u64 *out) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
        if (!out) {
            LOG_FATAL("out is NULL");
    
    double BitVecCorrelation(BitVec *bv1, BitVec *bv2) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
    double BitVecCorrelation(BitVec *bv1, BitVec *bv2) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
    
        u64 max_length = MAX2(bv1->length, bv2->length);
    
    double BitVecEntropy(BitVec *bv) {
        ValidateBitVec(bv);
    
        if (bv->length == 0)
    
    int BitVecAlignmentScore(BitVec *bv1, BitVec *bv2, int match, int mismatch) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
    int BitVecAlignmentScore(BitVec *bv1, BitVec *bv2, int match, int mismatch) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
    
        u64 min_length = MIN2(bv1->length, bv2->length);
    
    u64 BitVecBestAlignment(BitVec *bv1, BitVec *bv2) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
    u64 BitVecBestAlignment(BitVec *bv1, BitVec *bv2) {
        ValidateBitVec(bv1);
        ValidateBitVec(bv2);
    
        if (bv1->length == 0 || bv2->length == 0) {
    
    bool BitVecStartsWith(BitVec *bv, BitVec *prefix) {
        ValidateBitVec(bv);
        ValidateBitVec(prefix);
    bool BitVecStartsWith(BitVec *bv, BitVec *prefix) {
        ValidateBitVec(bv);
        ValidateBitVec(prefix);
    
        if (prefix->length > bv->length) {
    
    bool BitVecEndsWith(BitVec *bv, BitVec *suffix) {
        ValidateBitVec(bv);
        ValidateBitVec(suffix);
    bool BitVecEndsWith(BitVec *bv, BitVec *suffix) {
        ValidateBitVec(bv);
        ValidateBitVec(suffix);
    
        if (suffix->length > bv->length) {
    
    bool BitVecContainsAt(BitVec *bv, BitVec *pattern, u64 idx) {
        ValidateBitVec(bv);
        ValidateBitVec(pattern);
    bool BitVecContainsAt(BitVec *bv, BitVec *pattern, u64 idx) {
        ValidateBitVec(bv);
        ValidateBitVec(pattern);
    
        // Subtractive form so `idx + pattern->length` wrapping near UINT64_MAX
    
    u64 BitVecCountPattern(BitVec *bv, BitVec *pattern) {
        ValidateBitVec(bv);
        ValidateBitVec(pattern);
    u64 BitVecCountPattern(BitVec *bv, BitVec *pattern) {
        ValidateBitVec(bv);
        ValidateBitVec(pattern);
    
        if (pattern->length == 0 || pattern->length > bv->length) {
    
    u64 BitVecRFindPattern(BitVec *bv, BitVec *pattern, u64 start) {
        ValidateBitVec(bv);
        ValidateBitVec(pattern);
    u64 BitVecRFindPattern(BitVec *bv, BitVec *pattern, u64 start) {
        ValidateBitVec(bv);
        ValidateBitVec(pattern);
    
        if (pattern->length == 0 || pattern->length > bv->length || start >= bv->length) {
    
    bool BitVecReplace(BitVec *bv, BitVec *old_pattern, BitVec *new_pattern) {
        ValidateBitVec(bv);
        ValidateBitVec(old_pattern);
        ValidateBitVec(new_pattern);
    bool BitVecReplace(BitVec *bv, BitVec *old_pattern, BitVec *new_pattern) {
        ValidateBitVec(bv);
        ValidateBitVec(old_pattern);
        ValidateBitVec(new_pattern);
        ValidateBitVec(bv);
        ValidateBitVec(old_pattern);
        ValidateBitVec(new_pattern);
    
        u64 pos = BitVecFindPattern(bv, old_pattern);
    
    u64 BitVecReplaceAll(BitVec *bv, BitVec *old_pattern, BitVec *new_pattern) {
        ValidateBitVec(bv);
        ValidateBitVec(old_pattern);
        ValidateBitVec(new_pattern);
    u64 BitVecReplaceAll(BitVec *bv, BitVec *old_pattern, BitVec *new_pattern) {
        ValidateBitVec(bv);
        ValidateBitVec(old_pattern);
        ValidateBitVec(new_pattern);
        ValidateBitVec(bv);
        ValidateBitVec(old_pattern);
        ValidateBitVec(new_pattern);
    
        u64 replacements = 0;
    
    bool BitVecMatches(BitVec *bv, BitVec *pattern, BitVec *wildcard) {
        ValidateBitVec(bv);
        ValidateBitVec(pattern);
        ValidateBitVec(wildcard);
    bool BitVecMatches(BitVec *bv, BitVec *pattern, BitVec *wildcard) {
        ValidateBitVec(bv);
        ValidateBitVec(pattern);
        ValidateBitVec(wildcard);
        ValidateBitVec(bv);
        ValidateBitVec(pattern);
        ValidateBitVec(wildcard);
    
        if (bv->length != pattern->length || pattern->length != wildcard->length) {
    
    u64 BitVecFuzzyMatch(BitVec *bv, BitVec *pattern, u64 max_errors) {
        ValidateBitVec(bv);
        ValidateBitVec(pattern);
    u64 BitVecFuzzyMatch(BitVec *bv, BitVec *pattern, u64 max_errors) {
        ValidateBitVec(bv);
        ValidateBitVec(pattern);
    
        if (pattern->length > bv->length) {
    
    bool bitvec_regex_match_zstr(BitVec *bv, Zstr pattern) {
        ValidateBitVec(bv);
        if (!pattern) {
            LOG_FATAL("pattern is NULL");
    
    bool bitvec_regex_match_str(BitVec *bv, const Str *pattern) {
        ValidateBitVec(bv);
        if (!pattern) {
            LOG_FATAL("pattern is NULL");
    
    u64 BitVecPrefixMatch(BitVec *bv, BitVecs *patterns) {
        ValidateBitVec(bv);
        if (!patterns) {
            LOG_FATAL("invalid BitVecs object provided");
    
    u64 BitVecSuffixMatch(BitVec *bv, BitVecs *patterns) {
        ValidateBitVec(bv);
        if (!patterns) {
            LOG_FATAL("invalid arguments");
    }
    
    void ValidateBitVec(const BitVec *bv) {
        if (!bv) {
            LOG_FATAL("Invalid bitvec object: NULL.");
    // Test ValidateBitVec macro
    bool test_bitvec_validate(void) {
        WriteFmt("Testing ValidateBitVec macro\n");
    
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        // This should not abort
        ValidateBitVec(&bitvec);
    
        // Clean up
    ///
    static inline void ValidateInt(const Int *value) {
        ValidateBitVec(value ? &value->bits : NULL);
    }
    #define BitVecForeachIdx(bv, var, idx)                                                                                 \
        for (TYPE_OF(bv) UNPL(pbv) = (bv); UNPL(pbv); UNPL(pbv) = NULL)                                                    \
            if ((ValidateBitVec(UNPL(pbv)), 1) && UNPL(pbv)->length > 0)                                                   \
                for (u64 idx = 0, UNPL(d) = 1; UNPL(d); UNPL(d)--)                                                         \
                    for (bool var = 0; idx < UNPL(pbv)->length && (var = BitVecGet(UNPL(pbv), idx), 1); idx++)
    #define BitVecForeachReverseIdx(bv, var, idx)                                                                          \
        for (TYPE_OF(bv) UNPL(pbv) = (bv); UNPL(pbv); UNPL(pbv) = NULL)                                                    \
            if ((ValidateBitVec(UNPL(pbv)), 1) && UNPL(pbv)->length > 0)                                                   \
                for (u64 idx = UNPL(pbv)->length; idx-- > 0 && idx < UNPL(pbv)->length;)                                   \
                    for (u8 UNPL(run_once) = 1; UNPL(run_once); UNPL(run_once) = 0)                                        \
    #define BitVecForeachInRangeIdx(bv, var, idx, start, end)                                                              \
        for (TYPE_OF(bv) UNPL(pbv) = (bv); UNPL(pbv); UNPL(pbv) = NULL)                                                    \
            if ((ValidateBitVec(UNPL(pbv)), 1) && UNPL(pbv)->length > 0)                                                   \
                for (u64 UNPL(s) = (start), UNPL(e) = (end), idx = UNPL(s), UNPL(d) = 1;                                   \
                     UNPL(s) <= idx && idx < UNPL(e) && idx < UNPL(pbv)->length && UNPL(s) <= UNPL(e);                     \
Last updated on