1 /*
2 Z88DK Z80 Macro Assembler
3 
4 Generic doubly linked list, data allocation is handled by the caller.
5 Uses queue.h for implementation.
6 
7 Copyright (C) Gunther Strube, InterLogic 1993-99
8 Copyright (C) Paulo Custodio, 2011-2020
9 License: The Artistic License 2.0, http://www.perlfoundation.org/artistic_license_2_0
10 Repository: https://github.com/z88dk/z88dk
11 */
12 
13 #pragma once
14 
15 #include "class.h"
16 #include "types.h"
17 #include "queue.h"
18 
19 /*-----------------------------------------------------------------------------
20 *   List *list = NULL;			// init list
21 *	List_push( &list, data );	// add data
22 *	ListElem *iter;
23 *   for ( iter = List_first(list); iter != NULL; iter = List_next(iter) )
24 *	{ use iter->data }
25 *
26 *   OBJ_DELETE(List);			// is done automatically on exit
27 *----------------------------------------------------------------------------*/
28 typedef struct ListElem
29 {
30     void *data;							/* user data */
31 
32     TAILQ_ENTRY( ListElem ) entries;	/* tail queue. */
33 } ListElem;
34 
35 CLASS( List )
36 	size_t count;							/* number of objects */
37 	void ( *free_data )( void * );			/* function to free an element
38 											   called by List_remove_all() */
39 	TAILQ_HEAD( ListHead, ListElem ) head;	/* head of queue */
40 END_CLASS;
41 
42 /* add and retrieve at the end */
43 extern void  List_push( List **pself, void *data );
44 extern void *List_pop( List *self );
45 
46 /* add and retrieve at the start */
47 extern void  List_unshift( List **pself, void *data );
48 extern void *List_shift( List *self );
49 
50 /* set iterator to start and end of list, data is iter->data */
51 extern ListElem *List_first( List *self );
52 extern ListElem *List_last( List *self );
53 
54 /* advance iterator to next/previous element */
55 extern ListElem *List_next( ListElem *iter );
56 extern ListElem *List_prev( ListElem *iter );
57 
58 /* insert data before/after a given iterator */
59 extern void List_insert_after( List **pself, ListElem *iter, void *data );
60 extern void List_insert_before( List **pself, ListElem *iter, void *data );
61 
62 /* remove and return data pointed by iterator,
63    advance iterator to next element */
64 extern void *List_remove( List *self, ListElem **piter );
65 
66 /* remove all list; free_data if not NULL is called to free each element */
67 extern void List_remove_all( List *self );
68 
69 /* check if list is empty */
70 extern bool List_empty( List *self );
71