1 /*
2  * Copyright (C) 2008 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 #pragma once
18 
19 #include <stddef.h>
20 
21 #ifdef __cplusplus
22 extern "C" {
23 #endif /* __cplusplus */
24 
25 struct listnode
26 {
27     struct listnode *next;
28     struct listnode *prev;
29 };
30 
31 #define node_to_item(node, container, member) \
32     (container *) (((char*) (node)) - offsetof(container, member))
33 
34 #define list_declare(name) \
35     struct listnode name = { \
36         .next = &(name), \
37         .prev = &(name), \
38     }
39 
40 #define list_for_each_reverse(node, list) \
41     for ((node) = (list)->prev; (node) != (list); (node) = (node)->prev)
42 
43 #define list_for_each_safe(node, n, list) \
44     for ((node) = (list)->next, (n) = (node)->next; \
45          (node) != (list); \
46          (node) = (n), (n) = (node)->next)
47 
48 #define list_for_each(node, list)                                                \
49     for (struct listnode* __n = ((node) = (list)->next)->next; (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