#include <sys/queue.h>
#include <assert.h>
#include <stddef.h>
#include <stdbool.h>

#define HEADNAME_(S)                             S ## Head

#define BFX_INTRUSION(S)                         LIST_ENTRY(S) xx;
#define BFX_EXTRUSION_DECL(S)
#define BFX_EXTRUSION_FOLLOWUP(S)                LIST_HEAD(HEADNAME_(S), S);
#define BFX_LIST_HEAD_T(S)                       struct HEADNAME_(S)
#define BFX_LISTED_ELEM_T(S)                     S*

#define BFX_INSERT_FIRST(S, lst, item)           ({LIST_INSERT_HEAD(&lst, &item, xx); &item;})
#define BFX_INSERT_LAST(S, lst, item)            assert(false&&"unimplemented INSERT_LAST on lq-list")
#define BFX_INSERT_BEFORE(S, lst, item, refIter) ({LIST_INSERT_BEFORE(refIter, &item, xx); &item;})
#define BFX_INSERT_AFTER(S, lst, item, refIter)  ({LIST_INSERT_AFTER(refIter, &item, xx); &item;})
#define BFX_REMOVE_FIRST(S, lst)                 ({ S * first = LIST_FIRST( &lst ); LIST_REMOVE( first, xx ); })
#define BFX_REMOVE_LAST(S, lst)                  assert(false&&"unimplemented REMOVE_LAST on lq-list")
#define BFX_REMOVE_HERE(S, lst, refIter)         LIST_REMOVE( refIter, xx )
#define BFX_INIT(S, lst)                         LIST_INIT(&lst);

#define BFX_GET_FIRST(S, lst)                    LIST_FIRST(&lst)
#define BFX_GET_AFTER(S, lst, iter)              LIST_NEXT(iter, xx)
#define BFX_GET_BEFORE(S, lst, iter)             HACK_UNSUPPORTED_PREV(S, lst, iter, xx)
#define BFX_IS_VALID_POS(S, lst, iter)           ((iter)!=NULL)
#define BFX_DEREF_POS(S, lst, iter)              (iter)

#define HACK_UNSUPPORTED_PREV(S, lst, iter, NAME) ({ \
    S * answer = NULL; \
    S ** linkAtMe = (iter)->NAME.le_prev; \
    if ( &(lst) != (BFX_LIST_HEAD_T(S)*)linkAtMe ) { \
        answer = (S*)( (char*)linkAtMe - offsetof(S, NAME) ); \
    } \
    answer; \
})

#if 0
void bobs_moveNext() { observedItem = ((observedItem)->xx.le_next); } 
struct { struct B_UserItem *le_next; struct B_UserItem **le_prev; } xx;
struct { struct B_UserItem *tqe_next; struct B_UserItem * *tqe_prev; } xx;

void bobs_movePrev() { 
    observedItem = (*(((struct B_UserItemHead *)((observedItem)->xx.tqe_prev))->tqh_last)); } 

#endif
