Mercurial > code
changeset 11:7360d752183e
Added lists.h:
Manage linked lists using token concatenation to generate functions
for a specified type of structure.
At the moment only single linked list is supported.
author | David Demelier <markand@malikania.fr> |
---|---|
date | Wed, 07 Sep 2011 21:12:48 +0200 |
parents | da47652b60c5 |
children | cbfe95c9f7b7 |
files | lists.h |
diffstat | 1 files changed, 118 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lists.h Wed Sep 07 21:12:48 2011 +0200 @@ -0,0 +1,118 @@ +/* + * lists.h -- function to manipulate linked lists + * + * 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 _LISTS_H_ +#define _LISTS_H_ + +/* + * Available function for single linked lists : + * + * <prefix> refers to the prefix argument given to the LIST_IMPLEMENTS macro. + * all function will use this prefix to determine the correct function. + * + * <type> refers to the data type used as template. + * + * o void slist_<prefix>_init(struct slist *sls); + * Initialize the `ls' list structure. + * + * o void slist_<prefix>_push(struct slist *sls, <type> *var) + * Add the `var' to the beginning of the list, if the list is empty + * the tail also refers to the head. + * + * o void slist_<prefix>_pop(struct slist *sls) + * Remove the first element from the list. + * + * o void slist_<prefix>_after(struct slist *sls, <type> *after, <type> *var) + * Insert after the object referenced by `after'. + * + * o void slist_<prefix>_remove(struct slist *sls, <type> *var) + * Remove the var element from the list. + * + * o <type> *slist_<prefix>_head(const struct slist *sls) + * Returns the first list element. + */ + +struct slist { + int length; + void *head; +}; + +/* + * This declare prototype function, to prevent reimplementing function + * that already exists somewhere. + */ + +#define SLIST_HEADER(attr, prefix, type) \ +attr void slist_##prefix##_init(struct slist *); \ +attr void slist_##prefix##_push(struct slist *, type *); \ +attr void slist_##prefix##_pop(struct slist *); \ +attr void slist_##prefix##_after(struct slist *, type *, type *); \ +attr void slist_##prefix##_remove(struct slist *, type *); \ +attr type *slist_##prefix##_head(const struct slist *); + +/* + * Generate available function with the specified prefix. Name argument + * is the next pointer entry in the `type' structure used to go through + * the list. + */ + +#define SLIST_IMPLEMENTS(attr, prefix, type, field) \ +attr void \ +slist_##prefix##_init(struct slist *sls) \ +{ \ + sls->length = 0; \ + sls->head = NULL; \ +} \ + \ +attr void \ +slist_##prefix##_push(struct slist *sls, type *var) \ +{ \ + var->field = sls->head; \ + sls->head = var; \ + sls->length++; \ +} \ + \ +attr void \ +slist_##prefix##_pop(struct slist *sls) \ +{ \ + if (sls->head) { \ + sls->head = ((type *)sls->head)->field; \ + sls->length--; \ + } \ +} \ + \ +attr void \ +slist_##prefix##_after(struct slist *sls, type *after, type *var) \ +{ \ + var->field = after->field; \ + after->field = var; \ + sls->length++; \ +} \ + \ +attr type * \ +slist_##prefix##_head(const struct slist *sls) \ +{ \ + return (type *) sls->head; \ +} + +#define SLIST_FOREACH(list, entry, field) \ + for (entry = (list)->head; \ + entry; \ + entry = entry->field) + +#endif /* _LISTS_H_ */