dte test coverage


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