PageRenderTime 30ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llcommon/lldarray.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 223 lines | 152 code | 30 blank | 41 comment | 14 complexity | 93d21555b1674f2a25381ad677c1d740 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file lldarray.h
  3. * @brief Wrapped std::vector for backward compatibility.
  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_LLDARRAY_H
  27. #define LL_LLDARRAY_H
  28. #include "llerror.h"
  29. #include <vector>
  30. #include <map>
  31. // class LLDynamicArray<>; // = std::vector + reserves <BlockSize> elements
  32. // class LLDynamicArrayIndexed<>; // = std::vector + std::map if indices, only supports operator[] and begin(),end()
  33. //--------------------------------------------------------
  34. // LLDynamicArray declaration
  35. //--------------------------------------------------------
  36. // NOTE: BlockSize is used to reserve a minimal initial amount
  37. template <typename Type, int BlockSize = 32>
  38. class LLDynamicArray : public std::vector<Type>
  39. {
  40. public:
  41. enum
  42. {
  43. OKAY = 0,
  44. FAIL = -1
  45. };
  46. LLDynamicArray(S32 size=0) : std::vector<Type>(size) { if (size < BlockSize) std::vector<Type>::reserve(BlockSize); }
  47. void reset() { std::vector<Type>::clear(); }
  48. // ACCESSORS
  49. const Type& get(S32 index) const { return std::vector<Type>::operator[](index); }
  50. Type& get(S32 index) { return std::vector<Type>::operator[](index); }
  51. S32 find(const Type &obj) const;
  52. S32 count() const { return std::vector<Type>::size(); }
  53. S32 getLength() const { return std::vector<Type>::size(); }
  54. S32 getMax() const { return std::vector<Type>::capacity(); }
  55. // MANIPULATE
  56. S32 put(const Type &obj); // add to end of array, returns index
  57. // Type* reserve(S32 num); // reserve a block of indices in advance
  58. Type* reserve_block(U32 num); // reserve a block of indices in advance
  59. S32 remove(S32 index); // remove by index, no bounds checking
  60. S32 removeObj(const Type &obj); // remove by object
  61. S32 removeLast();
  62. void operator+=(const LLDynamicArray<Type,BlockSize> &other);
  63. };
  64. //--------------------------------------------------------
  65. // LLDynamicArray implementation
  66. //--------------------------------------------------------
  67. template <typename Type,int BlockSize>
  68. inline S32 LLDynamicArray<Type,BlockSize>::find(const Type &obj) const
  69. {
  70. typename std::vector<Type>::const_iterator iter = std::find(this->begin(), this->end(), obj);
  71. if (iter != this->end())
  72. {
  73. return iter - this->begin();
  74. }
  75. return FAIL;
  76. }
  77. template <typename Type,int BlockSize>
  78. inline S32 LLDynamicArray<Type,BlockSize>::remove(S32 i)
  79. {
  80. // This is a fast removal by swapping with the last element
  81. S32 sz = this->size();
  82. if (i < 0 || i >= sz)
  83. {
  84. return FAIL;
  85. }
  86. if (i < sz-1)
  87. {
  88. this->operator[](i) = this->back();
  89. }
  90. this->pop_back();
  91. return i;
  92. }
  93. template <typename Type,int BlockSize>
  94. inline S32 LLDynamicArray<Type,BlockSize>::removeObj(const Type& obj)
  95. {
  96. typename std::vector<Type>::iterator iter = std::find(this->begin(), this->end(), obj);
  97. if (iter != this->end())
  98. {
  99. S32 res = iter - this->begin();
  100. typename std::vector<Type>::iterator last = this->end();
  101. --last;
  102. *iter = *last;
  103. this->pop_back();
  104. return res;
  105. }
  106. return FAIL;
  107. }
  108. template <typename Type,int BlockSize>
  109. inline S32 LLDynamicArray<Type,BlockSize>::removeLast()
  110. {
  111. if (!this->empty())
  112. {
  113. this->pop_back();
  114. return OKAY;
  115. }
  116. return FAIL;
  117. }
  118. template <typename Type,int BlockSize>
  119. inline Type* LLDynamicArray<Type,BlockSize>::reserve_block(U32 num)
  120. {
  121. U32 sz = this->size();
  122. this->resize(sz+num);
  123. return &(this->operator[](sz));
  124. }
  125. template <typename Type,int BlockSize>
  126. inline S32 LLDynamicArray<Type,BlockSize>::put(const Type &obj)
  127. {
  128. this->push_back(obj);
  129. return this->size() - 1;
  130. }
  131. template <typename Type,int BlockSize>
  132. inline void LLDynamicArray<Type,BlockSize>::operator+=(const LLDynamicArray<Type,BlockSize> &other)
  133. {
  134. insert(this->end(), other.begin(), other.end());
  135. }
  136. //--------------------------------------------------------
  137. // LLDynamicArrayIndexed declaration
  138. //--------------------------------------------------------
  139. template <typename Type, typename Key, int BlockSize = 32>
  140. class LLDynamicArrayIndexed
  141. {
  142. public:
  143. typedef typename std::vector<Type>::iterator iterator;
  144. typedef typename std::vector<Type>::const_iterator const_iterator;
  145. typedef typename std::vector<Type>::reverse_iterator reverse_iterator;
  146. typedef typename std::vector<Type>::const_reverse_iterator const_reverse_iterator;
  147. typedef typename std::vector<Type>::size_type size_type;
  148. protected:
  149. std::vector<Type> mVector;
  150. std::map<Key, U32> mIndexMap;
  151. public:
  152. LLDynamicArrayIndexed() { mVector.reserve(BlockSize); }
  153. iterator begin() { return mVector.begin(); }
  154. const_iterator begin() const { return mVector.begin(); }
  155. iterator end() { return mVector.end(); }
  156. const_iterator end() const { return mVector.end(); }
  157. reverse_iterator rbegin() { return mVector.rbegin(); }
  158. const_reverse_iterator rbegin() const { return mVector.rbegin(); }
  159. reverse_iterator rend() { return mVector.rend(); }
  160. const_reverse_iterator rend() const { return mVector.rend(); }
  161. void reset() { mVector.resize(0); mIndexMap.resize(0); }
  162. bool empty() const { return mVector.empty(); }
  163. size_type size() const { return mVector.size(); }
  164. Type& operator[](const Key& k)
  165. {
  166. typename std::map<Key, U32>::const_iterator iter = mIndexMap.find(k);
  167. if (iter == mIndexMap.end())
  168. {
  169. U32 n = mVector.size();
  170. mIndexMap[k] = n;
  171. mVector.push_back(Type());
  172. llassert(mVector.size() == mIndexMap.size());
  173. return mVector[n];
  174. }
  175. else
  176. {
  177. return mVector[iter->second];
  178. }
  179. }
  180. const_iterator find(const Key& k) const
  181. {
  182. typename std::map<Key, U32>::const_iterator iter = mIndexMap.find(k);
  183. if(iter == mIndexMap.end())
  184. {
  185. return mVector.end();
  186. }
  187. else
  188. {
  189. return mVector.begin() + iter->second;
  190. }
  191. }
  192. };
  193. #endif