VecForeach

Table of Contents

VecForeach

Description

Iterate over each element var of the given vector v. This is a convenience macro that iterates forward using an internally managed index. The variable var is declared and defined by this macro.

Parameters

NameDirectionDescription
vin,outVector to iterate over.
varinName of the variable to be used which will contain the value of the current element during iteration. The type of var will be the data type of the vector elements (obtained via VEC_DATATYPE(v)).

Usage example (Cross-references)

    // Test VecForeach macro
    bool test_vec_foreach(void) {
    WriteFmt("Testing VecForeach\n");
    
    // Create a vector of integers
    // Use VecForeach to sum the values
    int sum = 0;
    VecForeach(&vec, item) {
    sum += item;
    }
    
    // Use VecForeach to double each value
    VecForeach(&vec, item) {
    item *= 2;
    }
    // Make idx go out of bounds during VecForeach by modifying vector during iteration
    bool test_vec_foreach_out_of_bounds_access(void) {
    WriteFmt("Testing VecForeach where modification causes out of bounds access (should crash)\n");
    
    typedef Vec(int) IntVec;
    // VecForeach doesn't use an explicit index but we can still cause issues
    int iteration_count = 0;
    VecForeach(&vec, val) {
    WriteFmt("Iteration {} (vec.length={}): {}\n", iteration_count, vec.length, val);
    StrDeinit(&result->binary_name);
    StrDeinit(&result->sha256);
    VecForeach(&result->tags, tag) {
    StrDeinit(&tag);
    }
    JW_OBJ(json, {
    JW_OBJ_KV(json, "functions", {
    VecForeach(&symbols, symbol) {
    Str source_key = StrInit();
    StrWriteFmt(&source_key, "{}", symbol.source_function_id);
    
    // Use VecForeach for iterating over entries
    VecForeach(&entries, e) {
    if (last_value == e.value - 1) {
    StrWriteFmt(&code, "    {},\n", e.name.data);
    
    // Use VecForeach for iterating over entries
    VecForeach(&entries, e) {
    const char *compareTemplate = "    if(ZstrCompareN(\"{}\", zstr, {}) == 0) {{return {};}}\n";
    // Store the length in a variable to avoid taking address of rvalue
    
    // Use VecForeach for iterating over entries
    VecForeach(&entries, e) {
    const char *caseTemplate = "        case {} : {{return \"{}\";}}\n";
    StrWriteFmt(&code, caseTemplate, e.name.data, e.str.data);
    StrDeinit(&code);
    
    VecForeach(&entries, e) {
    StrDeinit(&e.name);
    StrDeinit(&e.str);
    
    // recursively explore directories and get filenames
    VecForeach(&dir_paths, dir_name) {
    // keep track of current path we're exploring
    Str current_path = StrInit();
    SysDirContents dir_contents = SysGetDirContents(dir_name.data);
    Scope(&dir_contents, VecDeinit, {
    VecForeach(&dir_contents, dir_entry) {
    // if it's a directory then store it for exploration later on
    if (dir_entry.type == SYS_DIR_ENTRY_TYPE_DIRECTORY) {
    
    // go over each file and generate corresponding markdown
    VecForeach(&file_paths, file_path) {
    Str file_contents = StrInit();
    Scope(&file_contents, StrDeinit, {
    (void)___is_first___;                                                                                          \
    StrPushBack(&(j), '[');                                                                                        \
    VecForeach(&(arr), item) {                                                                                     \
    if (___is_first___) {                                                                                      \
    ___is_first___ = false;                                                                                \
    ///               the character type used by the `Str` implementation (e.g., `char`).
    ///
    #define StrForeach(str, chr) VecForeach((str), (chr))
    
    ///
    if (VecLen(vec) > 0) {
    int sum = 0;
    VecForeach(vec, item) {
    sum += item;
    }
    if (VecLen(vec) > 0) {
    size_t total_len = 0;
    VecForeach(vec, str) {
    total_len += ZstrLen(str.data);
    }
    if (VecLen(vec) > 0) {
    size_t total_len = 0;
    VecForeach(vec, str) {
    total_len += strlen(str);
    }

Share :

Related Posts

VecInitAlignedT

VecInitAlignedT Description Initialize given vector with given alignment. It is mandatory to initialize vectors before use. Not doing so is undefined behaviour. Provided alignment is used to keep all objects at an aligned memory location, avoiding UB in some cases. It’s recommended to use aligned vector when dealing with structs containing unions.

Read More

VecInitStack

VecInitStack Description Initialize given vector using memory from stack. Such vectors cannot be dynamically resized. Doing so is UB. It is mandatory to initialize vectors before use. Not doing so is undefined behaviour. These vectors are best used where user doesn’t get a chance to or does not want to deinit vector, given that no data in vector needs to be deinitialized. Example includes, but does not limit to a Vec(i8), Vec(f32), etc… Stack inited vectors mustn’t be deinited after use.

Read More

VecForeachIdx

VecForeachIdx Description Iterate over each element var of given vector v at each index idx into the vector. The variables var and idx declared and defined by this macro. idx will start from 0 and will go till v->length - 1

Read More