00001 00031 #ifndef LL_LLDQUEUEPTR_H 00032 #define LL_LLDQUEUEPTR_H 00033 00034 template <class Type> 00035 class LLDynamicQueuePtr 00036 { 00037 public: 00038 enum 00039 { 00040 OKAY = 0, 00041 FAIL = -1 00042 }; 00043 00044 LLDynamicQueuePtr(const S32 size=8); 00045 ~LLDynamicQueuePtr(); 00046 00047 void init(); 00048 void destroy(); 00049 void reset(); 00050 void realloc(U32 newsize); 00051 00052 // ACCESSORS 00053 const Type& get(const S32 index) const; // no bounds checking 00054 Type& get(const S32 index); // no bounds checking 00055 const Type& operator [] (const S32 index) const { return get(index); } 00056 Type& operator [] (const S32 index) { return get(index); } 00057 S32 find(const Type &obj) const; 00058 00059 S32 count() const { return (mLastObj >= mFirstObj ? mLastObj - mFirstObj : mLastObj + mMaxObj - mFirstObj); } 00060 S32 getMax() const { return mMaxObj; } 00061 S32 getFirst() const { return mFirstObj; } 00062 S32 getLast () const { return mLastObj; } 00063 00064 // MANIPULATE 00065 S32 push(const Type &obj); // add to end of Queue, returns index from start 00066 S32 pull( Type &obj); // pull from Queue, returns index from start 00067 00068 S32 remove (S32 index); // remove by index 00069 S32 removeObj(const Type &obj); // remove by object 00070 00071 protected: 00072 S32 mFirstObj, mLastObj, mMaxObj; 00073 Type* mMemory; 00074 00075 public: 00076 00077 void print() 00078 { 00079 /* 00080 Convert this to llinfos if it's intended to be used - djs 08/30/02 00081 00082 printf("Printing from %d to %d (of %d): ",mFirstObj, mLastObj, mMaxObj); 00083 00084 if (mFirstObj <= mLastObj) 00085 { 00086 for (S32 i=mFirstObj;i<mLastObj;i++) 00087 { 00088 printf("%d ",mMemory[i]); 00089 } 00090 } 00091 else 00092 { 00093 for (S32 i=mFirstObj;i<mMaxObj;i++) 00094 { 00095 printf("%d ",mMemory[i]); 00096 } 00097 for (i=0;i<mLastObj;i++) 00098 { 00099 printf("%d ",mMemory[i]); 00100 } 00101 } 00102 printf("\n"); 00103 */ 00104 } 00105 00106 }; 00107 00108 00109 //-------------------------------------------------------- 00110 // LLDynamicQueuePtrPtr implementation 00111 //-------------------------------------------------------- 00112 00113 00114 template <class Type> 00115 inline LLDynamicQueuePtr<Type>::LLDynamicQueuePtr(const S32 size) 00116 { 00117 init(); 00118 realloc(size); 00119 } 00120 00121 template <class Type> 00122 inline LLDynamicQueuePtr<Type>::~LLDynamicQueuePtr() 00123 { 00124 destroy(); 00125 } 00126 00127 template <class Type> 00128 inline void LLDynamicQueuePtr<Type>::init() 00129 { 00130 mFirstObj = 0; 00131 mLastObj = 0; 00132 mMaxObj = 0; 00133 mMemory = NULL; 00134 } 00135 00136 template <class Type> 00137 inline void LLDynamicQueuePtr<Type>::realloc(U32 newsize) 00138 { 00139 if (newsize) 00140 { 00141 if (mFirstObj > mLastObj && newsize > mMaxObj) 00142 { 00143 Type* new_memory = new Type[newsize]; 00144 00145 llassert(new_memory); 00146 00147 S32 _count = count(); 00148 S32 i, m = 0; 00149 for (i=mFirstObj; i < mMaxObj; i++) 00150 { 00151 new_memory[m++] = mMemory[i]; 00152 } 00153 for (i=0; i <=mLastObj; i++) 00154 { 00155 new_memory[m++] = mMemory[i]; 00156 } 00157 00158 delete[] mMemory; 00159 mMemory = new_memory; 00160 00161 mFirstObj = 0; 00162 mLastObj = _count; 00163 } 00164 else 00165 { 00166 Type* new_memory = new Type[newsize]; 00167 00168 llassert(new_memory); 00169 00170 S32 i, m = 0; 00171 for (i=0; i < mLastObj; i++) 00172 { 00173 new_memory[m++] = mMemory[i]; 00174 } 00175 delete[] mMemory; 00176 mMemory = new_memory; 00177 } 00178 } 00179 else if (mMemory) 00180 { 00181 delete[] mMemory; 00182 mMemory = NULL; 00183 } 00184 00185 mMaxObj = newsize; 00186 } 00187 00188 template <class Type> 00189 inline void LLDynamicQueuePtr<Type>::destroy() 00190 { 00191 reset(); 00192 delete[] mMemory; 00193 mMemory = NULL; 00194 } 00195 00196 00197 template <class Type> 00198 void LLDynamicQueuePtr<Type>::reset() 00199 { 00200 for (S32 i=0; i < mMaxObj; i++) 00201 { 00202 get(i) = NULL; // unrefs for pointers 00203 } 00204 00205 mFirstObj = 0; 00206 mLastObj = 0; 00207 } 00208 00209 00210 template <class Type> 00211 inline S32 LLDynamicQueuePtr<Type>::find(const Type &obj) const 00212 { 00213 S32 i; 00214 if (mFirstObj <= mLastObj) 00215 { 00216 for ( i = mFirstObj; i < mLastObj; i++ ) 00217 { 00218 if (mMemory[i] == obj) 00219 { 00220 return i; 00221 } 00222 } 00223 } 00224 else 00225 { 00226 for ( i = mFirstObj; i < mMaxObj; i++ ) 00227 { 00228 if (mMemory[i] == obj) 00229 { 00230 return i; 00231 } 00232 } 00233 for ( i = 0; i < mLastObj; i++ ) 00234 { 00235 if (mMemory[i] == obj) 00236 { 00237 return i; 00238 } 00239 } 00240 } 00241 00242 return FAIL; 00243 } 00244 00245 template <class Type> 00246 inline S32 LLDynamicQueuePtr<Type>::remove(S32 i) 00247 { 00248 if (mFirstObj > mLastObj) 00249 { 00250 if (i >= mFirstObj && i < mMaxObj) 00251 { 00252 while( i > mFirstObj) 00253 { 00254 mMemory[i] = mMemory[i-1]; 00255 i--; 00256 } 00257 mMemory[mFirstObj] = NULL; 00258 mFirstObj++; 00259 if (mFirstObj >= mMaxObj) mFirstObj = 0; 00260 00261 return count(); 00262 } 00263 else if (i < mLastObj && i >= 0) 00264 { 00265 while(i < mLastObj) 00266 { 00267 mMemory[i] = mMemory[i+1]; 00268 i++; 00269 } 00270 mMemory[mLastObj] = NULL; 00271 mLastObj--; 00272 if (mLastObj < 0) mLastObj = mMaxObj-1; 00273 00274 return count(); 00275 } 00276 } 00277 else if (i <= mLastObj && i >= mFirstObj) 00278 { 00279 while(i < mLastObj) 00280 { 00281 mMemory[i] = mMemory[i+1]; 00282 i++; 00283 } 00284 mMemory[mLastObj] = NULL; 00285 mLastObj--; 00286 if (mLastObj < 0) mLastObj = mMaxObj-1; 00287 00288 return count(); 00289 } 00290 00291 00292 return FAIL; 00293 } 00294 00295 template <class Type> 00296 inline S32 LLDynamicQueuePtr<Type>::removeObj(const Type& obj) 00297 { 00298 S32 ind = find(obj); 00299 if (ind >= 0) 00300 { 00301 return remove(ind); 00302 } 00303 return FAIL; 00304 } 00305 00306 template <class Type> 00307 inline S32 LLDynamicQueuePtr<Type>::push(const Type &obj) 00308 { 00309 if (mMaxObj - count() <= 1) 00310 { 00311 realloc(mMaxObj * 2); 00312 } 00313 00314 mMemory[mLastObj++] = obj; 00315 00316 if (mLastObj >= mMaxObj) 00317 { 00318 mLastObj = 0; 00319 } 00320 00321 return count(); 00322 } 00323 00324 template <class Type> 00325 inline S32 LLDynamicQueuePtr<Type>::pull(Type &obj) 00326 { 00327 obj = NULL; 00328 00329 if (count() < 1) return -1; 00330 00331 obj = mMemory[mFirstObj]; 00332 mMemory[mFirstObj] = NULL; 00333 00334 mFirstObj++; 00335 00336 if (mFirstObj >= mMaxObj) 00337 { 00338 mFirstObj = 0; 00339 } 00340 00341 return count(); 00342 } 00343 00344 template <class Type> 00345 inline const Type& LLDynamicQueuePtr<Type>::get(const S32 i) const 00346 { 00347 return mMemory[i]; 00348 } 00349 00350 template <class Type> 00351 inline Type& LLDynamicQueuePtr<Type>::get(const S32 i) 00352 { 00353 return mMemory[i]; 00354 } 00355 00356 00357 #endif // LL_LLDQUEUEPTR_H