Skip to content

Latest commit

 

History

History
144 lines (109 loc) · 2.9 KB

File metadata and controls

144 lines (109 loc) · 2.9 KB

Examples

1) Safe append loop

Array(int) arr = array_make(int, 8);
if (!arr) return 1;

for (int i = 0; i < 10; ++i)
{
    if (!array_try_push(arr, i))
    {
        array_free(arr);
        return 1;
    }
}

Why this matters: starting at capacity 8 avoids the first few tiny reallocations, and each append can still fail later due to growth/allocation.

2) Checked index access

int *value = NULL;
if (array_try_at(arr, 3, &value))
{
    printf("value=%d\n", *value);
}

Why this matters: bounds validation is explicit, and out_ptr is only written on success.

3) Reserve before batch append

if (!array_reserve(arr, 64))
{
    array_free(arr);
    return 1;
}

Why this matters: reserve once before many pushes to reduce repeated growth costs.

4) Checked slice window

Slice(int) window;
if (array_try_slice_t(int, arr, 2, 6, &window))
{
    for (array_size_t i = 0; i < window.count; ++i)
    {
        int *item = NULL;
        if (array_try_slice_at_t(int, arr, window, i, &item))
        {
            printf("%d\n", *item);
        }
    }
}

Why this matters: Slice(T) stores a range (start, count) instead of a raw element pointer, so the slice itself does not dangle when the array grows. Any pointer returned through the slice is still temporary.

5) Temporary span view

Span(int) view;
if (array_try_span_t(int, arr, window, &view))
{
    for (array_size_t i = 0; i < view.count; ++i)
    {
        printf("%d\n", view.elements[i]);
    }
}

Why this matters: Span(T) is the explicit borrowed pointer view. It is convenient, but it becomes invalid after array_reserve, array_try_push, array_push, or array_free.

6) Nullable helpers

Array(int) maybe_arr = NULL;
array_size_t len = array_length_or0(maybe_arr);
bool is_empty = array_is_empty_or_true(maybe_arr);

Why this matters: nullable helpers avoid null checks in read-only paths.

7) Strict C iteration (portable)

array_for_each_t(int, arr, it)
{
    printf("%d\n", *it);
}

Why this matters: this is the strict C11/C17 iteration path with explicit element type.

8) GNU convenience iteration

#if ARRAY_HAS_TYPEOF
array_for_each(arr, it)
{
    printf("%d\n", *it);
}
#endif

Why this matters: same runtime behavior as typed iteration, but shorter syntax when typeof is available.

9) Struct element push (non-scalar)

typedef struct { int x; int y; } Point;
generate_array_type(Point);

Array(Point) points = array_make(Point, 8);
Point p = { .x = 1, .y = 2 };

if (!array_try_push(points, p))
{
    array_free(points);
    return 1;
}

Why this matters: array_try_push is generic over your element type without a hard-coded scalar dispatch list.

10) Cleanup pattern

array_free(arr);
arr = NULL;

Why this matters: freeing ownership plus nulling local pointers helps prevent accidental reuse.

Compile-check all examples:

tests/compile/run.sh