lldarray.h

Go to the documentation of this file.
00001 
00032 #ifndef LL_LLDARRAY_H
00033 #define LL_LLDARRAY_H
00034 
00035 #include "llmath.h"
00036 #include "llerror.h"
00037 
00038 #include <vector>
00039 #include <map>
00040 
00041 // class LLDynamicArray<>; // = std::vector + reserves <BlockSize> elements
00042 // class LLDynamicArrayIndexed<>; // = std::vector + std::map if indices, only supports operator[] and begin(),end()
00043 
00044 //--------------------------------------------------------
00045 // LLDynamicArray declaration
00046 //--------------------------------------------------------
00047 // NOTE: BlockSize is used to reserve a minimal initial amount
00048 template <typename Type, int BlockSize = 32> 
00049 class LLDynamicArray : public std::vector<Type>
00050 {
00051 public:
00052         enum
00053         {
00054                 OKAY = 0,
00055                 FAIL = -1
00056         };
00057         
00058         LLDynamicArray(S32 size=0) : std::vector<Type>(size) { if (size < BlockSize) std::vector<Type>::reserve(BlockSize); }
00059 
00060         void reset() { std::vector<Type>::resize(0); }
00061 
00062         // ACCESSORS
00063         const Type& get(S32 index) const                                { return std::vector<Type>::operator[](index); }
00064         Type&       get(S32 index)                                              { return std::vector<Type>::operator[](index); }
00065         S32                     find(const Type &obj) const;
00066 
00067         S32                     count() const                                           { return std::vector<Type>::size(); }
00068         S32                     getLength() const                                       { return std::vector<Type>::size(); }
00069         S32                     getMax() const                                          { return std::vector<Type>::capacity(); }
00070 
00071         // MANIPULATE
00072         S32         put(const Type &obj);                                       // add to end of array, returns index
00073 //      Type*           reserve(S32 num);                                       // reserve a block of indices in advance
00074         Type*           reserve_block(U32 num);                 // reserve a block of indices in advance
00075 
00076         S32                     remove(S32 index);                              // remove by index, no bounds checking
00077         S32                     removeObj(const Type &obj);                             // remove by object
00078         S32                     removeLast();
00079 
00080         void            operator+=(const LLDynamicArray<Type,BlockSize> &other);
00081 };
00082 
00083 //--------------------------------------------------------
00084 // LLDynamicArray implementation
00085 //--------------------------------------------------------
00086 
00087 template <typename Type,int BlockSize>
00088 inline S32 LLDynamicArray<Type,BlockSize>::find(const Type &obj) const
00089 {
00090         typename std::vector<Type>::const_iterator iter = std::find(this->begin(), this->end(), obj);
00091         if (iter != this->end())
00092         {
00093                 return iter - this->begin();
00094         }
00095         return FAIL;
00096 }
00097 
00098 
00099 template <typename Type,int BlockSize>
00100 inline S32 LLDynamicArray<Type,BlockSize>::remove(S32 i)
00101 {
00102         // This is a fast removal by swapping with the last element
00103         S32 sz = this->size();
00104         if (i < 0 || i >= sz)
00105         {
00106                 return FAIL;
00107         }
00108         if (i < sz-1)
00109         {
00110                 this->operator[](i) = this->back();
00111         }
00112         this->pop_back();
00113         return i;
00114 }
00115 
00116 template <typename Type,int BlockSize>
00117 inline S32 LLDynamicArray<Type,BlockSize>::removeObj(const Type& obj)
00118 {
00119         typename std::vector<Type>::iterator iter = std::find(this->begin(), this->end(), obj);
00120         if (iter != this->end())
00121         {
00122                 S32 res = iter - this->begin();
00123                 typename std::vector<Type>::iterator last = this->end(); 
00124                 --last;
00125                 *iter = *last;
00126                 this->pop_back();
00127                 return res;
00128         }
00129         return FAIL;
00130 }
00131 
00132 template <typename Type,int BlockSize>
00133 inline S32      LLDynamicArray<Type,BlockSize>::removeLast()
00134 {
00135         if (!this->empty())
00136         {
00137                 this->pop_back();
00138                 return OKAY;
00139         }
00140         return FAIL;
00141 }
00142 
00143 template <typename Type,int BlockSize>
00144 inline Type* LLDynamicArray<Type,BlockSize>::reserve_block(U32 num)
00145 {
00146         U32 sz = this->size();
00147         this->resize(sz+num);
00148         return &(this->operator[](sz));
00149 }
00150 
00151 template <typename Type,int BlockSize>
00152 inline S32      LLDynamicArray<Type,BlockSize>::put(const Type &obj) 
00153 {
00154         this->push_back(obj);
00155         return this->size() - 1;
00156 }
00157 
00158 template <typename Type,int BlockSize>
00159 inline void LLDynamicArray<Type,BlockSize>::operator+=(const LLDynamicArray<Type,BlockSize> &other)
00160 {
00161         insert(this->end(), other.begin(), other.end());
00162 }
00163 
00164 //--------------------------------------------------------
00165 // LLDynamicArrayIndexed declaration
00166 //--------------------------------------------------------
00167 
00168 template <typename Type, typename Key, int BlockSize = 32> 
00169 class LLDynamicArrayIndexed
00170 {
00171 public:
00172         typedef typename std::vector<Type>::iterator iterator;
00173         typedef typename std::vector<Type>::const_iterator const_iterator;
00174         typedef typename std::vector<Type>::reverse_iterator reverse_iterator;
00175         typedef typename std::vector<Type>::const_reverse_iterator const_reverse_iterator;
00176         typedef typename std::vector<Type>::size_type size_type;
00177 protected:
00178         std::vector<Type> mVector;
00179         std::map<Key, U32> mIndexMap;
00180         
00181 public:
00182         LLDynamicArrayIndexed() { mVector.reserve(BlockSize); }
00183         
00184         iterator begin() { return mVector.begin(); }
00185         const_iterator begin() const { return mVector.begin(); }
00186         iterator end() { return mVector.end(); }
00187         const_iterator end() const { return mVector.end(); }
00188 
00189         reverse_iterator rbegin() { return mVector.rbegin(); }
00190         const_reverse_iterator rbegin() const { return mVector.rbegin(); }
00191         reverse_iterator rend() { return mVector.rend(); }
00192         const_reverse_iterator rend() const { return mVector.rend(); }
00193 
00194         void reset() { mVector.resize(0); mIndexMap.resize(0); }
00195         bool empty() const { return mVector.empty(); }
00196         size_type size() const { return mVector.size(); }
00197         
00198         Type& operator[](const Key& k)
00199         {
00200                 typename std::map<Key, U32>::const_iterator iter = mIndexMap.find(k);
00201                 if (iter == mIndexMap.end())
00202                 {
00203                         U32 n = mVector.size();
00204                         mIndexMap[k] = n;
00205                         mVector.resize(n+1);
00206                         llassert(mVector.size() == mIndexMap.size());
00207                         return mVector[n];
00208                 }
00209                 else
00210                 {
00211                         return mVector[iter->second];
00212                 }
00213         }
00214 
00215         const_iterator find(const Key& k) const
00216         {
00217                 typename std::map<Key, U32>::const_iterator iter = mIndexMap.find(k);
00218                 if(iter == mIndexMap.end())
00219                 {
00220                         return mVector.end();
00221                 }
00222                 else
00223                 {
00224                         return mVector.begin() + iter->second;
00225                 }
00226         }
00227 };
00228 
00229 #endif

Generated on Fri May 16 08:32:02 2008 for SecondLife by  doxygen 1.5.5