#ifndef UCS_LIST_H_
#define UCS_LIST_H_
#include <ucs/sys/compiler_def.h>
BEGIN_C_DECLS
#define UCS_LIST_INITIALIZER(_prev, _next) \
{ (_prev), (_next) }
#define UCS_LIST_HEAD(name) \
ucs_list_link_t name = UCS_LIST_INITIALIZER(&(name), &(name))
typedef struct ucs_list_link {
struct ucs_list_link *prev;
struct ucs_list_link *next;
} ucs_list_link_t;
static inline void ucs_list_head_init(ucs_list_link_t *head)
{
head->prev = head->next = head;
}
static inline void ucs_list_insert_replace(ucs_list_link_t *prev,
ucs_list_link_t *next,
ucs_list_link_t *elem)
{
elem->prev = prev;
elem->next = next;
prev->next = elem;
next->prev = elem;
}
static inline void ucs_list_replace(ucs_list_link_t *elem,
ucs_list_link_t *replacement)
{
ucs_list_insert_replace(elem->prev, elem->next, replacement);
}
static inline void ucs_list_insert_after(ucs_list_link_t *pos,
ucs_list_link_t *new_link)
{
ucs_list_insert_replace(pos, pos->next, new_link);
}
static inline void ucs_list_insert_before(ucs_list_link_t *pos,
ucs_list_link_t *new_link)
{
ucs_list_insert_replace(pos->prev, pos, new_link);
}
static inline void ucs_list_del(ucs_list_link_t *elem)
{
elem->prev->next = elem->next;
elem->next->prev = elem->prev;
}
static inline int ucs_list_is_empty(ucs_list_link_t *head)
{
return head->next == head;
}
static inline int ucs_list_is_only(ucs_list_link_t *head,
ucs_list_link_t *elem)
{
return (head->next == elem) && (elem->next == head);
}
static inline void ucs_list_splice_tail(ucs_list_link_t *head,
ucs_list_link_t *newlist)
{
ucs_list_link_t *first, *last, *tail;
if (ucs_list_is_empty(newlist)) {
return;
}
first = newlist->next;
last = newlist->prev;
tail = head->prev;
first->prev = tail;
tail->next = first;
last->next = head;
head->prev = last;
}
static inline unsigned long ucs_list_length(ucs_list_link_t *head)
{
unsigned long length;
ucs_list_link_t *ptr;
for (ptr = head->next, length = 0; ptr != head; ptr = ptr->next, ++length);
return length;
}
#define ucs_list_add_head(_head, _item) \
ucs_list_insert_after(_head, _item)
#define ucs_list_add_tail(_head, _item) \
ucs_list_insert_before(_head, _item)
#define ucs_list_prev(_elem, _type, _member) \
(ucs_container_of((_elem)->prev, _type, _member))
#define ucs_list_next(_elem, _type, _member) \
(ucs_container_of((_elem)->next, _type, _member))
#define ucs_list_head ucs_list_next
#define ucs_list_tail ucs_list_prev
#define ucs_list_for_each(_elem, _head, _member) \
for (_elem = ucs_container_of((_head)->next, ucs_typeof(*_elem), _member); \
&(_elem)->_member != (_head); \
_elem = ucs_container_of((_elem)->_member.next, ucs_typeof(*_elem), _member))
#define ucs_list_for_each_safe(_elem, _telem, _head, _member) \
for (_elem = ucs_container_of((_head)->next, ucs_typeof(*_elem), _member), \
_telem = ucs_container_of(_elem->_member.next, ucs_typeof(*_elem), _member); \
&_elem->_member != (_head); \
_elem = _telem, \
_telem = ucs_container_of(_telem->_member.next, ucs_typeof(*_telem), _member))
#define ucs_list_extract_head(_head, _type, _member) \
({ \
ucs_list_link_t *tmp = (_head)->next; \
ucs_list_del(tmp); \
ucs_container_of(tmp, _type, _member); \
})
END_C_DECLS
#endif