PageRenderTime 45ms CodeModel.GetById 2ms app.highlight 39ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llcommon/lldqueueptr.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 352 lines | 244 code | 53 blank | 55 comment | 36 complexity | d9be9724e285a91ede0d77d7d47902e2 MD5 | raw file
  1/** 
  2 * @file lldqueueptr.h
  3 * @brief LLDynamicQueuePtr declaration
  4 *
  5 * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26#ifndef LL_LLDQUEUEPTR_H
 27#define LL_LLDQUEUEPTR_H
 28
 29template <class Type> 
 30class LLDynamicQueuePtr
 31{
 32public:
 33	enum
 34	{
 35		OKAY = 0,
 36		FAIL = -1
 37	};
 38	
 39	LLDynamicQueuePtr(const S32 size=8);
 40	~LLDynamicQueuePtr();
 41
 42	void init();
 43	void destroy();
 44	void reset();
 45	void reallocate(U32 newsize);
 46
 47	// ACCESSORS
 48	const Type& get(const S32 index) const;					// no bounds checking
 49	Type&       get(const S32 index);						// no bounds checking
 50	const Type& operator []	(const S32 index) const			{ return get(index); }
 51	Type&       operator []	(const S32 index)				{ return get(index); }
 52	S32			find(const Type &obj) const;
 53
 54	S32			count() const								{ return (mLastObj >= mFirstObj ? mLastObj - mFirstObj : mLastObj + mMaxObj - mFirstObj); }
 55	S32			getMax() const								{ return mMaxObj; }
 56	S32			getFirst() const       { return mFirstObj; }
 57	S32			getLast () const       { return mLastObj; }
 58
 59	// MANIPULATE
 60	S32         push(const Type &obj);					// add to end of Queue, returns index from start
 61	S32			pull(      Type &obj);			        // pull from Queue, returns index from start
 62
 63	S32			remove   (S32 index);				    // remove by index
 64	S32			removeObj(const Type &obj);				// remove by object
 65
 66protected:
 67	S32           mFirstObj, mLastObj, mMaxObj;
 68	Type*		  mMemory;
 69
 70public:
 71
 72	void print()
 73	{
 74		/*
 75		Convert this to llinfos if it's intended to be used - djs 08/30/02
 76
 77		printf("Printing from %d to %d (of %d): ",mFirstObj, mLastObj, mMaxObj);
 78
 79		if (mFirstObj <= mLastObj)
 80		{
 81			for (S32 i=mFirstObj;i<mLastObj;i++)
 82			{
 83				printf("%d ",mMemory[i]);
 84			}
 85		}
 86		else
 87		{
 88			for (S32 i=mFirstObj;i<mMaxObj;i++)
 89			{
 90				printf("%d ",mMemory[i]);
 91			}
 92			for (i=0;i<mLastObj;i++)
 93			{
 94				printf("%d ",mMemory[i]);
 95			}
 96		}
 97		printf("\n");
 98		*/
 99	}
100
101};
102
103
104//--------------------------------------------------------
105// LLDynamicQueuePtrPtr implementation
106//--------------------------------------------------------
107
108
109template <class Type>
110inline LLDynamicQueuePtr<Type>::LLDynamicQueuePtr(const S32 size)
111{
112	init();
113	reallocate(size);
114}
115
116template <class Type>
117inline LLDynamicQueuePtr<Type>::~LLDynamicQueuePtr()
118{
119	destroy();
120}
121
122template <class Type>
123inline void LLDynamicQueuePtr<Type>::init()
124{ 
125	mFirstObj    = 0;
126	mLastObj     = 0;
127	mMaxObj      = 0;
128	mMemory      = NULL;
129}
130
131template <class Type>
132inline void LLDynamicQueuePtr<Type>::reallocate(U32 newsize)
133{ 
134	if (newsize)
135	{
136		if (mFirstObj > mLastObj && newsize > mMaxObj)
137		{
138			Type* new_memory = new Type[newsize];
139
140			llassert(new_memory);
141
142			S32 _count = count();
143			S32 i, m = 0;
144			for (i=mFirstObj; i < mMaxObj; i++)
145			{
146				new_memory[m++] = mMemory[i];
147			}
148			for (i=0; i <=mLastObj; i++)
149			{
150				new_memory[m++] = mMemory[i];
151			}
152
153			delete[] mMemory;
154			mMemory = new_memory;
155
156			mFirstObj = 0;
157			mLastObj  = _count;
158		}
159		else
160		{
161			Type* new_memory = new Type[newsize];
162
163			llassert(new_memory);
164
165			S32 i, m = 0;
166			for (i=0; i < mLastObj; i++)
167			{
168				new_memory[m++] = mMemory[i];
169			}
170			delete[] mMemory;
171			mMemory = new_memory;
172		}
173	}
174	else if (mMemory)
175	{
176		delete[] mMemory;
177		mMemory = NULL;
178	}
179
180	mMaxObj = newsize;
181}
182
183template <class Type>
184inline void LLDynamicQueuePtr<Type>::destroy()
185{
186	reset();
187	delete[] mMemory;
188	mMemory = NULL;
189}
190
191
192template <class Type>
193void LLDynamicQueuePtr<Type>::reset()	   
194{ 
195	for (S32 i=0; i < mMaxObj; i++)
196	{
197		get(i) = NULL; // unrefs for pointers
198	}
199
200	mFirstObj    = 0;
201	mLastObj     = 0;
202}
203
204
205template <class Type>
206inline S32 LLDynamicQueuePtr<Type>::find(const Type &obj) const
207{
208	S32 i;
209	if (mFirstObj <= mLastObj)
210	{
211		for ( i = mFirstObj; i < mLastObj; i++ )
212		{
213			if (mMemory[i] == obj)
214			{
215				return i;
216			}
217		}
218	}
219	else
220	{
221		for ( i = mFirstObj; i < mMaxObj; i++ )
222		{
223			if (mMemory[i] == obj)
224			{
225				return i;
226			}
227		}
228		for ( i = 0; i < mLastObj; i++ )
229		{
230			if (mMemory[i] == obj)
231			{
232				return i;
233			}
234		}
235	}
236
237	return FAIL;
238}
239
240template <class Type>
241inline S32 LLDynamicQueuePtr<Type>::remove(S32 i)
242{
243	if (mFirstObj > mLastObj)
244	{
245		if (i >= mFirstObj && i < mMaxObj)
246		{
247			while( i > mFirstObj)
248			{
249				mMemory[i] = mMemory[i-1];
250				i--;
251			}
252			mMemory[mFirstObj] = NULL;
253			mFirstObj++;
254			if (mFirstObj >= mMaxObj) mFirstObj = 0;
255
256			return count();
257		}
258		else if (i < mLastObj && i >= 0)
259		{
260			while(i < mLastObj)
261			{
262				mMemory[i] = mMemory[i+1];
263				i++;
264			}
265			mMemory[mLastObj] = NULL;
266			mLastObj--;
267			if (mLastObj < 0) mLastObj = mMaxObj-1;
268
269			return count();
270		}
271	}
272	else if (i <= mLastObj && i >= mFirstObj)
273	{
274		while(i < mLastObj)
275		{
276			mMemory[i] = mMemory[i+1];
277			i++;
278		}
279		mMemory[mLastObj] = NULL;
280		mLastObj--;
281		if (mLastObj < 0) mLastObj = mMaxObj-1;
282
283		return count();
284	}
285
286	
287	return FAIL;
288}
289
290template <class Type>
291inline S32 LLDynamicQueuePtr<Type>::removeObj(const Type& obj)
292{
293	S32 ind = find(obj);
294	if (ind >= 0)
295	{
296		return remove(ind);
297	}
298	return FAIL;
299}
300
301template <class Type>
302inline S32	LLDynamicQueuePtr<Type>::push(const Type &obj) 
303{
304	if (mMaxObj - count() <= 1)
305	{
306		reallocate(mMaxObj * 2);
307	}
308
309	mMemory[mLastObj++] = obj;
310
311	if (mLastObj >= mMaxObj) 
312	{
313		mLastObj = 0;
314	}
315
316	return count();
317}
318
319template <class Type>
320inline S32	LLDynamicQueuePtr<Type>::pull(Type &obj) 
321{
322	obj = NULL;
323
324	if (count() < 1) return -1;
325
326	obj = mMemory[mFirstObj];
327	mMemory[mFirstObj] = NULL;
328
329	mFirstObj++;
330
331	if (mFirstObj >= mMaxObj) 
332	{
333		mFirstObj = 0;
334	}
335
336	return count();
337}
338
339template <class Type>
340inline const Type& LLDynamicQueuePtr<Type>::get(const S32 i) const
341{
342	return mMemory[i];
343}
344
345template <class Type>
346inline Type& LLDynamicQueuePtr<Type>::get(const S32 i)
347{
348	return mMemory[i];
349}
350
351
352#endif // LL_LLDQUEUEPTR_H