1 #pragma once 2 #ifndef IWARRAYS_H 3 #define IWARRAYS_H 4 5 #include "basedefs.h" 6 IW_EXTERN_C_START 7 8 #include <stdio.h> 9 #include <stdbool.h> 10 11 /** 12 * @brief Insert new element into sorted array. 13 * 14 * @a els must point to an allocated memory with size at least `nels + 1`. 15 * Upon insert number of array elements will be shifted to the right (`memmove`). 16 * 17 * @param els Array pointer. 18 * @param nels Number of alive array elements. 19 * @param elsize Size of every array element. 20 * @param eptr Pointer to the new element to be inserted. 21 * @param cmp Elements comparison function 22 * @param skipeq If true and `eptr` is found in array it will not be inserted and method will return -1 23 * @return Index of inserted element 24 */ 25 IW_EXPORT off_t iwarr_sorted_insert(void *restrict els, 26 size_t nels, 27 size_t elsize, 28 void *restrict eptr, 29 int (*cmp)(const void *, const void *), 30 bool skipeq); 31 32 /** 33 * @brief Remove element from a sorteed array. 34 * Return true if element is found and removed. 35 * 36 * @param els Array pointer. 37 * @param nels Number of array elements. 38 * @param elsize Size of every array element. 39 * @param eptr Pointer to the element should to be removed. 40 * @param cmp Elements comparison function 41 * @return Index of removed element or -1 42 */ 43 IW_EXPORT off_t iwarr_sorted_remove(void *restrict els, 44 size_t nels, 45 size_t elsize, 46 void *restrict eptr, 47 int (*cmp)(const void *, const void *)); 48 49 50 IW_EXPORT off_t iwarr_sorted_find(void *restrict els, 51 size_t nels, 52 size_t elsize, 53 void *restrict eptr, 54 int (*cmp)(const void *, const void *)); 55 56 57 IW_EXPORT off_t iwarr_sorted_find2(void *restrict els, 58 size_t nels, 59 size_t elsize, 60 void *restrict eptr, 61 void *op, 62 bool *found, 63 iwrc(*cmp)(const void *, const void *, void *, int *res)); 64 65 /////////////////////////////////////////////////////////////////////////// 66 // Fixed sized item list // 67 /////////////////////////////////////////////////////////////////////////// 68 69 typedef struct { 70 char *array; /**< Continuous units array */ 71 size_t usize; /**< Unit size */ 72 size_t num; /**< Number of elements in units array */ 73 size_t anum; /**< Actual number of allocated units */ 74 size_t start; /**< Offset of units data */ 75 } IWULIST; 76 77 /** 78 * @brief Initialize units list. 79 * 80 * @param list Allocated list structure 81 * @param initial_length Number of preallocated units 82 * @param unit_size Unit size 83 */ 84 IW_EXPORT iwrc iwulist_init(IWULIST *list, size_t initial_length, size_t unit_size); 85 86 /** 87 * @brief Create new units list. 88 * 89 * @param initial_length Number of preallocated units 90 * @param unit_size Unit size 91 * @return Zero if memory allocation failed `errno` will be set respectively 92 */ 93 IW_EXPORT IWULIST *iwulist_create(size_t initial_length, size_t unit_size);\ 94 95 /** 96 * @brief Cleanup units list. 97 * 98 * @param list Unit list 99 */ 100 IW_EXPORT iwrc iwulist_clear(IWULIST *list); 101 102 /** 103 * @brief Destroys and deallocates a given unit list. 104 * 105 */ 106 IW_EXPORT void iwulist_destroy(IWULIST **listp); 107 108 /** 109 * @brief Destroys internal unit list buffers, 110 * but keep and doesn't free `list` pointer. 111 * 112 * @see iwulist_destroy() 113 */ 114 IW_EXPORT void iwulist_destroy_keep(IWULIST *list); 115 116 /** 117 * @brief Get number of stored elements. 118 */ 119 IW_EXPORT size_t iwulist_length(IWULIST *list); 120 121 /** 122 * @brief Clones a given list. 123 */ 124 IW_EXPORT IWULIST *iwulist_clone(IWULIST *list); 125 126 /** 127 * @brief Gets pinter to element at given `index` 128 * 129 * @param index Index of element 130 * @param [out] orc Set to `IW_ERROR_OUT_OF_BOUNDS` if index is invalid 131 */ 132 IW_EXPORT void *iwulist_at(IWULIST *list, size_t index, iwrc *orc); 133 134 IW_EXPORT void *iwulist_at2(IWULIST *list, size_t index); 135 136 /** 137 * @brief Inserts new element at given index. 138 * 139 * @param index Index of element 140 * @param data Pointer to unit data to copy 141 */ 142 IW_EXPORT iwrc iwulist_insert(IWULIST *list, size_t index, const void *data); 143 144 /** 145 * @brief Overwrite element at given index with new data. 146 * 147 * @param index Index of element 148 * @param data Pointer to unit data to copy 149 */ 150 IW_EXPORT iwrc iwulist_set(IWULIST *list, size_t index, const void *data); 151 152 /** 153 * @brief Removes element at specified index. 154 * 155 * @param index Index of element 156 * @param orc Output error code 157 */ 158 IW_EXPORT iwrc iwulist_remove(IWULIST *list, size_t index); 159 160 /** 161 * @brief Adds new element to end of list. 162 * 163 * @param data Pointer to unit data to copy 164 */ 165 IW_EXPORT iwrc iwulist_push(IWULIST *list, const void *data); 166 167 /** 168 * @brief Removes element from end of list. 169 */ 170 IW_EXPORT iwrc iwulist_pop(IWULIST *list); 171 172 /** 173 * @brief Adds element to front of list. 174 */ 175 IW_EXPORT iwrc iwulist_unshift(IWULIST *list, const void *data); 176 177 /** 178 * @brief Removes element from front of list. 179 * 180 * @param orc Output error code 181 */ 182 IW_EXPORT iwrc iwulist_shift(IWULIST *list); 183 184 /////////////////////////////////////////////////////////////////////////// 185 // Array list implementation // 186 /////////////////////////////////////////////////////////////////////////// 187 188 typedef struct { 189 char *val; 190 size_t size; 191 } IWLISTITEM; 192 193 typedef struct { 194 IWLISTITEM *array; 195 size_t anum; /**< Number of elements allocated */ 196 size_t start; /**< Index of first element */ 197 size_t num; /**< Actual number of elements */ 198 } IWLIST; 199 200 /** 201 * @brief Initialize allocated empty list object. 202 * 203 * @param list Allocated list structure 204 * @param anum Number of elements to allocate or zero to use defaults 205 * @return IW_EXPORT iwlist_init 206 */ 207 IW_EXPORT iwrc iwlist_init(IWLIST *list, size_t anum); 208 209 /** 210 * @brief Constructs new list instance and preallocate `anum` elements. 211 * 212 * @param anum Number of elements to allocate or zero to use defaults 213 * @return Zero if allocation failed, `errno` will be set. 214 */ 215 IW_EXPORT IWLIST *iwlist_create(size_t anum); 216 217 /** 218 * @brief Destroys a given list object. 219 */ 220 IW_EXPORT void iwlist_destroy(IWLIST **listp); 221 222 /** 223 * @brief Destroys internal list buffers, 224 * but keep and doesn't free `list` pointer. 225 * @see iwilist_destroy() 226 */ 227 IW_EXPORT void iwlist_destroy_keep(IWLIST *list); 228 229 /** 230 * @brief Returns number of elements stored in list. 231 */ 232 IW_EXPORT size_t iwlist_length(IWLIST *list); 233 234 /** 235 * @brief Clone a given list. 236 * @return Zero if allocation failed, `errno` will be set. 237 */ 238 IW_EXPORT IWLIST *iwlist_clone(IWLIST *list); 239 240 /** 241 * @brief Get element at specified index 242 * 243 * @param index Element index 244 * @param [out] osize Optional size of returned element 245 * @param [out] orc Set to `IW_ERROR_OUT_OF_BOUNDS` if index is invalid 246 * @return IW_EXPORT* iwlist_at 247 */ 248 IW_EXPORT void *iwlist_at(IWLIST *list, size_t index, size_t *osize, iwrc *orc); 249 250 /** 251 * @brief Add element to end of list. 252 */ 253 IW_EXPORT iwrc iwlist_push(IWLIST *list, const void *data, size_t data_size); 254 255 /** 256 * @brief Removes last element from list. 257 * 258 * @param [out] osize Optional size of removed element 259 * @param [out] orc Set to `IW_ERROR_OUT_OF_BOUNDS` if list is empty 260 * @return IW_EXPORT* iwlist_pop 261 */ 262 IW_EXPORT void *iwlist_pop(IWLIST *list, size_t *osize, iwrc *orc); 263 264 /** 265 * @brief Add element to start of list 266 */ 267 IW_EXPORT iwrc iwlist_unshift(IWLIST *list, const void *data, size_t data_size); 268 269 /** 270 * @brief Removes element at start of list. 271 272 * @param osize Optional size of removed element 273 * @param orc Set to `IW_ERROR_OUT_OF_BOUNDS` if list is empty 274 * @return IW_EXPORT* iwlist_shift 275 */ 276 IW_EXPORT void *iwlist_shift(IWLIST *list, size_t *osize, iwrc *orc); 277 278 /** 279 * @brief Inserts element at given position. 280 */ 281 IW_EXPORT iwrc iwlist_insert(IWLIST *list, size_t index, const void *data, size_t data_size); 282 283 /** 284 * @brief Set/overwrite element at given position. 285 */ 286 IW_EXPORT iwrc iwlist_set(IWLIST *list, size_t index, const void *data, size_t data_size); 287 288 /** 289 * @brief Remove element at given index. 290 * 291 * @param osize Optional size of removed element 292 */ 293 IW_EXPORT void *iwlist_remove(IWLIST *list, size_t index, size_t *osize, iwrc *orc); 294 295 IW_EXTERN_C_END 296 #endif 297