1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #ifndef prclist_h___
7 #define prclist_h___
8 
9 #include "prtypes.h"
10 
11 typedef struct PRCListStr PRCList;
12 
13 /*
14 ** Circular linked list
15 */
16 struct PRCListStr {
17     PRCList *next;
18     PRCList *prev;
19 };
20 
21 /*
22 ** Insert element "_e" into the list, before "_l".
23 */
24 #define PR_INSERT_BEFORE(_e,_l)  \
25     PR_BEGIN_MACRO       \
26     (_e)->next = (_l);   \
27     (_e)->prev = (_l)->prev; \
28     (_l)->prev->next = (_e); \
29     (_l)->prev = (_e);   \
30     PR_END_MACRO
31 
32 /*
33 ** Insert element "_e" into the list, after "_l".
34 */
35 #define PR_INSERT_AFTER(_e,_l)   \
36     PR_BEGIN_MACRO       \
37     (_e)->next = (_l)->next; \
38     (_e)->prev = (_l);   \
39     (_l)->next->prev = (_e); \
40     (_l)->next = (_e);   \
41     PR_END_MACRO
42 
43 /*
44 ** Return the element following element "_e"
45 */
46 #define PR_NEXT_LINK(_e)     \
47         ((_e)->next)
48 /*
49 ** Return the element preceding element "_e"
50 */
51 #define PR_PREV_LINK(_e)     \
52         ((_e)->prev)
53 
54 /*
55 ** Append an element "_e" to the end of the list "_l"
56 */
57 #define PR_APPEND_LINK(_e,_l) PR_INSERT_BEFORE(_e,_l)
58 
59 /*
60 ** Insert an element "_e" at the head of the list "_l"
61 */
62 #define PR_INSERT_LINK(_e,_l) PR_INSERT_AFTER(_e,_l)
63 
64 /* Return the head/tail of the list */
65 #define PR_LIST_HEAD(_l) (_l)->next
66 #define PR_LIST_TAIL(_l) (_l)->prev
67 
68 /*
69 ** Remove the element "_e" from it's circular list.
70 */
71 #define PR_REMOVE_LINK(_e)         \
72     PR_BEGIN_MACRO             \
73     (_e)->prev->next = (_e)->next; \
74     (_e)->next->prev = (_e)->prev; \
75     PR_END_MACRO
76 
77 /*
78 ** Remove the element "_e" from it's circular list. Also initializes the
79 ** linkage.
80 */
81 #define PR_REMOVE_AND_INIT_LINK(_e)    \
82     PR_BEGIN_MACRO             \
83     (_e)->prev->next = (_e)->next; \
84     (_e)->next->prev = (_e)->prev; \
85     (_e)->next = (_e);         \
86     (_e)->prev = (_e);         \
87     PR_END_MACRO
88 
89 /*
90 ** Return non-zero if the given circular list "_l" is empty, zero if the
91 ** circular list is not empty
92 */
93 #define PR_CLIST_IS_EMPTY(_l) \
94     ((_l)->next == (_l))
95 
96 /*
97 ** Initialize a circular list
98 */
99 #define PR_INIT_CLIST(_l)  \
100     PR_BEGIN_MACRO     \
101     (_l)->next = (_l); \
102     (_l)->prev = (_l); \
103     PR_END_MACRO
104 
105 #define PR_INIT_STATIC_CLIST(_l) \
106     {(_l), (_l)}
107 
108 #endif /* prclist_h___ */
109