MeVisLabToolboxReference
|
00001 // **InsertLicense** code 00002 //----------------------------------------------------------------------------- 00003 00004 #ifndef _SB_LIST_ 00005 #define _SB_LIST_ 00006 00007 #include "SoShaderSystem.h" 00008 00012 00013 // This class is loosely derived from class SbPList. 00014 00015 template <class Type> 00016 class SbList 00017 { 00018 public: 00019 00020 // Constructor 00021 SbList() { 00022 ptrs = NULL; 00023 nPtrs = ptrsSize = 0; 00024 00025 setSize(0); 00026 } 00027 00028 // Constructor allocates enough room for the given number of pointers 00029 SbList(int initSize) { 00030 ptrs = NULL; 00031 nPtrs = ptrsSize = 0; 00032 00033 setSize(initSize); // Makes enough room for initSize entries 00034 setSize(0); // Sets nPtrs back to 0 00035 } 00036 00037 // Constructor for copying 00038 SbList(const SbList &pl) { 00039 nPtrs = pl.nPtrs; 00040 ptrsSize = pl.ptrsSize; 00041 ptrs = new Type[ptrsSize]; 00042 00043 for(int i = 0; i < nPtrs; i++) 00044 ptrs[i] = pl.ptrs[i]; 00045 } 00046 00047 // Destructor 00048 ~SbList() { 00049 delete [] ptrs; 00050 } 00051 00052 // Adds given pointer to end of list 00053 void append(const Type &value) { 00054 if(nPtrs + 1 > ptrsSize) expand(nPtrs + 1); 00055 ptrs[nPtrs++] = value; 00056 } 00057 00058 // Returns index of given pointer in list, or -1 if not found 00059 int find(const Type &value) const { 00060 for(int i = 0; i < nPtrs; i++) 00061 if(ptrs[i] == value) 00062 return(i); 00063 00064 return -1; // Not found 00065 } 00066 00067 // Inserts given pointer in list before pointer with given index 00068 void insert(const Type &value, int addBefore) { 00069 // If addBefore is off the end of the list, grow the list (and 00070 // initialize any new elements to NULL) 00071 if(addBefore > nPtrs) grow(addBefore); 00072 00073 // Make room for one more 00074 setSize(nPtrs + 1); 00075 00076 // Move pointers forward to make room 00077 for(int i = nPtrs - 1; i > addBefore; --i) 00078 ptrs[i] = ptrs[i - 1]; 00079 00080 // Insert the new one 00081 ptrs[addBefore] = value; 00082 } 00083 00084 // Removes pointer with given index 00085 void remove(int which) { 00086 // Move all pointers after the ith one backward 00087 for(int i = which; i < nPtrs - 1; i++) 00088 ptrs[i] = ptrs[i + 1]; 00089 00090 // Shrink the list 00091 setSize(nPtrs - 1); 00092 } 00093 00094 // Returns number of pointers in list 00095 int getLength() const { 00096 return nPtrs; 00097 } 00098 00099 // Removes all pointers after one with given index, inclusive 00100 // ??? should really be an error check in here 00101 void truncate(int start) { 00102 nPtrs = start; 00103 } 00104 00105 // Copy a PList 00106 void copy(const SbList &pl) { 00107 setSize(pl.nPtrs); 00108 00109 for(int i = 0; i < nPtrs; i++) 00110 ptrs[i] = pl.ptrs[i]; 00111 } 00112 00113 SbList &operator =(const SbList &pl) { 00114 copy(pl); return *this; 00115 } 00116 00117 // Returns pointer with given index 00118 Type &operator [](int i) const { 00119 if(i >= nPtrs) grow(i); 00120 return ptrs[i]; 00121 } 00122 00123 // equality tests 00124 int operator ==(const SbList &pl) const { 00125 return pl.nPtrs == nPtrs ? compare(pl) : FALSE; 00126 } 00127 int operator !=(const SbList &pl) const { 00128 return pl.nPtrs == nPtrs ? ! compare(pl) : TRUE; 00129 } 00130 00131 // Internal versions of [] that do not check for bounds: 00132 SoINTERNAL public: 00133 00134 void * get(int i) const { 00135 return ptrs[i]; 00136 } 00137 void set(int i, void *j) { 00138 ptrs[i] = j; 00139 } 00140 00141 private: 00142 00143 // NOTE: this must be called only if the number of elements in the two 00144 // lists is the same, otherwise badness could result 00145 int compare(const SbList &pl) const { 00146 for(int i = 0; i < nPtrs; i++) 00147 if((*this)[i] != pl[i]) 00148 return FALSE; 00149 00150 return TRUE; 00151 } 00152 00153 Type *ptrs; // The collection of pointers 00154 int nPtrs; // Number of pointers used 00155 int ptrsSize; // Number of pointers allocated 00156 00157 // There are three(!) methods to expand the list. grow() is used 00158 // when space is dynamically created, and needs to be initialized 00159 // to NULL: 00160 void grow(int max) const { 00161 int newSize = max+1; 00162 int oldSize = nPtrs; 00163 00164 #ifdef DEBUG 00165 if(newSize <= oldSize) 00166 SoDebugError::post("(internal) SbList::grow", "newSize <= oldSize!"); 00167 #endif // DEBUG 00168 00169 // Get around the const thing: 00170 SbList *me = (SbList *)this; 00171 00172 me->setSize(newSize); 00173 00174 for(int i = oldSize; i < newSize; i++) 00175 me->ptrs[i] = NULL; 00176 } 00177 00178 // setSize is used by grow and in other places internally where we 00179 // know that nothing needs to be initialized to NULL. 00180 void setSize(int size) { 00181 if(size > ptrsSize) expand(size); 00182 nPtrs = size; 00183 } 00184 00185 // expand is the lowest level routine. It just reallocates the 00186 // array and copies over the old values. 00187 void expand(int size) { 00188 if(ptrsSize == 0) 00189 ptrsSize = 4; 00190 00191 while(size > ptrsSize) { 00192 #ifdef DEBUG 00193 // check for overflow 00194 int oldPtrsSize = ptrsSize; 00195 ptrsSize *= 2; 00196 if(ptrsSize < oldPtrsSize) 00197 SoDebugError::post("SbList::expand", "Attempt to expand list beyond capacity;\n A core dump is likely"); 00198 #else 00199 ptrsSize *= 2; 00200 #endif 00201 } 00202 00203 Type *newPtrs = new Type[ptrsSize]; 00204 00205 if(ptrs != NULL) { 00206 for(int i = 0; i < nPtrs; i++) 00207 newPtrs[i] = ptrs[i]; 00208 delete [] ptrs; 00209 } 00210 00211 ptrs = newPtrs; 00212 } 00213 }; 00214 00215 #endif // _SB_LIST_