1 | #ifndef GENERATOR_H
|
2 | #define GENERATOR_H
|
3 |
|
4 | #include <stddef.h>
|
5 | #include <stdbool.h>
|
6 | #include <sys/types.h>
|
7 |
|
8 | #define UNPACK(...) __VA_ARGS__
|
9 |
|
10 | #define DECLARE_GENERATOR(NAME, INPUT, YIELDS) \
|
11 | struct gen_result_ ## NAME { \
|
12 | UNPACK YIELDS \
|
13 | }; \
|
14 | struct gen_args_ ## NAME { \
|
15 | UNPACK INPUT \
|
16 | }; \
|
17 | int gen_func_ ## NAME(void* private, int(*const yield)(void* private, struct gen_result_ ## NAME*), const struct gen_args_ ## NAME*const args);
|
18 |
|
19 | #define DEFINE_GENERATOR(NAME, INPUT, YIELDS, BODY) \
|
20 | int gen_func_ ## NAME(void* private, int(*const yield)(void* private, struct gen_result_ ## NAME*), const struct gen_args_ ## NAME*const args){ \
|
21 | typedef struct gen_result_ ## NAME gen_result_type; \
|
22 | UNPACK BODY \
|
23 | }
|
24 |
|
25 | #define GENERATOR_YIELD(...) do { if(yield(private, &(gen_result_type){__VA_ARGS__})) return -1; } while(0)
|
26 |
|
27 | #define GENERATOR_TO_GENERIC(NAME) ((generic_generator_callback)(gen_func_ ## NAME))
|
28 | #define GENERATOR_COUNT(NAME, ARGS) generator_count(GENERATOR_TO_GENERIC(NAME), &(struct gen_args_ ## NAME){ UNPACK ARGS })
|
29 | #define GENERATOR_CALL(PRIVATE, NAME, ARGS) gen_func_ ## NAME((PRIVATE), GENERATOR_TO_GENERIC(NAME), &(struct gen_args_ ## NAME){ UNPACK ARGS })
|
30 | #define GENERATOR_TO_ARRAY(NAME, ARGS, N, RES, REVERSE) generator_to_array(GENERATOR_TO_GENERIC(NAME), &(struct gen_args_ ## NAME){ UNPACK ARGS }, sizeof(struct gen_result_ ## NAME), (N), (void**)(struct gen_result_ ## NAME**){(RES)}, (REVERSE))
|
31 |
|
32 | typedef int(*generic_generator_callback)(void* private, int(*const yield)(void*, void*), const void*const args);
|
33 |
|
34 | int generator_count( const generic_generator_callback generator, const void*const args );
|
35 | int generator_to_array( const generic_generator_callback generator, const void*const args, size_t result_size, size_t* n, void** result, bool reverse);
|
36 |
|
37 | #endif
|