MULE 0.0.1
Multi-Use Library Essentials
Loading...
Searching...
No Matches
Arr

Overview

A growable array of any element type.

Arr(T) is a struct with the same layout and rules as a Str, for any element type. The operations are macros, because only a macro can work for every T.

IntArr squares = { 0 };
for (int i = 0; i < 100; i++) CHECK(arr_push(&squares, i * i));
CHECK_EQ_INT(squares.len, 100);
CHECK_EQ_INT(squares.data[99], 9801);
CHECK_EQ_INT(arr_pop(&squares), 9801);
arr_free(&squares);
  • Name each array type once with a typedef: typedef Arr(int) IntArr;. Every spelling of Arr(...) is a distinct type, so use the name.
  • A zero-initialised array (IntArr xs = { 0 };) is valid, empty, and owns no memory.
  • The fields are data, len, capacity and alloc, where a null alloc means the libc heap. Index data directly to read and write elements, and pass it to qsort or memcpy.
  • Calls that may allocate return bool. On false the array is unchanged.
  • Growing may move data, so pointers into it do not survive arr_push(), arr_insert() or arr_reserve().
Warning
The macros evaluate the array argument more than once. Pass a variable or a plain pointer, never an expression with side effects.

Macros

#define Arr(T)
 A growable array of T.

Growing

Add elements.

Each call may move data.

#define arr_reserve(a, n)
 Make room for n more elements without another allocation.
#define arr_push(a, v)
 Append v.
#define arr_insert(a, i, v)
 Insert v before index i, shifting the rest up.

Shrinking

Remove elements.

None of these allocate or move data.

#define arr_remove(a, i)
 Remove the element at index i, shifting the rest down.
#define arr_pop(a)
 Remove and return the last element.
#define arr_clear(a)
 Set the length to zero.
#define arr_free(a)
 Free the elements' memory and reset to empty.

Macro Definition Documentation

◆ Arr

#define Arr ( T)
Value:
struct { \
T *data; \
size_t len; \
size_t capacity; \
const Allocator *alloc; \
}
Where a module gets its memory.
Definition mem.h:56

A growable array of T.

Declare it with a typedef before use.

Definition at line 36 of file arr.h.

◆ arr_reserve

#define arr_reserve ( a,
n )
Value:
arr_reserve_(&(a)->data, &(a)->capacity, (a)->len, (n), sizeof *(a)->data, \
(a)->alloc)

Make room for n more elements without another allocation.

Returns
False when out of memory or the size overflows. The array is then unchanged.

Definition at line 51 of file arr.h.

◆ arr_push

#define arr_push ( a,
v )
Value:
(arr_reserve((a), 1) ? ((a)->data[(a)->len] = (v), (a)->len++, true) \
: false)
#define arr_reserve(a, n)
Make room for n more elements without another allocation.
Definition arr.h:51

Append v.

v is evaluated after any growth and before len changes, so it may read the array itself, as in arr_push(&xs, xs.data[0]) or arr_push(&xs, xs.len).

Returns
False when out of memory. The array is then unchanged.

Definition at line 59 of file arr.h.

◆ arr_insert

#define arr_insert ( a,
i,
v )
Value:
(assert(arr_index_ok_((i), (a)->len)), \
arr_reserve((a), 1) ? (memmove((a)->data + (i) + 1, (a)->data + (i), \
((a)->len - (i)) * sizeof *(a)->data), \
(a)->data[(i)] = (v), (a)->len++, true) \
: false)

Insert v before index i, shifting the rest up.

i may equal len.

Returns
False when out of memory. The array is then unchanged.
Precondition
i <= len. An assert checks it.

Definition at line 66 of file arr.h.

◆ arr_remove

#define arr_remove ( a,
i )
Value:
(assert((i) < (a)->len), \
memmove((a)->data + (i), (a)->data + (i) + 1, \
((a)->len - (i) - 1) * sizeof *(a)->data), \
(void)(a)->len--)

Remove the element at index i, shifting the rest down.

Precondition
i < len. An assert checks it.

Definition at line 81 of file arr.h.

◆ arr_pop

#define arr_pop ( a)
Value:
(assert((a)->len > 0), (a)->data[--(a)->len])

Remove and return the last element.

Precondition
The array is not empty. An assert checks it.

Definition at line 89 of file arr.h.

◆ arr_clear

#define arr_clear ( a)
Value:
((void)((a)->len = 0))

Set the length to zero.

Keeps the allocation for reuse.

Definition at line 92 of file arr.h.

◆ arr_free

#define arr_free ( a)
Value:
(arr_free_(&(a)->data, (a)->capacity * sizeof *(a)->data, (a)->alloc), \
(a)->len = 0, (void)((a)->capacity = 0))

Free the elements' memory and reset to empty.

Keeps alloc, and is safe to call twice.

Definition at line 96 of file arr.h.