source: trunk/GDE/RAxML/ll_list.h

Last change on this file was 13845, checked in by westram, 10 years ago
  • remove executable flag
File size: 2.9 KB
Line 
1/*
2 *   Copyright (C) 2009, 2010, 2011 Lockless Inc., Steven Von Fuerst.
3 *
4 * This library is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17
18/* Header for intrinsic lists */
19#ifndef LL_LIST_H
20#define LL_LIST_H
21
22#include <stddef.h>
23#include <stdint.h>
24
25/* Go from a member * to its container */
26#define CONTAINER(T, S, P)\
27        ((T *) (((uintptr_t) P) - offsetof(T, S)))
28
29/* List types */
30typedef struct slist slist;
31struct slist
32{
33        slist *next;
34};
35
36typedef struct dlist dlist;
37struct dlist
38{
39        dlist *next;
40        dlist *prev;
41};
42
43
44#define list_entry(T, S, P) CONTAINER(T, S, P)
45
46#define scan_list(P, I)\
47        for (I = (P)->next; I != (P); I = I->next)
48
49#define scan_list_safe(P, I, T)\
50        for (I = (P)->next, T = I->next; I != (P); I = T, T = I->next)
51
52#define dlist_empty(T) ((T)->next == T)
53
54#define scan_slist(P, I)\
55        for (I = (P)->next; I; I = I->next)
56
57#define scan_slist_safe(P, I, T)\
58        for (I = (P)->next, I?(T = I->next):0; I; I = T, I?(T = I->next):0)
59
60/* Add an entry to the front of the list */
61static inline void slist_add(slist *s, slist *a)
62{
63        a->next = s->next;
64        s->next = a;
65}
66
67/* Remove first entry, and return it */
68static inline slist *slist_rem(slist *s)
69{
70        slist *r = s->next;
71        s->next = r->next;
72
73        return r;
74}
75
76#define DLIST_INIT(X) {.next = &X, .prev = &X}
77
78static inline void dlist_init(dlist *d)
79{
80        /* Point to self, so list deletion is faster */
81        d->next = d;
82        d->prev = d;
83}
84
85/* Adds "a" to start of dlist d */
86static inline void dlist_add(dlist *d, dlist *a)
87{
88        dlist *dn = d->next;
89
90        a->next = dn;
91        a->prev = d;
92        dn->prev = a;
93        d->next = a;
94}
95
96/* Adds "a" to end of dlist d */
97static inline void dlist_add_end(dlist *d, dlist *a)
98{
99        dlist *dp = d->prev;
100
101        a->next = d;
102        a->prev = dp;
103        dp->next = a;
104        d->prev = a;
105}
106
107/* Remove node "d" from the list */
108static inline void dlist_del(dlist *d)
109{
110        dlist *dp = d->prev;
111        dlist *dn = d->next;
112
113        dn->prev = dp;
114        dp->next = dn;
115}
116
117static inline dlist *dlist_rem_last(dlist *d)
118{
119        dlist *dp = d->prev;
120        if (dp == d) return NULL;
121
122        dlist_del(dp);
123
124        return dp;
125}
126
127/* Merge two dlists: d2 into d*/
128static inline void dlist_merge(dlist *d, dlist *d2)
129{
130        dlist *dp = d->prev;
131        dlist *d2n = d2->next;
132        dlist *d2p = d2->prev;
133
134        /* Don't need to do anything if adding an empty list */
135        if (d2n == d2) return;
136
137        dp->next = d2n;
138        d2n->prev = dp;
139
140        d->prev = d2p;
141        d2p->next = d;
142}
143
144#endif /* LL_LIST_H */
Note: See TracBrowser for help on using the repository browser.