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 DL_LIST_H
17 #define DL_LIST_H
18 
19 #include <stdio.h>
20 #include <stdbool.h>
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 
26 // Double linked list.
27 typedef struct DL_LIST {
28     struct DL_LIST *pstPrev;  // previous node
29     struct DL_LIST *pstNext;  // next node
30 } DL_LIST;
31 
32 /**
33  * @brief Perform instantiation of the DL_LIST.
34  *
35  * @param list DL_LIST pointer.
36  * @since 6
37  */
DL_ListInit(DL_LIST * list)38 static inline void DL_ListInit(DL_LIST *list)
39 {
40     list->pstNext = list;
41     list->pstPrev = list;
42 }
43 
44 /**
45  * @brief Insert a DL_LIST node into DL_LIST.
46  *
47  * @param list DL_LIST pointer.
48  * @param node DL_LIST node pointer.
49  * @since 6
50  */
DL_ListAdd(DL_LIST * list,DL_LIST * node)51 static inline void DL_ListAdd(DL_LIST *list, DL_LIST *node)
52 {
53     node->pstNext = list->pstNext;
54     node->pstPrev = list;
55     list->pstNext->pstPrev = node;
56     list->pstNext = node;
57 }
58 
59 /**
60  * @brief Insert a DL_LIST node into DL_LIST tail.
61  *
62  * @param list DL_LIST pointer.
63  * @param node DL_LIST node pointer.
64  * @since 6
65  */
DL_ListTailInsert(DL_LIST * list,DL_LIST * node)66 static inline void DL_ListTailInsert(DL_LIST *list, DL_LIST *node)
67 {
68     DL_ListAdd(list->pstPrev, node);
69 }
70 
71 /**
72  * @brief Insert a DL_LIST node into DL_LIST head.
73  *
74  * @param list DL_LIST pointer.
75  * @param node DL_LIST node pointer.
76  * @since 6
77  */
DL_ListHeadInsert(DL_LIST * list,DL_LIST * node)78 static inline void DL_ListHeadInsert(DL_LIST *list, DL_LIST *node)
79 {
80     DL_ListAdd(list, node);
81 }
82 
83 /**
84  * @brief Delete a DL_LIST node from DL_LIST.
85  *
86  * @param node DL_LIST node pointer.
87  * @since 6
88  */
DL_ListDelete(DL_LIST * node)89 static inline void DL_ListDelete(DL_LIST *node)
90 {
91     node->pstNext->pstPrev = node->pstPrev;
92     node->pstPrev->pstNext = node->pstNext;
93     node->pstNext = NULL;
94     node->pstPrev = NULL;
95 }
96 
97 /**
98  * @brief Whether a specific DL_LIST is empty.
99  *
100  * @param node DL_LIST node pointer.
101  * @return DL_List is empty return true, else return false.
102  * @since 6
103  */
DL_ListEmpty(DL_LIST * list)104 static inline bool DL_ListEmpty(DL_LIST *list)
105 {
106     return (bool)(list->pstNext == list);
107 }
108 
109 /**
110  * @brief Member's offset relative to specific struct.
111  *
112  * @param type Struct name.
113  * @param member Member name.
114  * @return Offset value type is unsigned long.
115  * @since 6
116  */
117 #define OFF_SET_OF(type, member) ((unsigned long int)&((type *)0)->member)
118 
119 /**
120  * @brief Get pointer of Given type struct, which includes DL_LIST member.
121  *
122  * @param item DL_LIST address.
123  * @param type Struct name.
124  * @param member Member name.
125  * @return Pointer of Given type struct.
126  * @since 6
127  */
128 #define DL_LIST_ENTRY(item, type, member) ((type *)(void *)((char *)(item)-OFF_SET_OF(type, member)))
129 
130 #ifdef __cplusplus
131 }
132 #endif
133 
134 #endif  // DL_LIST_H