diff options
author | Thomas "Cakeisalie5" Touhey <thomas@touhey.fr> | 2018-08-30 11:52:30 +0200 |
---|---|---|
committer | Thomas "Cakeisalie5" Touhey <thomas@touhey.fr> | 2018-08-30 11:52:30 +0200 |
commit | 54e75699b06aa9d2e4f276239bf062ba46142055 (patch) | |
tree | 255385c664d97a61d12a4b4da8b6a70506a67041 /include/libtio/iter.h |
Compiles now.
Diffstat (limited to 'include/libtio/iter.h')
-rw-r--r-- | include/libtio/iter.h | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/include/libtio/iter.h b/include/libtio/iter.h new file mode 100644 index 0000000..7a4bdd5 --- /dev/null +++ b/include/libtio/iter.h @@ -0,0 +1,83 @@ +#ifndef LIBTIO_ITER_H +# define LIBTIO_ITER_H 20180710 +# include "cdefs.h" + +TIO_BEGIN_NAMESPACE + +/* A few things in libtio work using iterators. This is the centralized + * iterator interface. */ + +struct tio_iter; +typedef struct tio_iter tio_iter_t; +struct tio_iter_functions; +typedef struct tio_iter_functions tio_iter_functions_t; + +/* --- + * Define something. + * --- */ + +/* The way this is done: + * + * When `tio_next()` is called, if there was a previous element, + * the `tio_nextfree_t` callback, if not NULL, will be called to free + * it, then in all cases, the `tio_next_t` callback will be called to + * get the next element. If the `tio_next_t` callback returns + * `tio_error_iter`, all following calls to `tio_next()` with this + * iterator won't call the callbacks and directly return the same error. + * + * When `tio_end()` is called, the `tio_end_t` callback, if not NULL, + * will be called. */ + +typedef int TIO_EXPORT tio_next_t + OF((void *tio__cookie, void **tio__ptr)); +typedef void TIO_EXPORT tio_nextfree_t + OF((void *tio__cookie, void *tio__ptr)); +typedef void TIO_EXPORT tio_end_t + OF((void *tio__cookie)); + +struct tio_iter_functions { + tio_next_t *tio_iter_functions_next; + tio_nextfree_t *tio_iter_functions_nextfree; + tio_end_t *tio_iter_functions_end; +}; + +/* --- + * Functions. + * --- */ + +TIO_BEGIN_DECLS + +/* Start an iterator with `tio_iter_<whatever>(&iter, <other data>)`, + * with `iter` being of the `tio_iter_t *` type. + * Get the next element through `tio_next_<whatever>(iter, &ptr)`, + * which is usually a macro or function defined as + * `tio_next(iter, (void **)(PTRP))`. + * Then end the iterator using `tio_end(iter)`. + * + * Beware: any time you use `tio_next()` or `tio_end()`, the previous + * element might be free'd or re-used, so if you are interested in what is + * in it, copy the data before using one of the previous functions. */ + +TIO_EXTERN int TIO_EXPORT tio_iter + OF((tio_iter_t **tio__iterp, void *tio__cookie, + tio_iter_functions_t const *tio__funcs)); + +TIO_EXTERN int TIO_EXPORT tio_next + OF((tio_iter_t *tio__iter, void **tio__ptr)); + +TIO_EXTERN void TIO_EXPORT tio_end + OF((tio_iter_t *tio__iter)); + +/* You can make a “super iterator” that makes an iterator out of two + * iterators! It will empty the first one, then the second one. + * It will also take care of closing them. */ + +TIO_EXTERN int TIO_EXPORT tio_combine_iterators + OF((tio_iter_t **tio__iterp, + tio_iter_t *tio__first, + tio_iter_t *tio__second)); + +TIO_END_DECLS +TIO_END_NAMESPACE + +#endif /* LIBTIO_ITER_H */ |