Last active
October 1, 2021 00:58
-
-
Save louisswarren/0a007b0825ee4f5b94e524e70d5ea7c9 to your computer and use it in GitHub Desktop.
Generators in C
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#define FIRST(N, ...) (N) | |
#define foreach(X, F, ...) \ | |
for (init_##F(__VA_ARGS__), X = F(FIRST(__VA_ARGS__));\ | |
FIRST(__VA_ARGS__)->_running;\ | |
X = F(FIRST(__VA_ARGS__))) | |
struct count_state { | |
int _running; | |
int n; | |
}; | |
void | |
init_count(struct count_state *g, int start) | |
{ | |
g->_running = 1; | |
g->n = start; | |
} | |
int | |
count(struct count_state *g) | |
{ | |
return g->n++; | |
} | |
struct range_state { | |
int _running; | |
int n; | |
int start; | |
int end; | |
int step; | |
}; | |
void | |
init_range(struct range_state *g, int start, int end, int step) | |
{ | |
g->_running = g->n < g->end; | |
g->start = start; | |
g->end = end; | |
g->step = step; | |
g->n = start; | |
} | |
struct list_iter_state { | |
int _running; | |
int *p; | |
size_t n; | |
}; | |
int | |
range(struct range_state *g) | |
{ | |
int r = g->n; | |
g->_running = g->n < g->end; | |
g->n += g->step; | |
return r; | |
} | |
void | |
init_list_iter(struct list_iter_state *g, int *p, size_t n) | |
{ | |
g->_running = g->n > 0; | |
g->p = p; | |
g->n = n; | |
} | |
int | |
list_iter(struct list_iter_state *g) | |
{ | |
g->_running = g->n > 0; | |
g->n--; | |
return *(g->p++); | |
} | |
int | |
main(void) | |
{ | |
struct range_state g; | |
int x; | |
foreach (x, range, &g, 1, 10, 3) { | |
printf("%d\n", x); | |
} | |
printf("\n"); | |
struct list_iter_state h; | |
int xs[] = {2, 3, 5, 7, 11}; | |
foreach (x, list_iter, &h, xs, sizeof(xs)/sizeof(xs[0])) { | |
printf("%d\n", x); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment