aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcommon/lldqueueptr.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/llcommon/lldqueueptr.h353
1 files changed, 353 insertions, 0 deletions
diff --git a/linden/indra/llcommon/lldqueueptr.h b/linden/indra/llcommon/lldqueueptr.h
new file mode 100644
index 0000000..4d8a5ca
--- /dev/null
+++ b/linden/indra/llcommon/lldqueueptr.h
@@ -0,0 +1,353 @@
1/**
2 * @file lldqueueptr.h
3 * @brief LLDynamicQueuePtr declaration
4 *
5 * Copyright (c) 2001-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27#ifndef LL_LLDQUEUEPTR_H
28#define LL_LLDQUEUEPTR_H
29
30template <class Type>
31class LLDynamicQueuePtr
32{
33public:
34 enum
35 {
36 OKAY = 0,
37 FAIL = -1
38 };
39
40 LLDynamicQueuePtr(const S32 size=8);
41 ~LLDynamicQueuePtr();
42
43 void init();
44 void destroy();
45 void reset();
46 void realloc(U32 newsize);
47
48 // ACCESSORS
49 const Type& get(const S32 index) const; // no bounds checking
50 Type& get(const S32 index); // no bounds checking
51 const Type& operator [] (const S32 index) const { return get(index); }
52 Type& operator [] (const S32 index) { return get(index); }
53 S32 find(const Type &obj) const;
54
55 S32 count() const { return (mLastObj >= mFirstObj ? mLastObj - mFirstObj : mLastObj + mMaxObj - mFirstObj); }
56 S32 getMax() const { return mMaxObj; }
57 S32 getFirst() const { return mFirstObj; }
58 S32 getLast () const { return mLastObj; }
59
60 // MANIPULATE
61 S32 push(const Type &obj); // add to end of Queue, returns index from start
62 S32 pull( Type &obj); // pull from Queue, returns index from start
63
64 S32 remove (S32 index); // remove by index
65 S32 removeObj(const Type &obj); // remove by object
66
67protected:
68 S32 mFirstObj, mLastObj, mMaxObj;
69 Type* mMemory;
70
71public:
72
73 void print()
74 {
75 /*
76 Convert this to llinfos if it's intended to be used - djs 08/30/02
77
78 printf("Printing from %d to %d (of %d): ",mFirstObj, mLastObj, mMaxObj);
79
80 if (mFirstObj <= mLastObj)
81 {
82 for (S32 i=mFirstObj;i<mLastObj;i++)
83 {
84 printf("%d ",mMemory[i]);
85 }
86 }
87 else
88 {
89 for (S32 i=mFirstObj;i<mMaxObj;i++)
90 {
91 printf("%d ",mMemory[i]);
92 }
93 for (i=0;i<mLastObj;i++)
94 {
95 printf("%d ",mMemory[i]);
96 }
97 }
98 printf("\n");
99 */
100 }
101
102};
103
104
105//--------------------------------------------------------
106// LLDynamicQueuePtrPtr implementation
107//--------------------------------------------------------
108
109
110template <class Type>
111inline LLDynamicQueuePtr<Type>::LLDynamicQueuePtr(const S32 size)
112{
113 init();
114 realloc(size);
115}
116
117template <class Type>
118inline LLDynamicQueuePtr<Type>::~LLDynamicQueuePtr()
119{
120 destroy();
121}
122
123template <class Type>
124inline void LLDynamicQueuePtr<Type>::init()
125{
126 mFirstObj = 0;
127 mLastObj = 0;
128 mMaxObj = 0;
129 mMemory = NULL;
130}
131
132template <class Type>
133inline void LLDynamicQueuePtr<Type>::realloc(U32 newsize)
134{
135 if (newsize)
136 {
137 if (mFirstObj > mLastObj && newsize > mMaxObj)
138 {
139 Type* new_memory = new Type[newsize];
140
141 llassert(new_memory);
142
143 S32 _count = count();
144 S32 i, m = 0;
145 for (i=mFirstObj; i < mMaxObj; i++)
146 {
147 new_memory[m++] = mMemory[i];
148 }
149 for (i=0; i <=mLastObj; i++)
150 {
151 new_memory[m++] = mMemory[i];
152 }
153
154 delete[] mMemory;
155 mMemory = new_memory;
156
157 mFirstObj = 0;
158 mLastObj = _count;
159 }
160 else
161 {
162 Type* new_memory = new Type[newsize];
163
164 llassert(new_memory);
165
166 S32 i, m = 0;
167 for (i=0; i < mLastObj; i++)
168 {
169 new_memory[m++] = mMemory[i];
170 }
171 delete[] mMemory;
172 mMemory = new_memory;
173 }
174 }
175 else if (mMemory)
176 {
177 delete[] mMemory;
178 mMemory = NULL;
179 }
180
181 mMaxObj = newsize;
182}
183
184template <class Type>
185inline void LLDynamicQueuePtr<Type>::destroy()
186{
187 reset();
188 delete[] mMemory;
189 mMemory = NULL;
190}
191
192
193template <class Type>
194void LLDynamicQueuePtr<Type>::reset()
195{
196 for (S32 i=0; i < mMaxObj; i++)
197 {
198 get(i) = NULL; // unrefs for pointers
199 }
200
201 mFirstObj = 0;
202 mLastObj = 0;
203}
204
205
206template <class Type>
207inline S32 LLDynamicQueuePtr<Type>::find(const Type &obj) const
208{
209 S32 i;
210 if (mFirstObj <= mLastObj)
211 {
212 for ( i = mFirstObj; i < mLastObj; i++ )
213 {
214 if (mMemory[i] == obj)
215 {
216 return i;
217 }
218 }
219 }
220 else
221 {
222 for ( i = mFirstObj; i < mMaxObj; i++ )
223 {
224 if (mMemory[i] == obj)
225 {
226 return i;
227 }
228 }
229 for ( i = 0; i < mLastObj; i++ )
230 {
231 if (mMemory[i] == obj)
232 {
233 return i;
234 }
235 }
236 }
237
238 return FAIL;
239}
240
241template <class Type>
242inline S32 LLDynamicQueuePtr<Type>::remove(S32 i)
243{
244 if (mFirstObj > mLastObj)
245 {
246 if (i >= mFirstObj && i < mMaxObj)
247 {
248 while( i > mFirstObj)
249 {
250 mMemory[i] = mMemory[i-1];
251 i--;
252 }
253 mMemory[mFirstObj] = NULL;
254 mFirstObj++;
255 if (mFirstObj >= mMaxObj) mFirstObj = 0;
256
257 return count();
258 }
259 else if (i < mLastObj && i >= 0)
260 {
261 while(i < mLastObj)
262 {
263 mMemory[i] = mMemory[i+1];
264 i++;
265 }
266 mMemory[mLastObj] = NULL;
267 mLastObj--;
268 if (mLastObj < 0) mLastObj = mMaxObj-1;
269
270 return count();
271 }
272 }
273 else if (i <= mLastObj && i >= mFirstObj)
274 {
275 while(i < mLastObj)
276 {
277 mMemory[i] = mMemory[i+1];
278 i++;
279 }
280 mMemory[mLastObj] = NULL;
281 mLastObj--;
282 if (mLastObj < 0) mLastObj = mMaxObj-1;
283
284 return count();
285 }
286
287
288 return FAIL;
289}
290
291template <class Type>
292inline S32 LLDynamicQueuePtr<Type>::removeObj(const Type& obj)
293{
294 S32 ind = find(obj);
295 if (ind >= 0)
296 {
297 return remove(ind);
298 }
299 return FAIL;
300}
301
302template <class Type>
303inline S32 LLDynamicQueuePtr<Type>::push(const Type &obj)
304{
305 if (mMaxObj - count() <= 1)
306 {
307 realloc(mMaxObj * 2);
308 }
309
310 mMemory[mLastObj++] = obj;
311
312 if (mLastObj >= mMaxObj)
313 {
314 mLastObj = 0;
315 }
316
317 return count();
318}
319
320template <class Type>
321inline S32 LLDynamicQueuePtr<Type>::pull(Type &obj)
322{
323 obj = NULL;
324
325 if (count() < 1) return -1;
326
327 obj = mMemory[mFirstObj];
328 mMemory[mFirstObj] = NULL;
329
330 mFirstObj++;
331
332 if (mFirstObj >= mMaxObj)
333 {
334 mFirstObj = 0;
335 }
336
337 return count();
338}
339
340template <class Type>
341inline const Type& LLDynamicQueuePtr<Type>::get(const S32 i) const
342{
343 return mMemory[i];
344}
345
346template <class Type>
347inline Type& LLDynamicQueuePtr<Type>::get(const S32 i)
348{
349 return mMemory[i];
350}
351
352
353#endif // LL_LLDQUEUEPTR_H