aboutsummaryrefslogtreecommitdiff
path: root/include/libtio/iter.h
diff options
context:
space:
mode:
authorThomas "Cakeisalie5" Touhey <thomas@touhey.fr>2018-08-30 11:52:30 +0200
committerThomas "Cakeisalie5" Touhey <thomas@touhey.fr>2018-08-30 11:52:30 +0200
commit54e75699b06aa9d2e4f276239bf062ba46142055 (patch)
tree255385c664d97a61d12a4b4da8b6a70506a67041 /include/libtio/iter.h
Compiles now.
Diffstat (limited to 'include/libtio/iter.h')
-rw-r--r--include/libtio/iter.h83
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 */