00001 //************************************************************************************// 00002 // Module : siforcelist.hpp 00003 // Date : 5/9/03 (DLR) 00004 // Copyright : 2003-2006 Copyright University Corporation for Atmospheric 00005 // Research 00006 // Description : Encapsulates the methods and data associated with 00007 // a linked list for state-independent (SIForce-based) 00008 // forces. It was taken largely from Algorithms and Data Structures 00009 // in C++ by Ameraal, although it has been modified significantly. 00010 // 00011 // NOTE: it is clear that this class and the GFieldList template 00012 // can be derived from a common base class. The GElemList may also 00013 // be recast in this way, but there is some ambiguity because 00014 // the Elem is also a base class itself, and the syntax may 00015 // cause difficulty on some OS's. 00016 // Derived From : none. 00017 // Modifications: 00018 //************************************************************************************// 00019 #if !defined(SIFORCELIST_HPP) 00020 #define SIFORCELIST_HPP 00021 00022 #include "gtypes.h" 00023 #include "siforce.hpp" 00024 #include <iostream.h> 00025 #include <stdlib.h> 00026 00027 #if !defined(SIFORCELIST_MEM) 00028 #define SIFORCELIST_MEM 00029 struct SIForceListSt { 00030 GINT id; // Key id 00031 GBOOL cf; // Was member fully instantiated? 00032 SIForce *member; // Member data 00033 SI_FORCE_TYPE type; // Element type id 00034 SIForceListSt *next; // Next in list 00035 SIForceListSt *prev; // Previous in list 00036 }; 00037 #endif 00038 00039 00040 00041 class SIForceList 00042 { 00043 00044 public: 00045 SIForceList(); 00046 SIForceList(const SIForceList &); 00047 ~SIForceList(); 00048 00049 void add(SIForce *c, GBOOL delete_here=FALSE); 00050 SIForce *del(SIForceListSt *c); 00051 SIForce *del(SIForce *c); 00052 SIForce *del(GINT id); 00053 inline void start(SIForceListSt *p=NULL) { 00054 pCurr = ( p!=NULL ? p : pStart ); 00055 } 00056 GINT size() const; 00057 inline SIForce *member() { 00058 SIForceListSt *e; 00059 e = pCurr ? pCurr : pEnd; 00060 if ( e == NULL ) return NULL; 00061 return e->member; 00062 } 00063 inline SIForce *member(GINT id) { 00064 SIForceListSt *e; 00065 if ( (e=find(id)) == NULL ) return NULL; 00066 return e->member; 00067 } 00068 inline SIForceListSt *next() { 00069 SIForceListSt *p = pCurr; 00070 if ( pCurr != NULL ) p = pCurr->next; 00071 pCurr = p; 00072 return pCurr; 00073 } 00074 SIForceListSt *curr(); 00075 inline SIForceListSt *find(GINT id) { 00076 SIForceListSt *p=pCurr; 00077 // check from current pointer first: 00078 if ( p && p->id == id ) return p; 00079 else if ( p && p->next && p->next->id == id ) { 00080 next(); 00081 return p->next; 00082 } 00083 start(NULL); // start at beginning and search: 00084 while ( (p=curr()) != NULL ) { 00085 if ( p->id == id ) return p; 00086 next(); 00087 } 00088 return NULL; 00089 } 00090 inline SIForceListSt *find(SIForce *member) { 00091 SIForceListSt *p=pCurr; 00092 // check from current pointer first: 00093 if ( p && p->member == member ) return p; 00094 else if ( p && p->next && p->next->member == member ) { 00095 next(); 00096 return p->next; 00097 } 00098 start(NULL); // start at beginning and search: 00099 while ( (p=curr()) != NULL ) { 00100 if ( p->member == member ) return p; 00101 next(); 00102 } 00103 return NULL; 00104 } 00105 inline SIForce *operator()(const GINT iElem) { 00106 SIForceListSt *tt; 00107 #if !defined(GLIST_BOUNDS) 00108 tt=find(iElem); 00109 #else 00110 00111 if ( (tt=find(iElem)) == NULL || tt->member == NULL ) { 00112 cout << "SIForceList::operator(): Cannot access element " << iElem << endl; 00113 exit(1); 00114 } 00115 #endif 00116 return tt->member; 00117 } 00118 inline SIForce *operator[](const GINT iElem) { 00119 SIForceListSt *tt; 00120 #if !defined(GLIST_BOUNDS) 00121 tt=find(iElem); 00122 #else 00123 if ( (tt=find(iElem)) == NULL || tt->member == NULL ) { 00124 cout << "SIForceList::operator[]: Cannot access element " << iElem << endl; 00125 exit(1); 00126 } 00127 #endif 00128 return tt->member; 00129 } 00130 GBOOL renumber(); 00131 void empty(); 00132 00133 // Private data: 00134 GINT nid; 00135 GINT num; 00136 SIForceListSt *pStart; 00137 SIForceListSt *pCurr; 00138 SIForceListSt *pEnd; 00139 }; 00140 #endif 00141