Add dual-license information.
[bertos.git] / mware / list.h
1 /*!
2  * \file
3  * Copyright (C) 2003,2004 Develer S.r.l. (http://www.develer.com/)
4  * Copyright (C) 2001 Bernardo Innocenti <bernie@develer.com>
5  * This file is part of DevLib - See devlib/README for information.
6  *
7  * \version $Id$
8  *
9  * \author Bernardo Innocenti <bernie@develer.com>
10  *
11  * \brief General pourpose double-linked lists
12  */
13
14 /*
15  * $Log$
16  * Revision 1.2  2004/06/03 11:27:09  bernie
17  * Add dual-license information.
18  *
19  * Revision 1.1  2004/05/23 15:43:16  bernie
20  * Import mware modules.
21  *
22  */
23 #ifndef MWARE_LIST_H
24 #define MWARE_LIST_H
25
26 typedef struct _Node
27 {
28         struct _Node *succ;
29         struct _Node *pred;
30 } Node;
31
32 typedef struct _List
33 {
34         Node *head;
35         Node *null;
36         Node *tail;
37 } List;
38
39
40 /*! Template for a list of \a T  structures */
41 #define DECLARE_LIST(T) \
42         struct { T *head; T *null; T *tail; }
43
44 /*! Template for a node in a list of \a T structures */
45 #define DECLARE_NODE(T) \
46         struct { T *succ; T *pred; }
47
48 /*! Template for a node in a list of \a T structures */
49 #define DECLARE_NODE_ANON(T) \
50         T *succ; T *pred;
51
52 /*!
53  * Iterate over all nodes in a list. This statement defines a for cicle
54  * accepting the following parameters:
55  * \param n   node pointer to be used in each iteration
56  * \param l   pointer to list
57  */
58 #define FOREACHNODE(n,l) \
59         for( \
60                 (n) = (typeof(n))((l)->head); \
61                 ((Node *)(n))->succ; \
62                 (n) = (typeof(n))(((Node *)(n))->succ) \
63         )
64
65 /*! Initialize a list */
66 #define INITLIST(l) \
67         do { \
68                 (l)->head = (Node *)(&(l)->null); \
69                 (l)->null = NULL; \
70                 (l)->tail = (Node *)(&(l)->head); \
71         } while (0)
72
73 /*! Add node to list head */
74 #define ADDHEAD(l,n) \
75         do { \
76                 (n)->succ = (l)->head; \
77                 (n)->pred = (Node *)&(l)->head; \
78                 (n)->succ->pred = (n); \
79                 (l)->head = (n); \
80         } while (0)
81
82 /*! Add node to list tail */
83 #define ADDTAIL(l,n) \
84         do { \
85                 (n)->succ = (Node *)(&(l)->null); \
86                 (n)->pred = (l)->tail; \
87                 (n)->pred->succ = (n); \
88                 (l)->tail = (n); \
89         } while (0)
90
91 /*!
92  * Insert node \a n before node \a ln
93  * Note: you can't pass in a list header as \a ln, but
94  * it is safe to pass list-\>head of an empty list.
95  */
96 #define INSERTBEFORE(n,ln) \
97         do { \
98                 (n)->succ = (ln); \
99                 (n)->pred = (ln)->pred; \
100                 (ln)->pred->succ = (n); \
101                 (ln)->pred = (n); \
102         } while (0)
103
104 /*! Remove \a n from whatever list it is in */
105 #define REMOVE(n) \
106         do { \
107                 (n)->pred->succ = (n)->succ; \
108                 (n)->succ->pred = (n)->pred; \
109         } while (0)
110
111 /*! Tell whether a list is empty */
112 #define ISLISTEMPTY(l)  ( (l)->head == (Node *)(&(l)->null) )
113
114 /*! \name Extract an element from the head/tail of the list. If the list empty, return NULL. */
115 /*\{*/
116 #define REMHEAD(l) _list_rem_head(l)
117 #define REMTAIL(l) _list_rem_tail(l)
118 /*\}*/
119
120 /* Prototypes for out-of-line functions */
121 Node *_list_rem_head(List *l);
122 Node *_list_rem_tail(List *l);
123
124
125 #endif /* MWARE_LIST_H */