list.h (4065B)
1 /* Copyright (C) 2013-2023, 2025 Vincent Forest (vaplv@free.fr) 2 * 3 * The RSys library is free software: you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published 5 * by the Free Software Foundation, either version 3 of the License, or 6 * (at your option) any later version. 7 * 8 * The RSys library is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with the RSys library. If not, see <http://www.gnu.org/licenses/>. */ 15 16 #ifndef LIST_H 17 #define LIST_H 18 19 #include "rsys.h" 20 21 struct list_node { 22 struct list_node* next; 23 struct list_node* prev; 24 }; 25 26 /****************************************************************************** 27 * Private functions 28 ******************************************************************************/ 29 static FINLINE void 30 add_node__ 31 (struct list_node* node, 32 struct list_node* prev, 33 struct list_node* next) 34 { 35 ASSERT(node && prev && next); 36 next->prev = node; 37 node->next = next; 38 node->prev = prev; 39 prev->next = node; 40 } 41 42 static FINLINE void 43 del_node__(struct list_node* prev, struct list_node* next) 44 { 45 ASSERT(prev && next); 46 next->prev = prev; 47 prev->next = next; 48 } 49 50 /****************************************************************************** 51 * Helper macros 52 ******************************************************************************/ 53 #define LIST_FOR_EACH(Pos, List) \ 54 for(Pos = (List)->next; Pos != (List); Pos = Pos->next) 55 56 #define LIST_FOR_EACH_REVERSE(Pos, List) \ 57 for(Pos = (List)->prev; Pos != (List); Pos = Pos->prev) 58 59 /* Safe against removal of list entry. */ 60 #define LIST_FOR_EACH_SAFE(Pos, Tmp, List) \ 61 for((Pos) = (List)->next, (Tmp) = (Pos)->next; \ 62 (Pos) != (List); \ 63 (Pos) = Tmp, Tmp = (Pos)->next) 64 65 /* Safe against removal of list entry. */ 66 #define LIST_FOR_EACH_REVERSE_SAFE(Pos, Tmp, List) \ 67 for((Pos) = (List)->prev, (Tmp) = (Pos)->prev; \ 68 (Pos) != (List); \ 69 (Pos) = Tmp, Tmp = (Pos)->prev) 70 71 /****************************************************************************** 72 * Node list functions 73 ******************************************************************************/ 74 static FINLINE void 75 list_init(struct list_node* node) 76 { 77 ASSERT(node); 78 node->next = node; 79 node->prev = node; 80 } 81 82 static FINLINE char 83 is_list_empty(const struct list_node* node) 84 { 85 ASSERT(node); 86 return node->next == node; 87 } 88 89 static FINLINE struct list_node* 90 list_head(struct list_node* node) 91 { 92 ASSERT(node && !is_list_empty(node)); 93 return node->next; 94 } 95 96 static FINLINE struct list_node* 97 list_tail(struct list_node* node) 98 { 99 ASSERT(node && !is_list_empty(node)); 100 return node->prev; 101 } 102 103 static FINLINE void 104 list_add(struct list_node* list, struct list_node* node) 105 { 106 ASSERT(list && node && is_list_empty(node)); 107 add_node__(node, list, list->next); 108 } 109 110 static FINLINE void 111 list_add_tail(struct list_node* list, struct list_node* node) 112 { 113 ASSERT(list && node && is_list_empty(node)); 114 add_node__(node, list->prev, list); 115 } 116 117 static FINLINE void 118 list_del(struct list_node* node) 119 { 120 ASSERT(node); 121 del_node__(node->prev, node->next); 122 list_init(node); 123 } 124 125 static FINLINE void 126 list_move(struct list_node* node, struct list_node* list) 127 { 128 ASSERT(node && list); 129 del_node__(node->prev, node->next); 130 add_node__(node, list, list->next); 131 } 132 133 static FINLINE void 134 list_move_tail(struct list_node* node, struct list_node* list) 135 { 136 ASSERT(node && list); 137 del_node__(node->prev, node->next); 138 add_node__(node, list->prev, list); 139 } 140 141 #endif /* LIST_H */