1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef NSTACKX_LIST_H
17 #define NSTACKX_LIST_H
18 
19 #include <stdio.h>
20 #include <stdint.h>
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 
26 typedef struct List {
27     struct List *prev;
28     struct List *next;
29 } List;
30 
ListInitHead(List * head)31 static inline void ListInitHead(List *head)
32 {
33     head->next = head;
34     head->prev = head;
35 }
36 
ListInsertHead(List * head,List * node)37 static inline void ListInsertHead(List *head, List *node)
38 {
39     node->next = head->next;
40     node->next->prev = node;
41     node->prev = head;
42     head->next = node;
43 }
44 
ListInsertTail(List * head,List * node)45 static inline void ListInsertTail(List *head, List *node)
46 {
47     node->prev = head->prev;
48     node->prev->next = node;
49     node->next = head;
50     head->prev = node;
51 }
52 
ListRemoveNode(List * node)53 static inline void ListRemoveNode(List *node)
54 {
55     if (node == NULL) {
56         return;
57     }
58     node->next->prev = node->prev;
59     node->prev->next = node->next;
60     node->next = NULL;
61     node->prev = NULL;
62 }
63 
ListIsEmpty(const List * head)64 static inline uint8_t ListIsEmpty(const List *head)
65 {
66     return (head == head->next);
67 }
68 
ListGetFront(List * head)69 static inline List *ListGetFront(List *head)
70 {
71     return head->next;
72 }
73 
ListPopFront(List * head)74 static inline List *ListPopFront(List *head)
75 {
76     List *element = NULL;
77     if (head == NULL || ListIsEmpty(head)) {
78         return NULL;
79     }
80 
81     element = head->next;
82     ListRemoveNode(element);
83     return element;
84 }
85 
ListInsertNewHead(List * prevHead,List * newHead)86 static inline void ListInsertNewHead(List *prevHead, List *newHead)
87 {
88     prevHead->prev->next = newHead->next;
89     newHead->next->prev = prevHead->prev;
90     newHead->prev->next = prevHead;
91     prevHead->prev = newHead->prev;
92 }
93 
ListMove(List * from,List * to)94 static inline void ListMove(List *from, List *to)
95 {
96     List *first = from->next;
97     List *last = from->prev;
98 
99     to->next = first;
100     to->prev = last;
101     first->prev = to;
102     last->next = to;
103     ListInitHead(from);
104 }
105 
106 #define LIST_FOR_EACH(curr, head) \
107     for ((curr) = (head)->next; (curr) != (head); (curr) = (curr)->next)
108 
109 #define LIST_FOR_EACH_SAFE(pos, tmp, head) \
110     for ((pos) = (head)->next, (tmp) = (pos)->next; (pos) != (head); \
111         (pos) = (tmp), (tmp) = (pos)->next)
112 
113 #ifdef __cplusplus
114 }
115 #endif
116 
117 #endif // NSTACKX_LIST_H
118