blob: 13ff9f3ac767401d77697ecf047b950d244cefc4 [file] [log] [blame] [view] [raw]
---
title: facil.io - Core Dynamic Array Type
toc: true
layout: api
---
# Simple Dynamic Arrays
The simple dynamic array offers a simple data structure that manages only it's own memory (but not the memory of any objects placed in the array).
## Overview
The simple dynamic array type is included in a single file library, `fio_ary.h` that can be used independently as well.
The Core Array is designed to contain `void *` pointers and doesn't manage any memory except it's own.
As a general rule, facil.io doen's make assumptions about allocation / deallocation except where mentioned. A good example is the `sock_write` function that copies the data vs. `sock_write2` which asks about the correct deallocation function to be used (defaults to `free`) and takes ownership of the data.
## Example
Here's a short example from [the introduction to the simple core types](types.md):
```c
#include "fio_ary.h"
int main(void) {
// The array container.
fio_ary_s ary;
// allocate and initialize internal data
fio_ary_new(&ary, 0);
// perform some actions
fio_ary_push(&ary, (void *)1);
FIO_ARY_FOR(&ary, pos) {
printf("index: %lu == %lu\n", (unsigned long)pos.i, (unsigned long)pos.obj);
}
// free the array's data to avoid memory leaks (doesn't free the objects)
fio_ary_free(&ary);
}
```
Note that the Array container can be placed on the stack (as well as allocated using `malloc`), but the internal data must be allocated and deallocated using `fio_ary_new` and `fio_ary_free`.
## Types
The Core Array uses the `fio_ary_s` type.
The data in in the `fio_ary_s` type shouldn't be accessed directly. Functional access should be preferred.
```c
typedef struct fio_ary_s {
size_t start;
size_t end;
size_t capa;
void **arry;
} fio_ary_s;
```
## Functions
### The `fio_ary_new` function
```c
void fio_ary_new(fio_ary_s *ary, size_t capa)
```
Initializes the array and allocates memory for it's internal data.
Note that `capa` indicates the **initial** (or *minimal*) capacity for the array, but the array can grow as long as memory allows.
This will assume that `ary` is uninitialized and overwrite any existing data.
### the `fio_ary_free` function
```c
void fio_ary_free(fio_ary_s *ary)
```
Frees the array's internal data.
If the `ary`'s container (the `fio_ary_s` object) was allocated using `malloc`, a subsequent call to `free(ary)` must be made.
### the `fio_ary_count` function
```c
size_t fio_ary_count(fio_ary_s *ary)
```
Returns the number of elements in the Array.
### the `fio_ary_capa` function
```c
size_t fio_ary_capa(fio_ary_s *ary)
```
Returns the current, temporary, array capacity (it's dynamic).
### the `fio_ary_index` function
```c
void *fio_ary_index(fio_ary_s *ary, int64_t pos)
```
Returns the object placed in the Array, if any. Returns NULL if no data or if
the index is out of bounds.
Negative values are retrived from the end of the array. i.e., `-1`
is the last item.
`fio_ary_entry` is an alias for `fiobj_ary_index`.
### the `fio_ary_set` function
```c
void *fio_ary_set(fio_ary_s *ary, void *data, int64_t pos)
```
Sets an object at the requested position.
Returns the old value, if any.
If an error occurs, the same data passed to the function is returned (test using `fiobj_ary_index`).
### the `fio_ary_push` function
```c
int fio_ary_push(fio_ary_s *ary, void *data)
```
Pushes an object to the end of the Array. Returns -1 on error.
### the `fio_ary_pop` function
```c
void *fio_ary_pop(fio_ary_s *ary)
```
Pops an object from the end of the Array
Returns NULL if the object was NULL or the Array was empty.
### the `fio_ary_unshift` function
```c
int fio_ary_unshift(fio_ary_s *ary, void *data)
```
Unshifts an object to the beginning of the Array. Returns -1 on error.
This could be expensive, causing `memmove`.
### the `fio_ary_shift` function
```c
void *fio_ary_shift(fio_ary_s *ary)
```
Shifts an object from the beginning of the Array.
Returns NULL if the object was NULL or the Array was empty.
### the `fio_ary_compact` function
```c
void fio_ary_compact(fio_ary_s *ary)
```
Removes any NULL *pointers* from an Array, keeping all other data in the
array.
This action is O(n) where n in the length of the array.
### the `FIO_ARY_FOR` macro
```c
FIO_ARY_FOR(ary, pos)
```
Iterates through the list using a `for` loop.
Access the data with `pos.obj` and it's index with `pos.i`.
The `pos` variable can be named however you please (i.e. `FIO_ARY_FOR(&bar, foo)` for `foo.i` and `foo.obj`).
### the `fio_ary_each` function
```c
size_t fio_ary_each(fio_ary_s *ary, size_t start_at,
int (*task)(void *pt, void *arg),
void *arg);
```
Iteration using a callback for each entry in the array.
The callback task function must accept an the entry data as well as an opaque
user pointer.
If the callback returns -1, the loop is broken. Any other value is ignored.
Returns the relative "stop" position, i.e., the number of items processed +
the starting point.