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