1ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross/*
2a6aad4cdb3ec75668838f3eced59bbb2c7b70c59Mark Salyzyn * Copyright (C) 2008-2013 The Android Open Source Project
3ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross *
4ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross * Licensed under the Apache License, Version 2.0 (the "License");
5ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross * you may not use this file except in compliance with the License.
6ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross * You may obtain a copy of the License at
7ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross *
8ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross *      http://www.apache.org/licenses/LICENSE-2.0
9ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross *
10ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross * Unless required by applicable law or agreed to in writing, software
11ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross * distributed under the License is distributed on an "AS IS" BASIS,
12ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross * See the License for the specific language governing permissions and
14ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross * limitations under the License.
15ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross */
16ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross
17da04c52ab1036048520fca265cf02b61dca789e0Dima Zavin#ifndef _CUTILS_LIST_H_
18da04c52ab1036048520fca265cf02b61dca789e0Dima Zavin#define _CUTILS_LIST_H_
19ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross
20b93e5812faffd3b6c5fb349072413aace31918d8Olivier Bailly#include <stddef.h>
210009b73ed88f5c1759c3b2d9df73492d53f79039Kenny Root
2277a62ceac5f1d3942b85b21d86f6b4d25d686190Kenny Root#ifdef __cplusplus
2377a62ceac5f1d3942b85b21d86f6b4d25d686190Kenny Rootextern "C" {
2477a62ceac5f1d3942b85b21d86f6b4d25d686190Kenny Root#endif /* __cplusplus */
25b93e5812faffd3b6c5fb349072413aace31918d8Olivier Bailly
26ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Crossstruct listnode
27ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross{
28ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross    struct listnode *next;
29ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross    struct listnode *prev;
30ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross};
31ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross
32ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross#define node_to_item(node, container, member) \
33ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross    (container *) (((char*) (node)) - offsetof(container, member))
34ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross
35ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross#define list_declare(name) \
36ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross    struct listnode name = { \
37ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross        .next = &name, \
38ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross        .prev = &name, \
39ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross    }
40ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross
41ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross#define list_for_each(node, list) \
42ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross    for (node = (list)->next; node != (list); node = node->next)
43ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross
4444b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross#define list_for_each_reverse(node, list) \
4544b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross    for (node = (list)->prev; node != (list); node = node->prev)
4644b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross
478cc74270405bbca5afa989b61c76b554c5b4f5a6Thierry Escande#define list_for_each_safe(node, n, list) \
488cc74270405bbca5afa989b61c76b554c5b4f5a6Thierry Escande    for (node = (list)->next, n = node->next; \
4930fb83b6e520e0167934b6defe105f2bdd408fd5Andrew Boie         node != (list); \
508cc74270405bbca5afa989b61c76b554c5b4f5a6Thierry Escande         node = n, n = node->next)
5130fb83b6e520e0167934b6defe105f2bdd408fd5Andrew Boie
52a6aad4cdb3ec75668838f3eced59bbb2c7b70c59Mark Salyzynstatic inline void list_init(struct listnode *node)
53a6aad4cdb3ec75668838f3eced59bbb2c7b70c59Mark Salyzyn{
54a6aad4cdb3ec75668838f3eced59bbb2c7b70c59Mark Salyzyn    node->next = node;
55a6aad4cdb3ec75668838f3eced59bbb2c7b70c59Mark Salyzyn    node->prev = node;
56a6aad4cdb3ec75668838f3eced59bbb2c7b70c59Mark Salyzyn}
57a6aad4cdb3ec75668838f3eced59bbb2c7b70c59Mark Salyzyn
58a6aad4cdb3ec75668838f3eced59bbb2c7b70c59Mark Salyzynstatic inline void list_add_tail(struct listnode *head, struct listnode *item)
59a6aad4cdb3ec75668838f3eced59bbb2c7b70c59Mark Salyzyn{
60a6aad4cdb3ec75668838f3eced59bbb2c7b70c59Mark Salyzyn    item->next = head;
61a6aad4cdb3ec75668838f3eced59bbb2c7b70c59Mark Salyzyn    item->prev = head->prev;
62a6aad4cdb3ec75668838f3eced59bbb2c7b70c59Mark Salyzyn    head->prev->next = item;
63a6aad4cdb3ec75668838f3eced59bbb2c7b70c59Mark Salyzyn    head->prev = item;
64a6aad4cdb3ec75668838f3eced59bbb2c7b70c59Mark Salyzyn}
65a6aad4cdb3ec75668838f3eced59bbb2c7b70c59Mark Salyzyn
66f8a1089ab5d3976c631cfe7b40eca8a5ed34c306Samuel Ortizstatic inline void list_add_head(struct listnode *head, struct listnode *item)
67f8a1089ab5d3976c631cfe7b40eca8a5ed34c306Samuel Ortiz{
68f8a1089ab5d3976c631cfe7b40eca8a5ed34c306Samuel Ortiz    item->next = head->next;
69f8a1089ab5d3976c631cfe7b40eca8a5ed34c306Samuel Ortiz    item->prev = head;
70f8a1089ab5d3976c631cfe7b40eca8a5ed34c306Samuel Ortiz    head->next->prev = item;
71f8a1089ab5d3976c631cfe7b40eca8a5ed34c306Samuel Ortiz    head->next = item;
72f8a1089ab5d3976c631cfe7b40eca8a5ed34c306Samuel Ortiz}
73f8a1089ab5d3976c631cfe7b40eca8a5ed34c306Samuel Ortiz
74a6aad4cdb3ec75668838f3eced59bbb2c7b70c59Mark Salyzynstatic inline void list_remove(struct listnode *item)
75a6aad4cdb3ec75668838f3eced59bbb2c7b70c59Mark Salyzyn{
76a6aad4cdb3ec75668838f3eced59bbb2c7b70c59Mark Salyzyn    item->next->prev = item->prev;
77a6aad4cdb3ec75668838f3eced59bbb2c7b70c59Mark Salyzyn    item->prev->next = item->next;
78a6aad4cdb3ec75668838f3eced59bbb2c7b70c59Mark Salyzyn}
79ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross
80ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross#define list_empty(list) ((list) == (list)->next)
81ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross#define list_head(list) ((list)->next)
82ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross#define list_tail(list) ((list)->prev)
83ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross
8477a62ceac5f1d3942b85b21d86f6b4d25d686190Kenny Root#ifdef __cplusplus
8577a62ceac5f1d3942b85b21d86f6b4d25d686190Kenny Root};
8677a62ceac5f1d3942b85b21d86f6b4d25d686190Kenny Root#endif /* __cplusplus */
870009b73ed88f5c1759c3b2d9df73492d53f79039Kenny Root
88ed8a7d84428ec945c48b6b53dc5a3a18fabaf683Colin Cross#endif
89