clean some tag stuff
[awesome.git] / list.h
blob21ff4344930ac205681ba353af32bace60c72df6
1 /*
2 * list.h - useful list handling header
4 * Copyright © 2008 Julien Danjou <julien@danjou.info>
5 * Copyright © 2006 Pierre Habouzit <madcoder@debian.org>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #ifndef AWESOME_LIST_H
24 #define AWESOME_LIST_H
26 #define DO_SLIST(type, prefix, dtor) \
27 static inline type *prefix##_list_pop(type **list) \
28 { \
29 if (*list) \
30 { \
31 type *res = *list; \
32 *list = res->next; \
33 res->next = NULL; \
34 return res; \
35 } \
36 return NULL; \
37 } \
38 static inline void prefix##_list_push(type **list, type *item) \
39 { \
40 item->next = *list; \
41 *list = item; \
42 } \
44 static inline type **prefix##_list_last(type **list) \
45 { \
46 while (*list && (*list)->next) \
47 list = &(*list)->next; \
48 return list; \
49 } \
51 static inline void prefix##_list_append(type **list, type *item) \
52 { \
53 if(*(list = prefix##_list_last(list))) \
54 (*list)->next = item; \
55 else \
56 (*list) = item; \
57 } \
58 static inline type *prefix##_list_rev(type *list) \
59 { \
60 type *l = NULL; \
61 while (list) \
62 prefix##_list_push(&l, prefix##_list_pop(&list)); \
63 return l; \
64 } \
66 static inline type **prefix##_list_init(type **list) \
67 { \
68 *list = NULL; \
69 return list; \
70 } \
71 static inline void prefix##_list_wipe(type **list) \
72 { \
73 while (*list) \
74 { \
75 type *item = prefix##_list_pop(list); \
76 dtor(&item); \
77 } \
78 } \
79 static inline void prefix##_list_swap(type **list, type *item1, \
80 type *item2) \
81 { \
82 type *i1n = item1->next; \
83 type *i2n = item2->next; \
84 item1->next = i2n == item1 ? item2 : i2n; \
85 item2->next = i1n == item2 ? item1 : i1n; \
87 if(*list == item1) \
88 *list = item2; \
89 else if(*list == item2) \
90 *list = item1; \
91 } \
92 static inline type *prefix##_list_prev(type **list, type *item) \
93 { \
94 type *tmp; \
95 if(*list == item) return NULL; \
96 for(tmp = *list; tmp && tmp->next != item; tmp = tmp->next); \
97 return tmp; \
98 } \
99 static inline type *prefix##_list_prev_cycle(type **list, type *item) \
101 type *tmp = prefix##_list_prev(list, item); \
102 if(!tmp) \
103 tmp = *prefix##_list_last(list); \
104 return tmp; \
106 static inline void prefix##_list_detach(type **list, type *item) \
108 type *prev = prefix##_list_prev(list, item); \
109 if(prev) \
110 prev->next = item->next; \
111 if(item == *list) \
112 *list = item->next; \
113 item->next = NULL; \
116 #endif
117 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80