Mercurial > code
diff parray.h @ 62:d10ab6bc555d
HG self failure
author | David Demelier <markand@malikania.fr> |
---|---|
date | Wed, 09 Nov 2011 19:26:09 +0100 |
parents | |
children | f773c76b1f3c |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/parray.h Wed Nov 09 19:26:09 2011 +0100 @@ -0,0 +1,94 @@ +/* + * array.h -- manipulate dynamic pointer arrays + * + * Copyright (c) 2011, David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _PARRAY_H_ +#define _PARRAY_H_ + +/* Add some nonnull attributes for gcc/clang */ +#ifdef __GNUC__ +# define __at_malloc __attribute__ ((malloc)) +# define __at_nonnull(...) __attribute__ ((nonnull (__VA_ARGS__))) +#else +# define __at_malloc +# define __at_nonnull(...) +#endif + +#define PARRAY_DEFAULT_BSIZE 128 + +enum parray_type { + PARRAY_FIXED = 0, + PARRAY_AUTO = 1 +}; + +struct parray { + enum parray_type type; /* array type (default FIXED) */ + void **datas; /* array of data */ + int length; /* number of element inside */ + size_t size; /* current buffer size (allocated memory) */ + int bsize; /* block size (used when growing array) */ + int i; /* only for PARRAY_FOREACH(_R) */ +}; + +typedef void (*parray_map_fn)(void *, void *); +typedef int (*parray_cmp_fn)(void *, void *); + +struct parray *parray_new(enum parray_type, int) __at_malloc; +int parray_push(struct parray *, void *) __at_nonnull(1); +int parray_insert(struct parray *, void *, int) __at_nonnull(1); +int parray_append(struct parray *, void *) __at_nonnull(1); +void parray_pop(struct parray *) __at_nonnull(1); +void parray_unqueue(struct parray *) __at_nonnull(1); +void parray_remove(struct parray *, int) __at_nonnull(1); +void parray_unref(struct parray *, const void *) __at_nonnull(1); +int parray_iswap(struct parray *, int, int) __at_nonnull(1); +int parray_pswap(struct parray *, const void *, const void *) __at_nonnull(1); +void parray_map(const struct parray *, parray_map_fn, void *) __at_nonnull(1, 2); +void *parray_find(const struct parray *, parray_cmp_fn, int *, void *) __at_nonnull(1, 2); +void parray_clear(struct parray *) __at_nonnull(1); +void parray_free(struct parray *) __at_nonnull(1); + +#define PARRAY_HEAD(a) \ + (a->datas[0]) +#define PARRAY_TAIL(a) \ + (a->datas[(a->length == 0) ? 0 : a->length - 1]) +#define PARRAY_INDEX(a, i) \ + (((i) < 0 || (a)->length == 0) ? (PARRAY_HEAD((a))) /* < 0 head */ \ + : ((i) >= (a)->length) ? (PARRAY_TAIL((a))) /* > l tail */ \ + : ((a)->datas[i])) /* correct */ + +#define PARRAY_FOREACH_R(a, var) \ + for ((a)->i = 0, var = PARRAY_TAIL((a)); \ + (a)->i < (a)->length; ++(a)->i, var = PARRAY_INDEX((a), (a)->i)) + +#define PARRAY_FOREACH(a, var) \ + for ((a)->i = 0, var = PARRAY_INDEX((a), (a)->i); \ + (a)->i < (a)->length; ++(a)->i, var = PARRAY_INDEX((a), (a)->i)) + +#define PARRAY_FLUSH(a) \ +do { \ + void *i; \ + \ + PARRAY_FOREACH_R(a, i) { \ + free(i); \ + parray_unqueue((a)); \ + } \ + \ + (a)->length = 0; \ +} while (/* CONSTCOND */ 0); + +#endif /* _PARRAY_H_ */