| 47 * The maximum item size in an array list that fits into |
47 * The maximum item size in an array list that fits into |
| 48 * a stack buffer when swapped. |
48 * a stack buffer when swapped. |
| 49 */ |
49 */ |
| 50 CX_EXPORT extern const unsigned cx_array_swap_sbo_size; |
50 CX_EXPORT extern const unsigned cx_array_swap_sbo_size; |
| 51 |
51 |
| |
52 /** |
| |
53 * Declares a typed array with size and capacity. |
| |
54 * |
| |
55 * @param type the type of the elements |
| |
56 * @param name the name of the array |
| |
57 */ |
| 52 #define CX_ARRAY(type, name) \ |
58 #define CX_ARRAY(type, name) \ |
| 53 struct { \ |
59 struct { \ |
| 54 type *data; \ |
60 type *data; \ |
| 55 size_t size; \ |
61 size_t size; \ |
| 56 size_t capacity; \ |
62 size_t capacity; \ |
| 57 } name |
63 } name |
| 58 |
64 |
| |
65 /** |
| |
66 * Internal structure for arrays. |
| |
67 * |
| |
68 * A generalization of array structures declared with CX_ARRAY(). |
| |
69 */ |
| 59 typedef struct cx_array_s { |
70 typedef struct cx_array_s { |
| |
71 /** The array data. */ |
| 60 void *data; |
72 void *data; |
| |
73 /** The number of elements. */ |
| 61 size_t size; |
74 size_t size; |
| |
75 /** The maximum number of elements. */ |
| 62 size_t capacity; |
76 size_t capacity; |
| 63 } CxArray; |
77 } CxArray; |
| 64 |
78 |
| |
79 /** |
| |
80 * Initializes an array by allocating memory. |
| |
81 * |
| |
82 * Internal function - do not use manually. |
| |
83 * |
| |
84 * @param allocator the allocator for the array |
| |
85 * @param array a pointer to the array structure |
| |
86 * @param elem_size size of one element |
| |
87 * @param capacity the initial maximum number of elements |
| |
88 * @retval zero allocation was successful |
| |
89 * @retval non-zero allocation failed |
| |
90 */ |
| 65 cx_attr_nonnull |
91 cx_attr_nonnull |
| 66 CX_EXPORT int cx_array_init_(const CxAllocator *allocator, CxArray *array, size_t elem_size, size_t capacity); |
92 CX_EXPORT int cx_array_init_(const CxAllocator *allocator, CxArray *array, size_t elem_size, size_t capacity); |
| 67 |
93 |
| |
94 /** |
| |
95 * Initializes an array by allocating memory. |
| |
96 * |
| |
97 * The size is set to zero. |
| |
98 * |
| |
99 * @attention If the array was already initialized, this will leak memory. |
| |
100 * Use cx_array_reserve() to change the capacity of an initialized array. |
| |
101 * |
| |
102 * @param allocator (@c CxAllocator*) the allocator for the array |
| |
103 * @param array the name of the array |
| |
104 * @param capacity (@c size_t) the initial maximum number of elements |
| |
105 * @retval zero allocation was successful |
| |
106 * @retval non-zero allocation failed |
| |
107 */ |
| 68 #define cx_array_init_a(allocator, array, capacity) cx_array_init_(allocator, (CxArray*)&(array), sizeof((array).data[0]), capacity) |
108 #define cx_array_init_a(allocator, array, capacity) cx_array_init_(allocator, (CxArray*)&(array), sizeof((array).data[0]), capacity) |
| 69 |
109 |
| |
110 /** |
| |
111 * Initializes an array by allocating memory. |
| |
112 * |
| |
113 * The size is set to zero. |
| |
114 * |
| |
115 * @attention If the array was already initialized, this will leak memory. |
| |
116 * |
| |
117 * @param array the name of the array |
| |
118 * @param capacity (@c size_t) the initial maximum number of elements |
| |
119 * @retval zero allocation was successful |
| |
120 * @retval non-zero allocation failed |
| |
121 */ |
| 70 #define cx_array_init(array, capacity) cx_array_init_a(cxDefaultAllocator, array, capacity) |
122 #define cx_array_init(array, capacity) cx_array_init_a(cxDefaultAllocator, array, capacity) |
| 71 |
123 |
| |
124 /** |
| |
125 * Initializes an array with fixed size memory. |
| |
126 * |
| |
127 * Internal function - do not use manually. |
| |
128 * |
| |
129 * @param array a pointer to the array structure |
| |
130 * @param data the fixed size array |
| |
131 * @param capacity the capacity of the fixed size array |
| |
132 * @param size the number of initialized elements in the fixed size array |
| |
133 */ |
| 72 cx_attr_nonnull |
134 cx_attr_nonnull |
| 73 CX_EXPORT void cx_array_init_fixed_(CxArray *array, const void *data, size_t capacity, size_t size); |
135 CX_EXPORT void cx_array_init_fixed_(CxArray *array, const void *data, size_t capacity, size_t size); |
| 74 |
136 |
| 75 #define cx_array_init_fixed(array, fixed_size_array, num_initialized) cx_array_init_fixed_((CxArray*)&(array), fixed_size_array, cx_nmemb(fixed_size_array), num_initialized) |
137 /** |
| 76 |
138 * Initializes an array with fixed size memory. |
| |
139 * |
| |
140 * This is useful, for example, when you want to work with memory on the stack |
| |
141 * and only want to move to the heap when the stack memory is not enough. |
| |
142 * |
| |
143 * With the @p num_initialized argument you can specify how many elements in the |
| |
144 * fixed size array are already correctly initialized, which determines the |
| |
145 * initial size of the array. |
| |
146 * |
| |
147 * The capacity is determined automatically by the compiler. |
| |
148 * |
| |
149 * @attention When you add elements to an array that was initialized with fixed |
| |
150 * size memory, you MUST check the capacity before adding the element and invoke |
| |
151 * cx_array_copy_to_new() when you intend to exceed the capacity. |
| |
152 * |
| |
153 * @attention When you pass a pointer to an array that does not have a fixed |
| |
154 * size, the behavior is unspecified. |
| |
155 * |
| |
156 * @param array the name of the array to initialize |
| |
157 * @param fixed_size_array (@c void*) the fixed size array |
| |
158 * @param num_initialized (@c size_t) the number of already initialized elements in the fixed size array |
| |
159 * @see cx_array_copy_to_new() |
| |
160 */ |
| |
161 #define cx_array_init_fixed(array, fixed_size_array, num_initialized) \ |
| |
162 cx_array_init_fixed_((CxArray*)&(array), fixed_size_array, cx_nmemb(fixed_size_array), num_initialized) |
| |
163 |
| |
164 /** |
| |
165 * Changes the capacity of an array. |
| |
166 * |
| |
167 * Internal function - do not use. |
| |
168 * |
| |
169 * @param allocator the allocator |
| |
170 * @param array a pointer to the array structure |
| |
171 * @param elem_size the size of one element |
| |
172 * @param capacity the new capacity |
| |
173 * @retval zero allocation was successful |
| |
174 * @retval non-zero allocation failed |
| |
175 */ |
| 77 cx_attr_nonnull |
176 cx_attr_nonnull |
| 78 CX_EXPORT int cx_array_reserve_(const CxAllocator *allocator, CxArray *array, size_t elem_size, size_t capacity); |
177 CX_EXPORT int cx_array_reserve_(const CxAllocator *allocator, CxArray *array, size_t elem_size, size_t capacity); |
| 79 |
178 |
| 80 #define cx_array_reserve_a(allocator, array, capacity) cx_array_reserve_(allocator, (CxArray*)&(array), sizeof((array).data[0]), capacity) |
179 /** |
| 81 |
180 * Changes the capacity of an array. |
| 82 #define cx_array_reserve(array, capacity) cx_array_reserve_a(cxDefaultAllocator, array, capacity) |
181 * |
| 83 |
182 * If required, the size is reduced to fit into the new capacity. |
| 84 cx_attr_nonnull |
183 * |
| 85 CX_EXPORT int cx_array_move_to_new_(const CxAllocator *allocator, CxArray *array, size_t elem_size, size_t capacity); |
184 * @param allocator (@c CxAllocator*) the allocator for the array |
| 86 |
185 * @param array the name of the array |
| 87 #define cx_array_move_to_new_a(allocator, array, capacity) cx_array_move_to_new_(allocator, (CxArray*)&(array), sizeof((array).data[0]), capacity) |
186 * @param capacity (@c size_t) the new maximum number of elements |
| 88 |
187 * @retval zero allocation was successful |
| 89 #define cx_array_move_to_new(array, capacity) cx_array_move_to_new_a(cxDefaultAllocator, array, capacity) |
188 * @retval non-zero allocation failed |
| 90 |
189 */ |
| |
190 #define cx_array_reserve_a(allocator, array, capacity) \ |
| |
191 cx_array_reserve_(allocator, (CxArray*)&(array), sizeof((array).data[0]), capacity) |
| |
192 |
| |
193 /** |
| |
194 * Changes the capacity of an array. |
| |
195 * |
| |
196 * If required, the size is reduced to fit into the new capacity. |
| |
197 * |
| |
198 * @param array the name of the array |
| |
199 * @param capacity (@c size_t) the new maximum number of elements |
| |
200 * @retval zero allocation was successful |
| |
201 * @retval non-zero allocation failed |
| |
202 */ |
| |
203 #define cx_array_reserve(array, capacity) \ |
| |
204 cx_array_reserve_a(cxDefaultAllocator, array, capacity) |
| |
205 |
| |
206 /** |
| |
207 * Copies the array to a new memory region. |
| |
208 * |
| |
209 * Internal function - do not use. |
| |
210 * |
| |
211 * @param allocator the allocator for new new memory |
| |
212 * @param array a pointer to the array structure |
| |
213 * @param elem_size the size of one element |
| |
214 * @param capacity the new capacity |
| |
215 * @retval zero allocation was successful |
| |
216 * @retval non-zero allocation failed |
| |
217 */ |
| |
218 cx_attr_nonnull |
| |
219 CX_EXPORT int cx_array_copy_to_new_(const CxAllocator *allocator, CxArray *array, size_t elem_size, size_t capacity); |
| |
220 |
| |
221 /** |
| |
222 * Copies the array to a new memory region. |
| |
223 * |
| |
224 * This is useful when you have initialized the array with a fixed size memory |
| |
225 * using cx_array_init_fixed(), and now you want to increase the capacity. |
| |
226 * |
| |
227 * @attention When the original memory does not belong to stack memory, and |
| |
228 * you do not have another reference to this memory, it will leak. |
| |
229 * |
| |
230 * @param allocator (@c CxAllocator*) the allocator for the new memory |
| |
231 * @param array the name of the array |
| |
232 * @param capacity (@c size_t) the new maximum number of elements |
| |
233 * @retval zero allocation was successful |
| |
234 * @retval non-zero allocation failed |
| |
235 * @see cx_array_init_fixed() |
| |
236 */ |
| |
237 #define cx_array_copy_to_new_a(allocator, array, capacity) \ |
| |
238 cx_array_copy_to_new_(allocator, (CxArray*)&(array), sizeof((array).data[0]), capacity) |
| |
239 |
| |
240 /** |
| |
241 * Copies the array to a new memory region. |
| |
242 * |
| |
243 * This is useful when you have initialized the array with a fixed size memory |
| |
244 * using cx_array_init_fixed(), and now you want to increase the capacity. |
| |
245 * |
| |
246 * @attention When the original memory does not belong to stack memory, and |
| |
247 * you do not have another reference to this memory, it will leak. |
| |
248 * |
| |
249 * @param array the name of the array |
| |
250 * @param capacity (@c size_t) the new maximum number of elements |
| |
251 * @retval zero allocation was successful |
| |
252 * @retval non-zero allocation failed |
| |
253 * @see cx_array_init_fixed() |
| |
254 */ |
| |
255 #define cx_array_copy_to_new(array, capacity) \ |
| |
256 cx_array_copy_to_new_a(cxDefaultAllocator, array, capacity) |
| |
257 |
| |
258 /** |
| |
259 * Inserts data into an array. |
| |
260 * |
| |
261 * Internal function - do not use. |
| |
262 * |
| |
263 * @param allocator the allocator to use for a possible reallocation |
| |
264 * @param array a pointer to the array structure |
| |
265 * @param elem_size the size of one element |
| |
266 * @param index the index where to insert the @p other data |
| |
267 * @param other a pointer to an array of data that shall be inserted |
| |
268 * @param n the number of elements that shall be inserted |
| |
269 * @retval zero success |
| |
270 * @retval non-zero a re-allocation was necessary but failed |
| |
271 */ |
| 91 cx_attr_nonnull_arg(1, 2) |
272 cx_attr_nonnull_arg(1, 2) |
| 92 CX_EXPORT int cx_array_insert_(const CxAllocator *allocator, CxArray *array, |
273 CX_EXPORT int cx_array_insert_(const CxAllocator *allocator, CxArray *array, |
| 93 size_t elem_size, size_t index, const void *other, size_t n); |
274 size_t elem_size, size_t index, const void *other, size_t n); |
| 94 |
275 |
| |
276 /** |
| |
277 * Appends an element to an array. |
| |
278 * |
| |
279 * When the capacity is not enough to hold the new element, a re-allocation is attempted. |
| |
280 * |
| |
281 * @param allocator (@c CxAllocator*) the allocator to use for a possible reallocation |
| |
282 * @param array the name of the array where the element shall be added |
| |
283 * @param element (@c void*) a pointer to the element that shall be added |
| |
284 * @retval zero success |
| |
285 * @retval non-zero a re-allocation was necessary but failed |
| |
286 */ |
| 95 #define cx_array_add_a(allocator, array, element) \ |
287 #define cx_array_add_a(allocator, array, element) \ |
| 96 cx_array_insert_(allocator, (CxArray*)&(array), sizeof((array).data[0]), (array).size, element, 1) |
288 cx_array_insert_(allocator, (CxArray*)&(array), sizeof((array).data[0]), (array).size, element, 1) |
| 97 |
289 |
| 98 #define cx_array_add(array, element) cx_array_add_a(cxDefaultAllocator, array, element) |
290 /** |
| 99 |
291 * Appends an element to an array. |
| |
292 * |
| |
293 * When the capacity is not enough to hold the new element, a re-allocation is attempted. |
| |
294 * |
| |
295 * @param array the name of the array where the element shall be added |
| |
296 * @param element (@c void*) a pointer to the element that shall be added |
| |
297 * @retval zero success |
| |
298 * @retval non-zero a re-allocation was necessary but failed |
| |
299 */ |
| |
300 #define cx_array_add(array, element) \ |
| |
301 cx_array_add_a(cxDefaultAllocator, array, element) |
| |
302 |
| |
303 /** |
| |
304 * Inserts an element into an array. |
| |
305 * |
| |
306 * When the capacity is not enough to hold the new element, a re-allocation is attempted. |
| |
307 * |
| |
308 * @param allocator (@c CxAllocator*) the allocator to use for a possible reallocation |
| |
309 * @param array the name of the array where the element shall be inserted |
| |
310 * @param index (@c size_t) the index where to insert the @p element |
| |
311 * @param element (@c void*) a pointer to the element that shall be inserted |
| |
312 * @retval zero success |
| |
313 * @retval non-zero a re-allocation was necessary but failed |
| |
314 */ |
| 100 #define cx_array_insert_a(allocator, array, index, element) \ |
315 #define cx_array_insert_a(allocator, array, index, element) \ |
| 101 cx_array_insert_(allocator, (CxArray*)&(array), sizeof((array).data[0]), index, element, 1) |
316 cx_array_insert_(allocator, (CxArray*)&(array), sizeof((array).data[0]), index, element, 1) |
| 102 |
317 |
| 103 #define cx_array_insert(array, index, element) cx_array_insert_a(cxDefaultAllocator, array, index, element) |
318 /** |
| 104 |
319 * Inserts an element into an array. |
| |
320 * |
| |
321 * When the capacity is not enough to hold the new element, a re-allocation is attempted. |
| |
322 * |
| |
323 * @param array the name of the array where the element shall be inserted |
| |
324 * @param index (@c size_t) the index where to insert the @p element |
| |
325 * @param element (@c void*) a pointer to the element that shall be inserted |
| |
326 * @retval zero success |
| |
327 * @retval non-zero a re-allocation was necessary but failed |
| |
328 */ |
| |
329 #define cx_array_insert(array, index, element) \ |
| |
330 cx_array_insert_a(cxDefaultAllocator, array, index, element) |
| |
331 |
| |
332 /** |
| |
333 * Inserts data into an array. |
| |
334 * |
| |
335 * When the capacity is not enough to hold the new elements, a re-allocation is attempted. |
| |
336 * |
| |
337 * @param allocator (@c CxAllocator*) the allocator to use for a possible reallocation |
| |
338 * @param array the name of the array where the elements shall be inserted |
| |
339 * @param index (@c size_t) the index where to insert the @p other data |
| |
340 * @param other (@c void*) a pointer to an array of data that shall be inserted |
| |
341 * @param n (@c size_t) the number of elements that shall be inserted |
| |
342 * @retval zero success |
| |
343 * @retval non-zero a re-allocation was necessary but failed |
| |
344 */ |
| 105 #define cx_array_insert_array_a(allocator, array, index, other, n) \ |
345 #define cx_array_insert_array_a(allocator, array, index, other, n) \ |
| 106 cx_array_insert_(allocator, (CxArray*)&(array), sizeof((array).data[0]), index, other, n) |
346 cx_array_insert_(allocator, (CxArray*)&(array), sizeof((array).data[0]), index, other, n) |
| 107 |
347 |
| 108 #define cx_array_insert_array(array, index, other, n) cx_array_insert_array_a(cxDefaultAllocator, array, index, other, n) |
348 /** |
| 109 |
349 * Inserts data into an array. |
| |
350 * |
| |
351 * When the capacity is not enough to hold the new elements, a re-allocation is attempted. |
| |
352 * |
| |
353 * @param array the name of the array where the elements shall be inserted |
| |
354 * @param index (@c size_t) the index where to insert the @p other data |
| |
355 * @param other (@c void*) a pointer to an array of data that shall be inserted |
| |
356 * @param n (@c size_t) the number of elements that shall be inserted |
| |
357 * @retval zero success |
| |
358 * @retval non-zero a re-allocation was necessary but failed |
| |
359 */ |
| |
360 #define cx_array_insert_array(array, index, other, n) \ |
| |
361 cx_array_insert_array_a(cxDefaultAllocator, array, index, other, n) |
| |
362 |
| |
363 /** |
| |
364 * Appends data to an array. |
| |
365 * |
| |
366 * When the capacity is not enough to hold the new elements, a re-allocation is attempted. |
| |
367 * |
| |
368 * @param allocator (@c CxAllocator*) the allocator to use for a possible reallocation |
| |
369 * @param array the name of the array where the elements shall be added |
| |
370 * @param other (@c void*) a pointer to an array of data that shall be added |
| |
371 * @param n (@c size_t) the number of elements that shall be added |
| |
372 * @retval zero success |
| |
373 * @retval non-zero a re-allocation was necessary but failed |
| |
374 */ |
| 110 #define cx_array_add_array_a(allocator, array, other, n) \ |
375 #define cx_array_add_array_a(allocator, array, other, n) \ |
| 111 cx_array_insert_(allocator, (CxArray*)&(array), sizeof((array).data[0]), (array).size, other, n) |
376 cx_array_insert_(allocator, (CxArray*)&(array), sizeof((array).data[0]), (array).size, other, n) |
| 112 |
377 |
| 113 #define cx_array_add_array(array, other, n) cx_array_add_array_a(cxDefaultAllocator, array, other, n) |
378 /** |
| 114 |
379 * Appends data to an array. |
| |
380 * |
| |
381 * When the capacity is not enough to hold the new elements, a re-allocation is attempted. |
| |
382 * |
| |
383 * @param array the name of the array where the elements shall be added |
| |
384 * @param other (@c void*) a pointer to an array of data that shall be added |
| |
385 * @param n (@c size_t) the number of elements that shall be added |
| |
386 * @retval zero success |
| |
387 * @retval non-zero a re-allocation was necessary but failed |
| |
388 */ |
| |
389 #define cx_array_add_array(array, other, n) \ |
| |
390 cx_array_add_array_a(cxDefaultAllocator, array, other, n) |
| |
391 |
| |
392 /** |
| |
393 * Inserts sorted data into a sorted array. |
| |
394 * |
| |
395 * Internal function - do not use. |
| |
396 * |
| |
397 * @param allocator the allocator to use for a possible reallocation |
| |
398 * @param array a pointer to the array structure |
| |
399 * @param elem_size the size of one element |
| |
400 * @param cmp_func |
| |
401 * @param sorted_data a pointer to an array of data that shall be inserted |
| |
402 * @param n the number of elements that shall be inserted |
| |
403 * @param allow_duplicates @c false if duplicates shall be skipped during insertion |
| |
404 * @retval zero success |
| |
405 * @retval non-zero a re-allocation was necessary but failed |
| |
406 */ |
| 115 cx_attr_nonnull |
407 cx_attr_nonnull |
| 116 CX_EXPORT int cx_array_insert_sorted_(const CxAllocator *allocator, CxArray *array, |
408 CX_EXPORT int cx_array_insert_sorted_(const CxAllocator *allocator, CxArray *array, |
| 117 size_t elem_size, cx_compare_func cmp_func, const void *sorted_data, size_t n, |
409 size_t elem_size, cx_compare_func cmp_func, const void *sorted_data, size_t n, |
| 118 bool allow_duplicates); |
410 bool allow_duplicates); |
| 119 |
411 |
| |
412 /** |
| |
413 * Inserts an element into a sorted array. |
| |
414 * |
| |
415 * When the capacity is not enough to hold the new element, a re-allocation is attempted. |
| |
416 * |
| |
417 * @attention if the array is not sorted according to the specified @p cmp_func, the behavior is undefined. |
| |
418 * |
| |
419 * @param allocator (@c CxAllocator*) the allocator to use for a possible reallocation |
| |
420 * @param array the name of the array where the elements shall be inserted |
| |
421 * @param cmp_func (@c cx_compare_func) the compare function that establishes the order |
| |
422 * @param element (@c void*) a pointer to element that shall be inserted |
| |
423 * @retval zero success |
| |
424 * @retval non-zero a re-allocation was necessary but failed |
| |
425 */ |
| 120 #define cx_array_insert_sorted_a(allocator, array, cmp_func, element) \ |
426 #define cx_array_insert_sorted_a(allocator, array, cmp_func, element) \ |
| 121 cx_array_insert_sorted_(allocator, (CxArray*)&(array), sizeof((array).data[0]), cmp_func, element, 1, true) |
427 cx_array_insert_sorted_(allocator, (CxArray*)&(array), sizeof((array).data[0]), cmp_func, element, 1, true) |
| 122 |
428 |
| 123 #define cx_array_insert_sorted(array, cmp_func, element) cx_array_insert_sorted_a(cxDefaultAllocator, array, cmp_func, element) |
429 /** |
| 124 |
430 * Inserts an element into a sorted array. |
| |
431 * |
| |
432 * When the capacity is not enough to hold the new element, a re-allocation is attempted. |
| |
433 * |
| |
434 * @attention if the array is not sorted according to the specified @p cmp_func, the behavior is undefined. |
| |
435 * |
| |
436 * @param array the name of the array where the elements shall be inserted |
| |
437 * @param cmp_func (@c cx_compare_func) the compare function that establishes the order |
| |
438 * @param element (@c void*) a pointer to element that shall be inserted |
| |
439 * @retval zero success |
| |
440 * @retval non-zero a re-allocation was necessary but failed |
| |
441 */ |
| |
442 #define cx_array_insert_sorted(array, cmp_func, element) \ |
| |
443 cx_array_insert_sorted_a(cxDefaultAllocator, array, cmp_func, element) |
| |
444 |
| |
445 /** |
| |
446 * Inserts sorted data into a sorted array. |
| |
447 * |
| |
448 * When the capacity is not enough to hold the new elements, a re-allocation is attempted. |
| |
449 * |
| |
450 * @attention if either array is not sorted according to the specified @p cmp_func, the behavior is undefined. |
| |
451 * |
| |
452 * @param allocator (@c CxAllocator*) the allocator to use for a possible reallocation |
| |
453 * @param array the name of the array where the elements shall be inserted |
| |
454 * @param cmp_func (@c cx_compare_func) the compare function that establishes the order |
| |
455 * @param sorted_data (@c void*) a pointer to an array of sorted data that shall be inserted |
| |
456 * @param n (@c size_t) the number of elements that shall be inserted |
| |
457 * @retval zero success |
| |
458 * @retval non-zero a re-allocation was necessary but failed |
| |
459 */ |
| 125 #define cx_array_insert_sorted_array_a(allocator, array, cmp_func, sorted_data, n) \ |
460 #define cx_array_insert_sorted_array_a(allocator, array, cmp_func, sorted_data, n) \ |
| 126 cx_array_insert_sorted_(allocator, (CxArray*)&(array), sizeof((array).data[0]), cmp_func, sorted_data, n, true) |
461 cx_array_insert_sorted_(allocator, (CxArray*)&(array), sizeof((array).data[0]), cmp_func, sorted_data, n, true) |
| 127 |
462 |
| 128 #define cx_array_insert_sorted_array(array, cmp_func, sorted_data, n) cx_array_insert_sorted_array_a(cxDefaultAllocator, array, cmp_func, sorted_data, n) |
463 /** |
| 129 |
464 * Inserts sorted data into a sorted array. |
| |
465 * |
| |
466 * When the capacity is not enough to hold the new elements, a re-allocation is attempted. |
| |
467 * |
| |
468 * @attention if either array is not sorted according to the specified @p cmp_func, the behavior is undefined. |
| |
469 * |
| |
470 * @param array the name of the array where the elements shall be inserted |
| |
471 * @param cmp_func (@c cx_compare_func) the compare function that establishes the order |
| |
472 * @param sorted_data (@c void*) a pointer to an array of sorted data that shall be inserted |
| |
473 * @param n (@c size_t) the number of elements that shall be inserted |
| |
474 * @retval zero success |
| |
475 * @retval non-zero a re-allocation was necessary but failed |
| |
476 */ |
| |
477 #define cx_array_insert_sorted_array(array, cmp_func, sorted_data, n) \ |
| |
478 cx_array_insert_sorted_array_a(cxDefaultAllocator, array, cmp_func, sorted_data, n) |
| |
479 |
| |
480 /** |
| |
481 * Inserts an element into a sorted array if it is not already contained. |
| |
482 * |
| |
483 * When the capacity is not enough to hold the new element, a re-allocation is attempted. |
| |
484 * |
| |
485 * @attention if the array is not sorted according to the specified @p cmp_func, the behavior is undefined. |
| |
486 * |
| |
487 * @param allocator (@c CxAllocator*) the allocator to use for a possible reallocation |
| |
488 * @param array the name of the array where the elements shall be inserted |
| |
489 * @param cmp_func (@c cx_compare_func) the compare function that establishes the order |
| |
490 * @param element (@c void*) a pointer to element that shall be inserted |
| |
491 * @retval zero success |
| |
492 * @retval non-zero a re-allocation was necessary but failed |
| |
493 */ |
| 130 #define cx_array_insert_unique_a(allocator, array, cmp_func, element) \ |
494 #define cx_array_insert_unique_a(allocator, array, cmp_func, element) \ |
| 131 cx_array_insert_sorted_(allocator, (CxArray*)&(array), sizeof((array).data[0]), cmp_func, element, 1, false) |
495 cx_array_insert_sorted_(allocator, (CxArray*)&(array), sizeof((array).data[0]), cmp_func, element, 1, false) |
| 132 |
496 |
| 133 #define cx_array_insert_unique(array, cmp_func, element) cx_array_insert_unique_a(cxDefaultAllocator, array, cmp_func, element) |
497 /** |
| 134 |
498 * Inserts an element into a sorted array if it is not already contained. |
| |
499 * |
| |
500 * When the capacity is not enough to hold the new element, a re-allocation is attempted. |
| |
501 * |
| |
502 * @attention if the array is not sorted according to the specified @p cmp_func, the behavior is undefined. |
| |
503 * |
| |
504 * @param array the name of the array where the elements shall be inserted |
| |
505 * @param cmp_func (@c cx_compare_func) the compare function that establishes the order |
| |
506 * @param element (@c void*) a pointer to element that shall be inserted |
| |
507 * @retval zero success |
| |
508 * @retval non-zero a re-allocation was necessary but failed |
| |
509 */ |
| |
510 #define cx_array_insert_unique(array, cmp_func, element) \ |
| |
511 cx_array_insert_unique_a(cxDefaultAllocator, array, cmp_func, element) |
| |
512 |
| |
513 /** |
| |
514 * Inserts sorted data into a sorted array, skipping duplicates. |
| |
515 * |
| |
516 * When the capacity is not enough to hold the new elements, a re-allocation is attempted. |
| |
517 * |
| |
518 * @attention if either array is not sorted according to the specified @p cmp_func, the behavior is undefined. |
| |
519 * |
| |
520 * @param allocator (@c CxAllocator*) the allocator to use for a possible reallocation |
| |
521 * @param array the name of the array where the elements shall be inserted |
| |
522 * @param cmp_func (@c cx_compare_func) the compare function that establishes the order |
| |
523 * @param sorted_data (@c void*) a pointer to an array of sorted data that shall be inserted |
| |
524 * @param n (@c size_t) the number of elements that shall be inserted |
| |
525 * @retval zero success |
| |
526 * @retval non-zero a re-allocation was necessary but failed |
| |
527 */ |
| 135 #define cx_array_insert_unique_array_a(allocator, array, cmp_func, sorted_data, n) \ |
528 #define cx_array_insert_unique_array_a(allocator, array, cmp_func, sorted_data, n) \ |
| 136 cx_array_insert_sorted_(allocator, (CxArray*)&(array), sizeof((array).data[0]), cmp_func, sorted_data, n, false) |
529 cx_array_insert_sorted_(allocator, (CxArray*)&(array), sizeof((array).data[0]), cmp_func, sorted_data, n, false) |
| 137 |
530 |
| 138 #define cx_array_insert_unique_array(array, cmp_func, sorted_data, n) cx_array_insert_unique_array_a(cxDefaultAllocator, array, cmp_func, sorted_data, n) |
531 /** |
| 139 |
532 * Inserts sorted data into a sorted array, skipping duplicates. |
| |
533 * |
| |
534 * When the capacity is not enough to hold the new elements, a re-allocation is attempted. |
| |
535 * |
| |
536 * @attention if either array is not sorted according to the specified @p cmp_func, the behavior is undefined. |
| |
537 * |
| |
538 * @param array the name of the array where the elements shall be inserted |
| |
539 * @param cmp_func (@c cx_compare_func) the compare function that establishes the order |
| |
540 * @param sorted_data (@c void*) a pointer to an array of sorted data that shall be inserted |
| |
541 * @param n (@c size_t) the number of elements that shall be inserted |
| |
542 * @retval zero success |
| |
543 * @retval non-zero a re-allocation was necessary but failed |
| |
544 */ |
| |
545 #define cx_array_insert_unique_array(array, cmp_func, sorted_data, n) \ |
| |
546 cx_array_insert_unique_array_a(cxDefaultAllocator, array, cmp_func, sorted_data, n) |
| |
547 |
| |
548 /** |
| |
549 * Creates an iterator over the elements of an array. |
| |
550 * |
| |
551 * Internal function - do not use. |
| |
552 * |
| |
553 * @param array a pointer to the array structure |
| |
554 * @param elem_size the size of one element |
| |
555 * @return an iterator over the elements |
| |
556 */ |
| 140 cx_attr_nodiscard cx_attr_nonnull |
557 cx_attr_nodiscard cx_attr_nonnull |
| 141 CX_EXPORT CxIterator cx_array_iterator_(CxArray *array, size_t elem_size); |
558 CX_EXPORT CxIterator cx_array_iterator_(CxArray *array, size_t elem_size); |
| 142 |
559 |
| 143 #define cx_array_iterator(array) cx_array_iterator_((CxArray*)&(array), sizeof((array).data[0])) |
560 /** |
| 144 |
561 * Creates an iterator over the elements of an array. |
| |
562 * |
| |
563 * The iterator will yield pointers to the elements. |
| |
564 * |
| |
565 * @param array the name of the array |
| |
566 * @return an iterator over the elements |
| |
567 * @see cx_array_iterator_ptr() |
| |
568 */ |
| |
569 #define cx_array_iterator(array) \ |
| |
570 cx_array_iterator_((CxArray*)&(array), sizeof((array).data[0])) |
| |
571 |
| |
572 /** |
| |
573 * Creates an iterator over the elements of an array containing pointers. |
| |
574 * |
| |
575 * Internal function - do not use. |
| |
576 * |
| |
577 * @param array the name of the array |
| |
578 * @return an iterator over the elements |
| |
579 */ |
| 145 cx_attr_nodiscard cx_attr_nonnull |
580 cx_attr_nodiscard cx_attr_nonnull |
| 146 CX_EXPORT CxIterator cx_array_iterator_ptr_(CxArray *array); |
581 CX_EXPORT CxIterator cx_array_iterator_ptr_(CxArray *array); |
| 147 |
582 |
| 148 #define cx_array_iterator_ptr(array) cx_array_iterator_ptr_((CxArray*)&(array)) |
583 /** |
| 149 |
584 * Creates an iterator over the elements of an array containing pointers. |
| |
585 * |
| |
586 * The iterator will yield the elements themselves, which are supposed to |
| |
587 * be pointers. |
| |
588 * |
| |
589 * @param array the name of the array |
| |
590 * @return an iterator over the elements |
| |
591 * @see cx_array_iterator() |
| |
592 */ |
| |
593 #define cx_array_iterator_ptr(array) \ |
| |
594 cx_array_iterator_ptr_((CxArray*)&(array)) |
| |
595 |
| |
596 /** |
| |
597 * Deallocates an array. |
| |
598 * |
| |
599 * Internal function - do not use. |
| |
600 * |
| |
601 * @param allocator (@c CxAllocator*) the allocator which was used to allocate the array |
| |
602 * @param array a pointer to the array structure |
| |
603 */ |
| 150 cx_attr_nonnull |
604 cx_attr_nonnull |
| 151 CX_EXPORT void cx_array_free_(const CxAllocator *allocator, CxArray *array); |
605 CX_EXPORT void cx_array_free_(const CxAllocator *allocator, CxArray *array); |
| 152 |
606 |
| |
607 /** |
| |
608 * Deallocates an array. |
| |
609 * |
| |
610 * The structure is reset to zero and can be re-initialized with |
| |
611 * cx_array_inita(). |
| |
612 * |
| |
613 * @param array the name of the array |
| |
614 */ |
| 153 #define cx_array_free(array) cx_array_free_(cxDefaultAllocator, (CxArray*)&(array)) |
615 #define cx_array_free(array) cx_array_free_(cxDefaultAllocator, (CxArray*)&(array)) |
| 154 |
616 |
| |
617 /** |
| |
618 * Deallocates an array. |
| |
619 * |
| |
620 * The structure is reset to zero and can be re-initialized with |
| |
621 * cx_array_init_a(). |
| |
622 * |
| |
623 * @param allocator (@c CxAllocator*) the allocator which was used to allocate the array |
| |
624 * @param array the name of the array |
| |
625 */ |
| 155 #define cx_array_free_a(allocator, array) cx_array_free_(allocator, (CxArray*)&(array)) |
626 #define cx_array_free_a(allocator, array) cx_array_free_(allocator, (CxArray*)&(array)) |
| 156 |
|
| 157 |
627 |
| 158 |
628 |
| 159 /** |
629 /** |
| 160 * Searches the largest lower bound in a sorted array. |
630 * Searches the largest lower bound in a sorted array. |
| 161 * |
631 * |