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
|
/* Copyright © Charliecloud contributors.
Facilities for typed, heap or stack arrays terminated by an all-zeroes
element. These are convenient to use because they are normal arrays and
compatible with lots of APIs. They also eliminate the need for a wrapper
struct that remembers anything, e.g. number and/or size of elements, and
generic containers are very hard in C. Disadvantages do include
(1) all-zero elements cannot be stored, (2) aggressive typecasting is often
needed, (3) the size of elements must be separately managed.
Use these lists in Charliecloud unless there is a good justification
otherwise. (Note that performance is unlikely to be an issue at the lengths
we have.)
Iteration example:
struct foo { int a; float b; };
struct foo *bar = ...;
for (int i = 0; bar[i].a != 0; i++)
do_stuff(bar[i]);
Note the conditional checks only one field of the struct (`a`) for zero;
this loop leverages knowledge of this specific data structure that checking
only `a` is sufficient.
Setting on stack via literal:
struct foo bar[] = { {1, 2.0}, {3, 4.0}, {0, 0.0} };
Heap creation via functions in this interface:
struct foo baz;
struct foo *qux = list_new(sizeof(struct foo), 0);
baz.a = 1;
baz.b = 2.0;
list_append((void **)&qux, &baz, sizeof(struct foo));
list_append((void **)&qux, &((struct foo){3, 4.0}), sizeof(struct foo));
These two examples create an equivalent list. Note also the C99 trick to
avoid creating `struct foo` variable for the second append. */
#define _GNU_SOURCE
#pragma once
#include <stddef.h>
/** Function prototypes **/
void list_append(void **ar, void *new, size_t size);
void list_cat(void **dst, void *src, size_t size);
void *list_copy(void *src, size_t size);
size_t list_count(void *ar, size_t size);
void list_dedup_strings(char **ar);
void *list_new_strings(char delim, const char *s);
void *list_new(size_t ct, size_t size);
char *list_stringify(void *list, char delim);
|