generator.h


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