libmetal  latest
list.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 /*
8  * @file list.h
9  * @brief List primitives for libmetal.
10  */
11 
12 #ifndef __METAL_LIST__H__
13 #define __METAL_LIST__H__
14 
15 #include <stdbool.h>
16 #include <stdlib.h>
17 
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21 
26 struct metal_list {
27  struct metal_list *next, *prev;
28 };
29 
30 /*
31  * METAL_INIT_LIST - used for initializing an list element in a static struct
32  * or global
33  */
34 #define METAL_INIT_LIST(name) { .next = &name, .prev = &name }
35 /*
36  * METAL_DECLARE_LIST - used for defining and initializing a global or
37  * static singleton list
38  */
39 #define METAL_DECLARE_LIST(name) \
40  struct metal_list name = METAL_INIT_LIST(name)
41 
42 static inline void metal_list_init(struct metal_list *list)
43 {
44  list->prev = list;
45  list->next = list;
46 }
47 
48 static inline void metal_list_add_before(struct metal_list *node,
49  struct metal_list *new_node)
50 {
51  new_node->prev = node->prev;
52  new_node->next = node;
53  new_node->next->prev = new_node;
54  new_node->prev->next = new_node;
55 }
56 
57 static inline void metal_list_add_after(struct metal_list *node,
58  struct metal_list *new_node)
59 {
60  new_node->prev = node;
61  new_node->next = node->next;
62  new_node->next->prev = new_node;
63  new_node->prev->next = new_node;
64 }
65 
66 static inline void metal_list_add_head(struct metal_list *list,
67  struct metal_list *node)
68 {
69  metal_list_add_after(list, node);
70 }
71 
72 static inline void metal_list_add_tail(struct metal_list *list,
73  struct metal_list *node)
74 {
75  metal_list_add_before(list, node);
76 }
77 
78 static inline int metal_list_is_empty(struct metal_list *list)
79 {
80  return list->next == list;
81 }
82 
83 static inline void metal_list_del(struct metal_list *node)
84 {
85  node->next->prev = node->prev;
86  node->prev->next = node->next;
87  node->prev = node;
88  node->next = node;
89 }
90 
91 static inline struct metal_list *metal_list_first(struct metal_list *list)
92 {
93  return metal_list_is_empty(list) ? NULL : list->next;
94 }
95 
102 #define metal_list_for_each(list, node) \
103  for ((node) = (list)->next; \
104  (node) != (list); \
105  (node) = (node)->next)
106 
114 #define metal_list_for_each_safe(list, temp, node) \
115  for ((node) = (list)->next, (temp) = (node)->next; \
116  (node) != (list); \
117  (node) = (temp), (temp) = (node)->next)
118 
119 static inline bool metal_list_find_node(struct metal_list *list,
120  struct metal_list *node)
121 {
122  struct metal_list *n;
123 
124  metal_list_for_each(list, n) {
125  if (n == node)
126  return true;
127  }
128  return false;
129 }
132 #ifdef __cplusplus
133 }
134 #endif
135 
136 #endif /* __METAL_LIST__H__ */
static void metal_list_add_tail(struct metal_list *list, struct metal_list *node)
Definition: list.h:72
static void metal_list_add_after(struct metal_list *node, struct metal_list *new_node)
Definition: list.h:57
static int metal_list_is_empty(struct metal_list *list)
Definition: list.h:78
static void metal_list_add_head(struct metal_list *list, struct metal_list *node)
Definition: list.h:66
#define metal_list_for_each(list, node)
Used for iterating over a list.
Definition: list.h:102
static void metal_list_del(struct metal_list *node)
Definition: list.h:83
static void metal_list_add_before(struct metal_list *node, struct metal_list *new_node)
Definition: list.h:48
static struct metal_list * metal_list_first(struct metal_list *list)
Definition: list.h:91
static void metal_list_init(struct metal_list *list)
Definition: list.h:42
static bool metal_list_find_node(struct metal_list *list, struct metal_list *node)
Definition: list.h:119
Definition: list.h:26
struct metal_list * next
Definition: list.h:27
struct metal_list * prev
Definition: list.h:27