00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef __RAKNET_MAP_H
00011 #define __RAKNET_MAP_H
00012
00013 #include "DS_OrderedList.h"
00014 #include "Export.h"
00015 #include "RakMemoryOverride.h"
00016 #include "RakAssert.h"
00017
00018
00019
00020
00023 namespace DataStructures
00024 {
00027 template <class key_type>
00028 int defaultMapKeyComparison(const key_type &a, const key_type &b)
00029 {
00030 if (a<b) return -1; if (a==b) return 0; return 1;
00031 }
00032
00034 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&, const key_type&)=defaultMapKeyComparison<key_type> >
00035 class RAK_DLL_EXPORT Map
00036 {
00037 public:
00038 static void IMPLEMENT_DEFAULT_COMPARISON(void) {DataStructures::defaultMapKeyComparison<key_type>(key_type(),key_type());}
00039
00040 struct MapNode
00041 {
00042 MapNode() {}
00043 MapNode(key_type _key, data_type _data) : mapNodeKey(_key), mapNodeData(_data) {}
00044 MapNode& operator = ( const MapNode& input ) {mapNodeKey=input.mapNodeKey; mapNodeData=input.mapNodeData; return *this;}
00045 MapNode( const MapNode & input) {mapNodeKey=input.mapNodeKey; mapNodeData=input.mapNodeData;}
00046 key_type mapNodeKey;
00047 data_type mapNodeData;
00048 };
00049
00050
00051 static int NodeComparisonFunc(const key_type &a, const MapNode &b)
00052 {
00053 #ifdef _MSC_VER
00054 #pragma warning( disable : 4127 ) // warning C4127: conditional expression is constant
00055 #endif
00056 return key_comparison_func(a, b.mapNodeKey);
00057 }
00058
00059 Map();
00060 ~Map();
00061 Map( const Map& original_copy );
00062 Map& operator= ( const Map& original_copy );
00063
00064 data_type& Get(const key_type &key) const;
00065 data_type Pop(const key_type &key);
00066
00067 void Set(const key_type &key, const data_type &data);
00068
00069 void SetExisting(const key_type &key, const data_type &data);
00070
00071 void SetNew(const key_type &key, const data_type &data);
00072 bool Has(const key_type &key) const;
00073 bool Delete(const key_type &key);
00074 data_type& operator[] ( const unsigned int position ) const;
00075 key_type GetKeyAtIndex( const unsigned int position ) const;
00076 unsigned GetIndexAtKey( const key_type &key );
00077 void RemoveAtIndex(const unsigned index);
00078 void Clear(void);
00079 unsigned Size(void) const;
00080
00081 protected:
00082 DataStructures::OrderedList< key_type,MapNode,&Map::NodeComparisonFunc > mapNodeList;
00083
00084 void SaveLastSearch(const key_type &key, unsigned index) const;
00085 bool HasSavedSearchResult(const key_type &key) const;
00086
00087 unsigned lastSearchIndex;
00088 key_type lastSearchKey;
00089 bool lastSearchIndexValid;
00090 };
00091
00092 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00093 Map<key_type, data_type, key_comparison_func>::Map()
00094 {
00095 lastSearchIndexValid=false;
00096 }
00097
00098 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00099 Map<key_type, data_type, key_comparison_func>::~Map()
00100 {
00101 Clear();
00102 }
00103
00104 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00105 Map<key_type, data_type, key_comparison_func>::Map( const Map& original_copy )
00106 {
00107 mapNodeList=original_copy.mapNodeList;
00108 lastSearchIndex=original_copy.lastSearchIndex;
00109 lastSearchKey=original_copy.lastSearchKey;
00110 lastSearchIndexValid=original_copy.lastSearchIndexValid;
00111 }
00112
00113 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00114 Map<key_type, data_type, key_comparison_func>& Map<key_type, data_type, key_comparison_func>::operator= ( const Map& original_copy )
00115 {
00116 mapNodeList=original_copy.mapNodeList;
00117 lastSearchIndex=original_copy.lastSearchIndex;
00118 lastSearchKey=original_copy.lastSearchKey;
00119 lastSearchIndexValid=original_copy.lastSearchIndexValid;
00120 return *this;
00121 }
00122
00123 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00124 data_type& Map<key_type, data_type, key_comparison_func>::Get(const key_type &key) const
00125 {
00126 if (HasSavedSearchResult(key))
00127 return mapNodeList[lastSearchIndex].mapNodeData;
00128
00129 bool objectExists;
00130 unsigned index;
00131 index=mapNodeList.GetIndexFromKey(key, &objectExists);
00132 RakAssert(objectExists);
00133 SaveLastSearch(key,index);
00134 return mapNodeList[index].mapNodeData;
00135 }
00136
00137 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00138 unsigned Map<key_type, data_type, key_comparison_func>::GetIndexAtKey( const key_type &key )
00139 {
00140 if (HasSavedSearchResult(key))
00141 return lastSearchIndex;
00142
00143 bool objectExists;
00144 unsigned index;
00145 index=mapNodeList.GetIndexFromKey(key, &objectExists);
00146 if (objectExists==false)
00147 {
00148 RakAssert(objectExists);
00149 }
00150 SaveLastSearch(key,index);
00151 return index;
00152 }
00153
00154 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00155 void Map<key_type, data_type, key_comparison_func>::RemoveAtIndex(const unsigned index)
00156 {
00157 mapNodeList.RemoveAtIndex(index);
00158 lastSearchIndexValid=false;
00159 }
00160
00161 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00162 data_type Map<key_type, data_type, key_comparison_func>::Pop(const key_type &key)
00163 {
00164 bool objectExists;
00165 unsigned index;
00166 if (HasSavedSearchResult(key))
00167 index=lastSearchIndex;
00168 else
00169 {
00170 index=mapNodeList.GetIndexFromKey(key, &objectExists);
00171 RakAssert(objectExists);
00172 }
00173 data_type tmp = mapNodeList[index].mapNodeData;
00174 mapNodeList.RemoveAtIndex(index);
00175 lastSearchIndexValid=false;
00176 return tmp;
00177 }
00178
00179 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00180 void Map<key_type, data_type, key_comparison_func>::Set(const key_type &key, const data_type &data)
00181 {
00182 bool objectExists;
00183 unsigned index;
00184
00185 if (HasSavedSearchResult(key))
00186 {
00187 mapNodeList[lastSearchIndex].mapNodeData=data;
00188 return;
00189 }
00190
00191 index=mapNodeList.GetIndexFromKey(key, &objectExists);
00192
00193 if (objectExists)
00194 {
00195 SaveLastSearch(key,index);
00196 mapNodeList[index].mapNodeData=data;
00197 }
00198 else
00199 {
00200 SaveLastSearch(key,mapNodeList.Insert(key,MapNode(key,data), true, __FILE__,__LINE__));
00201 }
00202 }
00203
00204 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00205 void Map<key_type, data_type, key_comparison_func>::SetExisting(const key_type &key, const data_type &data)
00206 {
00207 bool objectExists;
00208 unsigned index;
00209
00210 if (HasSavedSearchResult(key))
00211 {
00212 index=lastSearchIndex;
00213 }
00214 else
00215 {
00216 index=mapNodeList.GetIndexFromKey(key, &objectExists);
00217 RakAssert(objectExists);
00218 SaveLastSearch(key,index);
00219 }
00220
00221 mapNodeList[index].mapNodeData=data;
00222 }
00223
00224 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00225 void Map<key_type, data_type, key_comparison_func>::SetNew(const key_type &key, const data_type &data)
00226 {
00227 #ifdef _DEBUG
00228 bool objectExists;
00229 mapNodeList.GetIndexFromKey(key, &objectExists);
00230 RakAssert(objectExists==false);
00231 #endif
00232 SaveLastSearch(key,mapNodeList.Insert(key,MapNode(key,data), true, __FILE__,__LINE__));
00233 }
00234
00235 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00236 bool Map<key_type, data_type, key_comparison_func>::Has(const key_type &key) const
00237 {
00238 if (HasSavedSearchResult(key))
00239 return true;
00240
00241 bool objectExists;
00242 unsigned index;
00243 index=mapNodeList.GetIndexFromKey(key, &objectExists);
00244 if (objectExists)
00245 SaveLastSearch(key,index);
00246 return objectExists;
00247 }
00248
00249 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00250 bool Map<key_type, data_type, key_comparison_func>::Delete(const key_type &key)
00251 {
00252 if (HasSavedSearchResult(key))
00253 {
00254 lastSearchIndexValid=false;
00255 mapNodeList.RemoveAtIndex(lastSearchIndex);
00256 return true;
00257 }
00258
00259 bool objectExists;
00260 unsigned index;
00261 index=mapNodeList.GetIndexFromKey(key, &objectExists);
00262 if (objectExists)
00263 {
00264 lastSearchIndexValid=false;
00265 mapNodeList.RemoveAtIndex(index);
00266 return true;
00267 }
00268 else
00269 return false;
00270 }
00271
00272 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00273 void Map<key_type, data_type, key_comparison_func>::Clear(void)
00274 {
00275 lastSearchIndexValid=false;
00276 mapNodeList.Clear(false, __FILE__, __LINE__);
00277 }
00278
00279 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00280 data_type& Map<key_type, data_type, key_comparison_func>::operator[]( const unsigned int position ) const
00281 {
00282 return mapNodeList[position].mapNodeData;
00283 }
00284
00285 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00286 key_type Map<key_type, data_type, key_comparison_func>::GetKeyAtIndex( const unsigned int position ) const
00287 {
00288 return mapNodeList[position].mapNodeKey;
00289 }
00290
00291 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00292 unsigned Map<key_type, data_type, key_comparison_func>::Size(void) const
00293 {
00294 return mapNodeList.Size();
00295 }
00296
00297 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00298 void Map<key_type, data_type, key_comparison_func>::SaveLastSearch(const key_type &key, const unsigned index) const
00299 {
00300 (void) key;
00301 (void) index;
00302
00303
00304
00305
00306
00307
00308 }
00309
00310 template <class key_type, class data_type, int (*key_comparison_func)(const key_type&,const key_type&)>
00311 bool Map<key_type, data_type, key_comparison_func>::HasSavedSearchResult(const key_type &key) const
00312 {
00313 (void) key;
00314
00315
00316 return false;
00317
00318 }
00319 }
00320
00321 #endif