/* $Id: lists.h,v 1.4 2002/10/21 23:01:56 aa5779 Exp $ */
/*
	Copyright (C) 2001, 2002 Artem V. Andreev (artem@AA5779.spb.edu)

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

*/
#ifndef LISTS_H
#define LISTS_H
/*** \group[Declarations in '\thisfile'] */

/*** \typedefs[2]
Basic types for list routines. 
*/
typedef struct baselist_t
{
	struct baselist_t *next;
} baselist_t;

typedef void *list_t;

/*** \typedef
The type for generic list testing function.
\em[base] points to the current item. The function should return
1 when \em[base] is `equal' to \em[key], 0 otherwise
*/
typedef int (*list_predicate_t)(void *base, void *key);

/*** \typedef
The type for generic list iteration function.
\em[base] is the same as in the previous,
\em[extra] is a user-supplied data
*/
typedef void (*list_iterator_t)(void *base, void *extra);

/*** \typedef
The type for list content destruction function. 
\em[base] is the same as in the previous.
\note The function should \em[not] deallocate memory for \em[base].
*/
typedef void (*list_destroy_t)(void *base);

/*** \xmacro[DEFLIST]
A macro to declare structures compatible with \see[typedefs][baselist_t]
*/
#define DEFLIST(name, body) typedef struct name { \
								struct name *next; \
								body \
							} name
/*\end*/

/*** \macro[list_next]
A generic macro to get the tail of a list
*/
#define list_next(l) ((list_t)(((baselist_t *)(l))->next))

void list_free(list_t item, list_destroy_t destroy, int size);

list_t list_add(list_t base, list_t new);

list_t list_find(list_t base, void *key, list_predicate_t predicate);

int list_length(list_t l);
list_t list_nth(list_t l, int n);

void list_foreach(list_t base, list_iterator_t iterator, void *extra);

list_t list_insert(list_t base, void *after, list_t new, list_predicate_t predicate);
list_t list_append(list_t base, list_t new);

list_t list_pop(list_t base, list_destroy_t destroy, int elsize);
list_t list_remove(list_t base, void *key, list_predicate_t predicate, list_destroy_t destroy, int elsize);
list_t list_remove_all(list_t base, void *key, list_predicate_t predicate, list_destroy_t destroy, int elsize);

void list_delete(list_t base, list_destroy_t destroy, int elsize);

list_t list_reversip(list_t src);

#endif // LISTS_H
