Created
June 26, 2024 19:25
-
-
Save qexat/a97863c12333967a9f944deb5e12da69 to your computer and use it in GitHub Desktop.
basic generic iterators in C
This file contains 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> | |
#include <stdlib.h> | |
#define ITERATOR_IMPL(T, state_t) \ | |
struct \ | |
{ \ | |
T (*__next__)(state_t *); \ | |
} | |
#define ITERATOR_STATE(T) \ | |
struct iterator_state_##T \ | |
{ \ | |
bool finished; \ | |
T data; \ | |
} | |
#define ITERATOR(T) \ | |
struct iterator_##T \ | |
{ \ | |
ITERATOR_STATE(T) state; \ | |
ITERATOR_IMPL(T, ITERATOR_STATE(T)) impl; \ | |
} | |
#define ITERATOR_NEW(T, init, next) \ | |
{ \ | |
(ITERATOR_STATE(T)){ \ | |
false, \ | |
(init), \ | |
}, \ | |
{ \ | |
(next) \ | |
} \ | |
} | |
#define NEXT(iterator) \ | |
({ \ | |
if ((iterator).state.finished) \ | |
{ \ | |
fprintf(stderr, "Error: iterator is finished\n"); \ | |
exit(1); \ | |
} \ | |
(iterator).impl.__next__(&(iterator).state); \ | |
}) | |
#define STOP_ITERATION(iterator) (iterator).state.finished | |
#define YIELD(value) return (value) | |
#define ITERATOR_RETURN(state_p) (state_p)->finished = true | |
int foo(ITERATOR_STATE(int) * state) | |
{ | |
if (state->finished) | |
{ | |
return -1; | |
} | |
int value = state->data; | |
state->data++; | |
if (state->data > 9) | |
{ | |
ITERATOR_RETURN(state); | |
} | |
YIELD(value); | |
} | |
int main() | |
{ | |
ITERATOR(int) x = ITERATOR_NEW(int, 0, foo); | |
while (!STOP_ITERATION(x)) | |
{ | |
printf("%d\n", NEXT(x)); | |
} | |
return EXIT_SUCCESS; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment