diff --git a/lib/iqueue.h b/lib/iqueue.h index ca1beee2e..2fcfb577b 100644 --- a/lib/iqueue.h +++ b/lib/iqueue.h @@ -27,6 +27,7 @@ ele_type *next; \ } link; \ } *offset; \ + const ele_type *const_ele; \ }; \ } @@ -79,9 +80,73 @@ } while (0) +#define i_queue_push_head(list, ele) do { \ + if ((list)->head) { \ + __auto_type __link = (__typeof((list)->offset)) (list)->head; \ + __link->link.prev = ele; \ + } \ + __auto_type __link = (__typeof((list)->offset)) ele; \ + __link->link.next = (list)->head; \ + (list)->head = ele; \ + if (!(list)->tail) \ + (list)->tail = ele; \ + (list)->length++; \ +} while (0) + + +#define i_queue_delete(list, ele) do { \ + __auto_type __link = (__typeof((list)->offset)) ele; \ + if (__link->link.next) { \ + __auto_type __next_link = (__typeof((list)->offset)) __link->link.next; \ + __next_link->link.prev = __link->link.prev; \ + } \ + else \ + (list)->tail = __link->link.prev; \ + if (__link->link.prev) { \ + __auto_type __prev_link = (__typeof((list)->offset)) __link->link.prev; \ + __prev_link->link.next = __link->link.next; \ + } \ + else \ + (list)->head = __link->link.next; \ +} while (0) + + #define IQUEUE_FOREACH(list, var) \ for (__typeof__ ( ({ __typeof__ (*(list)->head) __t; &__t; }) ) var = (list)->head; \ var; var = ((__typeof((list)->offset)) var)->link.next) +#define IQUEUE_FOREACH_SAFE_DECL(list, var) \ + __typeof__ ( ({ __typeof__ (*(list)->head) __t; &__t; }) ) var, __next ## var \ + + +#define IQUEUE_FOREACH_SAFE(list, var) \ + for (var = (list)->head, \ + __next ## var = var ? ((__typeof((list)->offset)) var)->link.next : NULL; \ + var; \ + var = __next ## var, \ + __next ## var = var ? ((__typeof((list)->offset)) var)->link.next : NULL) + + +#define i_queue_clear_full(list, fn) do { \ + IQUEUE_FOREACH_SAFE_DECL(list, __ele); \ + IQUEUE_FOREACH_SAFE(list, __ele) \ + (fn)(__ele); \ + i_queue_init(list); \ +} while (0) + + +#define i_queue_find(list, fn) ({ \ + __typeof__ ((list)->head) __ret = NULL; \ + bool (*__fn)(__typeof__ ((list)->const_ele)) = (fn); \ + IQUEUE_FOREACH(list, __ele) { \ + if (__fn(__ele)) { \ + __ret = __ele; \ + break; \ + } \ + } \ + __ret; \ +}) + + #endif