/************************************************************************
 * AUTHOR: NiuJiuRu
 * FILENAME: swlist.h
 * DESCRIPTION: 双向循环链表
 * NOTE:
 * HISTORY:
 * 1, [2013-05-23] created by NiuJiuRu
 * 2, [2014-01-17] 修复"xlist_delete()"函数中, reset被删除节点时, 造成链表
                   结构被破坏的问题
 ***********************************************************************/
#ifndef __SWLIST_H__
#define __SWLIST_H__

// for "offsetof()"
#include <stddef.h>

// 定义链表节点结构
struct xlist_node
{
    struct xlist_node *prev;
    struct xlist_node *next;
};

// 初始化链表头节点
#define xlist_init(head_node_ptr) ((head_node_ptr)->prev = (head_node_ptr)->next = (head_node_ptr))

// 判断链表是否为空
#define xlist_isempty(head_node_ptr) ((head_node_ptr)->prev == (head_node_ptr) && (head_node_ptr)->next == (head_node_ptr))

// 在链表尾新增一个节点
#define xlist_add(head_node_ptr, new_node_ptr) \
    do{ \
        (new_node_ptr)->prev = (head_node_ptr)->prev; \
        (new_node_ptr)->prev->next = (new_node_ptr);  \
        (new_node_ptr)->next = (head_node_ptr);       \
        (head_node_ptr)->prev = (new_node_ptr);       \
    }while(0)

// 在链表中的某个节点后插入一个新节点
#define xlist_insert(one_node_ptr, new_node_ptr) \
    do{ \
        (new_node_ptr)->next = (one_node_ptr)->next; \
        (new_node_ptr)->next->prev = (new_node_ptr); \
        (new_node_ptr)->prev = (one_node_ptr);       \
        (one_node_ptr)->next = (new_node_ptr);       \
    }while(0)

// 从链表中移除一个节点
#define xlist_delete(one_node_ptr) \
    do{ \
        struct xlist_node *delete_node_ptr = one_node_ptr;  \
        (one_node_ptr)->next->prev = (one_node_ptr)->prev;  \
        (one_node_ptr)->prev->next = (one_node_ptr)->next;  \
        (delete_node_ptr)->prev = (delete_node_ptr)->next = (delete_node_ptr);  \
    }while(0)

// 将链表中的某个节点与其后续节点进行位置交换
#define xlist_swap(one_node_ptr) \
    do{ \
        struct xlist_node *next_node_ptr;              \
        (next_node_ptr) = (one_node_ptr)->next;        \
        (one_node_ptr)->next = (next_node_ptr)->next;  \
        (one_node_ptr)->next->prev = (one_node_ptr);   \
        (next_node_ptr)->prev = (one_node_ptr)->prev;  \
        (next_node_ptr)->prev->next = (next_node_ptr); \
        (next_node_ptr)->next = (one_node_ptr);	       \
        (one_node_ptr)->prev = (next_node_ptr);	       \
    }while(0)

// 替换链表中的一个节点
#define xlist_replace(old_node_ptr, new_node_ptr) \
    do{ \
        (new_node_ptr)->next = (old_node_ptr)->next;                  \
        (new_node_ptr)->next->prev = (new_node_ptr);                  \
        (new_node_ptr)->prev = (old_node_ptr)->prev;                  \
        (new_node_ptr)->prev->next = (new_node_ptr);                  \
        (old_node_ptr)->prev = (old_node_ptr)->next = (old_node_ptr); \
    }while(0)

// 根据链表中的某个节点地址, 获取该节点自身所在结构体对象的入口地址
#define xlist_entry(one_node_ptr, struct_name, member_name) \
    (struct_name *)((char *)(one_node_ptr) - offsetof(struct_name, member_name))

#endif /* __SWLIST_H__ */
