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( 26 void* restrict els, 27 size_t nels, 28 size_t elsize, 29 void* restrict eptr, 30 int (*cmp)(const void*, const void*), 31 bool skipeq); 32 33 /** 34 * @brief Remove element from a sorteed array. 35 * Return true if element is found and removed. 36 * 37 * @param els Array pointer. 38 * @param nels Number of array elements. 39 * @param elsize Size of every array element. 40 * @param eptr Pointer to the element should to be removed. 41 * @param cmp Elements comparison function 42 * @return Index of removed element or -1 43 */ 44 IW_EXPORT off_t iwarr_sorted_remove( 45 void* restrict els, 46 size_t nels, 47 size_t elsize, 48 void* restrict eptr, 49 int (*cmp)(const void*, const void*)); 50 51 52 IW_EXPORT off_t iwarr_sorted_find( 53 void* restrict els, 54 size_t nels, 55 size_t elsize, 56 void* restrict eptr, 57 int (*cmp)(const void*, const void*)); 58 59 60 IW_EXPORT off_t iwarr_sorted_find2( 61 void* restrict els, 62 size_t nels, 63 size_t elsize, 64 void* restrict eptr, 65 void *op, 66 bool *found, 67 iwrc (*cmp)(const void*, const void*, void*, int *res)); 68 69 /////////////////////////////////////////////////////////////////////////// 70 // Fixed sized item list // 71 /////////////////////////////////////////////////////////////////////////// 72 73 typedef struct { 74 char *array; /**< Continuous units array */ 75 size_t usize; /**< Unit size */ 76 size_t num; /**< Number of elements in units array */ 77 size_t anum; /**< Actual number of allocated units */ 78 size_t start; /**< Offset of units data */ 79 } IWULIST; 80 81 /** 82 * @brief Initialize units list. 83 * 84 * @param list Allocated list structure 85 * @param initial_length Number of preallocated units 86 * @param unit_size Unit size 87 */ 88 IW_EXPORT iwrc iwulist_init(IWULIST *list, size_t initial_length, size_t unit_size); 89 90 /** 91 * @brief Create new units list. 92 * 93 * @param initial_length Number of preallocated units 94 * @param unit_size Unit size 95 * @return Zero if memory allocation failed `errno` will be set respectively 96 */ 97 IW_EXPORT IW_ALLOC IWULIST* iwulist_create(size_t initial_length, size_t unit_size); 98 99 /** 100 * @brief Cleanup units list. 101 * 102 * @param list Unit list 103 */ 104 IW_EXPORT iwrc iwulist_clear(IWULIST *list); 105 106 /** 107 * @brief Destroys and deallocates a given unit list. 108 * 109 */ 110 IW_EXPORT void iwulist_destroy(IWULIST **listp); 111 112 /** 113 * @brief Destroys internal unit list buffers, 114 * but keep and doesn't free `list` pointer. 115 * 116 * @see iwulist_destroy() 117 */ 118 IW_EXPORT void iwulist_destroy_keep(IWULIST *list); 119 120 /** 121 * @brief Get number of stored elements. 122 */ 123 IW_EXPORT size_t iwulist_length(IWULIST *list); 124 125 /** 126 * @brief Clones a given list. 127 */ 128 IW_EXPORT IW_ALLOC IWULIST* iwulist_clone(IWULIST *list); 129 130 /** 131 * @brief Gets pinter to element at given `index` 132 * 133 * @param index Index of element 134 * @param [out] orc Set to `IW_ERROR_OUT_OF_BOUNDS` if index is invalid 135 */ 136 IW_EXPORT void* iwulist_at(IWULIST *list, size_t index, iwrc *orc); 137 138 IW_EXPORT void* iwulist_at2(IWULIST *list, size_t index); 139 140 /** 141 * @brief Inserts new element at given index. 142 * 143 * @param index Index of element 144 * @param data Pointer to unit data to copy 145 */ 146 IW_EXPORT iwrc iwulist_insert(IWULIST *list, size_t index, const void *data); 147 148 /** 149 * @brief Overwrite element at given index with new data. 150 * 151 * @param index Index of element 152 * @param data Pointer to unit data to copy 153 */ 154 IW_EXPORT iwrc iwulist_set(IWULIST *list, size_t index, const void *data); 155 156 /** 157 * @brief Removes element at specified index. 158 * 159 * @param index Index of element 160 * @param orc Output error code 161 */ 162 IW_EXPORT iwrc iwulist_remove(IWULIST *list, size_t index); 163 164 /** 165 * @brief Removes first element matches the given `data_ptr` content. 166 * @note `data_ptr` buffer must at least of list unit size. 167 * 168 * @param data_ptr Pointer to data buffer list items will be matched against. 169 * @return True if matched element was found. 170 */ 171 IW_EXPORT bool iwulist_remove_first_by(IWULIST *list, void *data_ptr); 172 173 /** 174 * @brief Finds first element matched the given `data_ptr` content. 175 * @note `data_ptr` buffer must at least of list unit size. 176 * 177 * @param data_ptr Pointer to data buffer list items will be matched against. 178 * @return Index of first matched element or `-1` if item not found. 179 */ 180 IW_EXPORT ssize_t iwulist_find_first(IWULIST *list, void *data_ptr); 181 182 /** 183 * @brief Adds new element to end of list. 184 * 185 * @param data Pointer to unit data to copy 186 */ 187 IW_EXPORT iwrc iwulist_push(IWULIST *list, const void *data); 188 189 /** 190 * @brief Removes element from end of list. 191 */ 192 IW_EXPORT iwrc iwulist_pop(IWULIST *list); 193 194 /** 195 * @brief Adds element to front of list. 196 */ 197 IW_EXPORT iwrc iwulist_unshift(IWULIST *list, const void *data); 198 199 /** 200 * @brief Removes element from front of list. 201 * 202 * @param orc Output error code 203 */ 204 IW_EXPORT iwrc iwulist_shift(IWULIST *list); 205 206 /** 207 * @brief Sorts list using given `compar` function. 208 * 209 * @param list IWULIST 210 * @param compar Elements comparator accepts user data as last argument 211 * @param op User data 212 */ 213 IW_EXPORT void iwulist_sort(IWULIST *list, int (*compar)(const void*, const void*, void*), void *op); 214 215 /////////////////////////////////////////////////////////////////////////// 216 // Array list implementation // 217 /////////////////////////////////////////////////////////////////////////// 218 219 typedef struct { 220 char *val; 221 size_t size; 222 } IWLISTITEM; 223 224 typedef struct { 225 IWLISTITEM *array; 226 size_t anum; /**< Number of elements allocated */ 227 size_t start; /**< Index of first element */ 228 size_t num; /**< Actual number of elements */ 229 } IWLIST; 230 231 /** 232 * @brief Initialize allocated empty list object. 233 * 234 * @param list Allocated list structure 235 * @param anum Number of elements to allocate or zero to use defaults 236 * @return IW_EXPORT iwlist_init 237 */ 238 IW_EXPORT iwrc iwlist_init(IWLIST *list, size_t anum); 239 240 /** 241 * @brief Constructs new list instance and preallocate `anum` elements. 242 * 243 * @param anum Number of elements to allocate or zero to use defaults 244 * @return Zero if allocation failed, `errno` will be set. 245 */ 246 IW_EXPORT IW_ALLOC IWLIST* iwlist_create(size_t anum); 247 248 /** 249 * @brief Destroys a given list object. 250 */ 251 IW_EXPORT void iwlist_destroy(IWLIST **listp); 252 253 /** 254 * @brief Destroys internal list buffers, 255 * but keep and doesn't free `list` pointer. 256 * @see iwilist_destroy() 257 */ 258 IW_EXPORT void iwlist_destroy_keep(IWLIST *list); 259 260 /** 261 * @brief Returns number of elements stored in list. 262 */ 263 IW_EXPORT size_t iwlist_length(IWLIST *list); 264 265 /** 266 * @brief Clone a given list. 267 * @return Zero if allocation failed, `errno` will be set. 268 */ 269 IW_EXPORT IW_ALLOC IWLIST* iwlist_clone(IWLIST *list); 270 271 /** 272 * @brief Get element at specified index. 273 * 274 * @param index Element index 275 * @param [out] osize Optional size of returned element data in bytes 276 * @param [out] orc Set to `IW_ERROR_OUT_OF_BOUNDS` if index is invalid 277 * @return Elements data buffer 278 */ 279 IW_EXPORT void* iwlist_at(IWLIST *list, size_t index, size_t *osize, iwrc *orc); 280 281 /** 282 * @brief Get element at specified index. 283 * @param index Element index 284 * @param [out] osize Optional size of returned element data in bytes 285 * @return Elements data buffer or zero if element is not found 286 */ 287 IW_EXPORT void* iwlist_at2(IWLIST *list, size_t index, size_t *osize); 288 289 /** 290 * @brief Add element to end of list. 291 */ 292 IW_EXPORT iwrc iwlist_push(IWLIST *list, const void *data, size_t data_size); 293 294 /** 295 * @brief Removes last element from list. 296 * 297 * @param [out] osize Optional size of removed element 298 * @param [out] orc Set to `IW_ERROR_OUT_OF_BOUNDS` if list is empty 299 * @return IW_EXPORT* iwlist_pop 300 */ 301 IW_EXPORT void* iwlist_pop(IWLIST *list, size_t *osize, iwrc *orc); 302 303 /** 304 * @brief Add element to start of list 305 */ 306 IW_EXPORT iwrc iwlist_unshift(IWLIST *list, const void *data, size_t data_size); 307 308 /** 309 * @brief Removes element at start of list. 310 311 * @param osize Optional size of removed element 312 * @param orc Set to `IW_ERROR_OUT_OF_BOUNDS` if list is empty 313 * @return IW_EXPORT* iwlist_shift 314 */ 315 IW_EXPORT void* iwlist_shift(IWLIST *list, size_t *osize, iwrc *orc); 316 317 /** 318 * @brief Inserts element at given position. 319 */ 320 IW_EXPORT iwrc iwlist_insert(IWLIST *list, size_t index, const void *data, size_t data_size); 321 322 /** 323 * @brief Set/overwrite element at given position. 324 */ 325 IW_EXPORT iwrc iwlist_set(IWLIST *list, size_t index, const void *data, size_t data_size); 326 327 /** 328 * @brief Remove element at given index. 329 * 330 * @param osize Optional size of removed element 331 */ 332 IW_EXPORT void* iwlist_remove(IWLIST *list, size_t index, size_t *osize, iwrc *orc); 333 334 /** 335 * @brief Sorts list using given `compar` function. 336 * 337 * @param list IWLIST 338 * @param compar Elements comparator accepts user data as last argument 339 * @param op User data 340 */ 341 IW_EXPORT void iwlist_sort(IWLIST *list, int (*compar)(const IWLISTITEM*, const IWLISTITEM*, void*), void *op); 342 343 IW_EXTERN_C_END 344 #endif 345