lldarray.h
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:7k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file lldarray.h
  3.  * @brief Wrapped std::vector for backward compatibility.
  4.  *
  5.  * $LicenseInfo:firstyear=2001&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2001-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #ifndef LL_LLDARRAY_H
  33. #define LL_LLDARRAY_H
  34. #include "llerror.h"
  35. #include <vector>
  36. #include <map>
  37. // class LLDynamicArray<>; // = std::vector + reserves <BlockSize> elements
  38. // class LLDynamicArrayIndexed<>; // = std::vector + std::map if indices, only supports operator[] and begin(),end()
  39. //--------------------------------------------------------
  40. // LLDynamicArray declaration
  41. //--------------------------------------------------------
  42. // NOTE: BlockSize is used to reserve a minimal initial amount
  43. template <typename Type, int BlockSize = 32> 
  44. class LLDynamicArray : public std::vector<Type>
  45. {
  46. public:
  47. enum
  48. {
  49. OKAY = 0,
  50. FAIL = -1
  51. };
  52. LLDynamicArray(S32 size=0) : std::vector<Type>(size) { if (size < BlockSize) std::vector<Type>::reserve(BlockSize); }
  53. void reset() { std::vector<Type>::resize(0); }
  54. // ACCESSORS
  55. const Type& get(S32 index) const   { return std::vector<Type>::operator[](index); }
  56. Type&       get(S32 index) { return std::vector<Type>::operator[](index); }
  57. S32 find(const Type &obj) const;
  58. S32 count() const { return std::vector<Type>::size(); }
  59. S32 getLength() const { return std::vector<Type>::size(); }
  60. S32 getMax() const { return std::vector<Type>::capacity(); }
  61. // MANIPULATE
  62. S32         put(const Type &obj); // add to end of array, returns index
  63. //  Type* reserve(S32 num); // reserve a block of indices in advance
  64. Type* reserve_block(U32 num); // reserve a block of indices in advance
  65. S32 remove(S32 index); // remove by index, no bounds checking
  66. S32 removeObj(const Type &obj); // remove by object
  67. S32 removeLast();
  68. void operator+=(const LLDynamicArray<Type,BlockSize> &other);
  69. };
  70. //--------------------------------------------------------
  71. // LLDynamicArray implementation
  72. //--------------------------------------------------------
  73. template <typename Type,int BlockSize>
  74. inline S32 LLDynamicArray<Type,BlockSize>::find(const Type &obj) const
  75. {
  76. typename std::vector<Type>::const_iterator iter = std::find(this->begin(), this->end(), obj);
  77. if (iter != this->end())
  78. {
  79. return iter - this->begin();
  80. }
  81. return FAIL;
  82. }
  83. template <typename Type,int BlockSize>
  84. inline S32 LLDynamicArray<Type,BlockSize>::remove(S32 i)
  85. {
  86. // This is a fast removal by swapping with the last element
  87. S32 sz = this->size();
  88. if (i < 0 || i >= sz)
  89. {
  90. return FAIL;
  91. }
  92. if (i < sz-1)
  93. {
  94. this->operator[](i) = this->back();
  95. }
  96. this->pop_back();
  97. return i;
  98. }
  99. template <typename Type,int BlockSize>
  100. inline S32 LLDynamicArray<Type,BlockSize>::removeObj(const Type& obj)
  101. {
  102. typename std::vector<Type>::iterator iter = std::find(this->begin(), this->end(), obj);
  103. if (iter != this->end())
  104. {
  105. S32 res = iter - this->begin();
  106. typename std::vector<Type>::iterator last = this->end(); 
  107. --last;
  108. *iter = *last;
  109. this->pop_back();
  110. return res;
  111. }
  112. return FAIL;
  113. }
  114. template <typename Type,int BlockSize>
  115. inline S32 LLDynamicArray<Type,BlockSize>::removeLast()
  116. {
  117. if (!this->empty())
  118. {
  119. this->pop_back();
  120. return OKAY;
  121. }
  122. return FAIL;
  123. }
  124. template <typename Type,int BlockSize>
  125. inline Type* LLDynamicArray<Type,BlockSize>::reserve_block(U32 num)
  126. {
  127. U32 sz = this->size();
  128. this->resize(sz+num);
  129. return &(this->operator[](sz));
  130. }
  131. template <typename Type,int BlockSize>
  132. inline S32 LLDynamicArray<Type,BlockSize>::put(const Type &obj) 
  133. {
  134. this->push_back(obj);
  135. return this->size() - 1;
  136. }
  137. template <typename Type,int BlockSize>
  138. inline void LLDynamicArray<Type,BlockSize>::operator+=(const LLDynamicArray<Type,BlockSize> &other)
  139. {
  140. insert(this->end(), other.begin(), other.end());
  141. }
  142. //--------------------------------------------------------
  143. // LLDynamicArrayIndexed declaration
  144. //--------------------------------------------------------
  145. template <typename Type, typename Key, int BlockSize = 32> 
  146. class LLDynamicArrayIndexed
  147. {
  148. public:
  149. typedef typename std::vector<Type>::iterator iterator;
  150. typedef typename std::vector<Type>::const_iterator const_iterator;
  151. typedef typename std::vector<Type>::reverse_iterator reverse_iterator;
  152. typedef typename std::vector<Type>::const_reverse_iterator const_reverse_iterator;
  153. typedef typename std::vector<Type>::size_type size_type;
  154. protected:
  155. std::vector<Type> mVector;
  156. std::map<Key, U32> mIndexMap;
  157. public:
  158. LLDynamicArrayIndexed() { mVector.reserve(BlockSize); }
  159. iterator begin() { return mVector.begin(); }
  160. const_iterator begin() const { return mVector.begin(); }
  161. iterator end() { return mVector.end(); }
  162. const_iterator end() const { return mVector.end(); }
  163. reverse_iterator rbegin() { return mVector.rbegin(); }
  164. const_reverse_iterator rbegin() const { return mVector.rbegin(); }
  165. reverse_iterator rend() { return mVector.rend(); }
  166. const_reverse_iterator rend() const { return mVector.rend(); }
  167. void reset() { mVector.resize(0); mIndexMap.resize(0); }
  168. bool empty() const { return mVector.empty(); }
  169. size_type size() const { return mVector.size(); }
  170. Type& operator[](const Key& k)
  171. {
  172. typename std::map<Key, U32>::const_iterator iter = mIndexMap.find(k);
  173. if (iter == mIndexMap.end())
  174. {
  175. U32 n = mVector.size();
  176. mIndexMap[k] = n;
  177. mVector.resize(n+1);
  178. llassert(mVector.size() == mIndexMap.size());
  179. return mVector[n];
  180. }
  181. else
  182. {
  183. return mVector[iter->second];
  184. }
  185. }
  186. const_iterator find(const Key& k) const
  187. {
  188. typename std::map<Key, U32>::const_iterator iter = mIndexMap.find(k);
  189. if(iter == mIndexMap.end())
  190. {
  191. return mVector.end();
  192. }
  193. else
  194. {
  195. return mVector.begin() + iter->second;
  196. }
  197. }
  198. };
  199. #endif