| 170 struct cx_array_reallocator_s { |
169 struct cx_array_reallocator_s { |
| 171 /** |
170 /** |
| 172 * Reallocates space for the given array. |
171 * Reallocates space for the given array. |
| 173 * |
172 * |
| 174 * Implementations are not required to free the original array. |
173 * Implementations are not required to free the original array. |
| 175 * This allows reallocation of static memory by allocating heap memory |
174 * This allows reallocation of static or stack memory by allocating heap memory |
| 176 * and copying the array contents. The information in the custom fields of |
175 * and copying the array contents; namely when @c stack_ptr in this struct |
| 177 * the referenced allocator can be used to track the state of the memory |
176 * is not @c NULL and @p array equals @c stack_ptr. |
| 178 * or to transport other additional data. |
|
| 179 * |
177 * |
| 180 * @param array the array to reallocate |
178 * @param array the array to reallocate |
| 181 * @param old_capacity the old number of elements |
179 * @param old_capacity the old number of elements |
| 182 * @param new_capacity the new number of elements |
180 * @param new_capacity the new number of elements |
| 183 * @param elem_size the size of each element |
181 * @param elem_size the size of each element |
| 184 * @param alloc a reference to this allocator |
182 * @param alloc a reference to this allocator |
| 185 * @return a pointer to the reallocated memory or @c NULL on failure |
183 * @return a pointer to the reallocated memory or @c NULL on failure |
| 186 */ |
184 */ |
| 187 cx_attr_nodiscard |
185 void *(*realloc)( void *array, size_t old_capacity, size_t new_capacity, |
| 188 cx_attr_nonnull_arg(5) |
186 size_t elem_size, struct cx_array_reallocator_s *alloc); |
| 189 cx_attr_allocsize(3, 4) |
|
| 190 void *(*realloc)( |
|
| 191 void *array, |
|
| 192 size_t old_capacity, |
|
| 193 size_t new_capacity, |
|
| 194 size_t elem_size, |
|
| 195 struct cx_array_reallocator_s *alloc |
|
| 196 ); |
|
| 197 |
187 |
| 198 /** |
188 /** |
| 199 * Custom data pointer. |
189 * The allocator that shall be used for the reallocations. |
| 200 */ |
190 */ |
| 201 void *ptr1; |
191 const CxAllocator *allocator; |
| 202 /** |
192 /** |
| 203 * Custom data pointer. |
193 * Optional pointer to stack memory |
| |
194 * if the array is originally located on the stack. |
| 204 */ |
195 */ |
| 205 void *ptr2; |
196 const void *stack_ptr; |
| 206 /** |
|
| 207 * Custom data integer. |
|
| 208 */ |
|
| 209 size_t int1; |
|
| 210 /** |
|
| 211 * Custom data integer. |
|
| 212 */ |
|
| 213 size_t int2; |
|
| 214 }; |
197 }; |
| 215 |
198 |
| 216 /** |
199 /** |
| 217 * Typedef for the array reallocator struct. |
200 * Typedef for the array reallocator struct. |
| 218 */ |
201 */ |
| 219 typedef struct cx_array_reallocator_s CxArrayReallocator; |
202 typedef struct cx_array_reallocator_s CxArrayReallocator; |
| 220 |
203 |
| 221 /** |
204 /** |
| 222 * A default array reallocator that is based on the cxDefaultAllocator. |
205 * A default array reallocator that is based on the cxDefaultAllocator. |
| 223 */ |
206 */ |
| 224 cx_attr_export |
207 CX_EXPORT extern CxArrayReallocator *cx_array_default_reallocator; |
| 225 extern CxArrayReallocator *cx_array_default_reallocator; |
|
| 226 |
208 |
| 227 /** |
209 /** |
| 228 * Creates a new array reallocator. |
210 * Creates a new array reallocator. |
| 229 * |
211 * |
| 230 * When @p allocator is @c NULL, the cxDefaultAllocator will be used. |
212 * When @p allocator is @c NULL, the cxDefaultAllocator will be used. |
| 231 * |
213 * |
| 232 * When @p stackmem is not @c NULL, the reallocator is supposed to be used |
214 * When @p stack_ptr is not @c NULL, the reallocator is supposed to be used |
| 233 * @em only for the specific array initially located at @p stackmem. |
215 * @em only for the specific array initially located at @p stack_ptr. |
| 234 * When reallocation is needed, the reallocator checks if the array is |
216 * When reallocation is needed, the reallocator checks if the array is |
| 235 * still located at @p stackmem and copies the contents to the heap. |
217 * still located at @p stack_ptr and copies the contents to the heap. |
| 236 * |
218 * |
| 237 * @note Invoking this function with both arguments being @c NULL will return a |
219 * @note Invoking this function with both arguments being @c NULL will return a |
| 238 * reallocator that behaves like #cx_array_default_reallocator. |
220 * reallocator that behaves like #cx_array_default_reallocator. |
| 239 * |
221 * |
| 240 * @param allocator the allocator this reallocator shall be based on |
222 * @param allocator the allocator this reallocator shall be based on |
| 241 * @param stackmem the address of the array when the array is initially located |
223 * @param stack_ptr the address of the array when the array is initially located |
| 242 * on the stack or shall not reallocate in place |
224 * on the stack or shall not reallocate in place |
| 243 * @return an array reallocator |
225 * @return an array reallocator |
| 244 */ |
226 */ |
| 245 cx_attr_export |
227 CX_EXPORT CxArrayReallocator cx_array_reallocator( |
| 246 CxArrayReallocator cx_array_reallocator( |
228 const struct cx_allocator_s *allocator, const void *stack_ptr); |
| 247 const struct cx_allocator_s *allocator, |
|
| 248 const void *stackmem |
|
| 249 ); |
|
| 250 |
229 |
| 251 /** |
230 /** |
| 252 * Reserves memory for additional elements. |
231 * Reserves memory for additional elements. |
| 253 * |
232 * |
| 254 * This function checks if the @p capacity of the array is sufficient to hold |
233 * This function checks if the @p capacity of the array is sufficient to hold |
| 263 * |
242 * |
| 264 * The @p width in bytes refers to the size and capacity. |
243 * The @p width in bytes refers to the size and capacity. |
| 265 * Both must have the same width. |
244 * Both must have the same width. |
| 266 * Supported are 0, 1, 2, and 4, as well as 8 if running on a 64-bit |
245 * Supported are 0, 1, 2, and 4, as well as 8 if running on a 64-bit |
| 267 * architecture. If set to zero, the native word width is used. |
246 * architecture. If set to zero, the native word width is used. |
| |
247 * |
| |
248 * @note This function will reserve the minimum required capacity to hold |
| |
249 * the additional elements and does not perform an overallocation. |
| 268 * |
250 * |
| 269 * @param array a pointer to the target array |
251 * @param array a pointer to the target array |
| 270 * @param size a pointer to the size of the array |
252 * @param size a pointer to the size of the array |
| 271 * @param capacity a pointer to the capacity of the array |
253 * @param capacity a pointer to the capacity of the array |
| 272 * @param width the width in bytes for the @p size and @p capacity or zero for default |
254 * @param width the width in bytes for the @p size and @p capacity or zero for default |
| 277 * @retval zero success |
259 * @retval zero success |
| 278 * @retval non-zero failure |
260 * @retval non-zero failure |
| 279 * @see cx_array_reallocator() |
261 * @see cx_array_reallocator() |
| 280 */ |
262 */ |
| 281 cx_attr_nonnull_arg(1, 2, 3) |
263 cx_attr_nonnull_arg(1, 2, 3) |
| 282 cx_attr_export |
264 CX_EXPORT int cx_array_reserve(void **array, void *size, void *capacity, |
| 283 int cx_array_reserve( |
265 unsigned width, size_t elem_size, size_t elem_count, |
| 284 void **array, |
266 CxArrayReallocator *reallocator); |
| 285 void *size, |
|
| 286 void *capacity, |
|
| 287 unsigned width, |
|
| 288 size_t elem_size, |
|
| 289 size_t elem_count, |
|
| 290 CxArrayReallocator *reallocator |
|
| 291 ); |
|
| 292 |
267 |
| 293 /** |
268 /** |
| 294 * Copies elements from one array to another. |
269 * Copies elements from one array to another. |
| 295 * |
270 * |
| 296 * The elements are copied to the @p target array at the specified @p index, |
271 * The elements are copied to the @p target array at the specified @p index, |
| 305 * |
280 * |
| 306 * The @p width in bytes refers to the size and capacity. |
281 * The @p width in bytes refers to the size and capacity. |
| 307 * Both must have the same width. |
282 * Both must have the same width. |
| 308 * Supported are 0, 1, 2, and 4, as well as 8 if running on a 64-bit |
283 * Supported are 0, 1, 2, and 4, as well as 8 if running on a 64-bit |
| 309 * architecture. If set to zero, the native word width is used. |
284 * architecture. If set to zero, the native word width is used. |
| |
285 * |
| |
286 * @note When this function does reallocate the array, it may allocate more |
| |
287 * space than required to avoid further allocations in the near future. |
| 310 * |
288 * |
| 311 * @param target a pointer to the target array |
289 * @param target a pointer to the target array |
| 312 * @param size a pointer to the size of the target array |
290 * @param size a pointer to the size of the target array |
| 313 * @param capacity a pointer to the capacity of the target array |
291 * @param capacity a pointer to the capacity of the target array |
| 314 * @param width the width in bytes for the @p size and @p capacity or zero for default |
292 * @param width the width in bytes for the @p size and @p capacity or zero for default |
| 319 * @param reallocator the array reallocator to use |
297 * @param reallocator the array reallocator to use |
| 320 * (@c NULL defaults to #cx_array_default_reallocator) |
298 * (@c NULL defaults to #cx_array_default_reallocator) |
| 321 * @retval zero success |
299 * @retval zero success |
| 322 * @retval non-zero failure |
300 * @retval non-zero failure |
| 323 * @see cx_array_reallocator() |
301 * @see cx_array_reallocator() |
| |
302 * @see cx_array_reserve() |
| 324 */ |
303 */ |
| 325 cx_attr_nonnull_arg(1, 2, 3, 6) |
304 cx_attr_nonnull_arg(1, 2, 3, 6) |
| 326 cx_attr_export |
305 CX_EXPORT int cx_array_copy(void **target, void *size, void *capacity, unsigned width, |
| 327 int cx_array_copy( |
306 size_t index, const void *src, size_t elem_size, size_t elem_count, |
| 328 void **target, |
307 CxArrayReallocator *reallocator); |
| 329 void *size, |
|
| 330 void *capacity, |
|
| 331 unsigned width, |
|
| 332 size_t index, |
|
| 333 const void *src, |
|
| 334 size_t elem_size, |
|
| 335 size_t elem_count, |
|
| 336 CxArrayReallocator *reallocator |
|
| 337 ); |
|
| 338 |
308 |
| 339 /** |
309 /** |
| 340 * Convenience macro that uses cx_array_copy() with a default layout and |
310 * Convenience macro that uses cx_array_copy() with a default layout and |
| 341 * the specified reallocator. |
311 * the specified reallocator. |
| 342 * |
312 * |
| 480 * (@c NULL defaults to #cx_array_default_reallocator) |
450 * (@c NULL defaults to #cx_array_default_reallocator) |
| 481 * @retval zero success |
451 * @retval zero success |
| 482 * @retval non-zero failure |
452 * @retval non-zero failure |
| 483 */ |
453 */ |
| 484 cx_attr_nonnull_arg(1, 2, 3, 5) |
454 cx_attr_nonnull_arg(1, 2, 3, 5) |
| 485 cx_attr_export |
455 CX_EXPORT int cx_array_insert_sorted(void **target, size_t *size, size_t *capacity, |
| 486 int cx_array_insert_sorted( |
456 cx_compare_func cmp_func, const void *src, size_t elem_size, size_t elem_count, |
| 487 void **target, |
457 CxArrayReallocator *reallocator); |
| 488 size_t *size, |
|
| 489 size_t *capacity, |
|
| 490 cx_compare_func cmp_func, |
|
| 491 const void *src, |
|
| 492 size_t elem_size, |
|
| 493 size_t elem_count, |
|
| 494 CxArrayReallocator *reallocator |
|
| 495 ); |
|
| 496 |
458 |
| 497 /** |
459 /** |
| 498 * Inserts an element into a sorted array. |
460 * Inserts an element into a sorted array. |
| 499 * |
461 * |
| 500 * If the target array is not already sorted with respect |
462 * If the target array is not already sorted with respect |
| 501 * to the specified @p cmp_func, the behavior is undefined. |
463 * to the specified @p cmp_func, the behavior is undefined. |
| 502 * |
464 * |
| 503 * If the capacity is insufficient to hold the new data, a reallocation |
465 * If the capacity is not enough to hold the new data, a reallocation |
| 504 * attempt is made. |
466 * attempt is made. |
| 505 * |
467 * |
| 506 * The \@ SIZE_TYPE is flexible and can be any unsigned integer type. |
468 * The \@ SIZE_TYPE is flexible and can be any unsigned integer type. |
| 507 * It is important, however, that @p size and @p capacity are pointers to |
469 * It is important, however, that @p size and @p capacity are pointers to |
| 508 * variables of the same type. |
470 * variables of the same type. |
| 609 * (@c NULL defaults to #cx_array_default_reallocator) |
571 * (@c NULL defaults to #cx_array_default_reallocator) |
| 610 * @retval zero success |
572 * @retval zero success |
| 611 * @retval non-zero failure |
573 * @retval non-zero failure |
| 612 */ |
574 */ |
| 613 cx_attr_nonnull_arg(1, 2, 3, 5) |
575 cx_attr_nonnull_arg(1, 2, 3, 5) |
| 614 cx_attr_export |
576 CX_EXPORT int cx_array_insert_unique(void **target, size_t *size, size_t *capacity, |
| 615 int cx_array_insert_unique( |
577 cx_compare_func cmp_func, const void *src, size_t elem_size, size_t elem_count, |
| 616 void **target, |
578 CxArrayReallocator *reallocator); |
| 617 size_t *size, |
|
| 618 size_t *capacity, |
|
| 619 cx_compare_func cmp_func, |
|
| 620 const void *src, |
|
| 621 size_t elem_size, |
|
| 622 size_t elem_count, |
|
| 623 CxArrayReallocator *reallocator |
|
| 624 ); |
|
| 625 |
579 |
| 626 /** |
580 /** |
| 627 * Inserts an element into a sorted array if it does not exist. |
581 * Inserts an element into a sorted array if it does not exist. |
| 628 * |
582 * |
| 629 * If the target array is not already sorted with respect |
583 * If the target array is not already sorted with respect |
| 794 * @return the index of the smallest upper bound, or @p size |
736 * @return the index of the smallest upper bound, or @p size |
| 795 * @see cx_array_binary_search_inf() |
737 * @see cx_array_binary_search_inf() |
| 796 * @see cx_array_binary_search() |
738 * @see cx_array_binary_search() |
| 797 */ |
739 */ |
| 798 cx_attr_nonnull |
740 cx_attr_nonnull |
| 799 cx_attr_export |
741 CX_EXPORT size_t cx_array_binary_search_sup(const void *arr, size_t size, |
| 800 size_t cx_array_binary_search_sup( |
742 size_t elem_size, const void *elem, cx_compare_func cmp_func); |
| 801 const void *arr, |
|
| 802 size_t size, |
|
| 803 size_t elem_size, |
|
| 804 const void *elem, |
|
| 805 cx_compare_func cmp_func |
|
| 806 ); |
|
| 807 |
743 |
| 808 /** |
744 /** |
| 809 * Swaps two array elements. |
745 * Swaps two array elements. |
| 810 * |
746 * |
| 811 * @param arr the array |
747 * @param arr the array |
| 812 * @param elem_size the element size |
748 * @param elem_size the element size |
| 813 * @param idx1 index of the first element |
749 * @param idx1 index of the first element |
| 814 * @param idx2 index of the second element |
750 * @param idx2 index of the second element |
| 815 */ |
751 */ |
| 816 cx_attr_nonnull |
752 cx_attr_nonnull |
| 817 cx_attr_export |
753 CX_EXPORT void cx_array_swap(void *arr, size_t elem_size, size_t idx1, size_t idx2); |
| 818 void cx_array_swap( |
|
| 819 void *arr, |
|
| 820 size_t elem_size, |
|
| 821 size_t idx1, |
|
| 822 size_t idx2 |
|
| 823 ); |
|
| 824 |
754 |
| 825 /** |
755 /** |
| 826 * Allocates an array list for storing elements with @p elem_size bytes each. |
756 * Allocates an array list for storing elements with @p elem_size bytes each. |
| 827 * |
757 * |
| 828 * If @p elem_size is #CX_STORE_POINTERS, the created list stores pointers instead of |
758 * If @p elem_size is #CX_STORE_POINTERS, the created list stores pointers instead of |