list.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /*
  2. * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #ifndef OSSL_INTERNAL_LIST_H
  10. # define OSSL_INTERNAL_LIST_H
  11. # pragma once
  12. # include <string.h>
  13. # include <assert.h>
  14. # ifdef NDEBUG
  15. # define OSSL_LIST_DBG(x)
  16. # else
  17. # define OSSL_LIST_DBG(x) x;
  18. # endif
  19. # define LIST_FOREACH_FROM(p, name, init) \
  20. for ((p) = (init); \
  21. (p) != NULL; \
  22. (p) = ossl_list_##name##_next(p))
  23. # define LIST_FOREACH(p, name, l) \
  24. LIST_FOREACH_FROM(p, name, ossl_list_##name##_head(l))
  25. # define LIST_FOREACH_REV_FROM(p, name, init) \
  26. for ((p) = (init); \
  27. (p) != NULL; \
  28. (p) = ossl_list_##name##_prev(p))
  29. # define LIST_FOREACH_REV(p, name, l) \
  30. LIST_FOREACH_FROM(p, name, ossl_list_##name##_tail(l))
  31. # define LIST_FOREACH_DELSAFE_FROM(p, pn, name, init) \
  32. for ((p) = (init); \
  33. (p) != NULL && (((pn) = ossl_list_##name##_next(p)), 1); \
  34. (p) = (pn))
  35. #define LIST_FOREACH_DELSAFE(p, pn, name, l) \
  36. LIST_FOREACH_DELSAFE_FROM(p, pn, name, ossl_list_##name##_head(l))
  37. # define LIST_FOREACH_REV_DELSAFE_FROM(p, pn, name, init) \
  38. for ((p) = (init); \
  39. (p) != NULL && (((pn) = ossl_list_##name##_prev(p)), 1); \
  40. (p) = (pn))
  41. # define LIST_FOREACH_REV_DELSAFE(p, pn, name, l) \
  42. LIST_FOREACH_REV_DELSAFE_FROM(p, pn, name, ossl_list_##name##_tail(l))
  43. /* Define a list structure */
  44. # define OSSL_LIST(name) OSSL_LIST_ ## name
  45. /* Define fields to include an element of a list */
  46. # define OSSL_LIST_MEMBER(name, type) \
  47. struct { \
  48. type *next, *prev; \
  49. OSSL_LIST_DBG(struct ossl_list_st_ ## name *list) \
  50. } ossl_list_ ## name
  51. # define DECLARE_LIST_OF(name, type) \
  52. typedef struct ossl_list_st_ ## name OSSL_LIST(name); \
  53. struct ossl_list_st_ ## name { \
  54. type *alpha, *omega; \
  55. size_t num_elems; \
  56. } \
  57. # define DEFINE_LIST_OF_IMPL(name, type) \
  58. static ossl_unused ossl_inline void \
  59. ossl_list_##name##_init(OSSL_LIST(name) *list) \
  60. { \
  61. memset(list, 0, sizeof(*list)); \
  62. } \
  63. static ossl_unused ossl_inline void \
  64. ossl_list_##name##_init_elem(type *elem) \
  65. { \
  66. memset(&elem->ossl_list_ ## name, 0, \
  67. sizeof(elem->ossl_list_ ## name)); \
  68. } \
  69. static ossl_unused ossl_inline int \
  70. ossl_list_##name##_is_empty(const OSSL_LIST(name) *list) \
  71. { \
  72. return list->num_elems == 0; \
  73. } \
  74. static ossl_unused ossl_inline size_t \
  75. ossl_list_##name##_num(const OSSL_LIST(name) *list) \
  76. { \
  77. return list->num_elems; \
  78. } \
  79. static ossl_unused ossl_inline type * \
  80. ossl_list_##name##_head(const OSSL_LIST(name) *list) \
  81. { \
  82. assert(list->alpha == NULL \
  83. || list->alpha->ossl_list_ ## name.list == list); \
  84. return list->alpha; \
  85. } \
  86. static ossl_unused ossl_inline type * \
  87. ossl_list_##name##_tail(const OSSL_LIST(name) *list) \
  88. { \
  89. assert(list->omega == NULL \
  90. || list->omega->ossl_list_ ## name.list == list); \
  91. return list->omega; \
  92. } \
  93. static ossl_unused ossl_inline type * \
  94. ossl_list_##name##_next(const type *elem) \
  95. { \
  96. assert(elem->ossl_list_ ## name.next == NULL \
  97. || elem->ossl_list_ ## name.next \
  98. ->ossl_list_ ## name.prev == elem); \
  99. return elem->ossl_list_ ## name.next; \
  100. } \
  101. static ossl_unused ossl_inline type * \
  102. ossl_list_##name##_prev(const type *elem) \
  103. { \
  104. assert(elem->ossl_list_ ## name.prev == NULL \
  105. || elem->ossl_list_ ## name.prev \
  106. ->ossl_list_ ## name.next == elem); \
  107. return elem->ossl_list_ ## name.prev; \
  108. } \
  109. static ossl_unused ossl_inline void \
  110. ossl_list_##name##_remove(OSSL_LIST(name) *list, type *elem) \
  111. { \
  112. assert(elem->ossl_list_ ## name.list == list); \
  113. OSSL_LIST_DBG(elem->ossl_list_ ## name.list = NULL) \
  114. if (list->alpha == elem) \
  115. list->alpha = elem->ossl_list_ ## name.next; \
  116. if (list->omega == elem) \
  117. list->omega = elem->ossl_list_ ## name.prev; \
  118. if (elem->ossl_list_ ## name.prev != NULL) \
  119. elem->ossl_list_ ## name.prev->ossl_list_ ## name.next = \
  120. elem->ossl_list_ ## name.next; \
  121. if (elem->ossl_list_ ## name.next != NULL) \
  122. elem->ossl_list_ ## name.next->ossl_list_ ## name.prev = \
  123. elem->ossl_list_ ## name.prev; \
  124. list->num_elems--; \
  125. memset(&elem->ossl_list_ ## name, 0, \
  126. sizeof(elem->ossl_list_ ## name)); \
  127. } \
  128. static ossl_unused ossl_inline void \
  129. ossl_list_##name##_insert_head(OSSL_LIST(name) *list, type *elem) \
  130. { \
  131. assert(elem->ossl_list_ ## name.list == NULL); \
  132. OSSL_LIST_DBG(elem->ossl_list_ ## name.list = list) \
  133. if (list->alpha != NULL) \
  134. list->alpha->ossl_list_ ## name.prev = elem; \
  135. elem->ossl_list_ ## name.next = list->alpha; \
  136. elem->ossl_list_ ## name.prev = NULL; \
  137. list->alpha = elem; \
  138. if (list->omega == NULL) \
  139. list->omega = elem; \
  140. list->num_elems++; \
  141. } \
  142. static ossl_unused ossl_inline void \
  143. ossl_list_##name##_insert_tail(OSSL_LIST(name) *list, type *elem) \
  144. { \
  145. assert(elem->ossl_list_ ## name.list == NULL); \
  146. OSSL_LIST_DBG(elem->ossl_list_ ## name.list = list) \
  147. if (list->omega != NULL) \
  148. list->omega->ossl_list_ ## name.next = elem; \
  149. elem->ossl_list_ ## name.prev = list->omega; \
  150. elem->ossl_list_ ## name.next = NULL; \
  151. list->omega = elem; \
  152. if (list->alpha == NULL) \
  153. list->alpha = elem; \
  154. list->num_elems++; \
  155. } \
  156. static ossl_unused ossl_inline void \
  157. ossl_list_##name##_insert_before(OSSL_LIST(name) *list, type *e, \
  158. type *elem) \
  159. { \
  160. assert(elem->ossl_list_ ## name.list == NULL); \
  161. OSSL_LIST_DBG(elem->ossl_list_ ## name.list = list) \
  162. elem->ossl_list_ ## name.next = e; \
  163. elem->ossl_list_ ## name.prev = e->ossl_list_ ## name.prev; \
  164. if (e->ossl_list_ ## name.prev != NULL) \
  165. e->ossl_list_ ## name.prev->ossl_list_ ## name.next = elem; \
  166. e->ossl_list_ ## name.prev = elem; \
  167. if (list->alpha == e) \
  168. list->alpha = elem; \
  169. list->num_elems++; \
  170. } \
  171. static ossl_unused ossl_inline void \
  172. ossl_list_##name##_insert_after(OSSL_LIST(name) *list, type *e, \
  173. type *elem) \
  174. { \
  175. assert(elem->ossl_list_ ## name.list == NULL); \
  176. OSSL_LIST_DBG(elem->ossl_list_ ## name.list = list) \
  177. elem->ossl_list_ ## name.prev = e; \
  178. elem->ossl_list_ ## name.next = e->ossl_list_ ## name.next; \
  179. if (e->ossl_list_ ## name.next != NULL) \
  180. e->ossl_list_ ## name.next->ossl_list_ ## name.prev = elem; \
  181. e->ossl_list_ ## name.next = elem; \
  182. if (list->omega == e) \
  183. list->omega = elem; \
  184. list->num_elems++; \
  185. } \
  186. struct ossl_list_st_ ## name
  187. # define DEFINE_LIST_OF(name, type) \
  188. DECLARE_LIST_OF(name, type); \
  189. DEFINE_LIST_OF_IMPL(name, type)
  190. #endif