1 /*
2  * Copyright (C) 2008-2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef _CUTILS_LIST_H_
18 #define _CUTILS_LIST_H_
19 
20 #include <stddef.h>
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif /* __cplusplus */
25 
26 struct listnode
27 {
28     struct listnode *next;
29     struct listnode *prev;
30 };
31 
32 #define node_to_item(node, container, member) \
33     (container *) (((char*) (node)) - offsetof(container, member))
34 
35 #define list_declare(name) \
36     struct listnode name = { \
37         .next = &(name), \
38         .prev = &(name), \
39     }
40 
41 #define list_for_each(node, list) \
42     for ((node) = (list)->next; (node) != (list); (node) = (node)->next)
43 
44 #define list_for_each_reverse(node, list) \
45     for ((node) = (list)->prev; (node) != (list); (node) = (node)->prev)
46 
47 #define list_for_each_safe(node, n, list) \
48     for ((node) = (list)->next, (n) = (node)->next; \
49          (node) != (list); \
50          (node) = (n), (n) = (node)->next)
51 
list_init(struct listnode * node)52 static inline void list_init(struct listnode *node)
53 {
54     node->next = node;
55     node->prev = node;
56 }
57 
list_add_tail(struct listnode * head,struct listnode * item)58 static inline void list_add_tail(struct listnode *head, struct listnode *item)
59 {
60     item->next = head;
61     item->prev = head->prev;
62     head->prev->next = item;
63     head->prev = item;
64 }
65 
list_add_head(struct listnode * head,struct listnode * item)66 static inline void list_add_head(struct listnode *head, struct listnode *item)
67 {
68     item->next = head->next;
69     item->prev = head;
70     head->next->prev = item;
71     head->next = item;
72 }
73 
list_remove(struct listnode * item)74 static inline void list_remove(struct listnode *item)
75 {
76     item->next->prev = item->prev;
77     item->prev->next = item->next;
78 }
79 
80 #define list_empty(list) ((list) == (list)->next)
81 #define list_head(list) ((list)->next)
82 #define list_tail(list) ((list)->prev)
83 
84 #ifdef __cplusplus
85 };
86 #endif /* __cplusplus */
87 
88 #endif
89