# carray.inl ## Overview
This file implements a growing array in C. It's based on Sean Barrett's [stretchy buffer](https://github.com/nothings/stb/blob/master/stretchy_buffer.h) implementation. An array is represented just by a regular pointer to the array object type: ~~~c uint32_t *a = 0; ~~~ Size and capacity of the array are stored in a header before the array pointer itself. The case where the array is `NULL` is handled correctly. Note that the functions here will modify the array pointer itself, so if you pass the carray to a function for modification, you must pass a pointer to it. You can also use static memory for the initial setup of an array, as long as you set the capacity to zero. This signals that the memory is statically allocated and should not be freed: ~~~c // b[-1] is the size and b[-2] the capacity. uint64_t b_data[] = {0, 3, 1, 2, 3}; uint64_t *b = b_data + 2; ~~~
## Index
`struct tm_carray_header_t`

Generic carray functions
`tm_carray_header()`
`tm_carray_size()`
`tm_carray_bytes()`
`tm_carray_end()`
`tm_carray_last()`
`tm_carray_capacity()`
`tm_carray_needs_to_grow()`
`tm_carray_pop()`
`tm_carray_shrink()`

tm_allocator_i interface
`tm_carray_grow_at()`
`tm_carray_grow()`
`tm_carray_ensure_at()`
`tm_carray_ensure()`
`tm_carray_set_capacity_at()`
`tm_carray_set_capacity()`
`tm_carray_push_at()`
`tm_carray_push()`
`tm_carray_push_array_at()`
`tm_carray_push_array()`
`tm_carray_resize_at()`
`tm_carray_resize()`
`tm_carray_resize_geom_at()`
`tm_carray_resize_geom()`
`tm_carray_free_at()`
`tm_carray_free()`

tm_temp_allocator_i interface
`tm_carray_temp_grow()`
`tm_carray_temp_ensure()`
`tm_carray_temp_set_capacity()`
`tm_carray_temp_push()`
`tm_carray_temp_push_array()`
`tm_carray_temp_resize()`
`tm_carray_temp_resize_geom()`
## API
### `struct tm_carray_header_t`
Header placed in front of the array data. ~~~c typedef struct tm_carray_header_t { uint64_t capacity; uint64_t size; } tm_carray_header_t; ~~~

Generic carray functions

### `tm_carray_header()`
~~~c #define tm_carray_header(a) ~~~ Returns the header data for `a`.
### `tm_carray_size()`
~~~c #define tm_carray_size(a) ~~~ Returns the number of elements of `a`.
### `tm_carray_bytes()`
~~~c #define tm_carray_bytes(a) ~~~ Returns the number of bytes used by `a`'s items (not including header data). This is the amount of bytes you need to `memcpy()` to copy all the items.
### `tm_carray_end()`
~~~c #define tm_carray_end(a) ~~~ Returns a pointer past the end of `a`. Returns NULL if `a` is not allocated.
### `tm_carray_last()`
~~~c #define tm_carray_last(a) ~~~ Returns a pointer to the last element of `a` or `NULL` if `a` is empty.
### `tm_carray_capacity()`
~~~c #define tm_carray_capacity(a) ~~~ Returns the number of elements allocated for `a`.
### `tm_carray_needs_to_grow()`
~~~c #define tm_carray_needs_to_grow(a, n) ~~~ Returns *true* if `a` needs to grow to hold `n` elements.
### `tm_carray_pop()`
~~~c #define tm_carray_pop(a) ~~~ Pops the last item from `a` and returns it.
### `tm_carray_shrink()`
~~~c #define tm_carray_shrink(a, n) ~~~ As `tm_carray_resize()` but can only shrink the array. Since this won't reallocate memory, you don't need to pass an allocator.

tm_allocator_i interface

### `tm_carray_grow_at()`
~~~c #define tm_carray_grow_at(a, n, allocator, file, line) ~~~ Grows the capacity of `a` geometrically to hold at least `n` elements. `a` is updated in-place by the macro.
### `tm_carray_grow()`
~~~c #define tm_carray_grow(a, n, allocator) ~~~
### `tm_carray_ensure_at()`
~~~c #define tm_carray_ensure_at(a, n, allocator, file, line) ~~~ Ensures that `a` has capacity to to hold at least `n` elements. Grows `a` as needed (geometrically) to hold the specified number of elements. `a` is updated in-place by the macro.
### `tm_carray_ensure()`
~~~c #define tm_carray_ensure(a, n, allocator) ~~~
### `tm_carray_set_capacity_at()`
~~~c #define tm_carray_set_capacity_at(a, n, allocator, file, line) ~~~ Sets the capacity of `a` to exactly `n`. `a` is updated in-place by the macro.
### `tm_carray_set_capacity()`
~~~c #define tm_carray_set_capacity(a, n, allocator) ~~~
### `tm_carray_push_at()`
~~~c #define tm_carray_push_at(a, item, allocator, file, line) ~~~ Pushes `item` to the end of `a`, growing it geometrically if needed. `a` is updated in-place by the macro. Returns a pointer to the pushed item in `a`.
### `tm_carray_push()`
~~~c #define tm_carray_push(a, item, allocator) ~~~
### `tm_carray_push_array_at()`
~~~c #define tm_carray_push_array_at(a, items, n, allocator, file, line) ~~~
### `tm_carray_push_array()`
~~~c #define tm_carray_push_array(a, items, n, allocator) ~~~
### `tm_carray_resize_at()`
~~~c #define tm_carray_resize_at(a, n, allocator, file, line) ~~~ Resizes `a` to `n` elements. If `a` needs to grow, it will grow to exactly `n` elements. Note that this growth is not geometric. Use `tm_carray_resize_geom()` instead if you want geometric growth. `a` is updated in-place by the macro.
### `tm_carray_resize()`
~~~c #define tm_carray_resize(a, n, allocator) ~~~
### `tm_carray_resize_geom_at()`
~~~c #define tm_carray_resize_geom_at(a, n, allocator, file, line) ~~~ As `tm_carray_resize()` but uses geometric growth.
### `tm_carray_resize_geom()`
~~~c #define tm_carray_resize_geom(a, n, allocator) ~~~
### `tm_carray_free_at()`
~~~c #define tm_carray_free_at(a, allocator, file, line) ~~~ Frees the memory used by the carray.
### `tm_carray_free()`
~~~c #define tm_carray_free(a, allocator) ~~~

tm_temp_allocator_i interface

### `tm_carray_temp_grow()`
~~~c #define tm_carray_temp_grow(a, n, ta) ~~~ As `tm_carray_grow()` for arrays allocated using a temp allocator.
### `tm_carray_temp_ensure()`
~~~c #define tm_carray_temp_ensure(a, n, ta) ~~~ As `tm_carray_ensure()` for arrays allocated using a temp allocator.
### `tm_carray_temp_set_capacity()`
~~~c #define tm_carray_temp_set_capacity(a, n, ta) ~~~ As `tm_carray_set_capacity()` for arrays allocated using a temp allocator.
### `tm_carray_temp_push()`
~~~c #define tm_carray_temp_push(a, item, ta) ~~~ As `tm_carray_push()` for arrays allocated using a temp allocator.
### `tm_carray_temp_push_array()`
~~~c #define tm_carray_temp_push_array(a, items, n, ta) ~~~
### `tm_carray_temp_resize()`
~~~c #define tm_carray_temp_resize(a, n, ta) ~~~ As `tm_carray_resize()` for arrays allocated using a temp allocator.
### `tm_carray_temp_resize_geom()`
~~~c #define tm_carray_temp_resize_geom(a, n, ta) ~~~