Line | Branch | Exec | Source |
---|---|---|---|
1 | /*********************************************************************************/ | ||
2 | /* Copyright 2009-2024 Barcelona Supercomputing Center */ | ||
3 | /* */ | ||
4 | /* This file is part of the DLB library. */ | ||
5 | /* */ | ||
6 | /* DLB is free software: you can redistribute it and/or modify */ | ||
7 | /* it under the terms of the GNU Lesser General Public License as published by */ | ||
8 | /* the Free Software Foundation, either version 3 of the License, or */ | ||
9 | /* (at your option) any later version. */ | ||
10 | /* */ | ||
11 | /* DLB is distributed in the hope that it will be useful, */ | ||
12 | /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ | ||
13 | /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ | ||
14 | /* GNU Lesser General Public License for more details. */ | ||
15 | /* */ | ||
16 | /* You should have received a copy of the GNU Lesser General Public License */ | ||
17 | /* along with DLB. If not, see <https://www.gnu.org/licenses/>. */ | ||
18 | /*********************************************************************************/ | ||
19 | |||
20 | /* Credits: https://www.davidpriver.com/ctemplates.html */ | ||
21 | |||
22 | /* Include this header multiple times to implement a simplistic array. | ||
23 | * Before inclusion define at least ARRAY_T to the type the array can hold. | ||
24 | */ | ||
25 | |||
26 | #ifndef ARRAY_TEMPLATE_H | ||
27 | #define ARRAY_TEMPLATE_H | ||
28 | |||
29 | #include "support/debug.h" | ||
30 | |||
31 | #include <stdlib.h> | ||
32 | |||
33 | #define ARRAY_IMPL(word) ARRAY_COMB1(ARRAY_PREFIX,word) | ||
34 | #define ARRAY_COMB1(pre, word) ARRAY_COMB2(pre, word) | ||
35 | #define ARRAY_COMB2(pre, word) pre##word | ||
36 | |||
37 | #endif /* ARRAY_TEMPLATE_H */ | ||
38 | |||
39 | #ifndef ARRAY_T | ||
40 | #error "ARRAY_T must be defined" | ||
41 | #endif | ||
42 | |||
43 | #ifndef ARRAY_KEY_T | ||
44 | #define ARRAY_KEY_T ARRAY_T | ||
45 | #endif | ||
46 | |||
47 | #define ARRAY_NAME ARRAY_COMB1(ARRAY_COMB1(array,_), ARRAY_T) | ||
48 | #define ARRAY_PREFIX ARRAY_COMB1(ARRAY_NAME, _) | ||
49 | |||
50 | #define ARRAY_init ARRAY_IMPL(init) | ||
51 | #define ARRAY_count ARRAY_IMPL(count) | ||
52 | #define ARRAY_clear ARRAY_IMPL(clear) | ||
53 | #define ARRAY_destroy ARRAY_IMPL(destroy) | ||
54 | #define ARRAY_get ARRAY_IMPL(get) | ||
55 | #define ARRAY_push ARRAY_IMPL(push) | ||
56 | #define ARRAY_compar ARRAY_IMPL(compar) | ||
57 | #define ARRAY_sort ARRAY_IMPL(sort) | ||
58 | |||
59 | typedef struct ARRAY_NAME { | ||
60 | ARRAY_T *items; | ||
61 | size_t count; | ||
62 | size_t capacity; | ||
63 | } ARRAY_NAME; | ||
64 | |||
65 | 145 | static inline void ARRAY_init(ARRAY_NAME *array, size_t capacity) { | |
66 | 145 | *array = (const ARRAY_NAME) { | |
67 | 145 | .items = malloc(sizeof(ARRAY_T) * capacity), | |
68 | .count = 0, | ||
69 | .capacity = capacity, | ||
70 | }; | ||
71 | 145 | } | |
72 | |||
73 | static inline size_t ARRAY_count(const ARRAY_NAME *array) { | ||
74 | return array->count; | ||
75 | } | ||
76 | |||
77 | 808 | static inline void ARRAY_clear(ARRAY_NAME *array) { | |
78 | 808 | array->count = 0; | |
79 | 808 | } | |
80 | |||
81 | 55 | static inline void ARRAY_destroy(ARRAY_NAME *array) { | |
82 | 55 | free(array->items); | |
83 | 55 | *array = (const ARRAY_NAME) {}; | |
84 | 55 | } | |
85 | |||
86 | static inline ARRAY_T ARRAY_get(const ARRAY_NAME *array, size_t index) { | ||
87 | ensure(index < array->count, | ||
88 | "Please report bug."); | ||
89 | return array->items[index]; | ||
90 | } | ||
91 | |||
92 | 2580 | static inline void ARRAY_push(ARRAY_NAME *array, ARRAY_T item) { | |
93 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1773 times.
|
2580 | ensure(array->count < array->capacity, |
94 | "ARRAY_push does not support dynamic size. Please report bug."); | ||
95 | 2580 | array->items[array->count++] = item; | |
96 | 2580 | } | |
97 | |||
98 | 71 | static inline int ARRAY_compar(const void *p1, const void* p2) { | |
99 | 71 | ARRAY_KEY_T item1 = *((ARRAY_KEY_T *)p1); | |
100 | 71 | ARRAY_KEY_T item2 = *((ARRAY_KEY_T *)p2); | |
101 | 71 | return item1 - item2; | |
102 | } | ||
103 | |||
104 | 17 | static inline void ARRAY_sort(ARRAY_NAME *array) { | |
105 | 17 | qsort(array->items, array->count, sizeof(ARRAY_T), ARRAY_compar); | |
106 | 17 | } | |
107 | |||
108 | #undef ARRAY_T | ||
109 | #undef ARRAY_KEY_T | ||
110 | #undef ARRAY_PREFIX | ||
111 | #undef ARRAY_NAME | ||
112 | #undef ARRAY_init | ||
113 | #undef ARRAY_count | ||
114 | #undef ARRAY_clear | ||
115 | #undef ARRAY_destroy | ||
116 | #undef ARRAY_get | ||
117 | #undef ARRAY_push | ||
118 | #undef ARRAY_compar | ||
119 | #undef ARRAY_sort | ||
120 |