P4C
The P4 Compiler
Loading...
Searching...
No Matches
backends/tofino/bf-asm/vector.h
1
17
18#ifndef BACKENDS_TOFINO_BF_ASM_VECTOR_H_
19#define BACKENDS_TOFINO_BF_ASM_VECTOR_H_
20
21/* C code and macros for VECTOR objects similar to C++ std::vector */
22#include <stddef.h>
23
24#define CAT(A, B) A##B
25#define VECTOR(NAME) CAT(NAME, _VECTOR)
26#define DECLARE_VECTOR(TYPE, ...) \
27 typedef struct CAT(TYPE, _VECTOR) { \
28 int capacity, size; \
29 TYPE *data; \
30 __VA_ARGS__ \
31 } CAT(TYPE, _VECTOR);
32#define DECLARE_VECTOR2(NAME, ELTYPE, ...) \
33 typedef struct CAT(NAME, _VECTOR) { \
34 int capacity, size; \
35 ELTYPE *data; \
36 __VA_ARGS__ \
37 } CAT(NAME, _VECTOR);
38
39#define RAW(X) X
40
41/* VECTOR constructors/destrutor
42 * can safely use memset(&vec, 0, sizeof(vec)) for initial capacity of 0,
43 * so global and calloc'd VECTORs are safe to use immediately
44 * local and malloc's VECTORs must be initialized before use, as they may
45 * contain garbage */
46
47/* VECTOR_init(vec, capacity)
48 * initialize an empty vector with optional initial capacity
49 * VECTOR_initcopy(vec, from)
50 * initialize a vector as a copy of an existing vector
51 * VECTOR_initN(vec, val1, ...)
52 * initialize a vector with N values
53 * RETURNS
54 * 0 success
55 * -1 failure (out of memory), vector has capacity 0
56 */
57#define VECTOR_init(vec, ...) init_raw_vector(&(vec), sizeof((vec).data[0]), RAW(__VA_ARGS__ + 0))
58
59#define VECTOR_initcopy(vec, from) \
60 (init_raw_vector(&(vec), sizeof((vec).data[0]), (from).size) \
61 ? -1 \
62 : (memcpy((vec).data, (from).data, ((vec).size = (from).size) * sizeof((vec).data[0])), \
63 0))
64
65#define VECTOR_init1(vec, v1) \
66 (init_raw_vector(&(vec), sizeof((vec).data[0]), 1) \
67 ? -1 \
68 : ((vec).size = 1, (vec).data[0] = (v1), 0))
69#define VECTOR_init2(vec, v1, v2) \
70 (init_raw_vector(&(vec), sizeof((vec).data[0]), 2) \
71 ? -1 \
72 : ((vec).size = 2, (vec).data[0] = (v1), (vec).data[1] = (v2), 0))
73#define VECTOR_init3(vec, v1, v2, v3) \
74 (init_raw_vector(&(vec), sizeof((vec).data[0]), 3) \
75 ? -1 \
76 : ((vec).size = 3, (vec).data[0] = (v1), (vec).data[1] = (v2), (vec).data[2] = (v3), 0))
77#define VECTOR_init4(vec, v1, v2, v3, v4) \
78 (init_raw_vector(&(vec), sizeof((vec).data[0]), 4) \
79 ? -1 \
80 : ((vec).size = 3, (vec).data[0] = (v1), (vec).data[1] = (v2), (vec).data[2] = (v3), \
81 (vec).data[3] = (v4), 0))
82#define VECTOR_init5(vec, v1, v2, v3, v4, v5) \
83 (init_raw_vector(&(vec), sizeof((vec).data[0]), 5) \
84 ? -1 \
85 : ((vec).size = 3, (vec).data[0] = (v1), (vec).data[1] = (v2), (vec).data[2] = (v3), \
86 (vec).data[3] = (v4), (vec).data[4] = (v5), 0))
87
88#define EMPTY_VECTOR_INIT {0, 0, 0}
89
90/* VECTOR_fini(vec)
91 * destroys a vector, freeing memory
92 * RETURNS
93 * void
94 */
95#define VECTOR_fini(vec) free((vec).data)
96
97/* VECTOR methods */
98
99/* VECTOR_add(vec, val)
100 * add a single value to the end of a vector, increasing its size (and
101 * capacity if necessary)
102 * VECTOR_addcopy(vec, ptr, n)
103 * add a multiple value to the end of a vector, increasing its size (and
104 * capacity as necessary)
105 * VECTOR_copy(vec, from)
106 * replace a vector with a copy of another vector
107 * RETURNS
108 * 0 success
109 * -1 failure (out of memory), vector is unchanged
110 */
111#define VECTOR_add(vec, val) \
112 (((vec).size == (vec).capacity && expand_raw_vector(&(vec), sizeof((vec).data[0]))) \
113 ? -1 \
114 : ((vec).data[(vec).size++] = (val), 0))
115#define VECTOR_addcopy(vec, ptr, n) \
116 (VECTOR_reserve(vec, (vec).size + (n)) \
117 ? -1 \
118 : (memcpy((vec).data + (vec).size, (ptr), (n) * sizeof((vec).data[0])), \
119 (vec).size += (n), 0))
120#define VECTOR_copy(vec, from) \
121 (VECTOR_reserve(vec, (from).size) \
122 ? -1 \
123 : (memcpy((vec).data, (from).data, (from).size * sizeof((vec).data[0])), \
124 (vec).size = (from).size, 0))
125
126#define VECTOR_begin(vec) ((vec).data)
127#define VECTOR_end(vec) ((vec).data + (vec).size)
128#define VECTOR_empty(vec) ((vec).size == 0)
129
130/* VECTOR_erase(vec, idx, cnt)
131 * erase cnt elements from a vector (defaults to 1). If there are fewer
132 * than cnt elements in the vector after idx (inclusive), all will be
133 * erased
134 * RETURNS
135 * 0 success
136 * -1 idx is out of range
137 */
138#define VECTOR_erase(vec, idx, ...) \
139 erase_raw_vector(&(vec), sizeof((vec).data[0]), idx, RAW(__VA_ARGS__ + 0))
140
141/* VECTOR_expand(vec)
142 * increase the capacity of a vector, if possible. Does not affect the size
143 * RETURNS
144 * 0 success
145 * -1 failure (out of memory), vector is unchanged
146 */
147#define VECTOR_expand(vec) expand_raw_vector(&(vec), sizeof((vec).data[0]))
148
149/* VECTOR_foreach(vec, apply)
150 * apply a function or macro to every element of a vector
151 * not a valid expression, so doesn't really return anything
152 */
153#define VECTOR_foreach(vec, apply) \
154 do { \
155 for (int i_ = 0; i_ < (vec).size; i_++) { \
156 apply((&(vec).data[i_])); \
157 } \
158 } while (0)
159
160/* VECTOR_insert(vec, idx, cnt)
161 * increase the size of a vector, adding uninitialized space at idx, and
162 * moving later elements of the vector up. cnt defaults to 1
163 * RETURNS
164 * 0 success
165 * -1 failure -- idx is out of range[ERANGE], or out of memeory[ENOMEM]
166 * vector is unchanged
167 */
168#define VECTOR_insert(vec, idx, ...) \
169 insert_raw_vector(&(vec), sizeof((vec).data[0]), idx, RAW(__VA_ARGS__ + 0))
170
171#define VECTOR_pop(vec) ((vec).data[--(vec).size])
172#define VECTOR_push(vec, val) VECTOR_add(vec, val)
173
174/* VECTOR_reserve(vec, size, shrink)
175 * change the capacity of a vector. If shrink is false (default), will only
176 * increase the capacity.
177 * RETURNS
178 * 0 success
179 * -1 failure (out of memory), vector is unchanged
180 */
181#define VECTOR_reserve(vec, size, ...) \
182 reserve_raw_vector(&(vec), sizeof((vec).data[0]), size, RAW(__VA_ARGS__ + 0))
183
184/* VECTOR_resize(vec, size, shrink)
185 * change the size of a vector. If shrink is false (default), will only
186 * increase the capacity.
187 * RETURNS
188 * 0 success
189 * -1 failure (out of memory), vector is unchanged
190 */
191#define VECTOR_resize(vec, sz, ...) \
192 (VECTOR_reserve(vec, sz, __VA_ARGS__) ? -1 : ((vec).size = (sz), 0))
193
194/* VECTOR_shrink_to_fit(vec)
195 * reduce capacity to match the size, releasing memory if possible
196 * RETURNS
197 * 0 success
198 * -1 failure (realloc failed to shrink?), vector is unchanged
199 */
200#define VECTOR_shrink_to_fit(vec) shrink_raw_vector(&(vec), sizeof((vec).data[0]))
201
202/* VECTOR_terminate(vec, val)
203 * ensure that capacity is greater than size, and store val after
204 * the end of the vector.
205 * RETURNS
206 * 0 success
207 * -1 failure (out of memory), vector is unchanged
208 */
209#define VECTOR_terminate(vec, val) \
210 (((vec).size == (vec).capacity && expand_raw_vector(&(vec), sizeof((vec).data[0]))) \
211 ? -1 \
212 : ((vec).data[(vec).size] = (val), 0))
213#define VECTOR_top(vec) ((vec).data[(vec).size - 1])
214
215#ifdef __cplusplus
216extern "C" {
217#endif
218extern int erase_raw_vector(void *vec, size_t elsize, int idx, unsigned cnt);
219extern int expand_raw_vector(void *vec, size_t elsize);
220extern int init_raw_vector(void *vec, size_t elsize, int mincap);
221extern int insert_raw_vector(void *vec, size_t elsize, int idx, unsigned cnt);
222extern int reserve_raw_vector(void *vec, size_t elsize, int size, int shrink);
223extern int shrink_raw_vector(void *vec, size_t elsize);
224#ifdef __cplusplus
225}
226#endif
227
228#endif /* BACKENDS_TOFINO_BF_ASM_VECTOR_H_ */