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
*UNUSED(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
);