00001 //************************************************************************************ 00002 // Module : gobjlist.hpp 00003 // Date : 8/9/02 (DLR) 00004 // Copyright : 2002-2006 Copyright University Corporation for Atmospheric 00005 // Research 00006 // Description : Encapsulates the methods and data associated with 00007 // a simple object template linked list. This class was taken 00008 // largely from Algorithms and Data Structures in C++ 00009 // by Ameraal, although it has been recast as a template 00010 // class. 00011 // Derived From : none. 00012 // Modifications: 00013 //************************************************************************************ 00014 #if !defined(GOBJLIST_HPP) 00015 #define GOBJLIST_HPP 00016 00017 #include "gtypes.h" 00018 #include <iostream.h> 00019 #include <stdlib.h> 00020 #include "vectorop.hpp" 00021 #include "gfieldgroup.hpp" 00022 #include "gllbasis.hpp" 00023 #include "glbasis.hpp" 00024 00025 #if !defined(GVecOpList) 00026 # define GVecOpList GObjList<VectorOp> 00027 #endif 00028 00029 #if !defined(GFGList) 00030 # define GFGList GObjList<GFieldGroup> 00031 #endif 00032 00033 #if !defined(OBJLINKELEMT) 00034 #define OBJLINKELEMT 00035 #define ObjLinkElem LinkElemObj<TT> 00036 template<class TT> class LinkElemObj { 00037 public: 00038 GINT id; 00039 GBOOL cf; 00040 TT *member; 00041 ObjLinkElem *next; 00042 ObjLinkElem *prev; 00043 }; 00044 #endif 00045 00046 00047 template <class TT> class GObjList 00048 { 00049 00050 public: 00051 GObjList(GBOOL renumber_on_delete=FALSE); 00052 GObjList(GINT nelems, GBOOL renumber_on_delete=FALSE); 00053 GObjList(const GObjList &); 00054 ~GObjList(); 00055 00056 void add(); 00057 void add(TT *c, GBOOL delete_here=FALSE); 00058 TT *del(ObjLinkElem *c); 00059 TT *del(TT *c); 00060 TT *del(GINT id); 00061 inline void start(ObjLinkElem *p=NULL) { 00062 pCurr = ( p!=NULL ? p : pStart ); 00063 } 00064 GINT size() ; 00065 inline TT *member() { 00066 return pCurr ? pCurr->member : NULL; 00067 } 00068 inline TT *member(GINT id) { 00069 ObjLinkElem *e; 00070 if ( (e=find(id)) == NULL ) return NULL; 00071 return e->member; 00072 } 00073 inline ObjLinkElem *next() { 00074 ObjLinkElem *p = pCurr ? pCurr->next : NULL; 00075 pCurr = p; 00076 return pCurr; 00077 } 00078 ObjLinkElem *curr(); 00079 inline ObjLinkElem *find(GINT id) { 00080 ObjLinkElem *p=pCurr; 00081 // check from current pointer first: 00082 if ( p && p->id == id ) return p; 00083 else if ( p && p->next && p->next->id == id ) { 00084 next(); 00085 return p->next; 00086 } 00087 start(); // start at beginning and search: 00088 while ( (p=curr()) != NULL ) { 00089 if ( p->id == id ) return p; 00090 next(); 00091 } 00092 return NULL; 00093 } 00094 inline ObjLinkElem *find(TT *member) { 00095 ObjLinkElem *p=pCurr; 00096 // check from current pointer first: 00097 if ( p && p->member == member ) return p; 00098 else if ( p && p->next && p->next->member == member ) { 00099 next(); 00100 return p->next; 00101 } 00102 start(); // start at beginning and search: 00103 while ( (p=curr()) != NULL ) { 00104 if ( p->member == member ) return p; 00105 next(); 00106 } 00107 return NULL; 00108 } 00109 inline TT *&operator()(const GINT iElem) { 00110 ObjLinkElem *tt; 00111 #if !defined(GLIST_BOUNDS) 00112 tt=find(iElem); 00113 #else 00114 if ( (tt=find(iElem)) == NULL ) { 00115 cout << "GObjList::operator(): Cannot access element " << iElem << endl; 00116 exit(1); 00117 } 00118 #endif 00119 return tt->member; 00120 } 00121 inline TT *&operator[](const GINT iElem) { 00122 ObjLinkElem *tt; 00123 #if !defined(GLIST_BOUNDS) 00124 tt=find(iElem); 00125 #else 00126 if ( (tt=find(iElem)) == NULL ) { 00127 cout << "GObjList::operator[]: Cannot access element " << iElem << endl; 00128 exit(1); 00129 } 00130 #endif 00131 return tt->member; 00132 } 00133 GBOOL renumber(); 00134 void empty(); 00135 00136 friend ostream& operator<<(ostream&, GObjList<TT>&); 00137 00138 private: 00139 // Private methods: 00140 00141 protected: 00142 00143 // Private data: 00144 GINT nid; 00145 GINT num; 00146 GBOOL doRenumber; 00147 ObjLinkElem *pStart; 00148 ObjLinkElem *pCurr; 00149 ObjLinkElem *pEnd; 00150 00151 }; 00152 # if defined(_LINUX) || defined(_AIX) 00153 template class GObjList<VectorOp>; 00154 template class GObjList<GFieldGroup>; 00155 template class GObjList<GLLBasis>; 00156 template class GObjList<GLBasis>; 00157 ostream &operator <<(ostream&, const GObjList<GFieldGroup>&); 00158 # endif 00159 #endif 00160