aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llcommon/llmap.h
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llcommon/llmap.h')
-rw-r--r--linden/indra/llcommon/llmap.h250
1 files changed, 250 insertions, 0 deletions
diff --git a/linden/indra/llcommon/llmap.h b/linden/indra/llcommon/llmap.h
new file mode 100644
index 0000000..2bda851
--- /dev/null
+++ b/linden/indra/llcommon/llmap.h
@@ -0,0 +1,250 @@
1/**
2 * @file llmap.h
3 * @brief LLMap class header file
4 *
5 * Copyright (c) 2001-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#ifndef LL_LLMAP_H
29#define LL_LLMAP_H
30
31#include <stdio.h>
32#include <utility>
33#include <map>
34
35// llmap uses the fast stl library code in a manner consistant with LLSkipMap, et. al.
36
37template<class INDEX_TYPE, class MAPPED_TYPE> class LLMap
38{
39private:
40 typedef typename std::map<INDEX_TYPE, MAPPED_TYPE> stl_map_t;
41 typedef typename stl_map_t::iterator stl_iter_t;
42 typedef typename stl_map_t::value_type stl_value_t;
43
44 stl_map_t mStlMap;
45 stl_iter_t mCurIter; // *iterator = pair<const INDEX_TYPE, MAPPED_TYPE>
46 MAPPED_TYPE dummy_data;
47 INDEX_TYPE dummy_index;
48
49public:
50 LLMap() : mStlMap()
51 {
52 memset((void*)(&dummy_data), 0x0, sizeof(MAPPED_TYPE));
53 memset((void*)(&dummy_index), 0x0, sizeof(INDEX_TYPE));
54 mCurIter = mStlMap.begin();
55 }
56 ~LLMap()
57 {
58 mStlMap.clear();
59 }
60
61 // use these functions to itterate through a list
62 void resetMap()
63 {
64 mCurIter = mStlMap.begin();
65 }
66
67 // get the current data and bump mCurrentp
68 // This is kind of screwy since it returns a reference;
69 // We have to have a dummy value for when we reach the end
70 // or in case we have an empty list. Presumably, this value
71 // will initialize to some NULL value that will end the iterator.
72 // We really shouldn't be using getNextData() or getNextKey() anyway...
73 MAPPED_TYPE &getNextData()
74 {
75 if (mCurIter == mStlMap.end())
76 {
77 return dummy_data;
78 }
79 else
80 {
81 return (*mCurIter++).second;
82 }
83 }
84
85 const INDEX_TYPE &getNextKey()
86 {
87 if (mCurIter == mStlMap.end())
88 {
89 return dummy_index;
90 }
91 else
92 {
93 return (*mCurIter++).first;
94 }
95 }
96
97 MAPPED_TYPE &getFirstData()
98 {
99 resetMap();
100 return getNextData();
101 }
102
103 const INDEX_TYPE &getFirstKey()
104 {
105 resetMap();
106 return getNextKey();
107 }
108
109 S32 getLength()
110 {
111 return mStlMap.size();
112 }
113
114 void addData(const INDEX_TYPE &index, MAPPED_TYPE pointed_to)
115 {
116 mStlMap.insert(stl_value_t(index, pointed_to));
117 }
118
119 void addData(const INDEX_TYPE &index)
120 {
121 mStlMap.insert(stl_value_t(index, dummy_data));
122 }
123
124 // if index doesn't exist, then insert a new node and return it
125 MAPPED_TYPE &getData(const INDEX_TYPE &index)
126 {
127 std::pair<stl_iter_t, bool> res;
128 res = mStlMap.insert(stl_value_t(index, dummy_data));
129 return res.first->second;
130 }
131
132 // if index doesn't exist, then insert a new node, return it, and set b_new_entry to true
133 MAPPED_TYPE &getData(const INDEX_TYPE &index, BOOL &b_new_entry)
134 {
135 std::pair<stl_iter_t, bool> res;
136 res = mStlMap.insert(stl_value_t(index, dummy_data));
137 b_new_entry = res.second;
138 return res.first->second;
139 }
140
141 // If there, returns the data.
142 // If not, returns NULL.
143 // Never adds entries to the map.
144 MAPPED_TYPE getIfThere(const INDEX_TYPE &index)
145 {
146 stl_iter_t iter;
147 iter = mStlMap.find(index);
148 if (iter == mStlMap.end())
149 {
150 return (MAPPED_TYPE)0;
151 }
152 else
153 {
154 return (*iter).second;
155 }
156 }
157
158
159 // if index doesn't exist, then make a new node and return it
160 MAPPED_TYPE &operator[](const INDEX_TYPE &index)
161 {
162 return getData(index);
163 }
164
165 // do a reverse look-up, return NULL if failed
166 INDEX_TYPE reverseLookup(const MAPPED_TYPE data)
167 {
168 stl_iter_t iter;
169 stl_iter_t end_iter;
170 iter = mStlMap.begin();
171 end_iter = mStlMap.end();
172 while (iter != end_iter)
173 {
174 if ((*iter).second == data)
175 return (*iter).first;
176 iter++;
177 }
178 return (INDEX_TYPE)0;
179 }
180
181 BOOL removeData(const INDEX_TYPE &index)
182 {
183 mCurIter = mStlMap.find(index);
184 if (mCurIter == mStlMap.end())
185 {
186 return FALSE;
187 }
188 else
189 {
190 stl_iter_t iter = mCurIter++; // incrament mCurIter to the next element
191 mStlMap.erase(iter);
192 return TRUE;
193 }
194 }
195
196 // does this index exist?
197 BOOL checkData(const INDEX_TYPE &index)
198 {
199 stl_iter_t iter;
200 iter = mStlMap.find(index);
201 if (iter == mStlMap.end())
202 {
203 return FALSE;
204 }
205 else
206 {
207 mCurIter = iter;
208 return TRUE;
209 }
210 }
211
212 BOOL deleteData(const INDEX_TYPE &index)
213 {
214 mCurIter = mStlMap.find(index);
215 if (mCurIter == mStlMap.end())
216 {
217 return FALSE;
218 }
219 else
220 {
221 stl_iter_t iter = mCurIter++; // incrament mCurIter to the next element
222 delete (*iter).second;
223 mStlMap.erase(iter);
224 return TRUE;
225 }
226 }
227
228 void deleteAllData()
229 {
230 stl_iter_t iter;
231 stl_iter_t end_iter;
232 iter = mStlMap.begin();
233 end_iter = mStlMap.end();
234 while (iter != end_iter)
235 {
236 delete (*iter).second;
237 iter++;
238 }
239 mStlMap.clear();
240 mCurIter = mStlMap.end();
241 }
242
243 void removeAllData()
244 {
245 mStlMap.clear();
246 }
247};
248
249
250#endif