Yume Project 3.0
Touhou-inspired Danmaku game made in C only
Chargement...
Recherche...
Aucune correspondance
dynarray.h
Aller à la documentation de ce fichier.
1#pragma once
2
3#include <assert.h>
4#include <stdint.h>
5#include <stdlib.h>
6#include <stdbool.h>
7
8#include "core/macro.h"
9
10typedef uint32_t dynarray_size_t;
11
12#define auto __auto_type
13
21#define DYNAMIC_ARRAY_BASE(type_elem) struct { \
22 type_elem *data; \
23 dynarray_size_t num_elements; \
24 dynarray_size_t capacity; \
25}
26
32typedef DYNAMIC_ARRAY_BASE(void) DynamicArray;
33
40#define DYNAMIC_ARRAY(elem_type) union { \
41 DYNAMIC_ARRAY_BASE(elem_type); \
42 DynamicArray din_array; \
43}
44
48#define DYNARRAY_CAST_TO_BASE(darr) &(darr)->din_array
49
53#define DYNARRAY_ELEM_SIZE(darr) sizeof(*(darr)->data)
54
61#define _dynarray_func(func, darr, ...) \
62 _dynarray_##func(DYNARRAY_ELEM_SIZE(darr), DYNARRAY_CAST_TO_BASE(darr), __VA_ARGS__)
63#define _dynarray_func_noargs(func, darr) \
64 _dynarray_##func(DYNARRAY_ELEM_SIZE(darr), DYNARRAY_CAST_TO_BASE(darr))
65
72void _dynarray_free_data(dynarray_size_t sizeof_element, DynamicArray *darr);
73#define dynarray_free_data(darr) _dynarray_func_noargs(free_data, darr)
74
82void _dynarray_ensure_capacity(dynarray_size_t sizeof_element, DynamicArray *darr, dynarray_size_t capacity);
83#define dynarray_ensure_capacity(darr, capacity) _dynarray_func(ensure_capacity, darr, capacity)
84
94
98#define dynarray_get_ptr(darr, idx) ({ \
99 (darr)->data + idx; \
100})
101
102#define _dynarray_append_min_capacity(darr, min_capacity, ...) ({ \
103 auto elem_p = dynarray_get_ptr(darr, _dynarray_func(prepare_append_min_capacity, darr, min_capacity)); \
104 __VA_OPT__(*elem_p = ((typeof(*elem_p)) __VA_ARGS__); ) \
105 elem_p; \
106})
107
108#define dynarray_append(darr, ...) \
109 _dynarray_append_min_capacity(darr, 2, ##__VA_ARGS__);
110
117void _dynarray_compact(dynarray_size_t sizeof_element, DynamicArray *darr);
118#define dynarray_compact(darr) _dynarray_func_noargs(compact, darr)
119
123#define dynarray_qsort(darr, compare_func) do { \
124 DynamicArray *b_darr = DYNARRAY_CAST_TO_BASE(darr); \
125 if (b_darr->data) { \
126 qsort(b_darr->data, b_darr->num_elements, DYNARRAY_ELEM_SIZE(darr), (compare_func)); \
127 } \
128} while(0)
129
133#define dynarray_get(darr, idx) (*dynarray_get_ptr(darr, idx))
137#define dynarray_set(darr,idx,...) (*dynarray_get_ptr(darr, idx) = (__VA_ARGS__))
138
147void _dynarray_set_elements(dynarray_size_t sizeof_element, DynamicArray *darr, dynarray_size_t num_elements, void *elements);
148// TODO: Failsafe si ce n'est pas le bon type d'éléments ? ou je vous fais confiance :)
149#define dynarray_set_elements(darr, num_elements, elements) _dynarray_func(set_elements, darr, num_elements, elements)
150
154typedef bool (*dynarray_filter_t)(const void *elem_p, void *userdata);
155
164void _dynarray_filter(dynarray_size_t sizeof_element, DynamicArray *darr, dynarray_filter_t predicate, void *userdata);
165#define dynarray_filter(darr, predicate, userdata) _dynarray_func(filter, darr, predicate, userdata)
166
170#define dynarray_indexof(darr, elem_p) ({ \
171 int idx = (int)(elem_p - darr->data;) \
172 (dynarray_size_t)idx; \
173})
174
179#define _dynarray_foreach_iter MACRO_ADDLINENUM(dynarray_foreach_iter)
180#define _dynarray_foreach_temp MACRO_ADDLINENUM(dynarray_foreach_temp)
181
185#define dynarray_foreach(darr, var, elem_var, ...) do { \
186 for (dynarray_size_t _dynarray_foreach_iter = 0; \
187 _dynarray_foreach_iter < (darr)->num_elements; _dynarray_foreach_iter++) { \
188 dynarray_size_t var = _dynarray_foreach_iter; \
189 elem_var = dynarray_get_ptr(darr, var); \
190 __VA_ARGS__; \
191 } \
192} while(0)
193
197#define dynarray_foreach_elem(darr, elem_var, ...) \
198 dynarray_foreach(darr, \
199 _dynarray_foreach_temp, \
200 elem_var, \
201 __VA_ARGS__ \
202 )
203
207#define dynarray_foreach_idx(darr, var, ...) \
208 dynarray_foreach(darr, \
209 var, \
210 _dynarray_foreach_temp, \
211 __VA_ARGS__ \
212 )
213
void _dynarray_compact(dynarray_size_t sizeof_element, DynamicArray *darr)
Fait en sorte qu'il n'y ait pas de mémoire vide dans data.
bool(* dynarray_filter_t)(const void *elem_p, void *userdata)
Fonction qui filtre un tableau.
Definition dynarray.h:154
#define DYNAMIC_ARRAY_BASE(type_elem)
base d'un tableau dynamique
Definition dynarray.h:21
dynarray_size_t _dynarray_prepare_append_min_capacity(dynarray_size_t sizeof_element, DynamicArray *darr, dynarray_size_t min_capacity)
Vérifie qu'il y a la capacité nécessaire pour append et en alloue si besoin.
void _dynarray_ensure_capacity(dynarray_size_t sizeof_element, DynamicArray *darr, dynarray_size_t capacity)
Fait en sorte que la capacité du tableau soit au moins capacity.
void _dynarray_free_data(dynarray_size_t sizeof_element, DynamicArray *darr)
Libère la mémoire du data d'un dynarray.
uint32_t dynarray_size_t
Definition dynarray.h:10
void _dynarray_set_elements(dynarray_size_t sizeof_element, DynamicArray *darr, dynarray_size_t num_elements, void *elements)
Rentre un tableau d'elements dans le tableau dynamique.
void _dynarray_filter(dynarray_size_t sizeof_element, DynamicArray *darr, dynarray_filter_t predicate, void *userdata)
Modifie un tableau pour ne garder que les valeurs respectant le filtre.