• 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(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