4 * Copyright (c) Tuomo Valkonen 1999-2005.
6 * You may distribute and modify this library under the terms of either
7 * the Clarified Artistic License or the GNU LGPL, version 2.1 or later.
17 static ObjList *reuse_first(ObjList **objlist)
19 ObjList *node=*objlist;
21 if(node!=NULL && node->watch.obj==NULL){
22 UNLINK_ITEM(*objlist, node, next, prev);
30 static ObjList *reuse_last(ObjList **objlist)
32 ObjList *node=*objlist;
39 if(node!=NULL && node->watch.obj==NULL){
40 UNLINK_ITEM(*objlist, node, next, prev);
48 static ObjList *reuse(ObjList **objlist)
50 ObjList *first=reuse_first(objlist);
51 ObjList *last=reuse_first(objlist);
63 static void optimise(ObjList **objlist)
65 ObjList *first=reuse_first(objlist);
66 ObjList *last=reuse_first(objlist);
75 void watch_handler(Watch *watch, Obj *obj)
77 ObjList *node=(ObjList*)watch;
79 assert(node->prev!=NULL);
82 /* Last item - can't free */
83 }else if(node->prev->next==NULL){
84 /* First item - can't free cheaply */
86 ObjList *tmp=node->prev;
87 node->next->prev=node->prev;
94 static void free_node(ObjList **objlist, ObjList *node)
96 watch_reset(&(node->watch));
97 UNLINK_ITEM(*objlist, node, next, prev);
102 static ObjList *mknode(void *obj)
114 watch_init(&(node->watch));
116 if(!watch_setup(&(node->watch), obj, watch_handler)){
125 static ObjList *objlist_find_node(ObjList *objlist, Obj *obj)
127 ObjList *node=objlist;
130 if(node->watch.obj==obj)
139 bool objlist_contains(ObjList *objlist, Obj *obj)
141 return (objlist_find_node(objlist, obj)!=NULL);
145 bool objlist_insert_last(ObjList **objlist, Obj *obj)
147 ObjList *node=reuse(objlist);
155 LINK_ITEM_LAST(*objlist, node, next, prev);
161 bool objlist_insert_first(ObjList **objlist, Obj *obj)
163 ObjList *node=reuse(objlist);
171 LINK_ITEM_FIRST(*objlist, node, next, prev);
177 bool objlist_reinsert_last(ObjList **objlist, Obj *obj)
183 node=objlist_find_node(*objlist, obj);
186 return objlist_insert_last(objlist, obj);
188 UNLINK_ITEM(*objlist, node, next, prev);
189 LINK_ITEM_LAST(*objlist, node, next, prev);
195 bool objlist_reinsert_first(ObjList **objlist, Obj *obj)
201 node=objlist_find_node(*objlist, obj);
204 return objlist_insert_first(objlist, obj);
206 UNLINK_ITEM(*objlist, node, next, prev);
207 LINK_ITEM_FIRST(*objlist, node, next, prev);
213 bool objlist_remove(ObjList **objlist, Obj *obj)
215 ObjList *node=objlist_find_node(*objlist, obj);
218 free_node(objlist, node);
226 void objlist_clear(ObjList **objlist)
228 while(*objlist!=NULL)
229 free_node(objlist, *objlist);
233 ObjListIterTmp objlist_iter_tmp=NULL;
236 void objlist_iter_init(ObjListIterTmp *state, ObjList *objlist)
242 Obj *objlist_iter(ObjListIterTmp *state)
246 while(obj==NULL && *state!=NULL){
247 obj=(*state)->watch.obj;
248 (*state)=(*state)->next;
255 void objlist_iter_rev_init(ObjListIterTmp *state, ObjList *objlist)
257 *state=(objlist==NULL ? NULL : objlist->prev);
261 Obj *objlist_iter_rev(ObjListIterTmp *state)
265 while(obj==NULL && *state!=NULL){
266 obj=(*state)->watch.obj;
267 *state=(*state)->prev;
268 if((*state)->next==NULL)
276 bool objlist_empty(ObjList *objlist)
281 FOR_ALL_ON_OBJLIST(Obj*, obj, objlist, tmp){
289 Obj *objlist_take_first(ObjList **objlist)
305 free_node(objlist, node);
311 Obj *objlist_take_last(ObjList **objlist)
329 free_node(objlist, node);