### Compile C Example with zvec (Bash) Source: https://github.com/z-libs/zvec.h/blob/main/examples/README.md Command to compile a C example program using zvec. It uses gcc, includes necessary directories for zvec.h and the registry header, and specifies the output executable name. The example program is then executed. ```bash gcc c/example_0.c -I.. -Iinclude -o example_c ./example_c ``` -------------------------------- ### Compile C++ Example with zvec (Bash) Source: https://github.com/z-libs/zvec.h/blob/main/examples/README.md Command to compile a C++ example program using zvec. It uses g++, includes necessary directories for zvec.h and the registry header, and specifies the output executable name. The example program is then executed. ```bash g++ cpp/example_0.cpp -I.. -Iinclude -o example_cpp ./example_cpp ``` -------------------------------- ### Generated z_registry.h Header (C) Source: https://github.com/z-libs/zvec.h/blob/main/examples/README.md An example of the auto-generated z_registry.h file created by zscanner.py. This file defines macros for vectors, lists, and maps, enabling type-safe container usage in zvec. Do not manually edit this file. ```c /* AUTO-GENERATED BY Z-SCANNER - DO NOT EDIT */ #ifndef Z_REGISTRY_H #define Z_REGISTRY_H /* Vectors */ #define Z_AUTOGEN_VECS(X) \ X(int, Int) \ X(Point, Point) \ /* Lists */ #define Z_AUTOGEN_LISTS(X) \ /* Maps */ #define Z_AUTOGEN_MAPS(X) \ #endif // Z_REGISTRY_H ``` -------------------------------- ### zvec.h Auto-Cleanup Extension Example (C) Source: https://github.com/z-libs/zvec.h/blob/main/README.md Demonstrates the experimental `zvec_autofree` macro for RAII-style automatic vector memory management in C, using compiler-specific cleanup attributes. ```c void process_data() { // 'nums' will be automatically freed when this function returns. zvec_autofree(int) nums = zvec_init(int); zvec_push(&nums, 100); } ``` -------------------------------- ### Register Types with zscanner.py (Bash) Source: https://github.com/z-libs/zvec.h/blob/main/examples/README.md This command uses the zscanner.py script to automatically generate a registry header file for zvec. It scans C or C++ source files to identify types and create the necessary macro definitions. Ensure git submodules are updated before running. ```bash git submodule update --init --recursive python3 ../z-core/zscanner.py c/ include/z_registry.h ``` -------------------------------- ### Library-Specific Custom Allocator Override for zvec.h (C) Source: https://github.com/z-libs/zvec.h/blob/main/README.md This example shows how to apply custom allocators specifically to zvec.h, overriding the global Z_ macros. This is useful when different containers require different memory management strategies. Note that ZVEC_MALLOC is unused by zvec but should be defined for consistency. ```c // Example: Vectors use a Frame Arena, everything else uses standard malloc. #define ZVEC_CALLOC(n, sz) arena_alloc_zero(frame_arena, (n) * (sz)) #define ZVEC_REALLOC(p, sz) arena_resize(frame_arena, p, sz) #define ZVEC_FREE(p) /* no-op for linear arena */ // (ZVEC_MALLOC is strictly unused by zvec internally, but good to define for consistency). #include "zvec.h" #include "zlist.h" // zlist will still use standard malloc! ``` -------------------------------- ### C Dynamic Array Initialization and Usage Source: https://github.com/z-libs/zvec.h/blob/main/README.md Demonstrates how to initialize and use dynamic arrays for integers and custom structs in C using zvec.h. It shows basic operations like pushing elements and accessing them safely, along with memory cleanup. ```c #include #include "zvec.h" // Define your struct. typedef struct { float x, y; } Point; // Request the vector types you need. // (These are no-ops for the compiler, but markers for the scanner). DEFINE_VEC_TYPE(int, Int) zvec_Point path = zvec_init(Point); zvec_push(&path, ((Point){1.0f, 2.0f})); int main(void) { // Initialize (Standard C style). zvec_Int nums = zvec_init(Int); zvec_push(&nums, 42); // Initialize Struct Vector. // Access elements safely (returns T*). printf("First number: %d\n", *zvec_at(&nums, 0)); // Cleanup. zvec_free(&nums); zvec_free(&path); return 0; } ``` -------------------------------- ### Initialize zvec.h Vectors Source: https://context7.com/z-libs/zvec.h/llms.txt Demonstrates initializing zvec.h vectors using different methods: `vec_init` for an empty vector, `vec_init_with_cap` for pre-allocated capacity, and `vec_from` for initialization with values. Requires type registration via X-Macros. ```c #include typedef struct { float x, y; } Point; #define REGISTER_ZVEC_TYPES(X) \ X(int, Int) \ X(Point, Point) #define ZVEC_SHORT_NAMES #include "zvec.h" int main(void) { // Initialize empty vector vec(Int) nums = vec_init(Int); // Initialize with pre-allocated capacity for 100 elements vec(Int) preallocated = vec_init_with_cap(Int, 100); // Initialize with values (macro expands to array creation) vec(Int) initialized = vec_from(Int, 1, 2, 3, 4, 5); printf("nums length: %zu, capacity: %zu\n", nums.length, nums.capacity); printf("preallocated capacity: %zu\n", preallocated.capacity); printf("initialized length: %zu\n", initialized.length); // Output: // nums length: 0, capacity: 0 // preallocated capacity: 100 // initialized length: 5 vec_free(&nums); vec_free(&preallocated); vec_free(&initialized); return 0; } ``` -------------------------------- ### C++ Vector Initialization and Usage Source: https://github.com/z-libs/zvec.h/blob/main/README.md Illustrates the usage of the C++ wrapper for zvec.h, providing a `std::vector`-like interface. It showcases RAII for automatic memory management, range-based for loops, and exception-safe element access. ```cpp #include #include "zvec.h" struct Point { float x, y; }; // Request types (scanner sees this even in .cpp files). DEFINE_VEC_TYPE(int, Int) DEFINE_VEC_TYPE(Point, Point) int main() { // RAII handles memory automatically. z_vec::vector nums = {1, 2, 3}; // Standard push_back API. nums.push_back(42); // Range-based for loops supported. for(int n : nums) { std::cout << n << " "; } // Bounds checking access. try { nums.at(99) = 10; } catch (const std::out_of_range& e) { std::cerr << "Error: " << e.what() << "\n"; } return 0; } ``` -------------------------------- ### zvec.h Initialization and Management Macros (C) Source: https://github.com/z-libs/zvec.h/blob/main/README.md Macros for initializing, managing memory, and freeing zvec vectors. These functions handle the creation, resizing, and deallocation of vector memory. ```c #define zvec_init(Type) \ ((zvec_t(Type)){.len = 0, .cap = 0, .data = NULL}) #define zvec_init_with_cap(Type, n) \ ((zvec_t(Type)){.len = 0, .cap = (n), .data = malloc((n) * sizeof(Type))}) #define zvec_from(Type, ...) #define zvec_free(v) #define zvec_clear(v) #define zvec_reserve(v, n) #define zvec_shrink_to_fit(v) ``` -------------------------------- ### Safe API Usage with zerror.h in C Source: https://github.com/z-libs/zvec.h/blob/main/README.md Demonstrates how to use the safe API of zvec.h with zerror.h for error handling. It shows checking for memory allocation failures during push operations and bounds checking during element access. Requires defining ZERROR_IMPLEMENTATION and ZERROR_SHORT_NAMES. ```c #define ZERROR_IMPLEMENTATION #define ZERROR_SHORT_NAMES #include "zvec.h" #include "zerror.h" DEFINE_VEC_TYPE(int, Int) zres process_data() { zvec_autofree(Int) nums = zvec_init(Int); // -> Check for OOM on push. // We use check_ctx to add context to the error if it fails. check_ctx(zvec_push_safe(&nums, 100), "Failed to push first item"); check_ctx(zvec_push_safe(&nums, 200), "Failed to push second item"); // -> Safe Access (Bounds Checking). // We use try_into() because vec_at_safe returns 'Res_Int', // but this function must return 'zres' on failure. int val = try_into(zres, zvec_at_safe(&nums, 1)); printf("Value is: %d\n", val); // -> Panic on failure (Crash with stack trace). // Useful if you are 100% sure the index exists. int must_exist = unwrap(zvec_at_safe(&nums, 0)); return zres_ok(); } int main(void) { // If process_data fails, it prints a full error log. run(process_data()); return 0; } ``` -------------------------------- ### zvec.h Algorithms and Iteration Macros (C) Source: https://github.com/z-libs/zvec.h/blob/main/README.md Macros for iterating over and performing algorithms on zvec vectors. Supports standard iteration, type-safe iteration declarations, sorting, and binary search. ```c #define zvec_foreach(v, it) #define zvec_foreach_decl(Name, v, it) #define zvec_sort(v, cmp) #define zvec_bsearch(v, key, cmp) #define zvec_lower_bound(v, key, cmp) ``` -------------------------------- ### Enabling Short Names for zvec.h API (C) Source: https://github.com/z-libs/zvec.h/blob/main/README.md This demonstrates how to enable the 'Short Names' feature in zvec.h by defining ZVEC_SHORT_NAMES before including the header. This allows for simpler function aliases like `vec_push` instead of `zvec_push`. ```c #define ZVEC_SHORT_NAMES #include "zvec.h" ``` -------------------------------- ### Registering Types with Short Names in zvec.h (C) Source: https://github.com/z-libs/zvec.h/blob/main/README.md Illustrates the correct way to register types with zvec.h when using short names. The macro `REGISTER_TYPES` requires two arguments: the actual type and a short name, which avoids C macro limitations with spaces in generated function names. ```c // Actual Type Short Name X(unsigned long, ulong) ``` -------------------------------- ### Compiling with Z-Scanner for zvec.h (Bash) Source: https://context7.com/z-libs/zvec.h/llms.txt Provides bash commands to set up the z-core submodule, run the zscanner.py script to automatically generate a type registry header (z_registry.h), and then compile C and C++ programs that use zvec.h with the generated registry. ```bash # Project structure # project/ # ↓ src/ # ↓ main.c (contains DEFINE_VEC_TYPE markers) # ↓ include/ # ↓ z_registry.h (auto-generated) # ↓ z-core/ (submodule with zscanner.py) # ↓ zvec.h # Add z-core submodule (one-time setup) git submodule add https://github.com/z-libs/z-core.git z-core git submodule update --init --recursive # Run scanner to generate registry python3 z-core/zscanner.py src/ include/z_registry.h # Output: # Scanning src/... # Generating include/z_registry.h... # Done. # Generated z_registry.h contents: # /* AUTO-GENERATED BY Z-SCANNER - DO NOT EDIT */ # #ifndef Z_REGISTRY_H # #define Z_REGISTRY_H # # #define Z_AUTOGEN_VECS(X) \ # X(int, Int) \ # X(Point, Point) # # #endif // Z_REGISTRY_H # Compile C program gcc src/main.c -I. -Iinclude -o main # Compile C++ program g++ src/main.cpp -I. -Iinclude -std=c++11 -o main ``` -------------------------------- ### Manual C Vector Type Registration Source: https://github.com/z-libs/zvec.h/blob/main/README.md Shows how to manually register custom vector types in C without using the zscanner.py script. This involves defining a registry header file and including zvec.h after the macro definitions. ```c #ifndef MY_VECTORS_H #define MY_VECTORS_H #define REGISTER_ZVEC_TYPES(X) \ X(int, Int) \ X(float, Float) // **IT HAS TO BE INCLUDED AFTER, NOT BEFORE**. #include "zvec.h" #endif ``` -------------------------------- ### C++: RAII Vector Wrapper with STL Compatibility Source: https://context7.com/z-libs/zvec.h/llms.txt Presents the `z_vec::vector` C++ class, a wrapper providing RAII memory management, initializer lists, range-based for loops, STL-compatible iterators, and bounds-checked access (`at()`). ```cpp #include #include struct Point { float x, y; }; #define Z_AUTOGEN_VECS(X) \ X(int, Int) \ X(Point, Point) #include "zvec.h" int main() { // Initializer list construction z_vec::vector nums = {10, 20, 30}; // STL-like API nums.push_back(40); nums.push_back(50); std::cout << "Size: " << nums.size() << ", Capacity: " << nums.capacity() << "\n"; // Output: Size: 5, Capacity: 32 // Range-based for loop std::cout << "Values: "; for (int x : nums) { std::cout << x << " "; } std::cout << "\n"; // Output: Values: 10 20 30 40 50 // Bounds-checked access with exception try { nums.at(99) = 999; // Throws std::out_of_range } catch (const std::out_of_range& e) { std::cout << "Exception: " << e.what() << "\n"; } // Output: Exception: vector::at // Unchecked access nums[0] = 999; std::cout << "Modified first: " << nums.front() << "\n"; // Output: Modified first: 999 // Struct vectors z_vec::vector points; points.push_back({1.5f, 2.5f}); points.push_back({3.0f, 4.0f}); for (const auto& p : points) { std::cout << "Point: {" << p.x << ", " << p.y << "}\n"; } // Output: // Point: {1.5, 2.5} // Point: {3.0, 4.0} // STL algorithm compatibility std::reverse(nums.begin(), nums.end()); std::cout << "Reversed: "; for (int x : nums) std::cout << x << " "; std::cout << "\n"; // Output: Reversed: 50 40 30 20 999 return 0; // Automatic cleanup - no delete/free needed } ``` -------------------------------- ### Custom Memory Allocators with zvec.h (C) Source: https://context7.com/z-libs/zvec.h/llms.txt Demonstrates how to override default memory allocation functions (malloc, calloc, realloc, free) for zvec.h by defining Z_MALLOC, Z_CALLOC, Z_REALLOC, and Z_FREE macros before including the header. This allows for custom memory tracking or pooling. ```c #include #include // Custom allocator example (tracking allocations) static size_t alloc_count = 0; static size_t free_count = 0; void* my_malloc(size_t sz) { alloc_count++; return malloc(sz); } void* my_calloc(size_t n, size_t sz) { alloc_count++; return calloc(n, sz); } void* my_realloc(void* p, size_t sz) { if (!p) alloc_count++; return realloc(p, sz); } void my_free(void* p) { if (p) free_count++; free(p); } // Override allocators BEFORE including zvec.h #define Z_MALLOC(sz) my_malloc(sz) #define Z_CALLOC(n, sz) my_calloc(n, sz) #define Z_REALLOC(p, sz) my_realloc(p, sz) #define Z_FREE(p) my_free(p) #define REGISTER_ZVEC_TYPES(X) X(int, Int) #define ZVEC_SHORT_NAMES #include "zvec.h" int main(void) { vec(Int) nums = vec_init(Int); for (int i = 0; i < 100; i++) { vec_push(&nums, i); } printf("Allocations: %zu\n", alloc_count); // Output: Allocations: 3 (initial + 2 growth reallocs) vec_free(&nums); printf("Frees: %zu\n", free_count); // Output: Frees: 1 return 0; } ``` -------------------------------- ### Type Registration Methods for zvec.h (C) Source: https://context7.com/z-libs/zvec.h/llms.txt Illustrates three methods for registering vector types with zvec.h: using DEFINE_VEC_TYPE markers for zscanner.py, manual X-Macro registration, and using an auto-generated registry from zscanner.py output. This allows zvec.h to create type-safe vectors for various data types. ```c // Method 1: Scanner markers (use with zscanner.py) // These are no-ops for compiler but detected by scanner #include "zvec.h" typedef struct { int id; char name[32]; } User; DEFINE_VEC_TYPE(int, Int) DEFINE_VEC_TYPE(float, Float) DEFINE_VEC_TYPE(User, User) // Method 2: Manual X-Macro registration // Define BEFORE including zvec.h #define REGISTER_ZVEC_TYPES(X) \ X(int, Int) \ X(float, Float) \ X(User, User) #include "zvec.h" // Method 3: Auto-generated registry (from zscanner.py output) // File: z_registry.h /* #ifndef Z_REGISTRY_H #define Z_REGISTRY_H #define Z_AUTOGEN_VECS(X) \ X(int, Int) \ X(float, Float) \ X(User, User) #endif */ // Then include registry before zvec.h #include "z_registry.h" #include "zvec.h" int main(void) { zvec_Int ints = zvec_init(Int); zvec_Float floats = zvec_init(Float); zvec_User users = zvec_init(User); zvec_push(&ints, 42); zvec_push(&floats, 3.14f); zvec_push(&users, ((User){1, "Alice"})); printf("Int: %d, Float: %.2f, User: %s\n", *zvec_at(&ints, 0), *zvec_at(&floats, 0), zvec_at(&users, 0)->name); // Output: Int: 42, Float: 3.14, User: Alice zvec_free(&ints); zvec_free(&floats); zvec_free(&users); return 0; } ``` -------------------------------- ### zvec.h Push and Pop Operations Source: https://context7.com/z-libs/zvec.h/llms.txt Illustrates how to add elements to a zvec.h vector using `vec_push`, remove the last element with `vec_pop`, and remove and retrieve the last element using `vec_pop_get`. Also shows `vec_push_slot` for zero-copy insertion of large structs. ```c #include typedef struct { float x, y; } Point; #define REGISTER_ZVEC_TYPES(X) \ X(int, Int) \ X(Point, Point) #define ZVEC_SHORT_NAMES #include "zvec.h" int main(void) { vec(Int) nums = vec_init(Int); // Push values to vector vec_push(&nums, 10); vec_push(&nums, 20); vec_push(&nums, 30); printf("After push: "); vec_foreach(&nums, n) printf("%d ", *n); printf("\n"); // Output: After push: 10 20 30 // Pop and get the last element int last = vec_pop_get(&nums); printf("Popped value: %d\n", last); // Output: Popped value: 30 // Pop without returning (just remove) vec_pop(&nums); printf("After pop: "); vec_foreach(&nums, n) printf("%d ", *n); printf("\n"); // Output: After pop: 10 // For structs, use push_slot for zero-copy insertion vec(Point) points = vec_init(Point); Point *slot = vec_push_slot(&points); if (slot) { slot->x = 1.5f; slot->y = 2.5f; } printf("Point: {%.1f, %.1f}\n", points.data[0].x, points.data[0].y); // Output: Point: {1.5, 2.5} vec_free(&nums); vec_free(&points); return 0; } ``` -------------------------------- ### Vector Extend, Reverse, and Reserve Operations in C Source: https://context7.com/z-libs/zvec.h/llms.txt Illustrates `zvec_extend` for appending multiple elements from an array, `zvec_reverse` for in-place reversal of elements, and `zvec_reserve` for pre-allocating capacity. These functions are useful for optimizing performance and managing vector growth. ```c #include #define REGISTER_ZVEC_TYPES(X) X(int, Int) #define ZVEC_SHORT_NAMES #include "zvec.h" int main(void) { vec(Int) nums = vec_init(Int); // Reserve capacity upfront to avoid reallocations vec_reserve(&nums, 100); printf("Reserved capacity: %zu\n", nums.capacity); // Output: Reserved capacity: 100 vec_push(&nums, 100); vec_push(&nums, 50); // Extend with bulk data from array int bulk_data[] = {10, 75, 25, 5}; vec_extend(&nums, bulk_data, 4); printf("After extend: "); vec_foreach(&nums, n) printf("%d ", *n); printf("\n"); // Output: After extend: 100 50 10 75 25 5 // Reverse in-place vec_reverse(&nums); printf("After reverse: "); vec_foreach(&nums, n) printf("%d ", *n); printf("\n"); // Output: After reverse: 5 25 75 10 50 100 // Shrink capacity to match length vec_shrink_to_fit(&nums); printf("After shrink: length=%zu, capacity=%zu\n", nums.length, nums.capacity); // Output: After shrink: length=6, capacity=6 vec_free(&nums); return 0; } ``` -------------------------------- ### C: Iterate Vectors with foreach and foreach_decl Source: https://context7.com/z-libs/zvec.h/llms.txt Demonstrates iterating over vectors using `zvec_foreach` for GCC/Clang auto-typed iteration and `zvec_foreach_decl` for portable C99 explicit type declaration. Supports basic types and structs. ```c #include typedef struct { float x, y; } Point; #define REGISTER_ZVEC_TYPES(X) \ X(int, Int) \ X(Point, Point) #define ZVEC_SHORT_NAMES #include "zvec.h" int main(void) { vec(Int) nums = vec_init(Int); vec_push(&nums, 10); vec_push(&nums, 20); vec_push(&nums, 30); // GCC/Clang: auto-declares iterator printf("Integers: "); vec_foreach(&nums, ptr) { printf("%d ", *ptr); } printf("\n"); // Output: Integers: 10 20 30 // Portable C99: explicit type declaration printf("Using foreach_decl: "); zvec_foreach_decl(Int, &nums, it) { printf("%d ", *it); } printf("\n"); // Output: Using foreach_decl: 10 20 30 // Struct iteration vec(Point) points = vec_init(Point); vec_push(&points, ((Point){1.0f, 1.0f})); vec_push(&points, ((Point){2.0f, 2.0f})); vec_push(&points, ((Point){3.0f, 3.0f})); int i = 0; vec_foreach(&points, p) { printf("[%d] {x:%.1f, y:%.1f}\n", i++, p->x, p->y); } // Output: // [0] {x:1.0, y:1.0} // [1] {x:2.0, y:2.0} // [2] {x:3.0, y:3.0} vec_free(&nums); vec_free(&points); return 0; } ``` -------------------------------- ### C++ Wrapper API Source: https://github.com/z-libs/zvec.h/blob/main/README.md The C++ wrapper for zvec.h, located in the `z_vec` namespace, adheres to RAII principles and leverages the underlying C implementation. It provides standard C++ container interfaces for easier integration into C++ projects. ```APIDOC ## API Reference (C++) The C++ wrapper lives in the **`z_vec`** namespace. It strictly adheres to RAII principles and delegates all logic to the underlying C implementation. ### `class z_vec::vector` **Constructors & Management** | Method | Description | | :--- | :--- | | `vector()` | Default constructor (empty). | | `vector(size_t cap)` | Constructs with initial capacity reserved. | | `vector({1, 2, ...})` | Constructs from an initializer list. | | `~vector()` | Destructor. Automatically calls `vec_free`. | | `operator=` | Copy and Move assignment operators. | **Access & Iterators** | Method | Description | | :--- | :--- | | `data()` | Returns `T*` (mutable) or `const T*`. | | `size()` | Returns current number of elements. | | `capacity()` | Returns current allocated capacity. | | `empty()` | Returns `true` if size is 0. | | `operator[]` | Unchecked access to element at index. | | `at(index)` | Bounds-checked access. Throws `std::out_of_range`. | | `front()`, `back()` | Access first/last element. | | `begin()`, `end()` | Standard iterators (pointers) compatible with STL algorithms. | **Modification** | Method | Description | | :--- | :--- | | `push_back(val)` | Appends value to the end. | | `pop_back()` | Removes the last element. | | `reserve(n)` | Reserves capacity for at least `n` items. | | `clear()` | Sets size to 0 (capacity remains). | | `shrink_to_fit()` | Reduces capacity to match size. | | `reverse()` | Reverses elements in-place. | | `remove(index)` | Removes element at index (O(N) shift). | | `swap_remove(index)` | Removes element at index by swapping with last (O(1)). | ``` -------------------------------- ### Vector Sorting and Binary Search in C Source: https://context7.com/z-libs/zvec.h/llms.txt Details `zvec_sort` for in-place sorting using a comparator function, `zvec_bsearch` for efficient binary search on sorted vectors, and `zvec_lower_bound` to find the insertion point for a key. These functions are crucial for ordered data management and retrieval. ```c #include typedef struct { float x, y; } Point; #define REGISTER_ZVEC_TYPES(X) \ X(int, Int) \ X(Point, Point) #define ZVEC_SHORT_NAMES #include "zvec.h" // Comparator: returns negative if a < b, positive if a > b, 0 if equal int compare_ints(const int *a, const int *b) { return (*a > *b) - (*a < *b); } int compare_points_x(const Point *a, const Point *b) { if (a->x < b->x) return -1; if (a->x > b->x) return 1; return 0; } int main(void) { vec(Int) nums = vec_init(Int); vec_push(&nums, 42); vec_push(&nums, 7); vec_push(&nums, 19); vec_push(&nums, 1); printf("Before sort: "); vec_foreach(&nums, n) printf("%d ", *n); printf("\n"); // Output: Before sort: 42 7 19 1 vec_sort(&nums, compare_ints); printf("After sort: "); vec_foreach(&nums, n) printf("%d ", *n); printf("\n"); // Output: After sort: 1 7 19 42 // Binary search (vector must be sorted) int key_found = 19; int key_missing = 99; int *result = vec_bsearch(&nums, &key_found, compare_ints); if (result) { long index = result - vec_data(&nums); printf("Found %d at index %ld\n", key_found, index); } // Output: Found 19 at index 2 result = vec_bsearch(&nums, &key_missing, compare_ints); printf("Key %d: %s\n", key_missing, result ? "found" : "not found"); // Output: Key 99: not found // Lower bound: find first element >= key int bound_key = 10; int *lb = vec_lower_bound(&nums, &bound_key, compare_ints); if (lb) { printf("Lower bound of %d: %d\n", bound_key, *lb); } // Output: Lower bound of 10: 19 vec_free(&nums); return 0; } ``` -------------------------------- ### Memory Management Source: https://github.com/z-libs/zvec.h/blob/main/README.md zvec.h utilizes standard C library memory functions by default. However, it allows for customization, enabling the use of alternative memory subsystems like memory arenas, pools, or debug allocators by overriding the default allocation functions. ```APIDOC ## Memory Management By default, `zvec.h` uses the standard C library functions (`malloc`, `calloc`, `realloc`, `free`). However, you can override these to use your own memory subsystem (e.g., **Memory Arenas**, **Pools**, or **Debug Allocators**). ``` -------------------------------- ### C: Automatic Vector Cleanup with RAII (GCC/Clang) Source: https://context7.com/z-libs/zvec.h/llms.txt Illustrates using `zvec_autofree` for vectors that automatically deallocate their memory when they go out of scope. This C extension simplifies memory management by eliminating the need for manual `vec_free` calls. ```c #include #define REGISTER_ZVEC_TYPES(X) X(int, Int) #define ZVEC_SHORT_NAMES #include "zvec.h" void process_data(void) { // Vector is automatically freed when function returns vec_autofree(Int) nums = vec_init(Int); vec_push(&nums, 100); vec_push(&nums, 200); vec_push(&nums, 300); printf("Processing: "); vec_foreach(&nums, n) printf("%d ", *n); printf("\n"); // No need for vec_free(&nums) - automatic cleanup! } int main(void) { process_data(); printf("Function returned, vector was auto-freed\n"); // Output: // Processing: 100 200 300 // Function returned, vector was auto-freed return 0; } ``` -------------------------------- ### zvec.h Data Access Macros (C) Source: https://github.com/z-libs/zvec.h/blob/main/README.md Macros for accessing elements within a zvec vector. These provide safe access to vector data, including bounds checking and retrieval of raw data pointers. ```c #define zvec_at(v, index) #define zvec_last(v) #define zvec_data(v) #define zvec_is_empty(v) ``` -------------------------------- ### Vector Removal Operations in C Source: https://context7.com/z-libs/zvec.h/llms.txt Demonstrates `zvec_remove` for order-preserving removal (O(n) shift), `zvec_swap_remove` for fast O(1) removal by swapping with the last element, and `zvec_clear` to remove all elements while retaining capacity. These operations are essential for managing dynamic array contents efficiently. ```c #include #define REGISTER_ZVEC_TYPES(X) X(int, Int) #define ZVEC_SHORT_NAMES #include "zvec.h" int main(void) { vec(Int) nums = vec_init(Int); vec_push(&nums, 100); vec_push(&nums, 200); vec_push(&nums, 300); vec_push(&nums, 400); printf("Original: "); vec_foreach(&nums, n) printf("%d ", *n); printf("\n"); // Output: Original: 100 200 300 400 // Order-preserving remove (shifts elements left) vec_remove(&nums, 1); // Remove 200 printf("After remove(1): "); vec_foreach(&nums, n) printf("%d ", *n); printf("\n"); // Output: After remove(1): 100 300 400 // Fast swap-remove (swaps with last, O(1) but order not preserved) vec_swap_remove(&nums, 0); // Remove 100 by swapping with 400 printf("After swap_remove(0): "); vec_foreach(&nums, n) printf("%d ", *n); printf("\n"); // Output: After swap_remove(0): 400 300 // Clear all elements (capacity remains) size_t cap_before = nums.capacity; vec_clear(&nums); printf("After clear: length=%zu, capacity=%zu\n", nums.length, cap_before); // Output: After clear: length=0, capacity=32 vec_free(&nums); return 0; } ``` -------------------------------- ### zvec.h Element Access and Checks Source: https://context7.com/z-libs/zvec.h/llms.txt Covers accessing elements in zvec.h vectors using `vec_at` for bounds-checked access, `vec_last` for the final element, and `vec_data` for raw array access. Also includes `vec_is_empty` to check if the vector contains elements. ```c #include typedef struct { float x, y; } Point; #define REGISTER_ZVEC_TYPES(X) \ X(int, Int) \ X(Point, Point) #define ZVEC_SHORT_NAMES #include "zvec.h" int main(void) { vec(Point) points = vec_init(Point); vec_push(&points, ((Point){1.0f, 2.0f})); vec_push(&points, ((Point){3.0f, 4.0f})); vec_push(&points, ((Point){5.0f, 6.0f})); // Safe access with bounds checking (returns NULL if out of bounds) Point *p0 = vec_at(&points, 0); Point *p_invalid = vec_at(&points, 999); if (p0) { printf("Point 0: {%.1f, %.1f}\n", p0->x, p0->y); } if (!p_invalid) { printf("Index 999: NULL (out of bounds)\n"); } // Output: // Point 0: {1.0, 2.0} // Index 999: NULL (out of bounds) // Get last element Point *last = vec_last(&points); printf("Last point: {%.1f, %.1f}\n", last->x, last->y); // Output: Last point: {5.0, 6.0} // Raw array access for direct manipulation Point *raw = vec_data(&points); printf("Raw access [1]: {%.1f, %.1f}\n", raw[1].x, raw[1].y); // Output: Raw access [1]: {3.0, 4.0} // Check if empty printf("Is empty: %s\n", vec_is_empty(&points) ? "yes" : "no"); // Output: Is empty: no vec_free(&points); return 0; } ``` -------------------------------- ### Safe API (Error Handling) Source: https://github.com/z-libs/zvec.h/blob/main/README.md The Safe API for zvec.h provides robust error handling by returning Result Objects (`zres` or `Res_Type`) instead of asserting or returning NULL. This allows for detailed error information, including stack traces, when operations like memory allocation or index access fail. ```APIDOC ## Safe API (Error Handling) ### Description If your project includes `zerror.h`, `zvec.h` automatically exposes a "Safe Mode" API. Unlike the standard API, the Safe API returns **Result Objects** (`zres` or `Res_Type`) which contain full stack traces and debug information if an error occurs (e.g., Out of Memory, Index Out of Bounds). To use the short macros (`try`, `check`, `unwrap`), you must define `#define Z_SHORT_ERR` before including the headers. ### Safe Macros | Macro | Returns | Description | | :--- | :--- | :--- | | `zvec_push_safe(v, val)` | `zres` | Appends a value. Returns an error if memory allocation fails (OOM). | | `zvec_reserve_safe(v, n)` | `zres` | Reserves capacity. Returns an error if memory allocation fails. | | `zvec_at_safe(v, index)` | `Res_Type` | Returns the value at `index`. Returns an error if the index is out of bounds. | | `zvec_pop_safe(v)` | `Res_Type` | Removes and returns the last element. Returns an error if the vector is empty. | | `zvec_last_safe(v)` | `Res_Type` | Returns the last element (without removing). Returns an error if empty. | ### Example Usage The Safe API is designed to work with `zerror`'s flow control macros. ```c #define ZERROR_IMPLEMENTATION #define ZERROR_SHORT_NAMES #include "zvec.h" #include "zerror.h" DEFINE_VEC_TYPE(int, Int) zres process_data() { zvec_autofree(Int) nums = zvec_init(Int); // -> Check for OOM on push. // We use check_ctx to add context to the error if it fails. check_ctx(zvec_push_safe(&nums, 100), "Failed to push first item"); check_ctx(zvec_push_safe(&nums, 200), "Failed to push second item"); // -> Safe Access (Bounds Checking). // We use try_into() because vec_at_safe returns 'Res_Int', // but this function must return 'zres' on failure. int val = try_into(zres, zvec_at_safe(&nums, 1)); printf("Value is: %d\n", val); // -> Panic on failure (Crash with stack trace). // Useful if you are 100% sure the index exists. int must_exist = unwrap(zvec_at_safe(&nums, 0)); return zres_ok(); } int main(void) { // If process_data fails, it prints a full error log. run(process_data()); return 0; } ``` ``` -------------------------------- ### Global Custom Allocator Override for zvec.h (C) Source: https://github.com/z-libs/zvec.h/blob/main/README.md This snippet demonstrates how to override the default memory allocation macros (Z_MALLOC, Z_CALLOC, Z_REALLOC, Z_FREE) globally for all z-libs, including zvec.h. It requires defining these macros before including the zvec.h header. Ensure all four macros are defined to prevent allocator conflicts. ```c #ifndef MY_VECTORS_H #define MY_VECTORS_H // Define your custom memory macros **HERE**. #include "my_memory_system.h" // IMPORTANT: Override all four to prevent mixing allocators. // This applies to all the z-libs. #define Z_MALLOC(sz) my_custom_alloc(sz) #define Z_CALLOC(n, sz) my_custom_calloc(n, sz) #define Z_REALLOC(p, sz) my_custom_realloc(p, sz) #define Z_FREE(p) my_custom_free(p) // Then include the library. #include "zvec.h" // ... Register types ... #endif ``` -------------------------------- ### zvec.h Modification Macros (C) Source: https://github.com/z-libs/zvec.h/blob/main/README.md Macros for modifying the contents of a zvec vector. These include appending, removing, and reordering elements, with considerations for efficiency and data copying. ```c #define zvec_push(v, value) #define zvec_push_slot(v, value) #define zvec_pop(v) #define zvec_pop_get(v) #define zvec_extend(v, arr, count) #define zvec_remove(v, index) #define zvec_swap_remove(v, index) #define zvec_reverse(v) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.