1 /* Copyright (C) 2004 MySQL AB
2    Copyright (C) 2004-2014 Alexey Kopytov <akopytov@gmail.com>
3 
4    This program 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 2 of the License, or
7    (at your option) any later version.
8 
9    This program 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, write to the Free Software
16    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
19 #ifndef SB_LIST_H
20 
21 #define SB_LIST_H
22 
23 typedef struct sb_list_item_t
24 {
25     struct sb_list_item_t *next_p;
26     struct sb_list_item_t *prev_p;
27 }
28 sb_list_item_t;
29 
30 typedef sb_list_item_t sb_list_item;
31 typedef sb_list_item_t sb_list_t ;
32 
33 #ifndef offsetof
34 # define offsetof(type, member) ((size_t) &((type *)0)->member)
35 #endif
36 
37 #define SB_LIST_DECLARE(name) \
38     SB_LIST_T name = { &(name), &(name) }
39 
40 #define SB_LIST_INIT(head_p) \
41     do { \
42         (head_p)->next_p = (head_p); \
43         (head_p)->prev_p = (head_p); \
44     } while (0)
45 
46 #define SB_LIST_ITEM_INIT(item_p) \
47     SB_LIST_INIT(item_p)
48 
49 #define SB_LIST_ADD(item_p, head_p) \
50     do { \
51         (item_p)->next_p = (head_p)->next_p; \
52         (item_p)->prev_p = (head_p); \
53         (head_p)->next_p = (item_p); \
54         (item_p)->next_p->prev_p = (item_p); \
55     } while (0)
56 
57 #define SB_LIST_ADD_TAIL(item_p, head_p) \
58     do { \
59         (item_p)->prev_p = (head_p)->prev_p; \
60         (item_p)->next_p = (head_p); \
61         (head_p)->prev_p = (item_p); \
62         (item_p)->prev_p->next_p = (item_p); \
63     } while (0);
64 
65 #define SB_LIST_DELETE(old_item_p) \
66     do { \
67         (old_item_p)->next_p->prev_p = (old_item_p)->prev_p; \
68         (old_item_p)->prev_p->next_p = (old_item_p)->next_p; \
69     } while (0)
70 
71 #define SB_LIST_REPLACE(item_p, old_item_p) \
72     do { \
73         (item_p)->next_p = (old_item_p)->next_p; \
74         (item_p)->prev_p = (old_item_p)->prev_p; \
75         (item_p)->next_p->prev_p = (item_p); \
76         (item_p)->prev_p->next_p = (item_p); \
77     } while (0)
78 
79 #define SB_LIST_IS_EMPTY(head_p) \
80     ((head_p)->next_p == (head_p))
81 
82 #define SB_LIST_ITEM_IN_LIST(item_p) \
83     ((item_p)->next_p != (item_p))
84 
85 #define SB_LIST_ITEM_FIRST(item_p, head_p) \
86   ((item_p)->prev_p != (head_p))
87 
88 #define SB_LIST_ITEM_LAST(item_p, head_p) \
89   ((item_p)->next_p == (head_p))
90 
91 #define SB_LIST_ITEM_NEXT(item_p) \
92   ((item_p)->next_p)
93 
94 #define SB_LIST_ITEM_PREV(item_p)               \
95   ((item_p)->prev_p)
96 
97 #define SB_LIST_ENTRY(ptr, type, member)            \
98     ((type *)(void *)(((char *)(ptr) - offsetof(type, member))))
99 
100 #define SB_LIST_ONCE(pos_p, head_p) \
101     pos_p= (head_p)->next_p; if (pos_p != (head_p))
102 
103 #define SB_LIST_FOR_EACH(pos_p, head_p) \
104   for (pos_p = (head_p)->next_p; pos_p != (head_p); pos_p = pos_p->next_p)
105 
106 #define SB_LIST_ENUM_START(head_p) \
107   (head_p)
108 
109 #define SB_LIST_ENUM_NEXT(pos_p, head_p)                         \
110   ((pos_p->next_p != (head_p)) ? (pos_p->next_p) : NULL)
111 
112 #define SB_LIST_FOR_EACH_SAFE(pos_p, temp_p, head_p) \
113     for (pos_p = (head_p)->next_p, temp_p = (pos_p)->next_p; pos_p != (head_p); \
114         pos_p = temp_p, temp_p = (pos_p)->next_p)
115 
116 #define SB_LIST_FOR_EACH_REV_SAFE(pos_p, temp_p, head_p) \
117     for (pos_p = (head_p)->prev_p, temp_p = (pos_p)->prev_p; pos_p != (head_p); \
118         pos_p = temp_p, temp_p = (pos_p)->prev_p)
119 
120 #endif /* SB_LIST_H */
121