Skip to content

VecAt

Description

Element at idx accessed by value. Use this rather than indexing data directly so element alignment is respected.

Parameters

Name Direction Description
v in Vector to query.
idx in Index in [0, length).

Usage example (Cross-references)

Usage examples (Cross-references)
    
        for (idx = 0; idx < VecLen(neighbors); idx++) {
            if (VecAt(neighbors, idx) == node_id) {
                return true;
            }
    
        for (idx = 0; idx < VecLen(neighbors); idx++) {
            if (VecAt(neighbors, idx) == node_id) {
                return idx;
            }
    
        while (idx < VecLen(neighbors)) {
            GraphNodeId             neighbor_id = VecAt(neighbors, idx);
            const GenericGraphSlot *slot;
    
                for (neighbor_i = 0; neighbor_i < VecLen(&slot->out_neighbors); neighbor_i++) {
                    GraphNodeId             neighbor_id = VecAt(&slot->out_neighbors, neighbor_i);
                    const GenericGraphSlot *target_slot;
    
                for (neighbor_i = 0; neighbor_i < VecLen(&slot->in_neighbors); neighbor_i++) {
                    GraphNodeId             predecessor_id = VecAt(&slot->in_neighbors, neighbor_i);
                    const GenericGraphSlot *source_slot;
    
        for (free_index_i = 0; free_index_i < VecLen(&graph->free_indices); free_index_i++) {
            u32 index = VecAt(&graph->free_indices, free_index_i);
            if ((u64)index >= VecLen(&graph->slots)) {
                LOG_FATAL("Graph free slot index out of bounds");
        }
    
        return VecAt(neighbors, neighbor_idx);
    }
        }
    
        return VecAt(neighbors, predecessor_idx);
    }
    
        while (iter->neighbor_index < VecLen(neighbors)) {
            GraphNodeId neighbor_id  = VecAt(neighbors, iter->neighbor_index);
            iter->neighbor_index    += 1;
    
        while (iter->predecessor_index < VecLen(neighbors)) {
            GraphNodeId predecessor_id  = VecAt(neighbors, iter->predecessor_index);
            iter->predecessor_index    += 1;
        bool     have_one = ok && VecLen(&addrs) > 0;
        if (have_one) {
            *out = VecAt(&addrs, 0);
        }
        VecDeinit(&addrs);
        u64 dir_off  = 0;
        if (st->file >= 1 && st->file - 1 < VecLen(&cs->file_offsets)) {
            file_off    = VecAt(&cs->file_offsets, st->file - 1);
            u64 dir_idx = VecAt(&cs->file_dir_idx, st->file - 1);
            if (dir_idx >= 1 && dir_idx - 1 < VecLen(&cs->dir_offsets)) {
        if (st->file >= 1 && st->file - 1 < VecLen(&cs->file_offsets)) {
            file_off    = VecAt(&cs->file_offsets, st->file - 1);
            u64 dir_idx = VecAt(&cs->file_dir_idx, st->file - 1);
            if (dir_idx >= 1 && dir_idx - 1 < VecLen(&cs->dir_offsets)) {
                dir_off = VecAt(&cs->dir_offsets, dir_idx - 1);
            u64 dir_idx = VecAt(&cs->file_dir_idx, st->file - 1);
            if (dir_idx >= 1 && dir_idx - 1 < VecLen(&cs->dir_offsets)) {
                dir_off = VecAt(&cs->dir_offsets, dir_idx - 1);
            }
        }
        if (ok) {
            for (u64 i = 0; i < VecLen(&out->entries); ++i) {
                u64 fo                           = VecAt(&pending_file_offsets, i);
                u64 dofs                         = VecAt(&pending_dir_offsets, i);
                VecPtrAt(&out->entries, i)->file = fo ? (Zstr)(StrBegin(&out->string_pool) + fo) : NULL;
            for (u64 i = 0; i < VecLen(&out->entries); ++i) {
                u64 fo                           = VecAt(&pending_file_offsets, i);
                u64 dofs                         = VecAt(&pending_dir_offsets, i);
                VecPtrAt(&out->entries, i)->file = fo ? (Zstr)(StrBegin(&out->string_pool) + fo) : NULL;
                VecPtrAt(&out->entries, i)->dir  = dofs ? (Zstr)(StrBegin(&out->string_pool) + dofs) : NULL;
            if (!stream_read(self, DBI_STREAM_INDEX, sec_hdr_off, VecBegin(&sh), 2))
                break;
            r.section_hdr_stream = (u16)VecAt(&sh, 0) | (u16)VecAt(&sh, 1) << 8;
            r.ok                 = true;
        }
                if (VecLen(vec) > 0 && *offset + 4 <= data_size) {
                    size_t index = extract_u32(data, offset, data_size) % VecLen(vec);
                    char  *str   = VecAt(vec, index);
                    (void)str; // Use the result to avoid warnings
                }
                            char *str = generate_cstring(data, offset, data_size, 16);
                            if (str) {
                                VecAt(vec, i) = (char *)ZstrDup(str, (Allocator *)alloc);
                                cleanup_cstring(str);
                            }
                if (VecLen(vec) > 0 && *offset + 4 <= data_size) {
                    size_t index = extract_u32(data, offset, data_size) % VecLen(vec);
                    Str    str   = VecAt(vec, index);
                    (void)str; // Use the result to avoid warnings
                }
                        for (size_t i = old_size; i < new_size; i++) {
                            Str str       = generate_str_from_input(data, offset, data_size, 16, alloc);
                            VecAt(vec, i) = str;
                        }
                    }
                uint16_t idx = extract_u16(data, offset, data_size);
                if (idx < VecLen(vec)) {
                    volatile i32 value = VecAt(vec, idx);
                    (void)value; // Prevent optimization
                }
        });
    
        if (obj.x_value == 1 && VecLen(&obj.filled_items) == 2 && VecAt(&obj.filled_items, 0) == 1 &&
            VecAt(&obj.filled_items, 1) == 2) {
            WriteFmt(
    
        if (obj.x_value == 1 && VecLen(&obj.filled_items) == 2 && VecAt(&obj.filled_items, 0) == 1 &&
            VecAt(&obj.filled_items, 1) == 2) {
            WriteFmt(
                "[DEBUG] Mixed empty and filled test passed - x: {}, items: {}\n",
            );
            if (VecLen(&obj.filled_items) > 0) {
                WriteFmt("[DEBUG] First item: {}\n", VecAt(&obj.filled_items, 0));
            }
            success = false;
                // Write dynamic key for source function ID
                Str source_key = StrInit(&alloc);
                u64 source_id  = VecLen(&response.data) > 0 ? VecAt(&response.data, 0).source_function_id : 0;
                StrAppendFmt(&source_key, "{}", source_id);
                JW_OBJ_KV(json, StrBegin(&source_key), {
                    if (VecLen(&response.data) > 0) {
                        AnnSymbol *s          = &VecAt(&response.data, 0);
                        Str        target_key = StrInit(&alloc);
                        StrAppendFmt(&target_key, "{}", s->target_function_id);
    
        if (VecLen(&symbols) >= 2) {
            AnnSymbol *sym1 = &VecAt(&symbols, 0);
            AnnSymbol *sym2 = &VecAt(&symbols, 1);
        if (VecLen(&symbols) >= 2) {
            AnnSymbol *sym1 = &VecAt(&symbols, 0);
            AnnSymbol *sym2 = &VecAt(&symbols, 1);
    
            if (!(sym1->source_function_id == 12345 || sym1->source_function_id == 54321)) {
    
        if (VecLen(&response.data) > 0) {
            AnnSymbol *sym = &VecAt(&response.data, 0);
    
            // Debug individual symbol checks
    
        if (VecLen(&response.data) > 0) {
            AnnSymbol *sym = &VecAt(&response.data, 0);
    
            if (sym->source_function_id != 12345) {
    
        if (VecLen(&response.data) > 0) {
            AnnSymbol *sym = &VecAt(&response.data, 0);
    
            if (sym->source_function_id != 12345) {
    
        if (VecLen(&languages) >= 3) {
            Str *lang1 = &VecAt(&languages, 0);
            Str *lang2 = &VecAt(&languages, 1);
            Str *lang3 = &VecAt(&languages, 2);
        if (VecLen(&languages) >= 3) {
            Str *lang1 = &VecAt(&languages, 0);
            Str *lang2 = &VecAt(&languages, 1);
            Str *lang3 = &VecAt(&languages, 2);
            Str *lang1 = &VecAt(&languages, 0);
            Str *lang2 = &VecAt(&languages, 1);
            Str *lang3 = &VecAt(&languages, 2);
    
            if (StrCmp(lang1, "C", 1) != 0) {
    
        if (VecLen(&product.tags) >= 3) {
            Str *tag1 = &VecAt(&product.tags, 0);
            Str *tag2 = &VecAt(&product.tags, 1);
            Str *tag3 = &VecAt(&product.tags, 2);
        if (VecLen(&product.tags) >= 3) {
            Str *tag1 = &VecAt(&product.tags, 0);
            Str *tag2 = &VecAt(&product.tags, 1);
            Str *tag3 = &VecAt(&product.tags, 2);
            Str *tag1 = &VecAt(&product.tags, 0);
            Str *tag2 = &VecAt(&product.tags, 1);
            Str *tag3 = &VecAt(&product.tags, 2);
    
            if (StrCmp(tag1, "electronics", 11) != 0) {
    
        for (size i = 0; i < VecLen(&a->features); i++) {
            if (StrCmp((Str *)&VecAt(&a->features, i), (Str *)&VecAt(&b->features, i)) != 0) {
                return false;
            }
        if (numbers_match) {
            for (size i = 0; i < VecLen(&original_numbers); i++) {
                if (VecAt(&original_numbers, i) != VecAt(&parsed_numbers, i)) {
                    numbers_match = false;
                    break;
        if (numbers_match) {
            for (size i = 0; i < VecLen(&original.numbers); i++) {
                if (VecAt(&original.numbers, i) != VecAt(&parsed.numbers, i)) {
                    numbers_match = false;
                    break;
        if (flags_match) {
            for (size i = 0; i < VecLen(&original.flags); i++) {
                if (VecAt(&original.flags, i) != VecAt(&parsed.flags, i)) {
                    flags_match = false;
                    break;
        }
    
        ok = ok && (VecLen(&v) == 1024) && (VecAt(&v, 0) == 0) && (VecAt(&v, 1023) == 1023);
        VecDeinit(&v);
        PageAllocatorDeinit(&alloc);
    
        // Check that the elements were swapped
        bool result = (VecAt(&vec, 0) == 50 && VecAt(&vec, 4) == 10);
    
        // Swap two elements in the middle
    
        // Check that the elements were swapped
        result = result && (VecAt(&vec, 1) == 40 && VecAt(&vec, 3) == 20);
    
        // Check that the middle element is unchanged
    
        // Check that the middle element is unchanged
        result = result && (VecAt(&vec, 2) == 30);
    
        // Clean up
        bool result = true;
        for (size i = 0; i < VecLen(&vec); i++) {
            result = result && (VecAt(&vec, i) == values[4 - i]);
        }
        // Check that the elements are back in the original order
        for (size i = 0; i < VecLen(&vec); i++) {
            result = result && (VecAt(&vec, i) == values[i]);
        }
        // Check that the elements are reversed
        for (size i = 0; i < VecLen(&vec); i++) {
            result = result && (VecAt(&vec, i) == even_values[3 - i]);
        }
        int  sorted_asc[] = {10, 20, 30, 40, 50};
        for (size i = 0; i < VecLen(&vec); i++) {
            result = result && (VecAt(&vec, i) == sorted_asc[i]);
        }
        int sorted_desc[] = {50, 40, 30, 20, 10};
        for (size i = 0; i < VecLen(&vec); i++) {
            result = result && (VecAt(&vec, i) == sorted_desc[i]);
        }
        // Check that the values in the vector are unchanged (foreach uses value, not reference)
        for (u64 i = 0; i < VecLen(&vec); i++) {
            result = result && (VecAt(&vec, i) == values[i]);
        }
        bool result = true;
        for (u64 i = 0; i < VecLen(&vec); i++) {
            result = result && (VecAt(&vec, i) == values[i] * 2);
        }
        bool result = true;
        for (u64 i = 0; i < VecLen(&vec); i++) {
            result = result && (VecAt(&vec, i) == i);
        }
        VecForeachReverseIdx(&vec, item, idx) {
            result = result && (item == values[idx]);
            result = result && (VecAt(&vec, idx) == item);
        }
        bool result     = true;
        for (size i = 0; i < VecLen(&vec); i++) {
            result = result && (VecAt(&vec, i) == expected[i]);
        }
        bool result     = true;
        for (size i = 0; i < VecLen(&vec); i++) {
            result = result && (VecAt(&vec, i) == expected[i]);
        }
        result                     = result && VecLen(&matches) == 5;
        if (result) {
            result = result && VecAt(&matches, 0) == 0;
            result = result && VecAt(&matches, 1) == 2;
            result = result && VecAt(&matches, 2) == 4;
        if (result) {
            result = result && VecAt(&matches, 0) == 0;
            result = result && VecAt(&matches, 1) == 2;
            result = result && VecAt(&matches, 2) == 4;
            result = result && VecAt(&matches, 3) == 6;
            result = result && VecAt(&matches, 0) == 0;
            result = result && VecAt(&matches, 1) == 2;
            result = result && VecAt(&matches, 2) == 4;
            result = result && VecAt(&matches, 3) == 6;
            result = result && VecAt(&matches, 4) == 8;
            result = result && VecAt(&matches, 1) == 2;
            result = result && VecAt(&matches, 2) == 4;
            result = result && VecAt(&matches, 3) == 6;
            result = result && VecAt(&matches, 4) == 8;
        }
            result = result && VecAt(&matches, 2) == 4;
            result = result && VecAt(&matches, 3) == 6;
            result = result && VecAt(&matches, 4) == 8;
        }
        }
    
        ok = ok && VecLen(&v) == 4096 && VecAt(&v, 0) == 0 && VecAt(&v, 4095) == 4095;
        VecDeinit(&v);
        ArenaAllocatorDeinit(&arena);
            VecPushBackR(&vec, 30);
    
            if (VecLen(&vec) != 3 || VecAt(&vec, 0) != 10 || VecAt(&vec, 1) != 20 || VecAt(&vec, 2) != 30) {
                result = false;
            }
            VecPushBackR(&test_vec, item);
    
            if (VecLen(&test_vec) != 1 || VecAt(&test_vec, 0).id != 1 || VecAt(&test_vec, 0).value != 3.14f) {
                result = false;
            }
            AlignedItem item = {.a = 7, .b = 2.71828};
            VecPushBackR(&av, item);
            if (VecLen(&av) != 1 || VecAt(&av, 0).a != 7 || VecAt(&av, 0).b != 2.71828) {
                result = false;
            }
        if (result) {
            for (size i = 0; i < VecLen(&src); i++) {
                if (VecAt(&clone, i) != VecAt(&src, i)) {
                    result = false;
                    break;
        // Check that the data is still intact
        for (size i = 0; i < VecLen(&vec); i++) {
            result = result && (VecAt(&vec, i) == values[i]);
        }
        // First 3 elements should be unchanged
        for (size i = 0; i < 3; i++) {
            result = result && (VecAt(&vec, i) == values[i]);
        }
        // First 3 elements should still be the same
        for (size i = 0; i < 3; i++) {
            result = result && (VecAt(&vec, i) == values[i]);
        }
        // Check remaining elements
        for (u64 i = 0; i < VecLen(&vec); i++) {
            result = result && (VecAt(&vec, i) == values[i]);
        }
        // Check remaining elements
        for (u64 i = 0; i < VecLen(&vec); i++) {
            result = result && (VecAt(&vec, i) == values[i + 1]);
        }
        int expected1[] = {10, 20, 40, 50};
        for (u64 i = 0; i < VecLen(&vec); i++) {
            result = result && (VecAt(&vec, i) == expected1[i]);
        }
        int expected2[] = {20, 40, 50};
        for (u64 i = 0; i < VecLen(&vec); i++) {
            result = result && (VecAt(&vec, i) == expected2[i]);
        }
        int expected[] = {10, 50, 30, 40};
        for (u64 i = 0; i < VecLen(&vec); i++) {
            result = result && (VecAt(&vec, i) == expected[i]);
        }
        int expected[] = {10, 20, 60, 70};
        for (u64 i = 0; i < VecLen(&vec); i++) {
            result = result && (VecAt(&vec, i) == expected[i]);
        }
        WriteFmt("Before fast range delete: ");
        for (u64 i = 0; i < VecLen(&vec); i++) {
            WriteFmt("{} ", VecAt(&vec, i));
        }
        WriteFmt("\n");
        int end_values[3];
        for (int i = 0; i < count; i++) {
            end_values[i] = VecAt(&vec, VecLen(&vec) - count + i);
        }
        WriteFmt("After fast range delete: ");
        for (u64 i = 0; i < VecLen(&vec); i++) {
            WriteFmt("{} ", VecAt(&vec, i));
        }
        WriteFmt("\n");
        // Check that the last 3 elements moved to the deleted positions
        for (int i = 0; i < count; i++) {
            result = result && (VecAt(&vec, start_index + i) == end_values[i]);
        }
        bool values_found[10] = {false};
        for (u64 i = 0; i < VecLen(&vec); i++) {
            int val   = VecAt(&vec, i);
            int index = val / 10;
            if (index >= 0 && index < 10) {
        // Check remaining elements
        for (u64 i = 0; i < VecLen(&vec); i++) {
            result = result && (VecAt(&vec, i) == values[i]);
        }
        // Check remaining elements
        for (u64 i = 0; i < VecLen(&vec); i++) {
            result = result && (VecAt(&vec, i) == values[i]);
        }
        int expected[] = {10, 20, 40, 50};
        for (u64 i = 0; i < VecLen(&vec); i++) {
            result = result && (VecAt(&vec, i) == expected[i]);
        }
        int expected[] = {10, 20, 40, 50};
        for (u64 i = 0; i < VecLen(&vec); i++) {
            result = result && (VecAt(&vec, i) == expected[i]);
        }
        WriteFmt("Before L-value fast delete: ");
        for (u64 i = 0; i < VecLen(&vec); i++) {
            WriteFmt("{} ", VecAt(&vec, i));
        }
        WriteFmt("\n");
        // Test L-value fast delete operation
        int fast_index       = 2;                             // Delete 30
        int valueToBeDeleted = VecAt(&vec, fast_index);
        int lastValue        = VecAt(&vec, VecLen(&vec) - 1); // Should move to deleted position
        VecDeleteFast(&vec, fast_index);
        int fast_index       = 2;                             // Delete 30
        int valueToBeDeleted = VecAt(&vec, fast_index);
        int lastValue        = VecAt(&vec, VecLen(&vec) - 1); // Should move to deleted position
        VecDeleteFast(&vec, fast_index);
        WriteFmt("After L-value fast delete: ");
        for (u64 i = 0; i < VecLen(&vec); i++) {
            WriteFmt("{} ", VecAt(&vec, i));
        }
        WriteFmt("\n");
        bool containsValue = false;
        for (u64 i = 0; i < VecLen(&vec); i++) {
            if (VecAt(&vec, i) == valueToBeDeleted) {
                containsValue = true;
                break;
    
        // Check that the value at the deleted position is now the last value
        result = result && (VecAt(&vec, fast_index) == lastValue);
        WriteFmtLn(
            "Value at deleted position ({}) is now {} (expected {})\n",
            "Value at deleted position ({}) is now {} (expected {})\n",
            fast_index,
            VecAt(&vec, fast_index),
            lastValue
        );
            bool found = false;
            for (u64 j = 0; j < VecLen(&vec); j++) {
                if (VecAt(&vec, j) == expected_values[i]) {
                    found = true;
                    break;
        WriteFmt("Before R-value fast delete: ");
        for (u64 i = 0; i < VecLen(&vec); i++) {
            WriteFmt("{} ", VecAt(&vec, i));
        }
        WriteFmt("\n");
    
        // Remember the value to be deleted and the last value
        int valueToBeDeleted = VecAt(&vec, 2);                // 30
        int lastValue        = VecAt(&vec, VecLen(&vec) - 1); // Should move to deleted position
        // Remember the value to be deleted and the last value
        int valueToBeDeleted = VecAt(&vec, 2);                // 30
        int lastValue        = VecAt(&vec, VecLen(&vec) - 1); // Should move to deleted position
    
        // Test R-value fast delete operation
        WriteFmt("After R-value fast delete: ");
        for (u64 i = 0; i < VecLen(&vec); i++) {
            WriteFmt("{} ", VecAt(&vec, i));
        }
        WriteFmt("\n");
        bool containsValue = false;
        for (u64 i = 0; i < VecLen(&vec); i++) {
            if (VecAt(&vec, i) == valueToBeDeleted) {
                containsValue = true;
                break;
    
        // Check that the value at the deleted position is now the last value
        result = result && (VecAt(&vec, 2) == lastValue);
        WriteFmtLn("Value at deleted position (2) is now {} (expected {})\n", VecAt(&vec, 2), lastValue);
        // Check that the value at the deleted position is now the last value
        result = result && (VecAt(&vec, 2) == lastValue);
        WriteFmtLn("Value at deleted position (2) is now {} (expected {})\n", VecAt(&vec, 2), lastValue);
    
        // Verify all expected values (except the deleted one and the moved one) are still present
            bool found = false;
            for (u64 j = 0; j < VecLen(&vec); j++) {
                if (VecAt(&vec, j) == expected_values[i]) {
                    found = true;
                    break;
        int expected[] = {10, 20, 60, 70};
        for (u64 i = 0; i < VecLen(&vec); i++) {
            result = result && (VecAt(&vec, i) == expected[i]);
        }
        int expected[] = {10, 20, 60, 70};
        for (u64 i = 0; i < VecLen(&vec); i++) {
            result = result && (VecAt(&vec, i) == expected[i]);
        }
        WriteFmt("Before L-value fast range delete: ");
        for (u64 i = 0; i < VecLen(&vec); i++) {
            WriteFmt("{} ", VecAt(&vec, i));
        }
        WriteFmt("\n");
        WriteFmt("After L-value fast range delete: ");
        for (u64 i = 0; i < VecLen(&vec); i++) {
            WriteFmt("{} ", VecAt(&vec, i));
        }
        WriteFmt("\n");
            bool found = false;
            for (u64 j = 0; j < VecLen(&vec); j++) {
                if (VecAt(&vec, j) == valuesToDelete[i]) {
                    found = true;
                    break;
            bool found = false;
            for (u64 j = 0; j < VecLen(&vec); j++) {
                if (VecAt(&vec, j) == remainingValues[i]) {
                    found = true;
                    break;
        WriteFmt("Before R-value fast range delete: ");
        for (u64 i = 0; i < VecLen(&vec); i++) {
            WriteFmt("{} ", VecAt(&vec, i));
        }
        WriteFmt("\n");
        WriteFmt("After R-value fast range delete: ");
        for (u64 i = 0; i < VecLen(&vec); i++) {
            WriteFmt("{} ", VecAt(&vec, i));
        }
        WriteFmt("\n");
            bool found = false;
            for (u64 j = 0; j < VecLen(&vec); j++) {
                if (VecAt(&vec, j) == valuesToDelete[i]) {
                    found = true;
                    break;
            bool found = false;
            for (u64 j = 0; j < VecLen(&vec); j++) {
                if (VecAt(&vec, j) == remainingValues[i]) {
                    found = true;
                    break;
        // Check the content of the strings
        if (result) {
            Str *str1 = &VecAt(&sv, 0);
            Str *str2 = &VecAt(&sv, 1);
        if (result) {
            Str *str1 = &VecAt(&sv, 0);
            Str *str2 = &VecAt(&sv, 1);
    
            result = result && (ZstrCompare(StrBegin(str1), "Hello") == 0);
    
        // Check that the item was copied correctly
        result = result && ComplexItemsEqual(&VecAt(&vec, 0), &item);
    
        // Modify the original item and verify the vector's copy is independent
    
        // The vector's copy should still have the original values
        result = result && (ZstrCompare(VecAt(&vec, 0).name, "Test Item") == 0);
        result = result && (VecAt(&vec, 0).values[0] == 1);
        // The vector's copy should still have the original values
        result = result && (ZstrCompare(VecAt(&vec, 0).name, "Test Item") == 0);
        result = result && (VecAt(&vec, 0).values[0] == 1);
    
        // Clean up
    
        // Check items order: item2, item1, item3
        result = result && (ZstrCompare(VecAt(&vec, 0).name, "Item 2") == 0);
        result = result && (ZstrCompare(VecAt(&vec, 1).name, "Item 1") == 0);
        result = result && (ZstrCompare(VecAt(&vec, 2).name, "Item 3") == 0);
        // Check items order: item2, item1, item3
        result = result && (ZstrCompare(VecAt(&vec, 0).name, "Item 2") == 0);
        result = result && (ZstrCompare(VecAt(&vec, 1).name, "Item 1") == 0);
        result = result && (ZstrCompare(VecAt(&vec, 2).name, "Item 3") == 0);
        result = result && (ZstrCompare(VecAt(&vec, 0).name, "Item 2") == 0);
        result = result && (ZstrCompare(VecAt(&vec, 1).name, "Item 1") == 0);
        result = result && (ZstrCompare(VecAt(&vec, 2).name, "Item 3") == 0);
    
        // Check values
    
        // Check values
        result = result && (VecAt(&vec, 0).values[0] == 40);
        result = result && (VecAt(&vec, 1).values[0] == 10);
        result = result && (VecAt(&vec, 2).values[0] == 70);
        // Check values
        result = result && (VecAt(&vec, 0).values[0] == 40);
        result = result && (VecAt(&vec, 1).values[0] == 10);
        result = result && (VecAt(&vec, 2).values[0] == 70);
        result = result && (VecAt(&vec, 0).values[0] == 40);
        result = result && (VecAt(&vec, 1).values[0] == 10);
        result = result && (VecAt(&vec, 2).values[0] == 70);
    
        // Clean up
    
        // Check items order: item2, item3, item1
        result = result && (ZstrCompare(VecAt(&vec, 0).name, "Item 2") == 0);
        result = result && (ZstrCompare(VecAt(&vec, 1).name, "Item 3") == 0);
        result = result && (ZstrCompare(VecAt(&vec, 2).name, "Item 1") == 0);
        // Check items order: item2, item3, item1
        result = result && (ZstrCompare(VecAt(&vec, 0).name, "Item 2") == 0);
        result = result && (ZstrCompare(VecAt(&vec, 1).name, "Item 3") == 0);
        result = result && (ZstrCompare(VecAt(&vec, 2).name, "Item 1") == 0);
        result = result && (ZstrCompare(VecAt(&vec, 0).name, "Item 2") == 0);
        result = result && (ZstrCompare(VecAt(&vec, 1).name, "Item 3") == 0);
        result = result && (ZstrCompare(VecAt(&vec, 2).name, "Item 1") == 0);
    
        // Clean up
    
        // Check items in vec1: item1, item2, item3
        result = result && (ZstrCompare(VecAt(&vec1, 0).name, "Item 1") == 0);
        result = result && (ZstrCompare(VecAt(&vec1, 1).name, "Item 2") == 0);
        result = result && (ZstrCompare(VecAt(&vec1, 2).name, "Item 3") == 0);
        // Check items in vec1: item1, item2, item3
        result = result && (ZstrCompare(VecAt(&vec1, 0).name, "Item 1") == 0);
        result = result && (ZstrCompare(VecAt(&vec1, 1).name, "Item 2") == 0);
        result = result && (ZstrCompare(VecAt(&vec1, 2).name, "Item 3") == 0);
        result = result && (ZstrCompare(VecAt(&vec1, 0).name, "Item 1") == 0);
        result = result && (ZstrCompare(VecAt(&vec1, 1).name, "Item 2") == 0);
        result = result && (ZstrCompare(VecAt(&vec1, 2).name, "Item 3") == 0);
    
        // Now test VecMergeL which transfers ownership
    
        // Check items in vec3: item4, item5
        result = result && (ZstrCompare(VecAt(&vec3, 0).name, "Item 4") == 0);
        result = result && (ZstrCompare(VecAt(&vec3, 1).name, "Item 5") == 0);
        // Check items in vec3: item4, item5
        result = result && (ZstrCompare(VecAt(&vec3, 0).name, "Item 4") == 0);
        result = result && (ZstrCompare(VecAt(&vec3, 1).name, "Item 5") == 0);
    
        // Clean up
    
        // Check items order: val2, val3, val1
        result = result && (VecAt(&vec, 0) == 20);
        result = result && (VecAt(&vec, 1) == 30);
        result = result && (VecAt(&vec, 2) == 10);
        // Check items order: val2, val3, val1
        result = result && (VecAt(&vec, 0) == 20);
        result = result && (VecAt(&vec, 1) == 30);
        result = result && (VecAt(&vec, 2) == 10);
        result = result && (VecAt(&vec, 0) == 20);
        result = result && (VecAt(&vec, 1) == 30);
        result = result && (VecAt(&vec, 2) == 10);
    
        // Test array operations
    
        // Check items: val2, val3, val1, arr[0], arr[1], arr[2]
        result = result && (VecAt(&vec, 3) == 40);
        result = result && (VecAt(&vec, 4) == 50);
        result = result && (VecAt(&vec, 5) == 60);
        // Check items: val2, val3, val1, arr[0], arr[1], arr[2]
        result = result && (VecAt(&vec, 3) == 40);
        result = result && (VecAt(&vec, 4) == 50);
        result = result && (VecAt(&vec, 5) == 60);
        result = result && (VecAt(&vec, 3) == 40);
        result = result && (VecAt(&vec, 4) == 50);
        result = result && (VecAt(&vec, 5) == 60);
    
        // Clean up
    
        // Check that the element was inserted
        result = result && (VecAt(&vec, 2) == 99);
    
        // Use regular insert range instead of fast insert range
    
        // Check that the array was inserted
        result = result && (VecAt(&vec, 1) == 100);
        result = result && (VecAt(&vec, 2) == 200);
        result = result && (VecAt(&vec, 3) == 300);
        // Check that the array was inserted
        result = result && (VecAt(&vec, 1) == 100);
        result = result && (VecAt(&vec, 2) == 200);
        result = result && (VecAt(&vec, 3) == 300);
        result = result && (VecAt(&vec, 1) == 100);
        result = result && (VecAt(&vec, 2) == 200);
        result = result && (VecAt(&vec, 3) == 300);
    
        // Clean up
    
        result = result && (VecLen(&vec2) == 6);
        result = result && (VecAt(&vec2, 2) == 42);
    
        // Now try the range insert with a small array
    
        // Check that the array was inserted
        result = result && (VecAt(&vec2, 1) == 111);
        result = result && (VecAt(&vec2, 2) == 222);
        // Check that the array was inserted
        result = result && (VecAt(&vec2, 1) == 111);
        result = result && (VecAt(&vec2, 2) == 222);
    
        // Clean up
    
        // Check that the element was deleted and elements shifted
        result = result && (VecAt(&vec, 0) == 10);
        result = result && (VecAt(&vec, 1) == 20);
        result = result && (VecAt(&vec, 2) == 40); // 30 was deleted, so now 40 is at index 2
        // Check that the element was deleted and elements shifted
        result = result && (VecAt(&vec, 0) == 10);
        result = result && (VecAt(&vec, 1) == 20);
        result = result && (VecAt(&vec, 2) == 40); // 30 was deleted, so now 40 is at index 2
        result = result && (VecAt(&vec, 0) == 10);
        result = result && (VecAt(&vec, 1) == 20);
        result = result && (VecAt(&vec, 2) == 40); // 30 was deleted, so now 40 is at index 2
    
        // Test VecDeleteRange (regular delete range)
    
        // Check that elements were deleted and remaining elements shifted
        result = result && (VecAt(&vec, 0) == 40);
        result = result && (VecAt(&vec, 1) == 50);
        // Check that elements were deleted and remaining elements shifted
        result = result && (VecAt(&vec, 0) == 40);
        result = result && (VecAt(&vec, 1) == 50);
    
        // Clean up this vector
    
        // Check that the element was deleted and replaced with the last element (90)
        result = result && (VecAt(&vec, 0) == 10);
        result = result && (VecAt(&vec, 1) == 20);
        result = result && (VecAt(&vec, 2) == 90); // 30 was replaced with 90
        // Check that the element was deleted and replaced with the last element (90)
        result = result && (VecAt(&vec, 0) == 10);
        result = result && (VecAt(&vec, 1) == 20);
        result = result && (VecAt(&vec, 2) == 90); // 30 was replaced with 90
        result = result && (VecAt(&vec, 7) == 80); // Last element is now 80
        result = result && (VecAt(&vec, 0) == 10);
        result = result && (VecAt(&vec, 1) == 20);
        result = result && (VecAt(&vec, 2) == 90); // 30 was replaced with 90
        result = result && (VecAt(&vec, 7) == 80); // Last element is now 80
        result = result && (VecAt(&vec, 1) == 20);
        result = result && (VecAt(&vec, 2) == 90); // 30 was replaced with 90
        result = result && (VecAt(&vec, 7) == 80); // Last element is now 80
    
        // Test VecDeleteRangeFast (fast delete range)
    
        // Check that the element was deleted
        result = result && (VecAt(&vec, 3) == 50); // 40 was deleted, so now 50 is at index 3
    
        // Clean up
        // Test pushing to empty vector
        VecPushBackR(&vec, 10);
        bool result = (VecLen(&vec) == 1 && VecAt(&vec, 0) == 10);
    
        // Test pushing with zero count
        // Test inserting at end index
        VecInsertR(&vec, 20, VecLen(&vec));
        result = result && (VecLen(&vec) == 2 && VecAt(&vec, 1) == 20);
    
        // Test with large number of elements
        bool all_correct = true;
        for (int i = 0; i < large_count; i++) {
            if (VecAt(&vec, i) != i) {
                all_correct = false;
                break;
        // Push an element (should auto-resize)
        VecPushBackR(&vec, 42);
        result = result && (VecLen(&vec) == 1 && VecAt(&vec, 0) == 42);
    
        // Clean up
    // Test VecAt function
    bool test_vec_at(void) {
        WriteFmt("Testing VecAt\n");
    
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        // Check values using VecAt
        bool result = (VecAt(&vec, 0) == 10);
        result      = result && (VecAt(&vec, 1) == 20);
        result      = result && (VecAt(&vec, 2) == 30);
        // Check values using VecAt
        bool result = (VecAt(&vec, 0) == 10);
        result      = result && (VecAt(&vec, 1) == 20);
        result      = result && (VecAt(&vec, 2) == 30);
        result      = result && (VecAt(&vec, 3) == 40);
        bool result = (VecAt(&vec, 0) == 10);
        result      = result && (VecAt(&vec, 1) == 20);
        result      = result && (VecAt(&vec, 2) == 30);
        result      = result && (VecAt(&vec, 3) == 40);
        result      = result && (VecAt(&vec, 4) == 50);
        result      = result && (VecAt(&vec, 1) == 20);
        result      = result && (VecAt(&vec, 2) == 30);
        result      = result && (VecAt(&vec, 3) == 40);
        result      = result && (VecAt(&vec, 4) == 50);
        result      = result && (VecAt(&vec, 2) == 30);
        result      = result && (VecAt(&vec, 3) == 40);
        result      = result && (VecAt(&vec, 4) == 50);
    
        // Modify a value using VecAt
    
        // Modify a value using VecAt
        VecAt(&vec, 2) = 35;
        result         = result && (VecAt(&vec, 2) == 35);
        // Modify a value using VecAt
        VecAt(&vec, 2) = 35;
        result         = result && (VecAt(&vec, 2) == 35);
    
        // Clean up
    
        // Verify changes
        result = result && (VecAt(&vec, 0) == 15);
        result = result && (VecAt(&vec, 2) == 35);
        // Verify changes
        result = result && (VecAt(&vec, 0) == 15);
        result = result && (VecAt(&vec, 2) == 35);
    
        // Clean up
    
        // Verify changes
        result = result && (VecAt(&vec, 0) == 15);
        result = result && (VecAt(&vec, 2) == 35);
        // Verify changes
        result = result && (VecAt(&vec, 0) == 15);
        result = result && (VecAt(&vec, 2) == 35);
    
        // Clean up
        // Check elements in order
        for (size i = 0; i < VecLen(&vec); i++) {
            result = result && (VecAt(&vec, i) == values[i]);
        }
        // Check elements in reverse order (since we pushed to front)
        for (size i = 0; i < VecLen(&vec); i++) {
            result = result && (VecAt(&vec, i) == values[4 - i]);
        }
    
        // Check first element
        bool result = (VecLen(&vec) == 1 && VecAt(&vec, 0) == 10);
    
        // Insert at the end
    
        // Check elements
        result = result && (VecLen(&vec) == 2 && VecAt(&vec, 0) == 10 && VecAt(&vec, 1) == 30);
    
        // Insert in the middle
        // Check all elements
        result = result && (VecLen(&vec) == 3);
        result = result && (VecAt(&vec, 0) == 10);
        result = result && (VecAt(&vec, 1) == 20);
        result = result && (VecAt(&vec, 2) == 30);
        result = result && (VecLen(&vec) == 3);
        result = result && (VecAt(&vec, 0) == 10);
        result = result && (VecAt(&vec, 1) == 20);
        result = result && (VecAt(&vec, 2) == 30);
        result = result && (VecAt(&vec, 0) == 10);
        result = result && (VecAt(&vec, 1) == 20);
        result = result && (VecAt(&vec, 2) == 30);
    
        // Clean up
        // Check elements in order
        for (size i = 0; i < VecLen(&vec); i++) {
            result = result && (VecAt(&vec, i) == values[i]);
        }
        // Check all elements
        for (size i = 0; i < 5; i++) {
            result = result && (VecAt(&vec, i) == values[i]);
        }
        for (size i = 0; i < 3; i++) {
        }
        for (size i = 0; i < 3; i++) {
            result = result && (VecAt(&vec, i + 5) == more_values[i]);
        }
        // Check elements in order
        for (size i = 0; i < VecLen(&vec); i++) {
            result = result && (VecAt(&vec, i) == values[i]);
        }
        // Check all elements
        for (size i = 0; i < 3; i++) {
            result = result && (VecAt(&vec, i) == more_values[i]);
        }
        for (size i = 0; i < 5; i++) {
        }
        for (size i = 0; i < 5; i++) {
            result = result && (VecAt(&vec, i + 3) == values[i]);
        }
        // Check all elements
        for (size i = 0; i < VecLen(&vec); i++) {
            result = result && (VecAt(&vec, i) == expected[i]);
        }
        // Check all elements
        for (size i = 0; i < VecLen(&vec); i++) {
            result = result && (VecAt(&vec, i) == expected[i]);
        }
        // Check all elements in vec1
        for (size i = 0; i < VecLen(&vec1); i++) {
            result = result && (VecAt(&vec1, i) == expected[i]);
        }
                      VecAllocator(&dst)->effort == ALLOCATOR_EFFORT_RETRY_FALLBACK &&
                      VecAllocator(&dst)->retry_limit == 11 && allocator_matches && VecLen(&src) == 3 &&
                      VecAt(&src, 0) == 10 && VecAt(&src, 1) == 20 && VecAt(&src, 2) == 30 && VecLen(&dst) == 3 &&
                      VecAt(&dst, 0) == 10 && VecAt(&dst, 1) == 20 && VecAt(&dst, 2) == 30;
                      VecAllocator(&dst)->retry_limit == 11 && allocator_matches && VecLen(&src) == 3 &&
                      VecAt(&src, 0) == 10 && VecAt(&src, 1) == 20 && VecAt(&src, 2) == 30 && VecLen(&dst) == 3 &&
                      VecAt(&dst, 0) == 10 && VecAt(&dst, 1) == 20 && VecAt(&dst, 2) == 30;
    
        VecDeinit(&src);
    
        // Check that the element was added
        bool result = (VecLen(&vec) == 1 && VecAt(&vec, 0) == 42);
    
        // Test L-value insert operations
    
        // Check that the element was added
        result = result && (VecLen(&vec) == 2 && VecAt(&vec, 1) == 100);
    
        // Test R-value insert at index
        // Check that the element was inserted
        result = result && (VecLen(&vec) == 3);
        result = result && (VecAt(&vec, 0) == 42);
        result = result && (VecAt(&vec, 1) == 50);
        result = result && (VecAt(&vec, 2) == 100);
        result = result && (VecLen(&vec) == 3);
        result = result && (VecAt(&vec, 0) == 42);
        result = result && (VecAt(&vec, 1) == 50);
        result = result && (VecAt(&vec, 2) == 100);
        result = result && (VecAt(&vec, 0) == 42);
        result = result && (VecAt(&vec, 1) == 50);
        result = result && (VecAt(&vec, 2) == 100);
    
        // Test L-value insert at index
        // Check that the element was inserted
        result = result && (VecLen(&vec) == 4);
        result = result && (VecAt(&vec, 0) == 42);
        result = result && (VecAt(&vec, 1) == 50);
        result = result && (VecAt(&vec, 2) == 75);
        result = result && (VecLen(&vec) == 4);
        result = result && (VecAt(&vec, 0) == 42);
        result = result && (VecAt(&vec, 1) == 50);
        result = result && (VecAt(&vec, 2) == 75);
        result = result && (VecAt(&vec, 3) == 100);
        result = result && (VecAt(&vec, 0) == 42);
        result = result && (VecAt(&vec, 1) == 50);
        result = result && (VecAt(&vec, 2) == 75);
        result = result && (VecAt(&vec, 3) == 100);
        result = result && (VecAt(&vec, 1) == 50);
        result = result && (VecAt(&vec, 2) == 75);
        result = result && (VecAt(&vec, 3) == 100);
    
        // Test R-value fast insert
        // Check that the element was inserted
        result = result && (VecLen(&vec) == 5);
        result = result && (VecAt(&vec, 1) == 60);
    
        // Test L-value fast insert
        // Check that the element was inserted
        result = result && (VecLen(&vec) == 6);
        result = result && (VecAt(&vec, 3) == 80);
    
        // Test array operations with L-values and R-values
        // Check that the elements were added
        result = result && (VecLen(&vec) == 9);
        result = result && (VecAt(&vec, 6) == 200);
        result = result && (VecAt(&vec, 7) == 300);
        result = result && (VecAt(&vec, 8) == 400);
        result = result && (VecLen(&vec) == 9);
        result = result && (VecAt(&vec, 6) == 200);
        result = result && (VecAt(&vec, 7) == 300);
        result = result && (VecAt(&vec, 8) == 400);
        result = result && (VecAt(&vec, 6) == 200);
        result = result && (VecAt(&vec, 7) == 300);
        result = result && (VecAt(&vec, 8) == 400);
    
        // L-value array operations
        // Check that the elements were added
        result = result && (VecLen(&vec) == 12);
        result = result && (VecAt(&vec, 0) == 200);
        result = result && (VecAt(&vec, 1) == 300);
        result = result && (VecAt(&vec, 2) == 400);
        result = result && (VecLen(&vec) == 12);
        result = result && (VecAt(&vec, 0) == 200);
        result = result && (VecAt(&vec, 1) == 300);
        result = result && (VecAt(&vec, 2) == 400);
        result = result && (VecAt(&vec, 0) == 200);
        result = result && (VecAt(&vec, 1) == 300);
        result = result && (VecAt(&vec, 2) == 400);
    
        // Clean up
    
        for (size i = 0; i < idx; i++) {
            result = result && (VecAt(&vec, i) == originals[i]);
        }
    
        for (size i = 0; i < new_count; i++) {
            result = result && (VecAt(&vec, idx + i) == new_items[i]);
        }
            bool found = false;
            for (size j = tail_start; j < tail_end; j++) {
                if (VecAt(&vec, j) == originals[i]) {
                    found = true;
                    break;
    /// TAGS: Vec, Access, First
    ///
    #define VecFirst(v) VecAt(v, 0)
    
    ///
    /// TAGS: Vec, Access, Last
    ///
    #define VecLast(v) VecAt(v, (v)->length - 1)
    
    ///
            if ((ValidateVec(UNPL(pv)), 1) && UNPL(pv)->length > 0)                                                        \
                for (u64 idx = 0, UNPL(d) = 1; UNPL(d); UNPL(d)--)                                                         \
                    for (VEC_DATATYPE(UNPL(pv)) var = {0}; idx < UNPL(pv)->length && (var = VecAt(UNPL(pv), idx), 1); idx++)
    
    ///
                for (u64 idx = UNPL(pv)->length; idx-- > 0 && idx < UNPL(pv)->length;)                                     \
                    for (u8 UNPL(run_once) = 1; UNPL(run_once); UNPL(run_once) = 0)                                        \
                        for (VEC_DATATYPE(UNPL(pv)) var = VecAt(UNPL(pv), idx); UNPL(run_once); UNPL(run_once) = 0)
    
    ///
                     UNPL(s) <= idx && idx < UNPL(e) && idx < UNPL(pv)->length && UNPL(s) <= UNPL(e);                      \
                     ++idx, UNPL(d) = 1)                                                                                   \
                    for (VEC_DATATYPE(UNPL(pv)) var = VecAt(UNPL(pv), idx); UNPL(d); UNPL(d) = 0)
    
    ///
    /// TAGS: Str, Access, Index
    ///
    #define StrCharAt(str, idx) VecAt(str, idx)
    
    ///
Last updated on