a31e3f513cee8774db86cb1aae5e06d818659995
[libfirm] / include / libfirm / adt / plist.h
1 /*
2  * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @author  Kimon Hoffmann
23  * @date    14.07.2005
24  * @brief   Simple, non circular, double linked pointer list.
25  *          Created because the properties of the standard circular list were
26  *          not very well suited for the interference graph implementation.
27  *          This list uses an obstack and a free-list to efficiently manage its
28  *          elements.
29  * @note    Until now the code is entirely untested so it probably contains
30  *          plenty of errors. (Matze: Is this still true, the code seems to be
31  *          used at some places....)
32  * @deprecated
33  */
34 #ifndef FIRM_ADT_PLIST_H
35 #define FIRM_ADT_PLIST_H
36
37 #include <stddef.h>
38 #include "obst.h"
39
40 #include "../begin.h"
41
42 typedef struct plist_element plist_element_t;
43 typedef struct plist plist_t;
44
45 /**
46  * The plist data type.
47  */
48 struct plist {
49         /**
50          * The obstack used for all allocations.
51          */
52         struct obstack *obst;
53
54         /* Set to 1 if plist uses a foreign obstack  */
55         unsigned foreign_obstack : 1;
56
57         /**
58          * First element in the list.
59          */
60         plist_element_t *first_element;
61
62         /**
63          * Last element in the list.
64          */
65         plist_element_t *last_element;
66
67         /**
68          * Current number of elements in the list.
69          */
70         int element_count;
71
72         /**
73          * First element in the free list.
74          * Please note that the free list is a single linked list and all back
75          * references are invalid.
76          */
77         plist_element_t* first_free_element;
78 };
79
80 /**
81  * An element in the pointer list.
82  */
83 struct plist_element {
84         plist_element_t *next;
85         plist_element_t *prev;
86         void *data;
87 };
88
89 /**
90  * Creates a new pointer list and initializes it.
91  * @return The newly created pointer list.
92  */
93 FIRM_API plist_t *plist_new(void);
94
95 /**
96  * Creates a new pointer list and initializes it.
97  * Uses the given obstack instead of creating one.
98  * @param obst  The obstack to use
99  * @return The newly created pointer list.
100  */
101 FIRM_API plist_t *plist_obstack_new(struct obstack *obst);
102
103 /**
104  * Frees the passed pointer list.
105  * After a call to this function all references to the list and any of
106  * its elements are invalid.
107  */
108 FIRM_API void plist_free(plist_t *list);
109
110 /**
111  * Returns the number of elements in a pointer list.
112  * @param list the pointer list
113  * @return The number of elements in a pointer list.
114  */
115 #define plist_count(list) \
116         ((list)->element_count)
117
118 /**
119  * Inserts an element at the back of a pointer list.
120  * @param list the pointer list to append the new element to.
121  * @param value the element value to append.
122  */
123 FIRM_API void plist_insert_back(plist_t *list, void *value);
124
125 /**
126  * Inserts an element at the front of a pointer list.
127  * @param list the pointer list to prepend the new element to.
128  * @param value the element value to prepend.
129  */
130 FIRM_API void plist_insert_front(plist_t *list, void *value);
131
132 /**
133  * Inserts an element into a pointer list before the specified element,
134  * which must be non null.
135  * @param list the pointer list to insert the new element into.
136  * @param element the list element before which the new element should
137  *                be inserted. This element must be a part of @p list.
138  * @param value the element value to insert.
139  */
140 FIRM_API void plist_insert_before(plist_t *list, plist_element_t *element, void *value);
141
142 /**
143  * Inserts an element into a pointer list after the specified element,
144  * which must be non null.
145  * @param list the pointer list to insert the new element into.
146  * @param element the list element after which the new element should
147  *                be inserted. This element must be a part of @p list.
148  * @param value the element value to insert.
149  */
150 FIRM_API void plist_insert_after(plist_t *list, plist_element_t *element, void *value);
151
152 /**
153  * Checks if list has an element with the given data pointer.
154  * @param list   the list to check
155  * @param value  the data pointer to look for
156  * @return 1 if element with data pointer found, 0 otherwise
157  */
158 FIRM_API int plist_has_value(plist_t *list, void *value);
159
160 /**
161  * Tries to find list element associated to the given data pointer.
162  * @param list   the list to check
163  * @param value  the data pointer to look for
164  * @return The first list element associated to data pointer if found, NULL otherwise
165  */
166 FIRM_API plist_element_t *plist_find_value(plist_t *list, void *value);
167
168 /**
169  * Erases the specified element from the pointer list.
170  * @param list the pointer list from which the element should be erased.
171  * @param element the list element to erase. This element must be a part
172  *                of @p list.
173  */
174 FIRM_API void plist_erase(plist_t *list, plist_element_t *element);
175
176 /**
177  * Erases all elements from the specified pointer list.
178  * @param list the pointer list that should be cleared.
179  */
180 FIRM_API void plist_clear(plist_t *list);
181
182 /**
183  * Returns the first element of a pointer list.
184  * @param list the pointer list to iterate
185  * @return a pointer to the element or NULL if the list is empty
186  */
187 #define plist_first(list) \
188         ((list)->first_element)
189
190 /**
191  * Returns the last element of a pointer list.
192  * @param list the pointer list to iterate
193  * @return a pointer to the element or NULL if the list is empty
194  */
195 #define plist_last(list) \
196         ((list)->last_element)
197
198 /**
199  * Checks whether a pointer list element has a successor or not.
200  * @param element the list element that should be queried for existence
201  *                of a successor.
202  * @return TRUE if @p element has a successor, otherwise FALSE.
203  */
204 #define plist_element_has_next(element) \
205         ((element)->next != NULL)
206
207 /**
208  * Checks whether a pointer list element has a predecessor or not.
209  * @param element the list element that should be queried for existence
210  *                of a predecessor.
211  * @return TRUE if @p element has a successor, otherwise FALSE.
212  */
213 #define plist_element_has_prev(element) \
214         ((element)->prev != NULL)
215
216 /**
217  * Gets the successor of the passed list element.
218  * @param element the list element to return the successor of.
219  * @return The successor of @p element or NULL if @p element is the last
220  *         element in the sequence.
221  */
222 #define plist_element_get_next(element) \
223         ((element)->next)
224
225 /**
226  * Gets the predecessor of the passed list element.
227  * @param element the list element to return the predecessor of.
228  * @return The predecessor of @p element or NULL if @p element is the last
229  *         element in the sequence.
230  */
231 #define plist_element_get_prev(element) \
232         ((element)->prev)
233
234 /**
235  * Gets the value stored in the passed list element.
236  * @param element the list element to return the value of.
237  * @return The value stored in @p element.
238  */
239 #define plist_element_get_value(element) \
240         ((element)->data)
241
242 /**
243  * Convenience macro to iterate over a plist.
244  */
245 #define foreach_plist(list, el) \
246         for (el = plist_first(list); el; el = plist_element_get_next(el))
247
248 #include "../end.h"
249
250 #endif