X-Git-Url: https://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Ftlist%2Ftlist.h;h=a99191a2e0ebd75e9b13145550ac90d0a859f72e;hp=9f62869b2b19c23c3fcb812ed2a6420a45a847a7;hb=03f100b281441a953d4ec858389f82e25a95c043;hpb=be2b527792d574ef8cf506d1a168d92354e23cc5 diff --git a/ccan/tlist/tlist.h b/ccan/tlist/tlist.h index 9f62869b..a99191a2 100644 --- a/ccan/tlist/tlist.h +++ b/ccan/tlist/tlist.h @@ -11,15 +11,16 @@ * * This declares a structure "struct tlist_@suffix" to use for * lists containing this type. The actual list can be accessed using - * ".raw" or tlist_raw(). + * ".raw" or tlist_raw(). For maximum portability, place tlists + * embedded in structures as the last member. * * Example: * // Defines struct tlist_children * TLIST_TYPE(children, struct child); * struct parent { * const char *name; - * struct tlist_children children; * unsigned int num_children; + * struct tlist_children children; * }; * * struct child { @@ -178,32 +179,64 @@ /** * tlist_top - get the first entry in a list * @h: the tlist - * @type: the type of the entry * @member: the list_node member of the type * * If the list is empty, returns NULL. * * Example: * struct child *first; - * first = tlist_top(&parent->children, struct child, list); + * first = tlist_top(&parent->children, list); + * if (!first) + * printf("Empty list!\n"); */ -#define tlist_top(h, type, member) \ - list_top(tlist_raw((h), (type *)NULL), type, member) +#define tlist_top(h, member) \ + ((tcon_type((h), canary)) \ + list_top_(&(h)->raw, \ + (char *)(&(h)->_tcon[0].canary->member) - \ + (char *)((h)->_tcon[0].canary))) /** * tlist_tail - get the last entry in a list * @h: the tlist - * @type: the type of the entry * @member: the list_node member of the type * * If the list is empty, returns NULL. * * Example: * struct child *last; - * last = tlist_tail(&parent->children, struct child, list); + * last = tlist_tail(&parent->children, list); + * if (!last) + * printf("Empty list!\n"); + */ +#define tlist_tail(h, member) \ + ((tcon_type((h), canary)) \ + list_tail_(&(h)->raw, \ + (char *)(&(h)->_tcon[0].canary->member) - \ + (char *)((h)->_tcon[0].canary))) + +/** + * tlist_next - get the next entry in a list + * @h: the tlist + * @n: the list element + * @member: the list_node member of the type + * + * Returns the element of list @h immediately after @n, or NULL, if @n + * is the last element in the list. + */ +#define tlist_next(h, n, member) \ + list_next(tlist_raw((h), (n)), (n), member) + +/** + * tlist_prev - get the previous entry in a list + * @h: the tlist + * @n: the list element + * @member: the list_node member of the type + * + * Returns the element of list @h immediately before @n, or NULL, if + * @n is the first element in the list. */ -#define tlist_tail(h, type, member) \ - list_tail(tlist_raw((h), (type *)NULL), type, member) +#define tlist_prev(h, n, member) \ + list_prev(tlist_raw((h), (n)), (n), member) /** * tlist_for_each - iterate through a list. @@ -221,6 +254,22 @@ #define tlist_for_each(h, i, member) \ list_for_each(tlist_raw((h), (i)), (i), member) +/** + * tlist_for_each - iterate through a list backwards. + * @h: the tlist + * @i: an iterator of suitable type for this list. + * @member: the list_node member of @i + * + * This is a convenient wrapper to iterate @i over the entire list. It's + * a for loop, so you can break and continue as normal. + * + * Example: + * tlist_for_each_rev(&parent->children, child, list) + * printf("Name: %s\n", child->name); + */ +#define tlist_for_each_rev(h, i, member) \ + list_for_each_rev(tlist_raw((h), (i)), (i), member) + /** * tlist_for_each_safe - iterate through a list, maybe during deletion * @h: the tlist