[sdk] Implement mini lists, which are singly-linked
[monolithium.git] / sdk / list.h
1 /*
2  * list.h
3  *
4  * Copyright (C) 2015 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Affero General Public License as
8  * published by the Free Software Foundation, either version 3 of the
9  * License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Affero General Public License for more details.
15  *
16  * You should have received a copy of the GNU Affero General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #ifndef __MONOLITHIUM_LIST_H__
21 #define __MONOLITHIUM_LIST_H__
22
23 #include "defs.h"
24
25 #define LIST_INITIALIZER(name) { &name, &name }
26 #define DECLARE_LIST(name) list_entry_t name = LIST_INITIALIZER(name)
27
28 #define list_put_after  list_prepend
29 #define list_put_before list_append
30
31 #define mini_list_put_after  mini_list_prepend
32 #define mini_list_put_before mini_list_append
33
34 typedef struct _list_entry_t
35 {
36     struct _list_entry_t *next, *prev;
37 } list_entry_t;
38
39 typedef struct _mini_list_entry_t
40 {
41     struct _mini_list_entry_t *next;
42 } mini_list_entry_t;
43
44 static inline void list_prepend(list_entry_t *list, list_entry_t *entry)
45 {
46     entry->next = list->next;
47     entry->prev = list;
48     entry->next->prev = entry;
49     entry->prev->next = entry;
50 }
51
52 static inline void list_append(list_entry_t *list, list_entry_t *entry)
53 {
54     entry->next = list;
55     entry->prev = list->prev;
56     entry->next->prev = entry;
57     entry->prev->next = entry;
58 }
59
60 static inline void list_remove(list_entry_t *entry)
61 {
62     entry->next->prev = entry->prev;
63     entry->prev->next = entry->next;
64 }
65
66 static inline void list_init(list_entry_t *list)
67 {
68     list->next = list->prev = list;
69 }
70
71 static inline void list_init_array(list_entry_t *list_array, size_t size)
72 {
73     size_t i;
74     for (i = 0; i < size; i++) list_init(&list_array[i]);
75 }
76
77 static inline void mini_list_prepend(mini_list_entry_t *list, mini_list_entry_t *entry)
78 {
79     entry->next = list->next;
80     list->next = entry;
81 }
82
83 static inline void mini_list_append(mini_list_entry_t *list, mini_list_entry_t *entry)
84 {
85     mini_list_entry_t *final = list->next;
86     while (final->next != list) final = final->next;
87
88     final->next = entry;
89     entry->next = list;
90 }
91
92 static inline void mini_list_remove(mini_list_entry_t *entry)
93 {
94     mini_list_entry_t *prev = entry->next;
95     while (prev->next != entry) prev = prev->next;
96     prev->next = entry->next;
97 }
98
99 static inline void mini_list_init(mini_list_entry_t *list)
100 {
101     list->next = list;
102 }
103
104 static inline void mini_list_init_array(mini_list_entry_t *list_array, size_t size)
105 {
106     size_t i;
107     for (i = 0; i < size; i++) mini_list_init(&list_array[i]);
108 }
109
110 #endif