/*** * libccd * --------------------------------- * Copyright (c)2010 Daniel Fiser * * * This file is part of libccd. * * Distributed under the OSI-approved BSD License (the "License"); * see accompanying file BDS-LICENSE for details or see * . * * This software is distributed WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the License for more information. */ #ifndef __CCD_LIST_H__ #define __CCD_LIST_H__ #include #include #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ struct _ccd_list_t { struct _ccd_list_t *next, *prev; }; typedef struct _ccd_list_t ccd_list_t; /** * Get the struct for this entry. * @ptr: the &ccd_list_t pointer. * @type: the type of the struct this is embedded in. * @member: the name of the list_struct within the struct. */ #define ccdListEntry(ptr, type, member) \ ccd_container_of(ptr, type, member) /** * Iterates over list. */ #define ccdListForEach(list, item) \ for (item = (list)->next; \ _ccd_prefetch((item)->next), item != (list); \ item = (item)->next) /** * Iterates over list safe against remove of list entry */ #define ccdListForEachSafe(list, item, tmp) \ for (item = (list)->next, tmp = (item)->next; \ item != (list); \ item = tmp, tmp = (item)->next) /** * Iterates over list of given type. * @pos: the type * to use as a loop cursor. * @head: the head for your list. * @member: the name of the list_struct within the struct. */ #define ccdListForEachEntry(head, pos, postype, member) \ for (pos = ccdListEntry((head)->next, postype, member); \ _ccd_prefetch(pos->member.next), &pos->member != (head); \ pos = ccdListEntry(pos->member.next, postype, member)) /** * Iterates over list of given type safe against removal of list entry * @pos: the type * to use as a loop cursor. * @n: another type * to use as temporary storage * @head: the head for your list. * @member: the name of the list_struct within the struct. */ #define ccdListForEachEntrySafe(head, pos, postype, n, ntype, member) \ for (pos = ccdListEntry((head)->next, postype, member), \ n = ccdListEntry(pos->member.next, postype, member); \ &pos->member != (head); \ pos = n, n = ccdListEntry(n->member.next, ntype, member)) /** * Initialize list. */ _ccd_inline void ccdListInit(ccd_list_t *l); _ccd_inline ccd_list_t *ccdListNext(ccd_list_t *l); _ccd_inline ccd_list_t *ccdListPrev(ccd_list_t *l); /** * Returns true if list is empty. */ _ccd_inline int ccdListEmpty(const ccd_list_t *head); /** * Appends item to end of the list l. */ _ccd_inline void ccdListAppend(ccd_list_t *l, ccd_list_t *item); /** * Removes item from list. */ _ccd_inline void ccdListDel(ccd_list_t *item); /// /// INLINES: /// _ccd_inline void ccdListInit(ccd_list_t *l) { l->next = l; l->prev = l; } _ccd_inline ccd_list_t *ccdListNext(ccd_list_t *l) { return l->next; } _ccd_inline ccd_list_t *ccdListPrev(ccd_list_t *l) { return l->prev; } _ccd_inline int ccdListEmpty(const ccd_list_t *head) { return head->next == head; } _ccd_inline void ccdListAppend(ccd_list_t *l, ccd_list_t *newccd) { newccd->prev = l->prev; newccd->next = l; l->prev->next = newccd; l->prev = newccd; } _ccd_inline void ccdListDel(ccd_list_t *item) { item->next->prev = item->prev; item->prev->next = item->next; item->next = item; item->prev = item; } #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* __CCD_LIST_H__ */