PageRenderTime 40ms CodeModel.GetById 15ms app.highlight 20ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llcommon/llmap.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 245 lines | 178 code | 26 blank | 41 comment | 18 complexity | b03343d28c807a3f6ad58f7b1f15b5c2 MD5 | raw file
  1/** 
  2 * @file llmap.h
  3 * @brief LLMap class header file
  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_LLMAP_H
 28#define LL_LLMAP_H
 29
 30// llmap uses the fast stl library code in a manner consistant with LLSkipMap, et. al. 
 31
 32template<class INDEX_TYPE, class MAPPED_TYPE> class LLMap
 33{
 34private:
 35	typedef typename std::map<INDEX_TYPE, MAPPED_TYPE> stl_map_t;
 36	typedef typename stl_map_t::iterator stl_iter_t;
 37	typedef typename stl_map_t::value_type stl_value_t;
 38	
 39	stl_map_t mStlMap;
 40	stl_iter_t mCurIter;	// *iterator = pair<const INDEX_TYPE, MAPPED_TYPE>
 41	MAPPED_TYPE dummy_data;
 42	INDEX_TYPE dummy_index;
 43	
 44public:
 45	LLMap() : mStlMap()
 46	{
 47		memset((void*)(&dummy_data),  0x0, sizeof(MAPPED_TYPE));
 48		memset((void*)(&dummy_index), 0x0, sizeof(INDEX_TYPE));
 49		mCurIter = mStlMap.begin();
 50	}
 51	~LLMap()
 52	{
 53		mStlMap.clear();
 54	}
 55
 56	// use these functions to itterate through a list
 57	void resetMap()
 58	{
 59		mCurIter = mStlMap.begin();
 60	}
 61
 62	// get the current data and bump mCurrentp
 63	// This is kind of screwy since it returns a reference;
 64	//   We have to have a dummy value for when we reach the end
 65	//   or in case we have an empty list. Presumably, this value
 66	//   will initialize to some NULL value that will end the iterator.
 67	// We really shouldn't be using getNextData() or getNextKey() anyway...
 68	MAPPED_TYPE &getNextData()
 69	{
 70		if (mCurIter == mStlMap.end())
 71		{
 72			return dummy_data;
 73		}
 74		else
 75		{
 76			return (*mCurIter++).second;
 77		}
 78	}
 79
 80	const INDEX_TYPE &getNextKey()
 81	{
 82		if (mCurIter == mStlMap.end())
 83		{
 84			return dummy_index;
 85		}
 86		else
 87		{
 88			return (*mCurIter++).first;
 89		}
 90	}
 91
 92	MAPPED_TYPE &getFirstData()
 93	{
 94		resetMap();
 95		return getNextData();
 96	}
 97
 98	const INDEX_TYPE &getFirstKey()
 99	{
100		resetMap();
101		return getNextKey();
102	}
103
104	S32 getLength()
105	{
106		return mStlMap.size();
107	}
108
109	void addData(const INDEX_TYPE &index, MAPPED_TYPE pointed_to)
110	{
111		mStlMap.insert(stl_value_t(index, pointed_to));
112	}
113
114	void addData(const INDEX_TYPE &index)
115	{
116		mStlMap.insert(stl_value_t(index, dummy_data));
117	}
118
119	// if index doesn't exist, then insert a new node and return it
120	MAPPED_TYPE &getData(const INDEX_TYPE &index)
121	{
122		std::pair<stl_iter_t, bool> res;
123		res = mStlMap.insert(stl_value_t(index, dummy_data));
124		return res.first->second;
125	}
126
127	// if index doesn't exist, then insert a new node, return it, and set b_new_entry to true
128	MAPPED_TYPE &getData(const INDEX_TYPE &index, BOOL &b_new_entry)
129	{
130		std::pair<stl_iter_t, bool> res;
131		res = mStlMap.insert(stl_value_t(index, dummy_data));
132		b_new_entry = res.second;
133		return res.first->second;
134	}
135
136	// If there, returns the data.
137	// If not, returns NULL.
138	// Never adds entries to the map.
139	MAPPED_TYPE getIfThere(const INDEX_TYPE &index)
140	{
141		stl_iter_t iter;
142		iter = mStlMap.find(index);
143		if (iter == mStlMap.end())
144		{
145			return (MAPPED_TYPE)0;
146		}
147		else
148		{
149			return (*iter).second;
150		}
151	}
152
153
154	// if index doesn't exist, then make a new node and return it
155	MAPPED_TYPE &operator[](const INDEX_TYPE &index)
156	{
157		return getData(index);
158	}
159
160	// do a reverse look-up, return NULL if failed
161	INDEX_TYPE reverseLookup(const MAPPED_TYPE data)
162	{
163		stl_iter_t iter;
164		stl_iter_t end_iter;
165		iter = mStlMap.begin();
166		end_iter = mStlMap.end();
167		while (iter != end_iter)
168		{
169			if ((*iter).second == data)
170				return (*iter).first;
171			iter++;
172		}
173		return (INDEX_TYPE)0;
174	}
175
176	BOOL removeData(const INDEX_TYPE &index)
177	{
178		mCurIter = mStlMap.find(index);
179		if (mCurIter == mStlMap.end())
180		{
181			return FALSE;
182		}
183		else
184		{
185			stl_iter_t iter = mCurIter++; // incrament mCurIter to the next element
186			mStlMap.erase(iter);
187			return TRUE;
188		}
189	}
190
191	// does this index exist?
192	BOOL checkData(const INDEX_TYPE &index)
193	{
194		stl_iter_t iter;
195		iter = mStlMap.find(index);
196		if (iter == mStlMap.end())
197		{
198			return FALSE;
199		}
200		else
201		{
202			mCurIter = iter;
203			return TRUE;
204		}
205	}
206
207	BOOL deleteData(const INDEX_TYPE &index)
208	{
209		mCurIter = mStlMap.find(index);
210		if (mCurIter == mStlMap.end())
211		{
212			return FALSE;
213		}
214		else
215		{
216			stl_iter_t iter = mCurIter++; // incrament mCurIter to the next element
217			delete (*iter).second;
218			mStlMap.erase(iter);
219			return TRUE;
220		}
221	}
222
223	void deleteAllData()
224	{
225		stl_iter_t iter;
226		stl_iter_t end_iter;
227		iter = mStlMap.begin();
228		end_iter = mStlMap.end();
229		while (iter != end_iter)
230		{
231			delete (*iter).second;
232			iter++;
233		}
234		mStlMap.clear();
235		mCurIter = mStlMap.end();
236	}
237	
238	void removeAllData()
239	{
240		mStlMap.clear();
241	}
242};
243
244
245#endif