00001 #ifndef __OUC_DLIST__ 00002 #define __OUC_DLIST__ 00003 /******************************************************************************/ 00004 /* */ 00005 /* X r d O u c D L l i s t . h h */ 00006 /* */ 00007 /*(c) 2003 by the Board of Trustees of the Leland Stanford, Jr., University */ 00008 /* All Rights Reserved */ 00009 /*Produced by Andrew Hanushevsky for Stanford University under contract */ 00010 /* DE-AC03-76-SFO0515 with the Deprtment of Energy */ 00011 /******************************************************************************/ 00012 00013 // $Id: XrdOucDLlist.hh 22437 2008-03-04 14:35:16Z rdm $ 00014 00015 template<class T> 00016 class XrdOucDLlist 00017 { 00018 public: 00019 00020 XrdOucDLlist(T *itemval=0) {prev=this; next=this; item=itemval;} 00021 ~XrdOucDLlist() {if (prev != next) Remove();} 00022 00023 // Apply() applies the specified function to every item in the list. Apply() 00024 // is pointer-safe in that the current node pointers may be changed 00025 // without affecting the traversal of the list. An argument may be 00026 // passed to the function. A null pointer is returned if the list 00027 // was completely traversed. Otherwise, the pointer to the node on 00028 // which the applied function returned a non-zero value is returned. 00029 // An optional starting point may be passed. 00030 // 00031 T *Apply(int (*func)(T *, void *), void *Arg, XrdOucDLlist *Start=0) 00032 {XrdOucDLlist *nextnode, *node; 00033 if (Start) node = Start; // Set correct starting point 00034 else node = this; 00035 00036 // Iterate through the list until we hit ourselves again. We do the 00037 // loop once on the current node to allow for anchorless lists. 00038 // 00039 do {nextnode = node->next; 00040 if (node->item && (*func)(node->item, Arg)) return node->item; 00041 node = nextnode; 00042 } while (node != this); 00043 00044 // All done, indicate we went through the whole list 00045 // 00046 return (T *)0; 00047 } 00048 00049 // Insert() inserts the specified node immediately off itself. If an item value 00050 // is not given, it is not changed. 00051 // 00052 void Insert(XrdOucDLlist *Node, T *Item=0) 00053 {Node->next = next; // Chain in the item; 00054 next->prev = Node; 00055 next = Node; 00056 Node->prev = this; 00057 if (Item) Node->item = Item; 00058 } 00059 00060 // Item() supplies the item value associated with itself (used with Next()). 00061 // 00062 T *Item() {return item;} 00063 00064 // Remove() removes itself from whatever list it happens to be in. 00065 // 00066 void Remove() 00067 {prev->next = next; // Unchain the item 00068 next->prev = prev; 00069 next = this; 00070 prev = this; 00071 } 00072 00073 // Next() supplies the next list node. 00074 // 00075 XrdOucDLlist *Next() {return next;} 00076 00077 // Prev() supplies the prev list node. 00078 // 00079 XrdOucDLlist *Prev() {return prev;} 00080 00081 // Set the item pointer 00082 // 00083 void setItem(T *ival) {item = ival;} 00084 00085 // Singleton() indicates whether or not the node points to something 00086 // 00087 int Singleton() {return next == this;} 00088 00089 private: 00090 XrdOucDLlist *next; 00091 XrdOucDLlist *prev; 00092 T *item; 00093 }; 00094 #endif