|
| 1 | +#ifndef CSNIP_ARRT_H |
| 2 | +#define CSNIP_ARRT_H |
| 3 | + |
| 4 | +/** @file arrt.h |
| 5 | + * @brief Dynamic arrays container type |
| 6 | + * @defgroup arrt Dynamic arrays container type |
| 7 | + * @{ |
| 8 | + * |
| 9 | + * @brief Dynamic arrays container type. |
| 10 | + * |
| 11 | + * Defines a container type for dynamic arrays, and wraps the |
| 12 | + * csnip_arr_* macros so that the container is used. Often, this |
| 13 | + * is simpler than using csnip's lower level (but more flexible) |
| 14 | + * arr interface. Another advantage over using arr directly is |
| 15 | + * that it standardizes the members of the array. For a type T, |
| 16 | + * the container type is of the form: |
| 17 | + * ``` |
| 18 | + * struct { |
| 19 | + * T* a; // array itself |
| 20 | + * size_t n; // size of the array in members |
| 21 | + * size_t cap; // capacity of the array |
| 22 | + * }; |
| 23 | + * ``` |
| 24 | + * Having the same standardized form in many places reduces |
| 25 | + * cognitive load. |
| 26 | + */ |
| 27 | + |
| 28 | +#include <stddef.h> |
| 29 | + |
| 30 | +#include <csnip/arr.h> |
| 31 | + |
| 32 | +/** Initialize an array. |
| 33 | + * |
| 34 | + * arrt version of @sa csnip_arr_Init() |
| 35 | + */ |
| 36 | +#define csnip_arrt_Init(arrp, initial_cap, err) \ |
| 37 | + csnip_arr_init((arrp)->a, (arrp)->n, (arrp)->cap, (initial_cap), (err)) |
| 38 | + |
| 39 | +/** Reserve space for members to be added. |
| 40 | + * |
| 41 | + * arrt version of @sa csnip_arr_Reserve() |
| 42 | + */ |
| 43 | +#define csnip_arrt_Reserve(arrp, least_cap, err) \ |
| 44 | + csnip_arr_Reserve((arrp)->a, (arrp)->n, (arrp)->cap, (least_cap), (err)) |
| 45 | + |
| 46 | +/** Append a new value at the end of the array. |
| 47 | + * |
| 48 | + * arrt version of @sa csnip_arr_Push() |
| 49 | + */ |
| 50 | +#define csnip_arrt_Push(arrp, value, err) \ |
| 51 | + csnip_arr_Push((arrp)->a, (arrp)->n, (arrp)->cap, (value), (err)) |
| 52 | + |
| 53 | +/** Delete the value at the end of the array. |
| 54 | + * |
| 55 | + * arrt version of @sa csnip_arr_Pop() |
| 56 | + */ |
| 57 | +#define csnip_arrt_Pop(arrp, err) \ |
| 58 | + csnip_arr_Pop(((arrp)->a, (arrp)->n, (arrp)->cap, (err)) |
| 59 | + |
| 60 | +/** Insert a new member at a given position in the array. |
| 61 | + * |
| 62 | + * arrt version of @sa csnip_arr_InsertAt() |
| 63 | + */ |
| 64 | +#define csnip_arrt_InsertAt(arrp, index, val, err) \ |
| 65 | + csnip_arr_InsertAt((arrp)->a, (arrp)->n, (arrp)->cap, \ |
| 66 | + (index), (val), (err)) |
| 67 | + |
| 68 | +/** Remove an array member at a given index. |
| 69 | + * |
| 70 | + * arrt version of @sa csnip_arr_DeleteAt() |
| 71 | + */ |
| 72 | +#define csnip_arrt_DeleteAt(arrp, index, err) \ |
| 73 | + csnip_arr_DeleteAt((arrp)->a, (arrp)->n, (arrp)->cap, (index), (err)) |
| 74 | + |
| 75 | +/** Free backend storage and reduce size to 0. |
| 76 | + * |
| 77 | + * arrt version of @sa csnip_arr_Deinit() |
| 78 | + */ |
| 79 | +#define csnip_arrt_Deinit(arrp) \ |
| 80 | + csnip_arr_Free((arrp)->a, (arrp)->n, (arrp)->cap) |
| 81 | + |
| 82 | +/** Define an array type. |
| 83 | + * |
| 84 | + * Creates a struct typedef for an array type, consisting of the |
| 85 | + * members `a` (the pointer to the first member), `n`, the array |
| 86 | + * size, and `cap`, the array capacity. |
| 87 | + * |
| 88 | + * @param arr_type |
| 89 | + * name of the type to assign. |
| 90 | + * |
| 91 | + * @param elem_type |
| 92 | + * type of the elements. |
| 93 | + */ |
| 94 | +#define CSNIP_ARRT_DEF_TYPE(arr_type, elem_type) \ |
| 95 | + typedef struct arr_type ## _s { \ |
| 96 | + elem_type* a; \ |
| 97 | + size_t n; \ |
| 98 | + size_t cap; \ |
| 99 | + } arr_type; |
| 100 | + |
| 101 | +/** Declare the array type. |
| 102 | + * |
| 103 | + * As @sa CSNIP_ARRT_DEF_TYPE, but don't define the struct, only |
| 104 | + * declare it as an opaque type. |
| 105 | + */ |
| 106 | +#define CSNIP_ARRT_DECL_TYPE(arr_type, elem_type) \ |
| 107 | + struct arr_type ## _s; \ |
| 108 | + typedef struct arr_type ## _s arr_type; |
| 109 | + |
| 110 | +/** Declare the array functions. */ |
| 111 | +#define CSNIP_ARRT_DECL_FUNCS(scope, prefix, arr_type, val_type) \ |
| 112 | + CSNIP_ARR_DECL_FUNCS(scope, prefix, val_type, \ |
| 113 | + args(arr_type*, int*)) |
| 114 | + |
| 115 | +/** Define the array functions. |
| 116 | + * |
| 117 | + * The functions defined are the same as in the lower level arr |
| 118 | + * module, @sa CSNIP_ARR_DEF_FUNCS. |
| 119 | + */ |
| 120 | +#define CSNIP_ARRT_DEF_FUNCS(scope, prefix, arr_type, val_type) \ |
| 121 | + CSNIP_ARR_DEF_FUNCS(scope, prefix, val_type, \ |
| 122 | + args(arr_type* A, int* err), \ |
| 123 | + A->a, A->n, A->cap, *err) |
| 124 | + |
| 125 | +/** @} */ |
| 126 | + |
| 127 | +#endif /* CSNIP_ARRT_H */ |
| 128 | + |
| 129 | +#if defined(CSNIP_SHORT_NAMES) && !defined(CSNIP_ARRT_HAVE_SHORT_NAMES) |
| 130 | +#define arrt_Init csnip_arr_Init |
| 131 | +#define arrt_Reserve csnip_arr_Reserve |
| 132 | +#define arrt_Push csnip_arr_Push |
| 133 | +#define arrt_Pop csnip_arr_Pop |
| 134 | +#define arrt_InsertAt csnip_arr_InsertAt |
| 135 | +#define arrt_DeleteAt csnip_arr_DeleteAt |
| 136 | +#define arrt_Free csnip_arr_Free |
| 137 | +#define CSNIP_ARR_HAVE_SHORT_NAMES |
| 138 | +#endif /* CSNIP_SHORT_NAMES && !CSNIP_ARRT_HAVE_SHORT_NAMES */ |
0 commit comments