dte test coverage


Directory: ./
File: src/util/ptr-array.h
Date: 2025-05-08 15:05:54
Exec Total Coverage
Lines: 34 34 100.0%
Functions: 7 7 100.0%
Branches: 6 6 100.0%

Line Branch Exec Source
1 #ifndef UTIL_PTR_ARRAY_H
2 #define UTIL_PTR_ARRAY_H
3
4 #include <stdlib.h>
5 #include "bit.h"
6 #include "debug.h"
7 #include "macros.h"
8 #include "xmalloc.h"
9
10 typedef struct {
11 void **ptrs;
12 size_t alloc;
13 size_t count;
14 } PointerArray;
15
16 #define PTR_ARRAY_INIT { \
17 .ptrs = NULL, \
18 .alloc = 0, \
19 .count = 0 \
20 }
21
22 typedef int (*CompareFunction)(const void *, const void *);
23 typedef void (*FreeFunction)(void *ptr);
24 #define FREE_FUNC(f) (FreeFunction)f
25
26 void ptr_array_grow_and_append(PointerArray *array, void *ptr) NONNULL_ARG(1) NOINLINE;
27 void ptr_array_insert(PointerArray *array, void *ptr, size_t idx) NONNULL_ARG(1);
28 void ptr_array_move(PointerArray *array, size_t from, size_t to) NONNULL_ARGS;
29 void ptr_array_free_cb(PointerArray *array, FreeFunction free_ptr) NONNULL_ARGS;
30 size_t ptr_array_remove(PointerArray *array, void *ptr) NONNULL_ARG(1);
31 void *ptr_array_remove_index(PointerArray *array, size_t idx) NONNULL_ARGS;
32 size_t ptr_array_index(const PointerArray *array, const void *ptr) NONNULL_ARG(1);
33 void ptr_array_trim_nulls(PointerArray *array) NONNULL_ARGS;
34
35 NONNULL_ARGS
36 9 static inline void ptr_array_init(PointerArray *array, size_t capacity)
37 {
38 9 capacity = next_multiple(capacity, 8);
39 9 array->count = 0;
40
2/2
✓ Branch 0 (2→3) taken 7 times.
✓ Branch 1 (2→4) taken 2 times.
9 array->ptrs = capacity ? xmallocarray(capacity, sizeof(array->ptrs[0])) : NULL;
41 9 array->alloc = capacity;
42 9 }
43
44 NONNULL_ARG(1)
45 41871 static inline void ptr_array_append(PointerArray *array, void *ptr)
46 {
47
2/2
✓ Branch 0 (2→3) taken 11745 times.
✓ Branch 1 (2→5) taken 30126 times.
41871 if (unlikely(array->alloc <= array->count)) {
48 11745 ptr_array_grow_and_append(array, ptr);
49 11745 return;
50 }
51 30126 array->ptrs[array->count++] = ptr;
52 }
53
54 // Like ptr_array_index(), but asserting that `ptr` should always be found
55 // in the array (i.e. is known to be present), instead of the caller doing so
56 1402 static inline size_t ptr_array_xindex(const PointerArray *array, const void *ptr)
57 {
58 1402 size_t idx = ptr_array_index(array, ptr);
59 1402 BUG_ON(idx >= array->count);
60 1402 return idx;
61 }
62
63 // Swap the pointers at two indices
64 NONNULL_ARGS
65 1 static inline void ptr_array_swap(PointerArray *array, size_t a, size_t b)
66 {
67 1 BUG_ON(a >= array->count);
68 1 BUG_ON(b >= array->count);
69 1 void **ptrs = array->ptrs;
70 1 void *tmp = ptrs[a];
71 1 ptrs[a] = ptrs[b];
72 1 ptrs[b] = tmp;
73 1 }
74
75 // Free each pointer and then free the array
76 NONNULL_ARGS
77 9021 static inline void ptr_array_free(PointerArray *array)
78 {
79 9021 ptr_array_free_cb(array, free);
80 9021 }
81
82 // Free the array itself but not the pointers (useful when the
83 // pointers are "borrowed" references)
84 NONNULL_ARGS
85 13911 static inline void ptr_array_free_array(PointerArray *array)
86 {
87 13911 free(array->ptrs);
88 13911 *array = (PointerArray) PTR_ARRAY_INIT;
89 13911 }
90
91 87 static inline void ptr_array_sort (
92 const PointerArray *array,
93 CompareFunction compare
94 ) {
95
2/2
✓ Branch 0 (2→3) taken 27 times.
✓ Branch 1 (2→4) taken 60 times.
87 if (array->count >= 2) {
96 27 qsort(array->ptrs, array->count, sizeof(*array->ptrs), compare);
97 }
98 87 }
99
100 static inline void *ptr_array_bsearch (
101 const PointerArray array,
102 const void *ptr,
103 CompareFunction compare
104 ) {
105 return bsearch(&ptr, array.ptrs, array.count, sizeof(*array.ptrs), compare);
106 }
107
108 #endif
109