cake
/
libcasio
Archived
1
1
Fork 0
This repository has been archived on 2024-03-16. You can view files and clone it, but cannot push or open issues or pull requests.
libcasio/include/libcasio/iter.h

100 lines
3.4 KiB
C

/* ****************************************************************************
* libcasio/iter.h -- libcasio iterators.
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
*
* This file is part of libcasio.
* libcasio is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3.0 of the License,
* or (at your option) any later version.
*
* libcasio is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libcasio; if not, see <http://www.gnu.org/licenses/>.
* ************************************************************************* */
#ifndef LIBCASIO_ITER_H
# define LIBCASIO_ITER_H 2018050901
# include "cdefs.h"
CASIO_BEGIN_NAMESPACE
/* Many things in libcasio work with iterators. This is the centralized
* iterator interface. */
struct casio_iter_s;
typedef struct casio_iter_s casio_iter_t;
/* ---
* Define something.
* --- */
/* The way this is done:
*
* When `casio_next()` is called, if there was a previous element,
* the `casio_nextfree_t` callback, if not NULL, will be called to free
* it, then in all cases, the `casio_next_t` callback will be called to
* get the next element. If the `casio_next_t` callback returns
* `casio_error_iter`, all following calls to `casio_next()` with this
* iterator won't call the callbacks and directly return the same error.
*
* When `casio_end()` is called, the `casio_end_t` callback, if not NULL,
* will be called. */
typedef int CASIO_EXPORT casio_next_t
OF((void *casio__cookie, void **casio__ptr));
typedef void CASIO_EXPORT casio_nextfree_t
OF((void *casio__cookie, void *casio__ptr));
typedef void CASIO_EXPORT casio_end_t
OF((void *casio__cookie));
typedef struct casio_iter_funcs_s {
casio_next_t *casio_iterfunc_next;
casio_nextfree_t *casio_iterfunc_nextfree;
casio_end_t *casio_iterfunc_end;
} casio_iter_funcs_t;
/* ---
* Functions.
* --- */
CASIO_BEGIN_DECLS
/* Start an iterator with `casio_iter_<whatever>(&iter, <other data>)`,
* with `iter` being of the `casio_iter_t *` type.
* Get the next element through `casio_next_<whatever>(iter, &ptr)`,
* which is usually a macro or function defined as
* `casio_next(iter, (void **)(PTRP))`.
* Then end the iterator using `casio_end(iter)`.
*
* Beware: any time you use `casio_next()` or `casio_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. */
CASIO_EXTERN int CASIO_EXPORT casio_iter
OF((casio_iter_t **casio__iterp, void *casio__cookie,
casio_iter_funcs_t const *casio__funcs));
CASIO_EXTERN int CASIO_EXPORT casio_next
OF((casio_iter_t *casio__iter, void **casio__ptr));
CASIO_EXTERN void CASIO_EXPORT casio_end
OF((casio_iter_t *casio__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. */
CASIO_EXTERN int CASIO_EXPORT casio_combine_iterators
OF((casio_iter_t **casio__iterp,
casio_iter_t *casio__first,
casio_iter_t *casio__second));
CASIO_END_DECLS
CASIO_END_NAMESPACE
#endif