WvStreams
|
00001 /* -*- Mode: C++ -*- 00002 * Worldvisions Weaver Software: 00003 * Copyright (C) 1997-2002 Net Integration Technologies, Inc. 00004 * 00005 * A linked list container. 00006 */ 00007 #ifndef __WVLINKLIST_H 00008 #define __WVLINKLIST_H 00009 00010 #include "wvtypetraits.h" 00011 #include "wvsorter.h" 00012 00021 class WvListBase 00022 { 00023 WvListBase(const WvListBase &l); // copy constructor - not actually defined anywhere! 00024 private: 00025 //This is private to force people to pass by reference, not by value 00026 WvListBase& operator= (const WvListBase &l); 00027 00028 public: 00029 WvLink head, *tail; 00030 00032 WvListBase() : head(NULL, false) 00033 { tail = &head; } 00034 00043 size_t count() const; 00044 00053 void reverse(); 00054 00062 bool isempty() const 00063 { return head.next == NULL; } 00064 00073 class IterBase 00074 { 00075 public: 00076 const WvListBase *list; 00077 WvLink *link, *prev; 00078 00083 IterBase(const WvListBase &l) 00084 { list = &l; link = NULL; } 00085 00090 void rewind() // dropping a const pointer here! Danger! 00091 { prev = NULL; link = &((WvListBase *)list)->head; } 00092 00093 00103 WvLink *next() 00104 { prev = link; return link = link->next; } 00105 00111 WvLink *cur() const 00112 { return link; } 00113 00118 void *vptr() const 00119 { return link->data; } 00120 00134 WvLink *find(const void *data); 00135 00146 WvLink *find_next(const void*data); 00147 }; 00148 }; 00149 00150 00196 template<class T> 00197 class WvList : public WvListBase 00198 { 00199 // copy constructor: not defined anywhere! 00200 WvList(const WvList &list); 00201 00202 public: 00204 WvList() 00205 { } 00206 00213 ~WvList() 00214 { zap(); } 00215 00217 void setup() {} 00218 00220 void shutdown() {} 00221 00228 void zap(bool destroy = true) 00229 { 00230 while (head.next) 00231 unlink_after(& head, destroy); 00232 } 00233 00241 T *first() const 00242 { return (T*)head.next->data; } 00243 00251 T *last() const 00252 { return (T*)tail->data; } 00253 00263 void add_after(WvLink *after, T *data, bool autofree, 00264 const char *id = NULL ) 00265 { 00266 (void)new WvLink((void *)data, after, tail, autofree, id); 00267 } 00268 00276 void append(T *data, bool autofree, const char *id = NULL) 00277 { add_after(tail, data, autofree, id); } 00278 00283 void add(T *data, bool autofree, const char *id = NULL) 00284 { append(data, autofree, id); } 00285 00293 void prepend(T *data, bool autofree, const char *id = NULL) 00294 { add_after(&head, data, autofree, id); } 00295 00303 void unlink(T *data) 00304 { Iter i(*this); while (i.find(data)) i.unlink(); } 00305 00312 void unlink_first() 00313 { 00314 if(head.next != NULL) 00315 { Iter i(*this); i.rewind(); i.next(); i.unlink(); } 00316 } 00325 void unlink_after(WvLink *after, bool destroy = true) 00326 { 00327 WvLink *next = after->next; 00328 if(next != NULL) 00329 { 00330 T *obj = (destroy && next->get_autofree()) ? 00331 static_cast<T*>(next->data) : NULL; 00332 if (next == tail) tail = after; 00333 next->unlink(after); 00334 if (obj) 00335 WvTraits<T>::release(obj); 00336 } 00337 } 00338 00350 class Iter : public WvListBase::IterBase 00351 { 00352 public: 00357 Iter(const WvList &l) : IterBase(l) 00358 { } 00359 00364 T *ptr() const 00365 { return (T *)link->data; } 00366 00367 WvIterStuff(T); 00368 00372 bool get_autofree() const 00373 { 00374 return link->get_autofree(); 00375 } 00376 00380 void set_autofree(bool autofree) 00381 { 00382 link->set_autofree(autofree); 00383 } 00384 00390 void unlink(bool destroy = true) 00391 { 00392 if (prev) ((WvList *)list)->unlink_after(prev, destroy); 00393 link = prev->next; 00394 } 00395 00409 void xunlink(bool destroy = true) 00410 { 00411 if (prev) ((WvList *)list)->unlink_after(prev, destroy); 00412 link = prev; 00413 } 00414 }; 00415 00417 typedef class WvSorter<T, WvListBase, WvListBase::IterBase> Sorter; 00418 }; 00419 00420 #define DeclareWvList2(_classname_, _type_) \ 00421 typedef class WvList<_type_> _classname_ 00422 00423 #define DeclareWvList(_type_) DeclareWvList2(_type_##List, _type_) 00424 00425 00426 #endif // __WVLINKLIST_H