tlist.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. #ifndef CCAN_TLIST_H
  2. #define CCAN_TLIST_H
  3. #include <ccan/list/list.h>
  4. #if HAVE_FLEXIBLE_ARRAY_MEMBER
  5. /**
  6. * TLIST_TYPE - declare a typed list type (struct tlist)
  7. * @suffix: the name to use (struct tlist_@suffix)
  8. * @type: the type the list will contain (void for any type)
  9. *
  10. * This declares a structure "struct tlist_@suffix" to use for
  11. * lists containing this type. The actual list can be accessed using
  12. * ".raw" or tlist_raw().
  13. *
  14. * Example:
  15. * // Defines struct tlist_children
  16. * TLIST_TYPE(children, struct child);
  17. * struct parent {
  18. * const char *name;
  19. * struct tlist_children children;
  20. * unsigned int num_children;
  21. * };
  22. *
  23. * struct child {
  24. * const char *name;
  25. * struct list_node list;
  26. * };
  27. */
  28. #define TLIST_TYPE(suffix, type) \
  29. struct tlist_##suffix { \
  30. struct list_head raw; \
  31. const type *tcheck[]; \
  32. }
  33. /**
  34. * tlist_raw - access the raw list inside a typed list head.
  35. * @h: the head of the typed list (struct tlist_@suffix)
  36. * @test_var: a pointer to the expected element type.
  37. *
  38. * This elaborate macro usually causes the compiler to emit a warning
  39. * if the variable is of an unexpected type. It is used internally
  40. * where we need to access the raw underlying list.
  41. */
  42. #define tlist_raw(h, test_var) \
  43. (sizeof((h)->tcheck[0] == (test_var)) ? &(h)->raw : &(h)->raw)
  44. #else
  45. #define TLIST_TYPE(suffix, type) \
  46. struct tlist_##suffix { \
  47. struct list_head raw; \
  48. }
  49. #define tlist_raw(h, test_var) (&(h)->raw)
  50. #endif
  51. /**
  52. * TLIST_INIT - initalizer for an empty tlist
  53. * @name: the name of the list.
  54. *
  55. * Explicit initializer for an empty list.
  56. *
  57. * See also:
  58. * tlist_init()
  59. *
  60. * Example:
  61. * static struct tlist_children my_list = TLIST_INIT(my_list);
  62. */
  63. #define TLIST_INIT(name) { LIST_HEAD_INIT(name.raw) }
  64. /**
  65. * tlist_check - check head of a list for consistency
  66. * @h: the tlist_head
  67. * @abortstr: the location to print on aborting, or NULL.
  68. *
  69. * Because list_nodes have redundant information, consistency checking between
  70. * the back and forward links can be done. This is useful as a debugging check.
  71. * If @abortstr is non-NULL, that will be printed in a diagnostic if the list
  72. * is inconsistent, and the function will abort.
  73. *
  74. * Returns non-NULL if the list is consistent, NULL otherwise (it
  75. * can never return NULL if @abortstr is set).
  76. *
  77. * See also: list_check()
  78. *
  79. * Example:
  80. * static void dump_parent(struct parent *p)
  81. * {
  82. * struct child *c;
  83. *
  84. * printf("%s (%u children):\n", p->name, p->num_children);
  85. * tlist_check(&p->children, "bad child list");
  86. * tlist_for_each(&p->children, c, list)
  87. * printf(" -> %s\n", c->name);
  88. * }
  89. */
  90. #define tlist_check(h, abortstr) \
  91. list_check(&(h)->raw, (abortstr))
  92. /**
  93. * tlist_init - initialize a tlist
  94. * @h: the tlist to set to the empty list
  95. *
  96. * Example:
  97. * ...
  98. * struct parent *parent = malloc(sizeof(*parent));
  99. *
  100. * tlist_init(&parent->children);
  101. * parent->num_children = 0;
  102. */
  103. #define tlist_init(h) list_head_init(&(h)->raw)
  104. /**
  105. * tlist_add - add an entry at the start of a linked list.
  106. * @h: the tlist to add the node to
  107. * @n: the entry to add to the list.
  108. * @member: the member of n to add to the list.
  109. *
  110. * The entry's list_node does not need to be initialized; it will be
  111. * overwritten.
  112. * Example:
  113. * struct child *child = malloc(sizeof(*child));
  114. *
  115. * child->name = "marvin";
  116. * tlist_add(&parent->children, child, list);
  117. * parent->num_children++;
  118. */
  119. #define tlist_add(h, n, member) list_add(tlist_raw((h), (n)), &(n)->member)
  120. /**
  121. * tlist_add_tail - add an entry at the end of a linked list.
  122. * @h: the tlist to add the node to
  123. * @n: the entry to add to the list.
  124. * @member: the member of n to add to the list.
  125. *
  126. * The list_node does not need to be initialized; it will be overwritten.
  127. * Example:
  128. * tlist_add_tail(&parent->children, child, list);
  129. * parent->num_children++;
  130. */
  131. #define tlist_add_tail(h, n, member) \
  132. list_add_tail(tlist_raw((h), (n)), &(n)->member)
  133. /**
  134. * tlist_del_from - delete an entry from a linked list.
  135. * @h: the tlist @n is in
  136. * @n: the entry to delete
  137. * @member: the member of n to remove from the list.
  138. *
  139. * This explicitly indicates which list a node is expected to be in,
  140. * which is better documentation and can catch more bugs.
  141. *
  142. * Note that this leaves @n->@member in an undefined state; it
  143. * can be added to another list, but not deleted again.
  144. *
  145. * See also: tlist_del()
  146. *
  147. * Example:
  148. * tlist_del_from(&parent->children, child, list);
  149. * parent->num_children--;
  150. */
  151. #define tlist_del_from(h, n, member) \
  152. list_del_from(tlist_raw((h), (n)), &(n)->member)
  153. /**
  154. * tlist_del - delete an entry from an unknown linked list.
  155. * @n: the entry to delete from the list.
  156. * @member: the member of @n which is in the list.
  157. *
  158. * Example:
  159. * tlist_del(child, list);
  160. * parent->num_children--;
  161. */
  162. #define tlist_del(n, member) \
  163. list_del(&(n)->member)
  164. /**
  165. * tlist_empty - is a list empty?
  166. * @h: the tlist
  167. *
  168. * If the list is empty, returns true.
  169. *
  170. * Example:
  171. * assert(tlist_empty(&parent->children) == (parent->num_children == 0));
  172. */
  173. #define tlist_empty(h) list_empty(&(h)->raw)
  174. /**
  175. * tlist_top - get the first entry in a list
  176. * @h: the tlist
  177. * @type: the type of the entry
  178. * @member: the list_node member of the type
  179. *
  180. * If the list is empty, returns NULL.
  181. *
  182. * Example:
  183. * struct child *first;
  184. * first = tlist_top(&parent->children, struct child, list);
  185. */
  186. #define tlist_top(h, type, member) \
  187. list_top(tlist_raw((h), (type *)NULL), type, member)
  188. /**
  189. * tlist_tail - get the last entry in a list
  190. * @h: the tlist
  191. * @type: the type of the entry
  192. * @member: the list_node member of the type
  193. *
  194. * If the list is empty, returns NULL.
  195. *
  196. * Example:
  197. * struct child *last;
  198. * last = tlist_tail(&parent->children, struct child, list);
  199. */
  200. #define tlist_tail(h, type, member) \
  201. list_tail(tlist_raw((h), (type *)NULL), type, member)
  202. /**
  203. * tlist_for_each - iterate through a list.
  204. * @h: the tlist
  205. * @i: an iterator of suitable type for this list.
  206. * @member: the list_node member of @i
  207. *
  208. * This is a convenient wrapper to iterate @i over the entire list. It's
  209. * a for loop, so you can break and continue as normal.
  210. *
  211. * Example:
  212. * tlist_for_each(&parent->children, child, list)
  213. * printf("Name: %s\n", child->name);
  214. */
  215. #define tlist_for_each(h, i, member) \
  216. list_for_each(tlist_raw((h), (i)), (i), member)
  217. /**
  218. * tlist_for_each_safe - iterate through a list, maybe during deletion
  219. * @h: the tlist
  220. * @i: an iterator of suitable type for this list.
  221. * @nxt: another iterator to store the next entry.
  222. * @member: the list_node member of the structure
  223. *
  224. * This is a convenient wrapper to iterate @i over the entire list. It's
  225. * a for loop, so you can break and continue as normal. The extra variable
  226. * @nxt is used to hold the next element, so you can delete @i from the list.
  227. *
  228. * Example:
  229. * struct child *next;
  230. * tlist_for_each_safe(&parent->children, child, next, list) {
  231. * tlist_del(child, list);
  232. * parent->num_children--;
  233. * }
  234. */
  235. #define tlist_for_each_safe(h, i, nxt, member) \
  236. list_for_each_safe(tlist_raw((h), (i)), (i), (nxt), member)
  237. #endif /* CCAN_TLIST_H */