SLikeNet 0.1.3

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DS_OrderedList.h
Go to the documentation of this file.
1 /*
2 * Original work: Copyright (c) 2014, Oculus VR, Inc.
3 * All rights reserved.
4 *
5 * This source code is licensed under the BSD-style license found in the
6 * RakNet License.txt file in the licenses directory of this source tree. An additional grant
7 * of patent rights can be found in the RakNet Patents.txt file in the same directory.
8 *
9 *
10 * Modified work: Copyright (c) 2016-2017, SLikeSoft UG (haftungsbeschränkt)
11 *
12 * This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
13 * license found in the license.txt file in the root directory of this source tree.
14 */
15
20
21 #include "DS_List.h"
22 #include "memoryoverride.h"
23 #include "Export.h"
24
25 #ifndef __ORDERED_LIST_H
26 #define __ORDERED_LIST_H
27
30 namespace DataStructures
31 {
32 template <class key_type, class data_type>
33 int defaultOrderedListComparison(const key_type &a, const data_type &b)
34 {
35 if (a<b) return -1; if (a==b) return 0; return 1;
36 }
37
39 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)=defaultOrderedListComparison<key_type, data_type> >
40 class RAK_DLL_EXPORT OrderedList
41 {
42 public:
43 static void IMPLEMENT_DEFAULT_COMPARISON(void) {DataStructures::defaultOrderedListComparison<key_type, data_type>(key_type(),data_type());}
44
45 OrderedList();
46 ~OrderedList();
47 OrderedList( const OrderedList& original_copy );
48 OrderedList& operator= ( const OrderedList& original_copy );
49
52 bool HasData(const key_type &key, int (*cf)(const key_type&, const data_type&)=default_comparison_function) const;
53 // GetIndexFromKey returns where the insert should go at the same time checks if it is there
54 unsigned GetIndexFromKey(const key_type &key, bool *objectExists, int (*cf)(const key_type&, const data_type&)=default_comparison_function) const;
55 data_type GetElementFromKey(const key_type &key, int (*cf)(const key_type&, const data_type&)=default_comparison_function) const;
56 bool GetElementFromKey(const key_type &key, data_type &element, int (*cf)(const key_type&, const data_type&)=default_comparison_function) const;
57 unsigned Insert(const key_type &key, const data_type &data, bool assertOnDuplicate, const char *file, unsigned int line, int (*cf)(const key_type&, const data_type&)=default_comparison_function);
58 unsigned Remove(const key_type &key, int (*cf)(const key_type&, const data_type&)=default_comparison_function);
59 unsigned RemoveIfExists(const key_type &key, int (*cf)(const key_type&, const data_type&)=default_comparison_function);
60 data_type& operator[] ( const unsigned int position ) const;
61 void RemoveAtIndex(const unsigned index);
62 void InsertAtIndex(const data_type &data, const unsigned index, const char *file, unsigned int line);
63 void InsertAtEnd(const data_type &data, const char *file, unsigned int line);
64 void RemoveFromEnd(const unsigned num=1);
65 void Clear(bool doNotDeallocate, const char *file, unsigned int line);
66 unsigned Size(void) const;
67
68 protected:
69 DataStructures::List<data_type> orderedList;
70 };
71
72 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)>
73 OrderedList<key_type, data_type, default_comparison_function>::OrderedList()
74 {
75 }
76
77 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)>
78 OrderedList<key_type, data_type, default_comparison_function>::~OrderedList()
79 {
80 Clear(false, _FILE_AND_LINE_);
81 }
82
83 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)>
84 OrderedList<key_type, data_type, default_comparison_function>::OrderedList( const OrderedList& original_copy )
85 {
86 orderedList=original_copy.orderedList;
87 }
88
89 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)>
90 OrderedList<key_type, data_type, default_comparison_function>& OrderedList<key_type, data_type, default_comparison_function>::operator= ( const OrderedList& original_copy )
91 {
92 orderedList=original_copy.orderedList;
93 return *this;
94 }
95
96 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)>
97 bool OrderedList<key_type, data_type, default_comparison_function>::HasData(const key_type &key, int (*cf)(const key_type&, const data_type&)) const
98 {
99 bool objectExists;
100 GetIndexFromKey(key, &objectExists, cf);
101 return objectExists;
102 }
103
104 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)>
105 data_type OrderedList<key_type, data_type, default_comparison_function>::GetElementFromKey(const key_type &key, int (*cf)(const key_type&, const data_type&)) const
106 {
107 bool objectExists;
108 unsigned index;
109 index = GetIndexFromKey(key, &objectExists, cf);
110 RakAssert(objectExists);
111 return orderedList[index];
112 }
113 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)>
114 bool OrderedList<key_type, data_type, default_comparison_function>::GetElementFromKey(const key_type &key, data_type &element, int (*cf)(const key_type&, const data_type&)) const
115 {
116 bool objectExists;
117 unsigned index;
118 index = GetIndexFromKey(key, &objectExists, cf);
119 if (objectExists)
120 element = orderedList[index];
121 return objectExists;
122 }
123 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)>
124 unsigned OrderedList<key_type, data_type, default_comparison_function>::GetIndexFromKey(const key_type &key, bool *objectExists, int (*cf)(const key_type&, const data_type&)) const
125 {
126 int index, upperBound, lowerBound;
127 int res;
128
129 if (orderedList.Size()==0)
130 {
131 *objectExists=false;
132 return 0;
133 }
134
135 upperBound=(int)orderedList.Size()-1;
136 lowerBound=0;
137 index = (int)orderedList.Size()/2;
138
139 for(;;)
140 {
141 res = cf(key,orderedList[index]);
142 if (res==0)
143 {
144 *objectExists=true;
145 return (unsigned)index;
146 }
147 else if (res<0)
148 {
149 upperBound=index-1;
150 }
151 else// if (res>0)
152 {
153
154 lowerBound=index+1;
155 }
156
157 index=lowerBound+(upperBound-lowerBound)/2;
158
159 if (lowerBound>upperBound)
160 {
161 *objectExists=false;
162 return (unsigned)lowerBound; // No match
163 }
164
165 if (index < 0 || index >= (int) orderedList.Size())
166 {
167 // This should never hit unless the comparison function was inconsistent
168 RakAssert(index && 0);
169 *objectExists=false;
170 return 0;
171 }
172 }
173 }
174
175 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)>
176 unsigned OrderedList<key_type, data_type, default_comparison_function>::Insert(const key_type &key, const data_type &data, bool assertOnDuplicate, const char *file, unsigned int line, int (*cf)(const key_type&, const data_type&))
177 {
178 (void) assertOnDuplicate;
179 bool objectExists;
180 unsigned index;
181 index = GetIndexFromKey(key, &objectExists, cf);
182
183 // Don't allow duplicate insertion.
184 if (objectExists)
185 {
186 // This is usually a bug!
187 RakAssert(assertOnDuplicate==false);
188 return (unsigned)-1;
189 }
190
191 if (index>=orderedList.Size())
192 {
193 orderedList.Insert(data, file, line);
194 return orderedList.Size()-1;
195 }
196 else
197 {
198 orderedList.Insert(data,index, file, line);
199 return index;
200 }
201 }
202
203 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)>
204 unsigned OrderedList<key_type, data_type, default_comparison_function>::Remove(const key_type &key, int (*cf)(const key_type&, const data_type&))
205 {
206 bool objectExists;
207 unsigned index;
208 index = GetIndexFromKey(key, &objectExists, cf);
209
210 // Can't find the element to remove if this assert hits
211 // RakAssert(objectExists==true);
212 if (objectExists==false)
213 {
214 RakAssert(objectExists==true);
215 return 0;
216 }
217
218 orderedList.RemoveAtIndex(index);
219 return index;
220 }
221
222 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)>
223 unsigned OrderedList<key_type, data_type, default_comparison_function>::RemoveIfExists(const key_type &key, int (*cf)(const key_type&, const data_type&))
224 {
225 bool objectExists;
226 unsigned index;
227 index = GetIndexFromKey(key, &objectExists, cf);
228
229 // Can't find the element to remove if this assert hits
230 if (objectExists==false)
231 return 0;
232
233 orderedList.RemoveAtIndex(index);
234 return index;
235 }
236
237 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)>
238 void OrderedList<key_type, data_type, default_comparison_function>::RemoveAtIndex(const unsigned index)
239 {
240 orderedList.RemoveAtIndex(index);
241 }
242
243 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)>
244 void OrderedList<key_type, data_type, default_comparison_function>::InsertAtIndex(const data_type &data, const unsigned index, const char *file, unsigned int line)
245 {
246 orderedList.Insert(data, index, file, line);
247 }
248
249 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)>
250 void OrderedList<key_type, data_type, default_comparison_function>::InsertAtEnd(const data_type &data, const char *file, unsigned int line)
251 {
252 orderedList.Insert(data, file, line);
253 }
254
255 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)>
256 void OrderedList<key_type, data_type, default_comparison_function>::RemoveFromEnd(const unsigned num)
257 {
258 orderedList.RemoveFromEnd(num);
259 }
260
261 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)>
262 void OrderedList<key_type, data_type, default_comparison_function>::Clear(bool doNotDeallocate, const char *file, unsigned int line)
263 {
264 orderedList.Clear(doNotDeallocate, file, line);
265 }
266
267 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)>
268 data_type& OrderedList<key_type, data_type, default_comparison_function>::operator[]( const unsigned int position ) const
269 {
270 return orderedList[position];
271 }
272
273 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)>
274 unsigned OrderedList<key_type, data_type, default_comparison_function>::Size(void) const
275 {
276 return orderedList.Size();
277 }
278 }
279
280 #endif