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/lib/iter/super.c

97 lines
2.5 KiB
C

/* ****************************************************************************
* iter/super.c -- super-iterator, for super-iterating.
* Copyright (C) 2018 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/>.
* ************************************************************************* */
#include "../internals.h"
typedef struct {
int i, len;
casio_iter_t *its[2];
} supercookie_t;
/* `next_super()`: next element from the super iterator. */
CASIO_LOCAL int next_super(supercookie_t *cookie, void **ptr)
{
int err;
if (cookie->i == cookie->len)
return (casio_error_iter);
while (cookie->i < cookie->len - 1) {
if ((err = casio_next(cookie->its[cookie->i], ptr))
!= casio_error_iter)
return (err);
casio_end(cookie->its[cookie->i++]);
}
if ((err = casio_next(cookie->its[cookie->i], ptr)) != casio_error_iter)
return (err);
casio_end(cookie->its[cookie->i++]);
return (casio_error_iter);
}
/* `end_super()`: end the super-iterator. */
CASIO_LOCAL void end_super(supercookie_t *cookie)
{
int i;
for (i = cookie->i; i < cookie->len; i++)
casio_end(cookie->its[i]);
free(cookie);
}
/* Callbacks. */
CASIO_LOCAL casio_iter_funcs_t const super_funcs = {
(casio_next_t *)next_super,
NULL,
(casio_end_t *)end_super
};
/**
* casio_combine_iterator:
* Make a super iterator.
*
* @arg iterp the super-iterator to create.
* @arg first the first iterator to put into the super-iterator.
* @arg second the second one.
* @return the error code (0 if ok).
*/
int CASIO_EXPORT casio_combine_iterators(casio_iter_t **iterp,
casio_iter_t *first, casio_iter_t *second)
{
supercookie_t *cookie;
if (!(cookie = malloc(sizeof(supercookie_t)))) {
casio_end(first);
casio_end(second);
return (casio_error_alloc);
}
cookie->len = 2;
cookie->i = 0;
cookie->its[0] = first;
cookie->its[1] = second;
return (casio_iter(iterp, cookie, &super_funcs));
}