rbdlsim/3rdparty/libccd/src/list.h

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__ */