![]() |
Shadowrun: Awakened 29 September 2011 - Build 871
|
00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 #include "DS_List.h" 00011 #include "RakMemoryOverride.h" 00012 #include "Export.h" 00013 00014 #ifndef __ORDERED_LIST_H 00015 #define __ORDERED_LIST_H 00016 00019 namespace DataStructures 00020 { 00021 template <class key_type, class data_type> 00022 int defaultOrderedListComparison(const key_type &a, const data_type &b) 00023 { 00024 if (a<b) return -1; if (a==b) return 0; return 1; 00025 } 00026 00028 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)=defaultOrderedListComparison<key_type, data_type> > 00029 class RAK_DLL_EXPORT OrderedList 00030 { 00031 public: 00032 static void IMPLEMENT_DEFAULT_COMPARISON(void) {DataStructures::defaultOrderedListComparison<key_type, data_type>(key_type(),data_type());} 00033 00034 OrderedList(); 00035 ~OrderedList(); 00036 OrderedList( const OrderedList& original_copy ); 00037 OrderedList& operator= ( const OrderedList& original_copy ); 00038 00041 bool HasData(const key_type &key, int (*cf)(const key_type&, const data_type&)=default_comparison_function) const; 00042 // GetIndexFromKey returns where the insert should go at the same time checks if it is there 00043 unsigned GetIndexFromKey(const key_type &key, bool *objectExists, int (*cf)(const key_type&, const data_type&)=default_comparison_function) const; 00044 data_type GetElementFromKey(const key_type &key, int (*cf)(const key_type&, const data_type&)=default_comparison_function) const; 00045 bool GetElementFromKey(const key_type &key, data_type &element, int (*cf)(const key_type&, const data_type&)=default_comparison_function) const; 00046 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); 00047 unsigned Remove(const key_type &key, int (*cf)(const key_type&, const data_type&)=default_comparison_function); 00048 unsigned RemoveIfExists(const key_type &key, int (*cf)(const key_type&, const data_type&)=default_comparison_function); 00049 data_type& operator[] ( const unsigned int position ) const; 00050 void RemoveAtIndex(const unsigned index); 00051 void InsertAtIndex(const data_type &data, const unsigned index, const char *file, unsigned int line); 00052 void InsertAtEnd(const data_type &data, const char *file, unsigned int line); 00053 void RemoveFromEnd(const unsigned num=1); 00054 void Clear(bool doNotDeallocate, const char *file, unsigned int line); 00055 unsigned Size(void) const; 00056 00057 protected: 00058 DataStructures::List<data_type> orderedList; 00059 }; 00060 00061 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)> 00062 OrderedList<key_type, data_type, default_comparison_function>::OrderedList() 00063 { 00064 } 00065 00066 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)> 00067 OrderedList<key_type, data_type, default_comparison_function>::~OrderedList() 00068 { 00069 Clear(false, _FILE_AND_LINE_); 00070 } 00071 00072 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)> 00073 OrderedList<key_type, data_type, default_comparison_function>::OrderedList( const OrderedList& original_copy ) 00074 { 00075 orderedList=original_copy.orderedList; 00076 } 00077 00078 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)> 00079 OrderedList<key_type, data_type, default_comparison_function>& OrderedList<key_type, data_type, default_comparison_function>::operator= ( const OrderedList& original_copy ) 00080 { 00081 orderedList=original_copy.orderedList; 00082 return *this; 00083 } 00084 00085 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)> 00086 bool OrderedList<key_type, data_type, default_comparison_function>::HasData(const key_type &key, int (*cf)(const key_type&, const data_type&)) const 00087 { 00088 bool objectExists; 00089 GetIndexFromKey(key, &objectExists, cf); 00090 return objectExists; 00091 } 00092 00093 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)> 00094 data_type OrderedList<key_type, data_type, default_comparison_function>::GetElementFromKey(const key_type &key, int (*cf)(const key_type&, const data_type&)) const 00095 { 00096 bool objectExists; 00097 unsigned index; 00098 index = GetIndexFromKey(key, &objectExists, cf); 00099 RakAssert(objectExists); 00100 return orderedList[index]; 00101 } 00102 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)> 00103 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 00104 { 00105 bool objectExists; 00106 unsigned index; 00107 index = GetIndexFromKey(key, &objectExists, cf); 00108 if (objectExists) 00109 element = orderedList[index]; 00110 return objectExists; 00111 } 00112 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)> 00113 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 00114 { 00115 int index, upperBound, lowerBound; 00116 int res; 00117 00118 if (orderedList.Size()==0) 00119 { 00120 *objectExists=false; 00121 return 0; 00122 } 00123 00124 upperBound=(int)orderedList.Size()-1; 00125 lowerBound=0; 00126 index = (int)orderedList.Size()/2; 00127 00128 #ifdef _MSC_VER 00129 #pragma warning( disable : 4127 ) // warning C4127: conditional expression is constant 00130 #endif 00131 while (1) 00132 { 00133 res = cf(key,orderedList[index]); 00134 if (res==0) 00135 { 00136 *objectExists=true; 00137 return index; 00138 } 00139 else if (res<0) 00140 { 00141 upperBound=index-1; 00142 } 00143 else// if (res>0) 00144 { 00145 lowerBound=index+1; 00146 } 00147 00148 index=lowerBound+(upperBound-lowerBound)/2; 00149 00150 if (lowerBound>upperBound) 00151 { 00152 *objectExists=false; 00153 return lowerBound; // No match 00154 } 00155 } 00156 } 00157 00158 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)> 00159 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&)) 00160 { 00161 (void) assertOnDuplicate; 00162 bool objectExists; 00163 unsigned index; 00164 index = GetIndexFromKey(key, &objectExists, cf); 00165 00166 // Don't allow duplicate insertion. 00167 if (objectExists) 00168 { 00169 // This is usually a bug! 00170 RakAssert(assertOnDuplicate==false); 00171 return (unsigned)-1; 00172 } 00173 00174 if (index>=orderedList.Size()) 00175 { 00176 orderedList.Insert(data, file, line); 00177 return orderedList.Size()-1; 00178 } 00179 else 00180 { 00181 orderedList.Insert(data,index, file, line); 00182 return index; 00183 } 00184 } 00185 00186 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)> 00187 unsigned OrderedList<key_type, data_type, default_comparison_function>::Remove(const key_type &key, int (*cf)(const key_type&, const data_type&)) 00188 { 00189 bool objectExists; 00190 unsigned index; 00191 index = GetIndexFromKey(key, &objectExists, cf); 00192 00193 // Can't find the element to remove if this assert hits 00194 // RakAssert(objectExists==true); 00195 if (objectExists==false) 00196 { 00197 RakAssert(objectExists==true); 00198 return 0; 00199 } 00200 00201 orderedList.RemoveAtIndex(index); 00202 return index; 00203 } 00204 00205 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)> 00206 unsigned OrderedList<key_type, data_type, default_comparison_function>::RemoveIfExists(const key_type &key, int (*cf)(const key_type&, const data_type&)) 00207 { 00208 bool objectExists; 00209 unsigned index; 00210 index = GetIndexFromKey(key, &objectExists, cf); 00211 00212 // Can't find the element to remove if this assert hits 00213 if (objectExists==false) 00214 return 0; 00215 00216 orderedList.RemoveAtIndex(index); 00217 return index; 00218 } 00219 00220 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)> 00221 void OrderedList<key_type, data_type, default_comparison_function>::RemoveAtIndex(const unsigned index) 00222 { 00223 orderedList.RemoveAtIndex(index); 00224 } 00225 00226 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)> 00227 void OrderedList<key_type, data_type, default_comparison_function>::InsertAtIndex(const data_type &data, const unsigned index, const char *file, unsigned int line) 00228 { 00229 orderedList.Insert(data, index, file, line); 00230 } 00231 00232 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)> 00233 void OrderedList<key_type, data_type, default_comparison_function>::InsertAtEnd(const data_type &data, const char *file, unsigned int line) 00234 { 00235 orderedList.Insert(data, file, line); 00236 } 00237 00238 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)> 00239 void OrderedList<key_type, data_type, default_comparison_function>::RemoveFromEnd(const unsigned num) 00240 { 00241 orderedList.RemoveFromEnd(num); 00242 } 00243 00244 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)> 00245 void OrderedList<key_type, data_type, default_comparison_function>::Clear(bool doNotDeallocate, const char *file, unsigned int line) 00246 { 00247 orderedList.Clear(doNotDeallocate, file, line); 00248 } 00249 00250 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)> 00251 data_type& OrderedList<key_type, data_type, default_comparison_function>::operator[]( const unsigned int position ) const 00252 { 00253 return orderedList[position]; 00254 } 00255 00256 template <class key_type, class data_type, int (*default_comparison_function)(const key_type&, const data_type&)> 00257 unsigned OrderedList<key_type, data_type, default_comparison_function>::Size(void) const 00258 { 00259 return orderedList.Size(); 00260 } 00261 } 00262 00263 #endif
Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.