• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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