diff options
Diffstat (limited to 'indra/llcommon/lldqueueptr.h')
-rw-r--r-- | indra/llcommon/lldqueueptr.h | 334 |
1 files changed, 334 insertions, 0 deletions
diff --git a/indra/llcommon/lldqueueptr.h b/indra/llcommon/lldqueueptr.h new file mode 100644 index 0000000000..b5407d826a --- /dev/null +++ b/indra/llcommon/lldqueueptr.h @@ -0,0 +1,334 @@ +/** + * @file lldqueueptr.h + * @brief LLDynamicQueuePtr declaration + * + * Copyright (c) 2001-$CurrentYear$, Linden Research, Inc. + * $License$ + */ +#ifndef LL_LLDQUEUEPTR_H +#define LL_LLDQUEUEPTR_H + +template <class Type> +class LLDynamicQueuePtr +{ +public: + enum + { + OKAY = 0, + FAIL = -1 + }; + + LLDynamicQueuePtr(const S32 size=8); + ~LLDynamicQueuePtr(); + + void init(); + void destroy(); + void reset(); + void realloc(U32 newsize); + + // ACCESSORS + const Type& get(const S32 index) const; // no bounds checking + Type& get(const S32 index); // no bounds checking + const Type& operator [] (const S32 index) const { return get(index); } + Type& operator [] (const S32 index) { return get(index); } + S32 find(const Type &obj) const; + + S32 count() const { return (mLastObj >= mFirstObj ? mLastObj - mFirstObj : mLastObj + mMaxObj - mFirstObj); } + S32 getMax() const { return mMaxObj; } + S32 getFirst() const { return mFirstObj; } + S32 getLast () const { return mLastObj; } + + // MANIPULATE + S32 push(const Type &obj); // add to end of Queue, returns index from start + S32 pull( Type &obj); // pull from Queue, returns index from start + + S32 remove (S32 index); // remove by index + S32 removeObj(const Type &obj); // remove by object + +protected: + S32 mFirstObj, mLastObj, mMaxObj; + Type* mMemory; + +public: + + void print() + { + /* + Convert this to llinfos if it's intended to be used - djs 08/30/02 + + printf("Printing from %d to %d (of %d): ",mFirstObj, mLastObj, mMaxObj); + + if (mFirstObj <= mLastObj) + { + for (S32 i=mFirstObj;i<mLastObj;i++) + { + printf("%d ",mMemory[i]); + } + } + else + { + for (S32 i=mFirstObj;i<mMaxObj;i++) + { + printf("%d ",mMemory[i]); + } + for (i=0;i<mLastObj;i++) + { + printf("%d ",mMemory[i]); + } + } + printf("\n"); + */ + } + +}; + + +//-------------------------------------------------------- +// LLDynamicQueuePtrPtr implementation +//-------------------------------------------------------- + + +template <class Type> +inline LLDynamicQueuePtr<Type>::LLDynamicQueuePtr(const S32 size) +{ + init(); + realloc(size); +} + +template <class Type> +inline LLDynamicQueuePtr<Type>::~LLDynamicQueuePtr() +{ + destroy(); +} + +template <class Type> +inline void LLDynamicQueuePtr<Type>::init() +{ + mFirstObj = 0; + mLastObj = 0; + mMaxObj = 0; + mMemory = NULL; +} + +template <class Type> +inline void LLDynamicQueuePtr<Type>::realloc(U32 newsize) +{ + if (newsize) + { + if (mFirstObj > mLastObj && newsize > mMaxObj) + { + Type* new_memory = new Type[newsize]; + + llassert(new_memory); + + S32 _count = count(); + S32 i, m = 0; + for (i=mFirstObj; i < mMaxObj; i++) + { + new_memory[m++] = mMemory[i]; + } + for (i=0; i <=mLastObj; i++) + { + new_memory[m++] = mMemory[i]; + } + + delete[] mMemory; + mMemory = new_memory; + + mFirstObj = 0; + mLastObj = _count; + } + else + { + Type* new_memory = new Type[newsize]; + + llassert(new_memory); + + S32 i, m = 0; + for (i=0; i < mLastObj; i++) + { + new_memory[m++] = mMemory[i]; + } + delete[] mMemory; + mMemory = new_memory; + } + } + else if (mMemory) + { + delete[] mMemory; + mMemory = NULL; + } + + mMaxObj = newsize; +} + +template <class Type> +inline void LLDynamicQueuePtr<Type>::destroy() +{ + reset(); + delete[] mMemory; + mMemory = NULL; +} + + +template <class Type> +void LLDynamicQueuePtr<Type>::reset() +{ + for (S32 i=0; i < mMaxObj; i++) + { + get(i) = NULL; // unrefs for pointers + } + + mFirstObj = 0; + mLastObj = 0; +} + + +template <class Type> +inline S32 LLDynamicQueuePtr<Type>::find(const Type &obj) const +{ + S32 i; + if (mFirstObj <= mLastObj) + { + for ( i = mFirstObj; i < mLastObj; i++ ) + { + if (mMemory[i] == obj) + { + return i; + } + } + } + else + { + for ( i = mFirstObj; i < mMaxObj; i++ ) + { + if (mMemory[i] == obj) + { + return i; + } + } + for ( i = 0; i < mLastObj; i++ ) + { + if (mMemory[i] == obj) + { + return i; + } + } + } + + return FAIL; +} + +template <class Type> +inline S32 LLDynamicQueuePtr<Type>::remove(S32 i) +{ + if (mFirstObj > mLastObj) + { + if (i >= mFirstObj && i < mMaxObj) + { + while( i > mFirstObj) + { + mMemory[i] = mMemory[i-1]; + i--; + } + mMemory[mFirstObj] = NULL; + mFirstObj++; + if (mFirstObj >= mMaxObj) mFirstObj = 0; + + return count(); + } + else if (i < mLastObj && i >= 0) + { + while(i < mLastObj) + { + mMemory[i] = mMemory[i+1]; + i++; + } + mMemory[mLastObj] = NULL; + mLastObj--; + if (mLastObj < 0) mLastObj = mMaxObj-1; + + return count(); + } + } + else if (i <= mLastObj && i >= mFirstObj) + { + while(i < mLastObj) + { + mMemory[i] = mMemory[i+1]; + i++; + } + mMemory[mLastObj] = NULL; + mLastObj--; + if (mLastObj < 0) mLastObj = mMaxObj-1; + + return count(); + } + + + return FAIL; +} + +template <class Type> +inline S32 LLDynamicQueuePtr<Type>::removeObj(const Type& obj) +{ + S32 ind = find(obj); + if (ind >= 0) + { + return remove(ind); + } + return FAIL; +} + +template <class Type> +inline S32 LLDynamicQueuePtr<Type>::push(const Type &obj) +{ + if (mMaxObj - count() <= 1) + { + realloc(mMaxObj * 2); + } + + mMemory[mLastObj++] = obj; + + if (mLastObj >= mMaxObj) + { + mLastObj = 0; + } + + return count(); +} + +template <class Type> +inline S32 LLDynamicQueuePtr<Type>::pull(Type &obj) +{ + obj = NULL; + + if (count() < 1) return -1; + + obj = mMemory[mFirstObj]; + mMemory[mFirstObj] = NULL; + + mFirstObj++; + + if (mFirstObj >= mMaxObj) + { + mFirstObj = 0; + } + + return count(); +} + +template <class Type> +inline const Type& LLDynamicQueuePtr<Type>::get(const S32 i) const +{ + return mMemory[i]; +} + +template <class Type> +inline Type& LLDynamicQueuePtr<Type>::get(const S32 i) +{ + return mMemory[i]; +} + + +#endif // LL_LLDQUEUEPTR_H |