#ifndef _ll_delete
#define _ll_delete free
#endif

#ifndef _ll_ffirst
#define _ll_ffirst _cat(first_,_ll_rec)
#endif

#ifndef _ll_flast
#define _ll_flast _cat(last_,_ll_rec)
#endif

#ifndef _ll_fnext
#define _ll_fnext _cat(next_,_ll_rec)
#endif

#ifndef _ll_dropfn
#define _ll_dropfn _cat(_cat(_ll_ns,_),_cat(drop_, _ll_rec))
#endif

#ifndef _ll_pushfn
#define _ll_pushfn _cat(_cat(_ll_ns,_),_cat(push_, _ll_rec))
#endif

void _ll_dropfn
(_ll_box* box, _ll_obj* obj) {
	if(box -> _ll_ffirst == obj) {
		if(box -> _ll_flast == obj) {
			box -> _ll_ffirst = box -> _ll_flast = null;
		} else {
			box -> _ll_ffirst = obj -> _ll_fnext;
		}
	} else {
		_ll_obj* a;
		if(box -> _ll_flast == obj) {
			_ll_iter (box, a) {
				if(a->_ll_fnext == obj) {
					box -> _ll_flast = a;
					a -> _ll_fnext = null;
					goto found1;
				}
			}
			_fatal("BUG in last elt deletion routine");
			found1 :;
		} else /* in the middle */ {
			_ll_iter (box, a) {
				if(a->_ll_fnext == obj) {
					a->_ll_fnext = obj -> _ll_fnext;
					goto found2;
				}
			}
			_fatal("BUG in elt deletion routine");
			found2 :;
		}
	}
	_ll_delete (obj);
}

#undef _ll_ffirst
#undef _ll_flast
#undef _ll_ns
#undef _ll_box
#undef _ll_obj
#undef _ll_rec
#undef _ll_iter
#undef _ll_delete
