1 #ifndef UTIL_PTR_ARRAY_H
2 #define UTIL_PTR_ARRAY_H
3
4 #include <stdlib.h>
5 #include "macros.h"
6 #include "xmalloc.h"
7
8 typedef struct {
9 void **ptrs;
10 size_t alloc;
11 size_t count;
12 } PointerArray;
13
14 #define PTR_ARRAY_INIT { \
15 .ptrs = NULL, \
16 .alloc = 0, \
17 .count = 0 \
18 }
19
20 typedef int (*CompareFunction)(const void *, const void *);
21 typedef void (*FreeFunction)(void *ptr);
22 #define FREE_FUNC(f) (FreeFunction)f
23
24 void ptr_array_add(PointerArray *array, void *ptr) NONNULL_ARG(1);
25 void ptr_array_insert(PointerArray *array, void *ptr, size_t pos) NONNULL_ARG(1);
26 void ptr_array_free_cb(PointerArray *array, FreeFunction free_ptr) NONNULL_ARGS;
27 void ptr_array_remove(PointerArray *array, void *ptr) NONNULL_ARG(1);
28 void *ptr_array_remove_idx(PointerArray *array, size_t pos) NONNULL_ARG(1);
29 size_t ptr_array_idx(const PointerArray *array, const void *ptr) NONNULL_ARG(1);
30 void *ptr_array_rel(const PointerArray *array, const void *ptr, size_t offset) NONNULL_ARG(1);
31 void ptr_array_trim_nulls(PointerArray *array) NONNULL_ARGS;
32
33 NONNULL_ARGS
ptr_array_init(PointerArray * array,size_t capacity)34 static inline void ptr_array_init(PointerArray *array, size_t capacity)
35 {
36 capacity = ROUND_UP(capacity, 8);
37 array->count = 0;
38 array->ptrs = capacity ? xnew(array->ptrs, capacity) : NULL;
39 array->alloc = capacity;
40 }
41
42 NONNULL_ARG(1)
ptr_array_next(const PointerArray * array,const void * ptr)43 static inline void *ptr_array_next(const PointerArray *array, const void *ptr)
44 {
45 return ptr_array_rel(array, ptr, 1);
46 }
47
48 NONNULL_ARG(1)
ptr_array_prev(const PointerArray * array,const void * ptr)49 static inline void *ptr_array_prev(const PointerArray *array, const void *ptr)
50 {
51 return ptr_array_rel(array, ptr, -1);
52 }
53
54 // Free each pointer and then free the array.
55 NONNULL_ARGS
ptr_array_free(PointerArray * array)56 static inline void ptr_array_free(PointerArray *array)
57 {
58 ptr_array_free_cb(array, free);
59 }
60
61 // Free the array itself but not the pointers. Useful when the pointers
62 // are "borrowed" references.
63 NONNULL_ARGS
ptr_array_free_array(PointerArray * array)64 static inline void ptr_array_free_array(PointerArray *array)
65 {
66 free(array->ptrs);
67 *array = (PointerArray) PTR_ARRAY_INIT;
68 }
69
ptr_array_sort(const PointerArray * array,CompareFunction compare)70 static inline void ptr_array_sort (
71 const PointerArray *array,
72 CompareFunction compare
73 ) {
74 if (array->count >= 2) {
75 qsort(array->ptrs, array->count, sizeof(*array->ptrs), compare);
76 }
77 }
78
ptr_array_bsearch(const PointerArray array,const void * ptr,CompareFunction compare)79 static inline void *ptr_array_bsearch (
80 const PointerArray array,
81 const void *ptr,
82 CompareFunction compare
83 ) {
84 return bsearch(&ptr, array.ptrs, array.count, sizeof(*array.ptrs), compare);
85 }
86
87 #endif
88