This source file includes following definitions.
- DYNARRAY_NAME
- __attribute_nonnull__
- __attribute_nonnull__
- __attribute_nonnull__
- __attribute_nonnull__
- __attribute_nonnull__
- __attribute_nonnull__
- __attribute_nonnull__
- __attribute_nonnull__
- __attribute_nonnull__
- DYNARRAY_NAME
- DYNARRAY_NAME
- __attribute_nonnull__
- __attribute_nonnull__
- __attribute_nonnull__
- __attribute_nonnull__
- __attribute_nonnull__
- __attribute_nonnull__
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88 #include <malloc/dynarray.h>
89
90 #include <errno.h>
91 #include <stdlib.h>
92 #include <string.h>
93
94 #ifndef DYNARRAY_STRUCT
95 # error "DYNARRAY_STRUCT must be defined"
96 #endif
97
98 #ifndef DYNARRAY_ELEMENT
99 # error "DYNARRAY_ELEMENT must be defined"
100 #endif
101
102 #ifndef DYNARRAY_PREFIX
103 # error "DYNARRAY_PREFIX must be defined"
104 #endif
105
106 #ifdef DYNARRAY_INITIAL_SIZE
107 # if DYNARRAY_INITIAL_SIZE < 0
108 # error "DYNARRAY_INITIAL_SIZE must be non-negative"
109 # endif
110 # if DYNARRAY_INITIAL_SIZE > 0
111 # define DYNARRAY_HAVE_SCRATCH 1
112 # else
113 # define DYNARRAY_HAVE_SCRATCH 0
114 # endif
115 #else
116
117
118 # define DYNARRAY_INITIAL_SIZE \
119 (sizeof (DYNARRAY_ELEMENT) > 64 ? 2 : 128 / sizeof (DYNARRAY_ELEMENT))
120 # define DYNARRAY_HAVE_SCRATCH 1
121 #endif
122
123
124
125
126 struct DYNARRAY_STRUCT
127 {
128 union
129 {
130 struct dynarray_header dynarray_abstract;
131 struct
132 {
133
134 size_t used;
135 size_t allocated;
136 DYNARRAY_ELEMENT *array;
137 } dynarray_header;
138 } u;
139
140 #if DYNARRAY_HAVE_SCRATCH
141
142 DYNARRAY_ELEMENT scratch[DYNARRAY_INITIAL_SIZE];
143 #endif
144 };
145
146
147
148
149 #define DYNARRAY_CONCAT0(prefix, name) prefix##name
150 #define DYNARRAY_CONCAT1(prefix, name) DYNARRAY_CONCAT0(prefix, name)
151 #define DYNARRAY_NAME(name) DYNARRAY_CONCAT1(DYNARRAY_PREFIX, name)
152
153
154
155 #define DYNARRAY_FREE DYNARRAY_CONCAT1 (DYNARRAY_NAME (f), ree)
156
157
158 #if DYNARRAY_HAVE_SCRATCH
159 # define DYNARRAY_SCRATCH(list) (list)->scratch
160 #else
161 # define DYNARRAY_SCRATCH(list) NULL
162 #endif
163
164
165
166
167
168
169 static inline void
170 DYNARRAY_NAME (free__elements__) (DYNARRAY_ELEMENT *__dynarray_array,
171 size_t __dynarray_used)
172 {
173 #ifdef DYNARRAY_ELEMENT_FREE
174 for (size_t __dynarray_i = 0; __dynarray_i < __dynarray_used; ++__dynarray_i)
175 DYNARRAY_ELEMENT_FREE (&__dynarray_array[__dynarray_i]);
176 #endif
177 }
178
179
180 static inline void
181 DYNARRAY_NAME (free__array__) (struct DYNARRAY_STRUCT *list)
182 {
183 #if DYNARRAY_HAVE_SCRATCH
184 if (list->u.dynarray_header.array != list->scratch)
185 free (list->u.dynarray_header.array);
186 #else
187 free (list->u.dynarray_header.array);
188 #endif
189 }
190
191
192
193
194
195 __attribute_nonnull__ ((1))
196 static void
197 DYNARRAY_NAME (init) (struct DYNARRAY_STRUCT *list)
198 {
199 list->u.dynarray_header.used = 0;
200 list->u.dynarray_header.allocated = DYNARRAY_INITIAL_SIZE;
201 list->u.dynarray_header.array = DYNARRAY_SCRATCH (list);
202 }
203
204
205 __attribute_maybe_unused__ __attribute_nonnull__ ((1))
206 static void
207 DYNARRAY_FREE (struct DYNARRAY_STRUCT *list)
208 {
209 DYNARRAY_NAME (free__elements__)
210 (list->u.dynarray_header.array, list->u.dynarray_header.used);
211 DYNARRAY_NAME (free__array__) (list);
212 DYNARRAY_NAME (init) (list);
213 }
214
215
216 __attribute_nonnull__ ((1))
217 static inline bool
218 DYNARRAY_NAME (has_failed) (const struct DYNARRAY_STRUCT *list)
219 {
220 return list->u.dynarray_header.allocated == __dynarray_error_marker ();
221 }
222
223
224
225 __attribute_nonnull__ ((1))
226 static void
227 DYNARRAY_NAME (mark_failed) (struct DYNARRAY_STRUCT *list)
228 {
229 DYNARRAY_NAME (free__elements__)
230 (list->u.dynarray_header.array, list->u.dynarray_header.used);
231 DYNARRAY_NAME (free__array__) (list);
232 list->u.dynarray_header.array = DYNARRAY_SCRATCH (list);
233 list->u.dynarray_header.used = 0;
234 list->u.dynarray_header.allocated = __dynarray_error_marker ();
235 }
236
237
238
239 __attribute_nonnull__ ((1))
240 static inline size_t
241 DYNARRAY_NAME (size) (const struct DYNARRAY_STRUCT *list)
242 {
243 return list->u.dynarray_header.used;
244 }
245
246
247
248 __attribute_nonnull__ ((1))
249 static inline DYNARRAY_ELEMENT *
250 DYNARRAY_NAME (at) (struct DYNARRAY_STRUCT *list, size_t index)
251 {
252 if (__glibc_unlikely (index >= DYNARRAY_NAME (size) (list)))
253 __libc_dynarray_at_failure (DYNARRAY_NAME (size) (list), index);
254 return list->u.dynarray_header.array + index;
255 }
256
257
258
259
260 __attribute_nonnull__ ((1))
261 static inline DYNARRAY_ELEMENT *
262 DYNARRAY_NAME (begin) (struct DYNARRAY_STRUCT *list)
263 {
264 return list->u.dynarray_header.array;
265 }
266
267
268
269
270 __attribute_nonnull__ ((1))
271 static inline DYNARRAY_ELEMENT *
272 DYNARRAY_NAME (end) (struct DYNARRAY_STRUCT *list)
273 {
274 return list->u.dynarray_header.array + list->u.dynarray_header.used;
275 }
276
277
278 static void
279 DYNARRAY_NAME (add__) (struct DYNARRAY_STRUCT *list, DYNARRAY_ELEMENT item)
280 {
281 if (__glibc_unlikely
282 (!__libc_dynarray_emplace_enlarge (&list->u.dynarray_abstract,
283 DYNARRAY_SCRATCH (list),
284 sizeof (DYNARRAY_ELEMENT))))
285 {
286 DYNARRAY_NAME (mark_failed) (list);
287 return;
288 }
289
290
291 list->u.dynarray_header.array[list->u.dynarray_header.used++] = item;
292 }
293
294
295
296
297 __attribute_nonnull__ ((1))
298 static inline void
299 DYNARRAY_NAME (add) (struct DYNARRAY_STRUCT *list, DYNARRAY_ELEMENT item)
300 {
301
302 if (DYNARRAY_NAME (has_failed) (list))
303 return;
304
305
306 if (__glibc_unlikely (list->u.dynarray_header.used
307 == list->u.dynarray_header.allocated))
308 {
309 DYNARRAY_NAME (add__) (list, item);
310 return;
311 }
312
313
314 list->u.dynarray_header.array[list->u.dynarray_header.used++] = item;
315 }
316
317
318
319 static inline DYNARRAY_ELEMENT *
320 DYNARRAY_NAME (emplace__tail__) (struct DYNARRAY_STRUCT *list)
321 {
322 DYNARRAY_ELEMENT *result
323 = &list->u.dynarray_header.array[list->u.dynarray_header.used];
324 ++list->u.dynarray_header.used;
325 #if defined (DYNARRAY_ELEMENT_INIT)
326 DYNARRAY_ELEMENT_INIT (result);
327 #elif defined (DYNARRAY_ELEMENT_FREE)
328 memset (result, 0, sizeof (*result));
329 #endif
330 return result;
331 }
332
333
334 static DYNARRAY_ELEMENT *
335 DYNARRAY_NAME (emplace__) (struct DYNARRAY_STRUCT *list)
336 {
337 if (__glibc_unlikely
338 (!__libc_dynarray_emplace_enlarge (&list->u.dynarray_abstract,
339 DYNARRAY_SCRATCH (list),
340 sizeof (DYNARRAY_ELEMENT))))
341 {
342 DYNARRAY_NAME (mark_failed) (list);
343 return NULL;
344 }
345 return DYNARRAY_NAME (emplace__tail__) (list);
346 }
347
348
349
350
351 __attribute_maybe_unused__ __attribute_warn_unused_result__
352 __attribute_nonnull__ ((1))
353 static
354
355 #if !(defined (DYNARRAY_ELEMENT_INIT) || defined (DYNARRAY_ELEMENT_FREE))
356 inline
357 #endif
358 DYNARRAY_ELEMENT *
359 DYNARRAY_NAME (emplace) (struct DYNARRAY_STRUCT *list)
360 {
361
362 if (DYNARRAY_NAME (has_failed) (list))
363 return NULL;
364
365
366 if (__glibc_unlikely (list->u.dynarray_header.used
367 == list->u.dynarray_header.allocated))
368 return (DYNARRAY_NAME (emplace__) (list));
369 return DYNARRAY_NAME (emplace__tail__) (list);
370 }
371
372
373
374
375
376 __attribute_maybe_unused__ __attribute_nonnull__ ((1))
377 static bool
378 DYNARRAY_NAME (resize) (struct DYNARRAY_STRUCT *list, size_t size)
379 {
380 if (size > list->u.dynarray_header.used)
381 {
382 bool ok;
383 #if defined (DYNARRAY_ELEMENT_INIT)
384
385 size_t old_size = list->u.dynarray_header.used;
386 ok = __libc_dynarray_resize (&list->u.dynarray_abstract,
387 size, DYNARRAY_SCRATCH (list),
388 sizeof (DYNARRAY_ELEMENT));
389 if (ok)
390 for (size_t i = old_size; i < size; ++i)
391 {
392 DYNARRAY_ELEMENT_INIT (&list->u.dynarray_header.array[i]);
393 }
394 #elif defined (DYNARRAY_ELEMENT_FREE)
395
396
397 ok = __libc_dynarray_resize_clear
398 (&list->u.dynarray_abstract, size,
399 DYNARRAY_SCRATCH (list), sizeof (DYNARRAY_ELEMENT));
400 #else
401 ok = __libc_dynarray_resize (&list->u.dynarray_abstract,
402 size, DYNARRAY_SCRATCH (list),
403 sizeof (DYNARRAY_ELEMENT));
404 #endif
405 if (__glibc_unlikely (!ok))
406 DYNARRAY_NAME (mark_failed) (list);
407 return ok;
408 }
409 else
410 {
411
412 DYNARRAY_NAME (free__elements__)
413 (list->u.dynarray_header.array + size,
414 list->u.dynarray_header.used - size);
415 list->u.dynarray_header.used = size;
416 return true;
417 }
418 }
419
420
421 __attribute_maybe_unused__ __attribute_nonnull__ ((1))
422 static void
423 DYNARRAY_NAME (remove_last) (struct DYNARRAY_STRUCT *list)
424 {
425
426 if (list->u.dynarray_header.used > 0)
427 {
428 size_t new_length = list->u.dynarray_header.used - 1;
429 #ifdef DYNARRAY_ELEMENT_FREE
430 DYNARRAY_ELEMENT_FREE (&list->u.dynarray_header.array[new_length]);
431 #endif
432 list->u.dynarray_header.used = new_length;
433 }
434 }
435
436
437
438 __attribute_maybe_unused__ __attribute_nonnull__ ((1))
439 static void
440 DYNARRAY_NAME (clear) (struct DYNARRAY_STRUCT *list)
441 {
442
443
444 DYNARRAY_NAME (free__elements__)
445 (list->u.dynarray_header.array, list->u.dynarray_header.used);
446 list->u.dynarray_header.used = 0;
447 }
448
449 #ifdef DYNARRAY_FINAL_TYPE
450
451
452
453
454
455
456 __attribute_maybe_unused__ __attribute_warn_unused_result__
457 __attribute_nonnull__ ((1, 2))
458 static bool
459 DYNARRAY_NAME (finalize) (struct DYNARRAY_STRUCT *list,
460 DYNARRAY_FINAL_TYPE *result)
461 {
462 struct dynarray_finalize_result res;
463 if (__libc_dynarray_finalize (&list->u.dynarray_abstract,
464 DYNARRAY_SCRATCH (list),
465 sizeof (DYNARRAY_ELEMENT), &res))
466 {
467
468 DYNARRAY_NAME (init) (list);
469 *result = (DYNARRAY_FINAL_TYPE) { res.array, res.length };
470 return true;
471 }
472 else
473 {
474
475 DYNARRAY_FREE (list);
476 errno = ENOMEM;
477 return false;
478 }
479 }
480 #else
481
482
483
484
485
486
487
488 __attribute_maybe_unused__ __attribute_warn_unused_result__
489 __attribute_nonnull__ ((1))
490 static DYNARRAY_ELEMENT *
491 DYNARRAY_NAME (finalize) (struct DYNARRAY_STRUCT *list, size_t *lengthp)
492 {
493 struct dynarray_finalize_result res;
494 if (__libc_dynarray_finalize (&list->u.dynarray_abstract,
495 DYNARRAY_SCRATCH (list),
496 sizeof (DYNARRAY_ELEMENT), &res))
497 {
498
499 DYNARRAY_NAME (init) (list);
500 if (lengthp != NULL)
501 *lengthp = res.length;
502 return res.array;
503 }
504 else
505 {
506
507 DYNARRAY_FREE (list);
508 errno = ENOMEM;
509 return NULL;
510 }
511 }
512 #endif
513
514
515
516 #undef DYNARRAY_CONCAT0
517 #undef DYNARRAY_CONCAT1
518 #undef DYNARRAY_NAME
519 #undef DYNARRAY_SCRATCH
520 #undef DYNARRAY_HAVE_SCRATCH
521
522 #undef DYNARRAY_STRUCT
523 #undef DYNARRAY_ELEMENT
524 #undef DYNARRAY_PREFIX
525 #undef DYNARRAY_ELEMENT_FREE
526 #undef DYNARRAY_ELEMENT_INIT
527 #undef DYNARRAY_INITIAL_SIZE
528 #undef DYNARRAY_FINAL_TYPE