/*
    zlist.h - double linked lists
    Copyright (C) 2011 Ladislav Vaiz <ok1zia@nagano.cz>

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    version 2 as published by the Free Software Foundation.

*/

#ifndef __ZLIST_H
#define __ZLIST_H


struct list_head {
    void *next;
    void *prev;
};

#define init_list(x) {(x).next=&(x); (x).prev=&(x);}
#define list_empty(x) ((x).next == &(x))
#define del_from_list(x) {((struct list_head *)(x)->next)->prev=(x)->prev; ((struct list_head *)(x)->prev)->next=(x)->next;}
#define add_at_pos(p,x) do {(x)->next=(p)->next; (x)->prev=(p); (p)->next=(x); (x)->next->prev=(x);} while(0)
#define free_list(l) {while ((l).next != &(l)) {struct list_head *a=(l).next; del_from_list(a); g_free(a); }}

#ifdef __GNUC__

#define add_to_list(l,x) add_at_pos((typeof(x))&(l),(x))
#define foreach(e,l) for ((e)=(l).next; (e)!=(typeof(e))&(l); (e)=(e)->next)
#define foreachback(e,l) for ((e)=(l).prev; (e)!=(typeof(e))&(l); (e)=(e)->prev)

#else

struct xlist_head {
    struct xlist_head *next;
    struct xlist_head *prev;
};
#define add_to_list(l,x) add_at_pos((struct xlist_head *)&(l),(struct xlist_head *)(x))
#define foreach(e,l) for ((e)=(l).next; (e)!=(void *)&(l); (e)=(e)->next)
#define foreachback(e,l) for ((e)=(l).prev; (e)!=(void *)&(l); (e)=(e)->prev)

#endif




#endif
