dte test coverage


Directory: ./
File: src/util/ptr-array.h
Date: 2024-12-21 16:03: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 8 static inline void ptr_array_init(PointerArray *array, size_t capacity)
36 {
37 8 capacity = round_size_to_next_multiple(capacity, 8);
38 8 array->count = 0;
39
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
8 array->ptrs = capacity ? xnew(array->ptrs, capacity) : NULL;
40 8 array->alloc = capacity;
41 8 }
42
43 NONNULL_ARG(1)
44 38569 static inline void ptr_array_append(PointerArray *array, void *ptr)
45 {
46
2/2
✓ Branch 0 taken 10773 times.
✓ Branch 1 taken 27796 times.
38569 if (unlikely(array->alloc <= array->count)) {
47 10773 ptr_array_grow_and_append(array, ptr);
48 10773 return;
49 }
50 27796 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 1205 static inline size_t ptr_array_xindex(const PointerArray *array, const void *ptr)
56 {
57 1205 size_t idx = ptr_array_index(array, ptr);
58 1205 BUG_ON(idx >= array->count);
59 1205 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 8293 static inline void ptr_array_free(PointerArray *array)
77 {
78 8293 ptr_array_free_cb(array, free);
79 8293 }
80
81 // Free the array itself but not the pointers (useful when the
82 // pointers are "borrowed" references)
83 NONNULL_ARGS
84 13074 static inline void ptr_array_free_array(PointerArray *array)
85 {
86 13074 free(array->ptrs);
87 13074 *array = (PointerArray) PTR_ARRAY_INIT;
88 13074 }
89
90 86 static inline void ptr_array_sort (
91 const PointerArray *array,
92 CompareFunction compare
93 ) {
94
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 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