Merge branch 'glsl2'
[profile/ivi/mesa.git] / src / glsl / list.h
1 /*
2  * Copyright © 2008, 2010 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23
24 /**
25  * \file list.h
26  * \brief Doubly-linked list abstract container type.
27  *
28  * Each doubly-linked list has a sentinel head and tail node.  These nodes
29  * contain no data.  The head sentinel can be identified by its \c prev
30  * pointer being \c NULL.  The tail sentinel can be identified by its
31  * \c next pointer being \c NULL.
32  *
33  * A list is empty if either the head sentinel's \c next pointer points to the
34  * tail sentinel or the tail sentinel's \c prev poiner points to the head
35  * sentinel.
36  *
37  * Instead of tracking two separate \c node structures and a \c list structure
38  * that points to them, the sentinel nodes are in a single structure.  Noting
39  * that each sentinel node always has one \c NULL pointer, the \c NULL
40  * pointers occupy the same memory location.  In the \c list structure
41  * contains a the following:
42  *
43  *   - A \c head pointer that represents the \c next pointer of the
44  *     head sentinel node.
45  *   - A \c tail pointer that represents the \c prev pointer of the head
46  *     sentinel node and the \c next pointer of the tail sentinel node.  This
47  *     pointer is \b always \c NULL.
48  *   - A \c tail_prev pointer that represents the \c prev pointer of the
49  *     tail sentinel node.
50  *
51  * Therefore, if \c head->next is \c NULL or \c tail_prev->prev is \c NULL,
52  * the list is empty.
53  *
54  * To anyone familiar with "exec lists" on the Amiga, this structure should
55  * be immediately recognizable.  See the following link for the original Amiga
56  * operating system documentation on the subject.
57  *
58  * http://www.natami.net/dev/Libraries_Manual_guide/node02D7.html
59  *
60  * \author Ian Romanick <ian.d.romanick@intel.com>
61  */
62
63 #pragma once
64 #ifndef LIST_CONTAINER_H
65 #define LIST_CONTAINER_H
66
67 #ifndef __cplusplus
68 #include <stddef.h>
69 #include <talloc.h>
70 #else
71 extern "C" {
72 #include <talloc.h>
73 }
74 #endif
75
76 #include <assert.h>
77
78 struct exec_node {
79    struct exec_node *next;
80    struct exec_node *prev;
81
82 #ifdef __cplusplus
83    /* Callers of this talloc-based new need not call delete. It's
84     * easier to just talloc_free 'ctx' (or any of its ancestors). */
85    static void* operator new(size_t size, void *ctx)
86    {
87       void *node;
88
89       node = talloc_size(ctx, size);
90       assert(node != NULL);
91
92       return node;
93    }
94
95    /* If the user *does* call delete, that's OK, we will just
96     * talloc_free in that case. */
97    static void operator delete(void *node)
98    {
99       talloc_free(node);
100    }
101
102    exec_node() : next(NULL), prev(NULL)
103    {
104       /* empty */
105    }
106
107    const exec_node *get_next() const
108    {
109       return next;
110    }
111
112    exec_node *get_next()
113    {
114       return next;
115    }
116
117    const exec_node *get_prev() const
118    {
119       return prev;
120    }
121
122    exec_node *get_prev()
123    {
124       return prev;
125    }
126
127    void remove()
128    {
129       next->prev = prev;
130       prev->next = next;
131       next = NULL;
132       prev = NULL;
133    }
134
135    /**
136     * Link a node with itself
137     *
138     * This creates a sort of degenerate list that is occasionally useful.
139     */
140    void self_link()
141    {
142       next = this;
143       prev = this;
144    }
145
146    /**
147     * Insert a node in the list after the current node
148     */
149    void insert_after(exec_node *after)
150    {
151       after->next = this->next;
152       after->prev = this;
153
154       this->next->prev = after;
155       this->next = after;
156    }
157    /**
158     * Insert a node in the list before the current node
159     */
160    void insert_before(exec_node *before)
161    {
162       before->next = this;
163       before->prev = this->prev;
164
165       this->prev->next = before;
166       this->prev = before;
167    }
168    /**
169     * Replace the current node with the given node.
170     */
171    void replace_with(exec_node *replacement)
172    {
173       replacement->prev = this->prev;
174       replacement->next = this->next;
175
176       this->prev->next = replacement;
177       this->next->prev = replacement;
178    }
179
180    /**
181     * Is this the sentinel at the tail of the list?
182     */
183    bool is_tail_sentinel() const
184    {
185       return this->next == NULL;
186    }
187
188    /**
189     * Is this the sentinel at the head of the list?
190     */
191    bool is_head_sentinel() const
192    {
193       return this->prev == NULL;
194    }
195 #endif
196 };
197
198
199 #ifdef __cplusplus
200 /* This macro will not work correctly if `t' uses virtual inheritance.  If you
201  * are using virtual inheritance, you deserve a slow and painful death.  Enjoy!
202  */
203 #define exec_list_offsetof(t, f, p) \
204    (((char *) &((t *) p)->f) - ((char *) p))
205 #else
206 #define exec_list_offsetof(t, f, p) offsetof(t, f)
207 #endif
208
209 /**
210  * Get a pointer to the structure containing an exec_node
211  *
212  * Given a pointer to an \c exec_node embedded in a structure, get a pointer to
213  * the containing structure.
214  *
215  * \param type  Base type of the structure containing the node
216  * \param node  Pointer to the \c exec_node
217  * \param field Name of the field in \c type that is the embedded \c exec_node
218  */
219 #define exec_node_data(type, node, field) \
220    ((type *) (((char *) node) - exec_list_offsetof(type, field, node)))
221
222 #ifdef __cplusplus
223 struct exec_node;
224
225 class iterator {
226 public:
227    void next()
228    {
229    }
230
231    void *get()
232    {
233       return NULL;
234    }
235
236    bool has_next() const
237    {
238       return false;
239    }
240 };
241
242 class exec_list_iterator : public iterator {
243 public:
244    exec_list_iterator(exec_node *n) : node(n), _next(n->next)
245    {
246       /* empty */
247    }
248
249    void next()
250    {
251       node = _next;
252       _next = node->next;
253    }
254
255    void remove()
256    {
257       node->remove();
258    }
259
260    exec_node *get()
261    {
262       return node;
263    }
264
265    bool has_next() const
266    {
267       return _next != NULL;
268    }
269
270 private:
271    exec_node *node;
272    exec_node *_next;
273 };
274
275 #define foreach_iter(iter_type, iter, container) \
276    for (iter_type iter = (container) . iterator(); iter.has_next(); iter.next())
277 #endif
278
279
280 struct exec_list {
281    struct exec_node *head;
282    struct exec_node *tail;
283    struct exec_node *tail_pred;
284
285 #ifdef __cplusplus
286    /* Callers of this talloc-based new need not call delete. It's
287     * easier to just talloc_free 'ctx' (or any of its ancestors). */
288    static void* operator new(size_t size, void *ctx)
289    {
290       void *node;
291
292       node = talloc_size(ctx, size);
293       assert(node != NULL);
294
295       return node;
296    }
297
298    /* If the user *does* call delete, that's OK, we will just
299     * talloc_free in that case. */
300    static void operator delete(void *node)
301    {
302       talloc_free(node);
303    }
304
305    exec_list()
306    {
307       make_empty();
308    }
309
310    void make_empty()
311    {
312       head = (exec_node *) & tail;
313       tail = NULL;
314       tail_pred = (exec_node *) & head;
315    }
316
317    bool is_empty() const
318    {
319       /* There are three ways to test whether a list is empty or not.
320        *
321        * - Check to see if the \c head points to the \c tail.
322        * - Check to see if the \c tail_pred points to the \c head.
323        * - Check to see if the \c head is the sentinel node by test whether its
324        *   \c next pointer is \c NULL.
325        *
326        * The first two methods tend to generate better code on modern systems
327        * because they save a pointer dereference.
328        */
329       return head == (exec_node *) &tail;
330    }
331
332    const exec_node *get_head() const
333    {
334       return !is_empty() ? head : NULL;
335    }
336
337    exec_node *get_head()
338    {
339       return !is_empty() ? head : NULL;
340    }
341
342    const exec_node *get_tail() const
343    {
344       return !is_empty() ? tail_pred : NULL;
345    }
346
347    exec_node *get_tail()
348    {
349       return !is_empty() ? tail_pred : NULL;
350    }
351
352    void push_head(exec_node *n)
353    {
354       n->next = head;
355       n->prev = (exec_node *) &head;
356
357       n->next->prev = n;
358       head = n;
359    }
360
361    void push_tail(exec_node *n)
362    {
363       n->next = (exec_node *) &tail;
364       n->prev = tail_pred;
365
366       n->prev->next = n;
367       tail_pred = n;
368    }
369
370    void push_degenerate_list_at_head(exec_node *n)
371    {
372       assert(n->prev->next == n);
373
374       n->prev->next = head;
375       head->prev = n->prev;
376       n->prev = (exec_node *) &head;
377       head = n;
378    }
379
380    /**
381     * Move all of the nodes from this list to the target list
382     */
383    void move_nodes_to(exec_list *target)
384    {
385       if (is_empty()) {
386          target->make_empty();
387       } else {
388          target->head = head;
389          target->tail = NULL;
390          target->tail_pred = tail_pred;
391
392          target->head->prev = (exec_node *) &target->head;
393          target->tail_pred->next = (exec_node *) &target->tail;
394
395          make_empty();
396       }
397    }
398
399    /**
400     * Append all nodes from the source list to the target list
401     */
402    void
403    append_list(exec_list *source)
404    {
405       if (source->is_empty())
406          return;
407
408       /* Link the first node of the source with the last node of the target list.
409        */
410       this->tail_pred->next = source->head;
411       source->head->prev = this->tail_pred;
412
413       /* Make the tail of the source list be the tail of the target list.
414        */
415       this->tail_pred = source->tail_pred;
416       this->tail_pred->next = (exec_node *) &this->tail;
417
418       /* Make the source list empty for good measure.
419        */
420       source->make_empty();
421    }
422
423    exec_list_iterator iterator()
424    {
425       return exec_list_iterator(head);
426    }
427
428    exec_list_iterator iterator() const
429    {
430       return exec_list_iterator((exec_node *) head);
431    }
432 #endif
433 };
434
435 /**
436  * This version is safe even if the current node is removed.
437  */ 
438 #define foreach_list_safe(__node, __list)                            \
439    for (exec_node * __node = (__list)->head, * __next = __node->next \
440         ; __next != NULL                                             \
441         ; __node = __next, __next = __next->next)
442
443 #define foreach_list(__node, __list)                    \
444    for (exec_node * __node = (__list)->head             \
445         ; (__node)->next != NULL                        \
446         ; (__node) = (__node)->next)
447
448 #define foreach_list_const(__node, __list)              \
449    for (const exec_node * __node = (__list)->head       \
450         ; (__node)->next != NULL                        \
451         ; (__node) = (__node)->next)
452
453 #define foreach_list_typed(__type, __node, __field, __list)             \
454    for (__type * __node =                                               \
455            exec_node_data(__type, (__list)->head, __field);             \
456         (__node)->__field.next != NULL;                                 \
457         (__node) = exec_node_data(__type, (__node)->__field.next, __field))
458
459 #define foreach_list_typed_const(__type, __node, __field, __list)       \
460    for (const __type * __node =                                         \
461            exec_node_data(__type, (__list)->head, __field);             \
462         (__node)->__field.next != NULL;                                 \
463         (__node) = exec_node_data(__type, (__node)->__field.next, __field))
464
465 #endif /* LIST_CONTAINER_H */