| 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 | 252 | static inline void ARRAY_init(ARRAY_NAME *array, size_t capacity) { | |
| 66 | 252 | *array = (const ARRAY_NAME) { | |
| 67 | 252 | .items = malloc(sizeof(ARRAY_T) * capacity), | |
| 68 | .count = 0, | ||
| 69 | .capacity = capacity, | ||
| 70 | }; | ||
| 71 | 252 | } | |
| 72 | |||
| 73 | 429 | static inline size_t ARRAY_count(const ARRAY_NAME *array) { | |
| 74 | 429 | return array->count; | |
| 75 | } | ||
| 76 | |||
| 77 | 1416 | static inline void ARRAY_clear(ARRAY_NAME *array) { | |
| 78 | 1416 | array->count = 0; | |
| 79 | 1416 | } | |
| 80 | |||
| 81 | 198 | static inline void ARRAY_destroy(ARRAY_NAME *array) { | |
| 82 | 198 | free(array->items); | |
| 83 | 198 | *array = (const ARRAY_NAME) {}; | |
| 84 | 198 | } | |
| 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 | 3498 | static inline void ARRAY_push(ARRAY_NAME *array, ARRAY_T item) { | |
| 93 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2525 times.
|
3498 | ensure(array->count < array->capacity, |
| 94 | "ARRAY_push does not support dynamic size. Please report bug."); | ||
| 95 | 3498 | array->items[array->count++] = item; | |
| 96 | 3498 | } | |
| 97 | |||
| 98 | 175 | static inline int ARRAY_compar(const void *p1, const void* p2) { | |
| 99 | 175 | ARRAY_KEY_T item1 = *((ARRAY_KEY_T *)p1); | |
| 100 | 175 | ARRAY_KEY_T item2 = *((ARRAY_KEY_T *)p2); | |
| 101 | 175 | return item1 - item2; | |
| 102 | } | ||
| 103 | |||
| 104 | 31 | static inline void ARRAY_sort(ARRAY_NAME *array) { | |
| 105 | 31 | qsort(array->items, array->count, sizeof(ARRAY_T), ARRAY_compar); | |
| 106 | 31 | } | |
| 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 |