libpulsar
A modular compiler for the pulsar programming language
Loading...
Searching...
No Matches
dynarr.h
Go to the documentation of this file.
1
8#pragma once
9
10#include <stdlib.h>
11
12#include "def.h"
13#include "capture.h"
14#include "abort.h"
15
16#ifndef PS_DYNARR_INITIAL_CAP
17 #define PS_DYNARR_INITIAL_CAP 4
18#endif
19
20#ifndef PS_DYNARR_GROWTH_FACTOR
21 #define PS_DYNARR_GROWTH_FACTOR 2
22#endif
23
24#define _ps_dynarr_ptr(arr) ((char*)arr + sizeof((arr)->header))
25#define _ps_dynarr_size(arr, cap) \
26 sizeof(*arr) + (cap) * sizeof(*(arr)->contents)
27
28#define ps_dynarr(T) \
29 { \
30 usize length; \
31 usize capacity; \
32 T contents[]; \
33 }
34
35#define ps_dynarr_new(T) \
36 ({ \
37 T* arr = malloc(_ps_dynarr_size(arr, PS_DYNARR_INITIAL_CAP)); \
38 if (!arr) PS_NO_MEMORY(); \
39 if (arr) { \
40 arr->length = 0; \
41 arr->capacity = PS_DYNARR_INITIAL_CAP; \
42 } \
43 arr; \
44 })
45
46#define ps_push(__arrptr, __new_elem) \
47 ps_add( \
48 __arrptr, $(__elem) in { *(__elem) = (__new_elem); })
49
50#define ps_add(__arrptr, __capture) \
51 do { \
52 auto_t __arr = *(__arrptr); \
53 if (__arr->length + 1 > __arr->capacity) { \
54 __arr->capacity *= PS_DYNARR_GROWTH_FACTOR; \
55 __arr = realloc(__arr, _ps_dynarr_size(__arr, __arr->capacity)); \
56 } \
57 if (__arr) { \
58 $run(__capture, &__arr->contents[__arr->length++]); \
59 } else { \
60 PS_NO_MEMORY(); \
61 } \
62 *(__arrptr) = __arr; \
63 } while (0)
64
65#define ps_dynarr_free(__arr) free(__arr)
66
67#define $arr(__arr) ((__arr)->contents)
68
69#define $for(__arr, __capture) \
70 do { \
71 for (usize i = 0; i < (__arr)->length; i++) { \
72 $run(__capture, ($arr(__arr)[i])); \
73 } \
74 } while (0)
Defines assertion and abortion functionality.
Syntactic sugar for capture blocks.
Base definitions.