list_gen.h 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /*
  2. * Copyright (c) 2016 Intel Corporation
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #ifndef ZEPHYR_INCLUDE_SYS_LIST_GEN_H_
  7. #define ZEPHYR_INCLUDE_SYS_LIST_GEN_H_
  8. #include <stddef.h>
  9. #include <stdbool.h>
  10. #include <sys/util.h>
  11. #define Z_GENLIST_FOR_EACH_NODE(__lname, __l, __sn) \
  12. for (__sn = sys_ ## __lname ## _peek_head(__l); __sn != NULL; \
  13. __sn = sys_ ## __lname ## _peek_next(__sn))
  14. #define Z_GENLIST_ITERATE_FROM_NODE(__lname, __l, __sn) \
  15. for (__sn = __sn ? sys_ ## __lname ## _peek_next_no_check(__sn) \
  16. : sys_ ## __lname ## _peek_head(__l); \
  17. __sn != NULL; \
  18. __sn = sys_ ## __lname ## _peek_next(__sn))
  19. #define Z_GENLIST_FOR_EACH_NODE_SAFE(__lname, __l, __sn, __sns) \
  20. for (__sn = sys_ ## __lname ## _peek_head(__l), \
  21. __sns = sys_ ## __lname ## _peek_next(__sn); \
  22. __sn != NULL ; __sn = __sns, \
  23. __sns = sys_ ## __lname ## _peek_next(__sn))
  24. #define Z_GENLIST_CONTAINER(__ln, __cn, __n) \
  25. ((__ln) ? CONTAINER_OF((__ln), __typeof__(*(__cn)), __n) : NULL)
  26. #define Z_GENLIST_PEEK_HEAD_CONTAINER(__lname, __l, __cn, __n) \
  27. Z_GENLIST_CONTAINER(sys_ ## __lname ## _peek_head(__l), __cn, __n)
  28. #define Z_GENLIST_PEEK_TAIL_CONTAINER(__lname, __l, __cn, __n) \
  29. Z_GENLIST_CONTAINER(sys_ ## __lname ## _peek_tail(__l), __cn, __n)
  30. #define Z_GENLIST_PEEK_NEXT_CONTAINER(__lname, __cn, __n) \
  31. ((__cn) ? Z_GENLIST_CONTAINER( \
  32. sys_ ## __lname ## _peek_next(&((__cn)->__n)), \
  33. __cn, __n) : NULL)
  34. #define Z_GENLIST_FOR_EACH_CONTAINER(__lname, __l, __cn, __n) \
  35. for (__cn = Z_GENLIST_PEEK_HEAD_CONTAINER(__lname, __l, __cn, \
  36. __n); \
  37. __cn != NULL; \
  38. __cn = Z_GENLIST_PEEK_NEXT_CONTAINER(__lname, __cn, __n))
  39. #define Z_GENLIST_FOR_EACH_CONTAINER_SAFE(__lname, __l, __cn, __cns, __n) \
  40. for (__cn = Z_GENLIST_PEEK_HEAD_CONTAINER(__lname, __l, __cn, __n), \
  41. __cns = Z_GENLIST_PEEK_NEXT_CONTAINER(__lname, __cn, __n); \
  42. __cn != NULL; __cn = __cns, \
  43. __cns = Z_GENLIST_PEEK_NEXT_CONTAINER(__lname, __cn, __n))
  44. #define Z_GENLIST_IS_EMPTY(__lname) \
  45. static inline bool \
  46. sys_ ## __lname ## _is_empty(sys_ ## __lname ## _t *list) \
  47. { \
  48. return (sys_ ## __lname ## _peek_head(list) == NULL); \
  49. }
  50. #define Z_GENLIST_PEEK_NEXT_NO_CHECK(__lname, __nname) \
  51. static inline sys_ ## __nname ## _t * \
  52. sys_ ## __lname ## _peek_next_no_check(sys_ ## __nname ## _t *node) \
  53. { \
  54. return z_ ## __nname ## _next_peek(node); \
  55. }
  56. #define Z_GENLIST_PEEK_NEXT(__lname, __nname) \
  57. static inline sys_ ## __nname ## _t * \
  58. sys_ ## __lname ## _peek_next(sys_ ## __nname ## _t *node) \
  59. { \
  60. return node != NULL ? \
  61. sys_ ## __lname ## _peek_next_no_check(node) : \
  62. NULL; \
  63. }
  64. #define Z_GENLIST_PREPEND(__lname, __nname) \
  65. static inline void \
  66. sys_ ## __lname ## _prepend(sys_ ## __lname ## _t *list, \
  67. sys_ ## __nname ## _t *node) \
  68. { \
  69. z_ ## __nname ## _next_set(node, \
  70. sys_ ## __lname ## _peek_head(list)); \
  71. z_ ## __lname ## _head_set(list, node); \
  72. \
  73. if (sys_ ## __lname ## _peek_tail(list) == NULL) { \
  74. z_ ## __lname ## _tail_set(list, \
  75. sys_ ## __lname ## _peek_head(list)); \
  76. } \
  77. }
  78. #define Z_GENLIST_APPEND(__lname, __nname) \
  79. static inline void \
  80. sys_ ## __lname ## _append(sys_ ## __lname ## _t *list, \
  81. sys_ ## __nname ## _t *node) \
  82. { \
  83. z_ ## __nname ## _next_set(node, NULL); \
  84. \
  85. if (sys_ ## __lname ## _peek_tail(list) == NULL) { \
  86. z_ ## __lname ## _tail_set(list, node); \
  87. z_ ## __lname ## _head_set(list, node); \
  88. } else { \
  89. z_ ## __nname ## _next_set( \
  90. sys_ ## __lname ## _peek_tail(list), \
  91. node); \
  92. z_ ## __lname ## _tail_set(list, node); \
  93. } \
  94. }
  95. #define Z_GENLIST_APPEND_LIST(__lname, __nname) \
  96. static inline void \
  97. sys_ ## __lname ## _append_list(sys_ ## __lname ## _t *list, \
  98. void *head, void *tail) \
  99. { \
  100. if (sys_ ## __lname ## _peek_tail(list) == NULL) { \
  101. z_ ## __lname ## _head_set(list, \
  102. (sys_ ## __nname ## _t *)head); \
  103. } else { \
  104. z_ ## __nname ## _next_set( \
  105. sys_ ## __lname ## _peek_tail(list), \
  106. (sys_ ## __nname ## _t *)head); \
  107. } \
  108. z_ ## __lname ## _tail_set(list, \
  109. (sys_ ## __nname ## _t *)tail); \
  110. }
  111. #define Z_GENLIST_MERGE_LIST(__lname, __nname) \
  112. static inline void \
  113. sys_ ## __lname ## _merge_ ## __lname ( \
  114. sys_ ## __lname ## _t *list, \
  115. sys_ ## __lname ## _t *list_to_append) \
  116. { \
  117. sys_ ## __nname ## _t *head, *tail; \
  118. head = sys_ ## __lname ## _peek_head(list_to_append); \
  119. tail = sys_ ## __lname ## _peek_tail(list_to_append); \
  120. sys_ ## __lname ## _append_list(list, head, tail); \
  121. sys_ ## __lname ## _init(list_to_append); \
  122. }
  123. #define Z_GENLIST_INSERT(__lname, __nname) \
  124. static inline void \
  125. sys_ ## __lname ## _insert(sys_ ## __lname ## _t *list, \
  126. sys_ ## __nname ## _t *prev, \
  127. sys_ ## __nname ## _t *node) \
  128. { \
  129. if (prev == NULL) { \
  130. sys_ ## __lname ## _prepend(list, node); \
  131. } else if (z_ ## __nname ## _next_peek(prev) == NULL) { \
  132. sys_ ## __lname ## _append(list, node); \
  133. } else { \
  134. z_ ## __nname ## _next_set(node, \
  135. z_ ## __nname ## _next_peek(prev)); \
  136. z_ ## __nname ## _next_set(prev, node); \
  137. } \
  138. }
  139. #define Z_GENLIST_GET_NOT_EMPTY(__lname, __nname) \
  140. static inline sys_ ## __nname ## _t * \
  141. sys_ ## __lname ## _get_not_empty(sys_ ## __lname ## _t *list) \
  142. { \
  143. sys_ ## __nname ## _t *node = \
  144. sys_ ## __lname ## _peek_head(list); \
  145. \
  146. z_ ## __lname ## _head_set(list, \
  147. z_ ## __nname ## _next_peek(node)); \
  148. if (sys_ ## __lname ## _peek_tail(list) == node) { \
  149. z_ ## __lname ## _tail_set(list, \
  150. sys_ ## __lname ## _peek_head(list)); \
  151. } \
  152. \
  153. return node; \
  154. }
  155. #define Z_GENLIST_GET(__lname, __nname) \
  156. static inline sys_ ## __nname ## _t * \
  157. sys_ ## __lname ## _get(sys_ ## __lname ## _t *list) \
  158. { \
  159. return sys_ ## __lname ## _is_empty(list) ? NULL : \
  160. sys_ ## __lname ## _get_not_empty(list); \
  161. }
  162. #define Z_GENLIST_REMOVE(__lname, __nname) \
  163. static inline void \
  164. sys_ ## __lname ## _remove(sys_ ## __lname ## _t *list, \
  165. sys_ ## __nname ## _t *prev_node, \
  166. sys_ ## __nname ## _t *node) \
  167. { \
  168. if (prev_node == NULL) { \
  169. z_ ## __lname ## _head_set(list, \
  170. z_ ## __nname ## _next_peek(node)); \
  171. \
  172. /* Was node also the tail? */ \
  173. if (sys_ ## __lname ## _peek_tail(list) == node) { \
  174. z_ ## __lname ## _tail_set(list, \
  175. sys_ ## __lname ## _peek_head(list)); \
  176. } \
  177. } else { \
  178. z_ ## __nname ## _next_set(prev_node, \
  179. z_ ## __nname ## _next_peek(node)); \
  180. \
  181. /* Was node the tail? */ \
  182. if (sys_ ## __lname ## _peek_tail(list) == node) { \
  183. z_ ## __lname ## _tail_set(list, \
  184. prev_node); \
  185. } \
  186. } \
  187. \
  188. z_ ## __nname ## _next_set(node, NULL); \
  189. }
  190. #define Z_GENLIST_FIND_AND_REMOVE(__lname, __nname) \
  191. static inline bool \
  192. sys_ ## __lname ## _find_and_remove(sys_ ## __lname ## _t *list, \
  193. sys_ ## __nname ## _t *node) \
  194. { \
  195. sys_ ## __nname ## _t *prev = NULL; \
  196. sys_ ## __nname ## _t *test; \
  197. \
  198. Z_GENLIST_FOR_EACH_NODE(__lname, list, test) { \
  199. if (test == node) { \
  200. sys_ ## __lname ## _remove(list, prev, \
  201. node); \
  202. return true; \
  203. } \
  204. \
  205. prev = test; \
  206. } \
  207. \
  208. return false; \
  209. }
  210. #endif /* ZEPHYR_INCLUDE_SYS_LIST_GEN_H_ */