VecAt

Table of Contents

VecAt

Description

Value at given index in a vector. It’s strongly recommended to always use this instead of directly accessing the data.

Parameters

NameDirectionDescription
vinVector to get data from
idxinIndex to get data at

Usage example (Cross-references)

    /// Access character at given index
    ///
    #define StrCharAt(str, idx) VecAt(str, idx)
    
    ///
    if ((v)->length > 0) {                                                                                         \
    for ((idx) = 0; (idx) < (v)->length; ++(idx)) {                                                            \
    var = VecAt(v, idx);                                                                                   \
    { body }                                                                                               \
    if ((idx) >= (v)->length) {                                                                            \
    if ((v)->length > 0) {                                                                                         \
    for ((idx) = (v)->length - 1; (idx) < (v)->length; --(idx)) {                                              \
    var = VecAt(v, idx);                                                                                   \
    { body }                                                                                               \
    if ((idx) >= (v)->length) {                                                                            \
    );                                                                                                 \
    }                                                                                                      \
    var = VecAt(v, idx);                                                                                   \
    { body }                                                                                               \
    }                                                                                                          \
    /// v[in] : Vector to get first element of.
    ///
    #define VecFirst(v) VecAt(v, 0)
    
    ///
    /// v[in] : Vector to get last element of.
    ///
    #define VecLast(v) VecAt(v, (v)->length - 1)
    
    ///
    size total_len = 0;
    for (size i = 0; i < argv->length; i++) {
    Str* arg   = &VecAt(argv, i);
    total_len += arg->length;
    if (i > 0)
    
    for (size i = 0; i < argv->length; i++) {
    Str* arg = &VecAt(argv, i);
    
    if (i > 0) {
    size total_len = 0;
    for (size i = 0; i < env->length; i++) {
    Str* env_var  = &VecAt(env, i);
    total_len    += env_var->length + 1; // +1 for null terminator
    }
    char* ptr = env_block;
    for (size i = 0; i < env->length; i++) {
    Str* env_var = &VecAt(env, i);
    memcpy(ptr, env_var->data, env_var->length);
    ptr    += env_var->length;
    
    for (size i = 0; i < argv->length; i++) {
    Str* arg     = &VecAt(argv, i);
    arg_array[i] = (char*)malloc(arg->length + 1);
    if (!arg_array[i]) {
    
    for (size i = 0; i < env->length; i++) {
    Str* env_var = &VecAt(env, i);
    env_array[i] = (char*)malloc(env_var->length + 1);
    if (!env_array[i]) {
    
    if (languages.length >= 3) {
    Str* lang1 = &VecAt(&languages, 0);
    Str* lang2 = &VecAt(&languages, 1);
    Str* lang3 = &VecAt(&languages, 2);
    if (languages.length >= 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 (StrCmpCstr(lang1, "C", 1) != 0) {
    
    if (product.tags.length >= 3) {
    Str* tag1 = &VecAt(&product.tags, 0);
    Str* tag2 = &VecAt(&product.tags, 1);
    Str* tag3 = &VecAt(&product.tags, 2);
    if (product.tags.length >= 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 (StrCmpCstr(tag1, "electronics", 11) != 0) {
    });
    
    if (obj.x_value == 1 && VecLen(&obj.filled_items) == 2 && VecAt(&obj.filled_items, 0) == 1 &&
    VecAt(&obj.filled_items, 1) == 2) {
    printf(
    
    if (obj.x_value == 1 && VecLen(&obj.filled_items) == 2 && VecAt(&obj.filled_items, 0) == 1 &&
    VecAt(&obj.filled_items, 1) == 2) {
    printf(
    "[DEBUG] Mixed empty and filled test passed - x: %d, items: %zu\n",
    );
    if (VecLen(&obj.filled_items) > 0) {
    printf("[DEBUG] First item: %d\n", VecAt(&obj.filled_items, 0));
    }
    success = false;
    // Write dynamic key for source function ID
    Str source_key = StrInit();
    u64 source_id  = response.data.length > 0 ? VecAt(&response.data, 0).source_function_id : 0;
    StrWriteFmt(&source_key, "{}", source_id);
    JW_OBJ_KV(json, source_key.data, {
    if (response.data.length > 0) {
    AnnSymbol* s          = &VecAt(&response.data, 0);
    Str        target_key = StrInit();
    StrWriteFmt(&target_key, "{}", s->target_function_id);
    
    for (size i = 0; i < VecLen(&a->features); i++) {
    if (StrCmp(&VecAt(&a->features, i), &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 (strings_match) {
    for (size i = 0; i < VecLen(&original_strings); i++) {
    if (VecAt(&original_strings, i).length != VecAt(&parsed_strings, i).length ||
    (VecAt(&original_strings, i).length &&
    StrCmp(&VecAt(&original_strings, i), &VecAt(&parsed_strings, i)) != 0)) {
    for (size i = 0; i < VecLen(&original_strings); i++) {
    if (VecAt(&original_strings, i).length != VecAt(&parsed_strings, i).length ||
    (VecAt(&original_strings, i).length &&
    StrCmp(&VecAt(&original_strings, i), &VecAt(&parsed_strings, i)) != 0)) {
    strings_match = false;
    if (VecAt(&original_strings, i).length != VecAt(&parsed_strings, i).length ||
    (VecAt(&original_strings, i).length &&
    StrCmp(&VecAt(&original_strings, i), &VecAt(&parsed_strings, i)) != 0)) {
    strings_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;
    
    if (symbols.length >= 2) {
    AnnSymbol* sym1 = &VecAt(&symbols, 0);
    AnnSymbol* sym2 = &VecAt(&symbols, 1);
    if (symbols.length >= 2) {
    AnnSymbol* sym1 = &VecAt(&symbols, 0);
    AnnSymbol* sym2 = &VecAt(&symbols, 1);
    
    if (!(sym1->source_function_id == 12345 || sym1->source_function_id == 54321)) {
    
    if (response.data.length > 0) {
    AnnSymbol* sym = &VecAt(&response.data, 0);
    
    // Debug individual symbol checks
    
    if (response.data.length > 0) {
    AnnSymbol* sym = &VecAt(&response.data, 0);
    
    if (sym->source_function_id != 12345) {
    
    if (response.data.length > 0) {
    AnnSymbol* sym = &VecAt(&response.data, 0);
    
    if (sym->source_function_id != 12345) {
    // 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(str1->data, "Hello") == 0);
    // Check that the values in the vector are unchanged (foreach uses value, not reference)
    for (size i = 0; i < vec.length; i++) {
    result = result && (VecAt(&vec, i) == values[i]);
    }
    bool result = true;
    for (size i = 0; i < vec.length; i++) {
    result = result && (VecAt(&vec, i) == values[i] * 2);
    }
    bool result = true;
    for (size i = 0; i < vec.length; 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 < vec.length; i++) {
    result = result && (VecAt(&vec, i) == expected[i]);
    }
    bool result     = true;
    for (size i = 0; i < vec.length; i++) {
    result = result && (VecAt(&vec, i) == expected[i]);
    }
    // Test VecAt function
    bool test_vec_at(void) {
    printf("Testing VecAt\n");
    
    // Create a vector of integers
    
    // 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 < vec.length; i++) {
    result = result && (VecAt(&vec, i) == values[i]);
    }
    // Check elements in reverse order (since we pushed to front)
    for (size i = 0; i < vec.length; i++) {
    result = result && (VecAt(&vec, i) == values[4 - i]);
    }
    
    // Check first element
    bool result = (vec.length == 1 && VecAt(&vec, 0) == 10);
    
    // Insert at the end
    
    // Check elements
    result = result && (vec.length == 2 && VecAt(&vec, 0) == 10 && VecAt(&vec, 1) == 30);
    
    // Insert in the middle
    // Check all elements
    result = result && (vec.length == 3);
    result = result && (VecAt(&vec, 0) == 10);
    result = result && (VecAt(&vec, 1) == 20);
    result = result && (VecAt(&vec, 2) == 30);
    result = result && (vec.length == 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 < vec.length; 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 < vec.length; 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 < vec.length; i++) {
    result = result && (VecAt(&vec, i) == expected[i]);
    }
    // Check all elements
    for (size i = 0; i < vec.length; i++) {
    result = result && (VecAt(&vec, i) == expected[i]);
    }
    // Check all elements in vec1
    for (size i = 0; i < vec1.length; i++) {
    result = result && (VecAt(&vec1, i) == expected[i]);
    }
    
    // Check that the element was added
    bool result = (vec.length == 1 && VecAt(&vec, 0) == 42);
    
    // Test L-value insert operations
    
    // Check that the element was added
    result = result && (vec.length == 2 && VecAt(&vec, 1) == 100);
    
    // Test R-value insert at index
    // Check that the element was inserted
    result = result && (vec.length == 3);
    result = result && (VecAt(&vec, 0) == 42);
    result = result && (VecAt(&vec, 1) == 50);
    result = result && (VecAt(&vec, 2) == 100);
    result = result && (vec.length == 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 && (vec.length == 4);
    result = result && (VecAt(&vec, 0) == 42);
    result = result && (VecAt(&vec, 1) == 50);
    result = result && (VecAt(&vec, 2) == 75);
    result = result && (vec.length == 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 && (vec.length == 5);
    result = result && (VecAt(&vec, 1) == 60);
    
    // Test L-value fast insert
    // Check that the element was inserted
    result = result && (vec.length == 6);
    result = result && (VecAt(&vec, 3) == 80);
    
    // Test array operations with L-values and R-values
    // Check that the elements were added
    result = result && (vec.length == 9);
    result = result && (VecAt(&vec, 6) == 200);
    result = result && (VecAt(&vec, 7) == 300);
    result = result && (VecAt(&vec, 8) == 400);
    result = result && (vec.length == 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 && (vec.length == 12);
    result = result && (VecAt(&vec, 0) == 200);
    result = result && (VecAt(&vec, 1) == 300);
    result = result && (VecAt(&vec, 2) == 400);
    result = result && (vec.length == 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
    // Check that the data is still intact
    for (size i = 0; i < vec.length; 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 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 && (strcmp(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 && (strcmp(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 && (strcmp(VecAt(&vec, 0).name, "Item 2") == 0);
    result = result && (strcmp(VecAt(&vec, 1).name, "Item 1") == 0);
    result = result && (strcmp(VecAt(&vec, 2).name, "Item 3") == 0);
    // Check items order: item2, item1, item3
    result = result && (strcmp(VecAt(&vec, 0).name, "Item 2") == 0);
    result = result && (strcmp(VecAt(&vec, 1).name, "Item 1") == 0);
    result = result && (strcmp(VecAt(&vec, 2).name, "Item 3") == 0);
    result = result && (strcmp(VecAt(&vec, 0).name, "Item 2") == 0);
    result = result && (strcmp(VecAt(&vec, 1).name, "Item 1") == 0);
    result = result && (strcmp(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 && (strcmp(VecAt(&vec, 0).name, "Item 2") == 0);
    result = result && (strcmp(VecAt(&vec, 1).name, "Item 3") == 0);
    result = result && (strcmp(VecAt(&vec, 2).name, "Item 1") == 0);
    // Check items order: item2, item3, item1
    result = result && (strcmp(VecAt(&vec, 0).name, "Item 2") == 0);
    result = result && (strcmp(VecAt(&vec, 1).name, "Item 3") == 0);
    result = result && (strcmp(VecAt(&vec, 2).name, "Item 1") == 0);
    result = result && (strcmp(VecAt(&vec, 0).name, "Item 2") == 0);
    result = result && (strcmp(VecAt(&vec, 1).name, "Item 3") == 0);
    result = result && (strcmp(VecAt(&vec, 2).name, "Item 1") == 0);
    
    // Clean up
    
    // Check items in vec1: item1, item2, item3
    result = result && (strcmp(VecAt(&vec1, 0).name, "Item 1") == 0);
    result = result && (strcmp(VecAt(&vec1, 1).name, "Item 2") == 0);
    result = result && (strcmp(VecAt(&vec1, 2).name, "Item 3") == 0);
    // Check items in vec1: item1, item2, item3
    result = result && (strcmp(VecAt(&vec1, 0).name, "Item 1") == 0);
    result = result && (strcmp(VecAt(&vec1, 1).name, "Item 2") == 0);
    result = result && (strcmp(VecAt(&vec1, 2).name, "Item 3") == 0);
    result = result && (strcmp(VecAt(&vec1, 0).name, "Item 1") == 0);
    result = result && (strcmp(VecAt(&vec1, 1).name, "Item 2") == 0);
    result = result && (strcmp(VecAt(&vec1, 2).name, "Item 3") == 0);
    
    // Now test VecMergeL which transfers ownership
    
    // Check items in vec3: item4, item5
    result = result && (strcmp(VecAt(&vec3, 0).name, "Item 4") == 0);
    result = result && (strcmp(VecAt(&vec3, 1).name, "Item 5") == 0);
    // Check items in vec3: item4, item5
    result = result && (strcmp(VecAt(&vec3, 0).name, "Item 4") == 0);
    result = result && (strcmp(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 && (vec2.length == 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 = (vec.length == 1 && VecAt(&vec, 0) == 10);
    
    // Test pushing with zero count
    // Test inserting at end index
    VecInsertR(&vec, 20, vec.length);
    result = result && (vec.length == 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 && (vec.length == 1 && VecAt(&vec, 0) == 42);
    
    // Clean up
    // Check remaining elements
    for (size i = 0; i < vec.length; i++) {
    result = result && (VecAt(&vec, i) == values[i]);
    }
    // Check remaining elements
    for (size i = 0; i < vec.length; i++) {
    result = result && (VecAt(&vec, i) == values[i + 1]);
    }
    int expected1[] = {10, 20, 40, 50};
    for (size i = 0; i < vec.length; i++) {
    result = result && (VecAt(&vec, i) == expected1[i]);
    }
    int expected2[] = {20, 40, 50};
    for (size i = 0; i < vec.length; i++) {
    result = result && (VecAt(&vec, i) == expected2[i]);
    }
    int expected[] = {10, 50, 30, 40};
    for (size i = 0; i < vec.length; i++) {
    result = result && (VecAt(&vec, i) == expected[i]);
    }
    int expected[] = {10, 20, 60, 70};
    for (size i = 0; i < vec.length; i++) {
    result = result && (VecAt(&vec, i) == expected[i]);
    }
    printf("Before fast range delete: ");
    for (size i = 0; i < vec.length; i++) {
    printf("%d ", VecAt(&vec, i));
    }
    printf("\n");
    int end_values[3];
    for (int i = 0; i < count; i++) {
    end_values[i] = VecAt(&vec, vec.length - count + i);
    }
    printf("After fast range delete: ");
    for (size i = 0; i < vec.length; i++) {
    printf("%d ", VecAt(&vec, i));
    }
    printf("\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 (size i = 0; i < vec.length; i++) {
    int val   = VecAt(&vec, i);
    int index = val / 10;
    if (index >= 0 && index < 10) {
    // Check remaining elements
    for (size i = 0; i < vec.length; i++) {
    result = result && (VecAt(&vec, i) == values[i]);
    }
    // Check remaining elements
    for (size i = 0; i < vec.length; i++) {
    result = result && (VecAt(&vec, i) == values[i]);
    }
    int expected[] = {10, 20, 40, 50};
    for (size i = 0; i < vec.length; i++) {
    result = result && (VecAt(&vec, i) == expected[i]);
    }
    int expected[] = {10, 20, 40, 50};
    for (size i = 0; i < vec.length; i++) {
    result = result && (VecAt(&vec, i) == expected[i]);
    }
    printf("Before L-value fast delete: ");
    for (size i = 0; i < vec.length; i++) {
    printf("%d ", VecAt(&vec, i));
    }
    printf("\n");
    // Test L-value fast delete operation
    int fast_index       = 2;                           // Delete 30
    int valueToBeDeleted = VecAt(&vec, fast_index);
    int lastValue        = VecAt(&vec, vec.length - 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, vec.length - 1); // Should move to deleted position
    VecDeleteFast(&vec, fast_index);
    printf("After L-value fast delete: ");
    for (size i = 0; i < vec.length; i++) {
    printf("%d ", VecAt(&vec, i));
    }
    printf("\n");
    bool containsValue = false;
    for (size i = 0; i < vec.length; 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);
    printf("Value at deleted position (%d) is now %d (expected %d)\n", fast_index, VecAt(&vec, fast_index), lastValue);
    // Check that the value at the deleted position is now the last value
    result = result && (VecAt(&vec, fast_index) == lastValue);
    printf("Value at deleted position (%d) is now %d (expected %d)\n", fast_index, VecAt(&vec, fast_index), lastValue);
    
    // Verify all expected values (except the deleted one and the moved one) are still present
    bool found = false;
    for (size j = 0; j < vec.length; j++) {
    if (VecAt(&vec, j) == expected_values[i]) {
    found = true;
    break;
    printf("Before R-value fast delete: ");
    for (size i = 0; i < vec.length; i++) {
    printf("%d ", VecAt(&vec, i));
    }
    printf("\n");
    
    // Remember the value to be deleted and the last value
    int valueToBeDeleted = VecAt(&vec, 2);              // 30
    int lastValue        = VecAt(&vec, vec.length - 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, vec.length - 1); // Should move to deleted position
    
    // Test R-value fast delete operation
    printf("After R-value fast delete: ");
    for (size i = 0; i < vec.length; i++) {
    printf("%d ", VecAt(&vec, i));
    }
    printf("\n");
    bool containsValue = false;
    for (size i = 0; i < vec.length; 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);
    printf("Value at deleted position (2) is now %d (expected %d)\n", VecAt(&vec, 2), lastValue);
    // Check that the value at the deleted position is now the last value
    result = result && (VecAt(&vec, 2) == lastValue);
    printf("Value at deleted position (2) is now %d (expected %d)\n", VecAt(&vec, 2), lastValue);
    
    // Verify all expected values (except the deleted one and the moved one) are still present
    bool found = false;
    for (size j = 0; j < vec.length; j++) {
    if (VecAt(&vec, j) == expected_values[i]) {
    found = true;
    break;
    int expected[] = {10, 20, 60, 70};
    for (size i = 0; i < vec.length; i++) {
    result = result && (VecAt(&vec, i) == expected[i]);
    }
    int expected[] = {10, 20, 60, 70};
    for (size i = 0; i < vec.length; i++) {
    result = result && (VecAt(&vec, i) == expected[i]);
    }
    printf("Before L-value fast range delete: ");
    for (size i = 0; i < vec.length; i++) {
    printf("%d ", VecAt(&vec, i));
    }
    printf("\n");
    printf("After L-value fast range delete: ");
    for (size i = 0; i < vec.length; i++) {
    printf("%d ", VecAt(&vec, i));
    }
    printf("\n");
    bool found = false;
    for (size j = 0; j < vec.length; j++) {
    if (VecAt(&vec, j) == valuesToDelete[i]) {
    found = true;
    break;
    bool found = false;
    for (size j = 0; j < vec.length; j++) {
    if (VecAt(&vec, j) == remainingValues[i]) {
    found = true;
    break;
    printf("Before R-value fast range delete: ");
    for (size i = 0; i < vec.length; i++) {
    printf("%d ", VecAt(&vec, i));
    }
    printf("\n");
    printf("After R-value fast range delete: ");
    for (size i = 0; i < vec.length; i++) {
    printf("%d ", VecAt(&vec, i));
    }
    printf("\n");
    bool found = false;
    for (size j = 0; j < vec.length; j++) {
    if (VecAt(&vec, j) == valuesToDelete[i]) {
    found = true;
    break;
    bool found = false;
    for (size j = 0; j < vec.length; j++) {
    if (VecAt(&vec, j) == remainingValues[i]) {
    found = true;
    break;
    
    // Check that the data was added correctly
    if (vec.length != 3 || VecAt(&vec, 0) != 10 || VecAt(&vec, 1) != 20 || VecAt(&vec, 2) != 30) {
    result = false;
    }
    
    // Check that the item was added correctly
    if (test_vec.length != 1 || VecAt(&test_vec, 0).id != 1 || VecAt(&test_vec, 0).value != 3.14f) {
    result = false;
    }
    if (result) {
    for (size i = 0; i < src.length; i++) {
    if (VecAt(&clone, i) != VecAt(&src, i)) {
    result = false;
    break;
    
    // 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 < vec.length; i++) {
    result = result && (VecAt(&vec, i) == values[4 - i]);
    }
    // Check that the elements are back in the original order
    for (size i = 0; i < vec.length; i++) {
    result = result && (VecAt(&vec, i) == values[i]);
    }
    // Check that the elements are reversed
    for (size i = 0; i < vec.length; i++) {
    result = result && (VecAt(&vec, i) == even_values[3 - i]);
    }
    int  sorted_asc[] = {10, 20, 30, 40, 50};
    for (size i = 0; i < vec.length; i++) {
    result = result && (VecAt(&vec, i) == sorted_asc[i]);
    }
    int sorted_desc[] = {50, 40, 30, 20, 10};
    for (size i = 0; i < vec.length; i++) {
    result = result && (VecAt(&vec, i) == sorted_desc[i]);
    }

Share :