1/* Copyright (c) 2012 Massachusetts Institute of Technology 2 * 3 * Permission is hereby granted, free of charge, to any person obtaining a copy 4 * of this software and associated documentation files (the "Software"), to deal 5 * in the Software without restriction, including without limitation the rights 6 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 * copies of the Software, and to permit persons to whom the Software is 8 * furnished to do so, subject to the following conditions: 9 * 10 * The above copyright notice and this permission notice shall be included in 11 * all copies or substantial portions of the Software. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 * THE SOFTWARE. 20 */ 21 22#ifndef __MAP_H__ 23#define __MAP_H__ 24 25#include <iostream> 26#include <map> 27 28#include "String.h" 29#include "Assert.h" 30 31namespace LibUtil 32{ 33 using std::map; 34 35 template<class T> class Map 36 { 37 public: 38 typedef typename map<String, T>::iterator Iterator; 39 typedef typename map<String, T>::const_iterator ConstIterator; 40 typedef typename map<String, T>::size_type SizeType; 41 42 public: 43 Map(); 44 virtual ~Map(); 45 46 public: 47 // Return a new copy of this Map instance 48 Map* clone() const; 49 // Copy map_ to this instance 50 void copyFrom(const Map<T>* map_); 51 // Return the size of the map 52 SizeType size() const; 53 // Check if the map is empty 54 bool isEmpty() const; 55 // Check if the key exists 56 bool keyExist(const String& key_) const; 57 // Get the value_ corresponding to the key_ 58 const T& get(const String& key_) const; 59 // Get the value_ corresponding to the key_ if the key_ exist, otherwise, the default_value_is returned 60 const T& getIfKeyExist(const String& key_, const T& default_value_ = T()) const; 61 // Add/Update a <key_, value_> entry 62 void set(const String& key_, const T& value_); 63 // Get iterator to the element 64 Iterator find(const String& key_); 65 ConstIterator find(const String& key_) const; 66 // Remove an entry corresponding to key_ 67 void remove(const String& key_); 68 // Remove an entry at 'it' 69 void remove(Iterator it); 70 // Remove all keys 71 void clear(); 72 // Merge a map. Values with same key will be overwritten. 73 void merge(const Map<T>* map_); 74 // Returns a MapIterator referring to the first element in the map 75 Iterator begin(); 76 ConstIterator begin() const; 77 // Returns a MapIterator referring to the past-the-end element in the map 78 Iterator end(); 79 ConstIterator end() const; 80 81 protected: 82 Map(const Map& map_); 83 84 protected: 85 map<String, T> mMap; 86 }; 87 88 template<class T> Map<T>::Map() 89 {} 90 91 template<class T> Map<T>::~Map() 92 {} 93 94 template<class T> Map<T>* Map<T>::clone() const 95 { 96 return new Map<T>(*this); 97 } 98 99 template<class T> void Map<T>::copyFrom(const Map<T>* map_) 100 { 101 // Remove all keys (it won't free the content if T is a pointer) 102 mMap.clear(); 103 104 // Copy the contents 105 mMap = map_->mMap; 106 } 107 108 template<class T> typename Map<T>::SizeType Map<T>::size() const 109 { 110 return mMap.size(); 111 } 112 113 template<class T> bool Map<T>::isEmpty() const 114 { 115 return (mMap.empty()); 116 } 117 118 template<class T> bool Map<T>::keyExist(const String& key_) const 119 { 120 ConstIterator it = mMap.find(key_); 121 return (it != mMap.end()); 122 } 123 124 template<class T> const T& Map<T>::get(const String& key_) const 125 { 126 ConstIterator it; 127 128 it = mMap.find(key_); 129 ASSERT((it != mMap.end()), "Key not found: " + key_); 130 return (it->second); 131 } 132 133 template<class T> const T& Map<T>::getIfKeyExist(const String& key_, const T& default_value_) const 134 { 135 if(keyExist(key_)) 136 { 137 return get(key_); 138 } 139 else 140 { 141 return default_value_; 142 } 143 } 144 145 template<class T> void Map<T>::set(const String& key_, const T& value_) 146 { 147 mMap[key_] = value_; 148 return; 149 } 150 151 template<class T> typename Map<T>::Iterator Map<T>::find(const String& key_) 152 { 153 return mMap.find(key_); 154 } 155 156 template<class T> typename Map<T>::ConstIterator Map<T>::find(const String& key_) const 157 { 158 return mMap.find(key_); 159 } 160 161 template<class T> void Map<T>::remove(const String& key_) 162 { 163 mMap.erase(key_); 164 return; 165 } 166 167 template<class T> void Map<T>::remove(Iterator it) 168 { 169 mMap.erase(it); 170 return; 171 } 172 173 template<class T> void Map<T>::clear() 174 { 175 mMap.clear(); 176 return; 177 } 178 179 template<class T> void Map<T>::merge(const Map<T>* map_) 180 { 181 ConstIterator it; 182 for(it = map_->begin(); it != map_->end(); it++) 183 { 184 const String& key = it->first; 185 const T& value = it->second; 186 set(key, value); 187 } 188 return; 189 } 190 191 template<class T> typename Map<T>::Iterator Map<T>::begin() 192 { 193 return mMap.begin(); 194 } 195 196 template<class T> typename Map<T>::ConstIterator Map<T>::begin() const 197 { 198 return mMap.begin(); 199 } 200 201 template<class T> typename Map<T>::Iterator Map<T>::end() 202 { 203 return mMap.end(); 204 } 205 206 template<class T> typename Map<T>::ConstIterator Map<T>::end() const 207 { 208 return mMap.end(); 209 } 210 211 inline std::ostream& operator<<(std::ostream& ost_, const Map<String>& map_) 212 { 213 Map<String>::ConstIterator it; 214 for(it = map_.begin(); it != map_.end(); it++) 215 { 216 ost_ << it->first << " = " << it->second << std::endl; 217 } 218 return ost_; 219 } 220 221 template<class T> Map<T>::Map(const Map<T>& map_) 222 : mMap(map_.mMap) 223 {} 224 225 typedef Map<String> StringMap; 226 227 228 // Handy function to delete all pointers in a map 229 template<class T> void clearPtrMap(Map<T*>* map_) 230 { 231 for(typename Map<T*>::Iterator it = map_->begin(); it != map_->end(); ++it) 232 { 233 T* temp_T = it->second; 234 delete temp_T; 235 } 236 map_->clear(); 237 return; 238 } 239 240 // Handy function to delete all pointers in a map and the map itself 241 template<class T> void deletePtrMap(Map<T*>* map_) 242 { 243 clearPtrMap<T>(map_); 244 delete map_; 245 return; 246 } 247 248 // Handy function to clone all pointers in a map 249 template<class T> Map<T*>* clonePtrMap(const Map<T*>* map_) 250 { 251 Map<T*>* new_T_map = new Map<T*>; 252 for(typename Map<T*>::ConstIterator it = map_->begin(); it != map_->end(); ++it) 253 { 254 const String& temp_name = it->first; 255 const T* temp_T = it->second; 256 new_T_map->set(temp_name, temp_T->clone()); 257 } 258 return new_T_map; 259 } 260} 261 262#endif // __MAP_H__ 263 264