156 lines
3.7 KiB
C
156 lines
3.7 KiB
C
/***
|
|
* libccd
|
|
* ---------------------------------
|
|
* Copyright (c)2010 Daniel Fiser <danfis@danfis.cz>
|
|
*
|
|
*
|
|
* This file is part of libccd.
|
|
*
|
|
* Distributed under the OSI-approved BSD License (the "License");
|
|
* see accompanying file BDS-LICENSE for details or see
|
|
* <http://www.opensource.org/licenses/bsd-license.php>.
|
|
*
|
|
* 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 <string.h>
|
|
#include <ccd/compiler.h>
|
|
|
|
#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 *new)
|
|
{
|
|
new->prev = l->prev;
|
|
new->next = l;
|
|
l->prev->next = new;
|
|
l->prev = new;
|
|
}
|
|
|
|
_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__ */
|