| /* Copyright (c) 2012 Massachusetts Institute of Technology |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a copy |
| * of this software and associated documentation files (the "Software"), to deal |
| * in the Software without restriction, including without limitation the rights |
| * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| * copies of the Software, and to permit persons to whom the Software is |
| * furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be included in |
| * all copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| * THE SOFTWARE. |
| */ |
| |
| #ifndef __MAP_H__ |
| #define __MAP_H__ |
| |
| #include <iostream> |
| #include <map> |
| |
| #include "String.h" |
| #include "Assert.h" |
| |
| namespace LibUtil |
| { |
| using std::map; |
| |
| template<class T> class Map |
| { |
| public: |
| typedef typename map<String, T>::iterator Iterator; |
| typedef typename map<String, T>::const_iterator ConstIterator; |
| typedef typename map<String, T>::size_type SizeType; |
| |
| public: |
| Map(); |
| virtual ~Map(); |
| |
| public: |
| // Return a new copy of this Map instance |
| Map* clone() const; |
| // Copy map_ to this instance |
| void copyFrom(const Map<T>* map_); |
| // Return the size of the map |
| SizeType size() const; |
| // Check if the map is empty |
| bool isEmpty() const; |
| // Check if the key exists |
| bool keyExist(const String& key_) const; |
| // Get the value_ corresponding to the key_ |
| const T& get(const String& key_) const; |
| // Get the value_ corresponding to the key_ if the key_ exist, otherwise, the default_value_is returned |
| const T& getIfKeyExist(const String& key_, const T& default_value_ = T()) const; |
| // Add/Update a <key_, value_> entry |
| void set(const String& key_, const T& value_); |
| // Get iterator to the element |
| Iterator find(const String& key_); |
| ConstIterator find(const String& key_) const; |
| // Remove an entry corresponding to key_ |
| void remove(const String& key_); |
| // Remove an entry at 'it' |
| void remove(Iterator it); |
| // Remove all keys |
| void clear(); |
| // Merge a map. Values with same key will be overwritten. |
| void merge(const Map<T>* map_); |
| // Returns a MapIterator referring to the first element in the map |
| Iterator begin(); |
| ConstIterator begin() const; |
| // Returns a MapIterator referring to the past-the-end element in the map |
| Iterator end(); |
| ConstIterator end() const; |
| |
| protected: |
| Map(const Map& map_); |
| |
| protected: |
| map<String, T> mMap; |
| }; |
| |
| template<class T> Map<T>::Map() |
| {} |
| |
| template<class T> Map<T>::~Map() |
| {} |
| |
| template<class T> Map<T>* Map<T>::clone() const |
| { |
| return new Map<T>(*this); |
| } |
| |
| template<class T> void Map<T>::copyFrom(const Map<T>* map_) |
| { |
| // Remove all keys (it won't free the content if T is a pointer) |
| mMap.clear(); |
| |
| // Copy the contents |
| mMap = map_->mMap; |
| } |
| |
| template<class T> typename Map<T>::SizeType Map<T>::size() const |
| { |
| return mMap.size(); |
| } |
| |
| template<class T> bool Map<T>::isEmpty() const |
| { |
| return (mMap.empty()); |
| } |
| |
| template<class T> bool Map<T>::keyExist(const String& key_) const |
| { |
| ConstIterator it = mMap.find(key_); |
| return (it != mMap.end()); |
| } |
| |
| template<class T> const T& Map<T>::get(const String& key_) const |
| { |
| ConstIterator it; |
| |
| it = mMap.find(key_); |
| ASSERT((it != mMap.end()), "Key not found: " + key_); |
| return (it->second); |
| } |
| |
| template<class T> const T& Map<T>::getIfKeyExist(const String& key_, const T& default_value_) const |
| { |
| if(keyExist(key_)) |
| { |
| return get(key_); |
| } |
| else |
| { |
| return default_value_; |
| } |
| } |
| |
| template<class T> void Map<T>::set(const String& key_, const T& value_) |
| { |
| mMap[key_] = value_; |
| return; |
| } |
| |
| template<class T> typename Map<T>::Iterator Map<T>::find(const String& key_) |
| { |
| return mMap.find(key_); |
| } |
| |
| template<class T> typename Map<T>::ConstIterator Map<T>::find(const String& key_) const |
| { |
| return mMap.find(key_); |
| } |
| |
| template<class T> void Map<T>::remove(const String& key_) |
| { |
| mMap.erase(key_); |
| return; |
| } |
| |
| template<class T> void Map<T>::remove(Iterator it) |
| { |
| mMap.erase(it); |
| return; |
| } |
| |
| template<class T> void Map<T>::clear() |
| { |
| mMap.clear(); |
| return; |
| } |
| |
| template<class T> void Map<T>::merge(const Map<T>* map_) |
| { |
| ConstIterator it; |
| for(it = map_->begin(); it != map_->end(); it++) |
| { |
| const String& key = it->first; |
| const T& value = it->second; |
| set(key, value); |
| } |
| return; |
| } |
| |
| template<class T> typename Map<T>::Iterator Map<T>::begin() |
| { |
| return mMap.begin(); |
| } |
| |
| template<class T> typename Map<T>::ConstIterator Map<T>::begin() const |
| { |
| return mMap.begin(); |
| } |
| |
| template<class T> typename Map<T>::Iterator Map<T>::end() |
| { |
| return mMap.end(); |
| } |
| |
| template<class T> typename Map<T>::ConstIterator Map<T>::end() const |
| { |
| return mMap.end(); |
| } |
| |
| inline std::ostream& operator<<(std::ostream& ost_, const Map<String>& map_) |
| { |
| Map<String>::ConstIterator it; |
| for(it = map_.begin(); it != map_.end(); it++) |
| { |
| ost_ << it->first << " = " << it->second << std::endl; |
| } |
| return ost_; |
| } |
| |
| template<class T> Map<T>::Map(const Map<T>& map_) |
| : mMap(map_.mMap) |
| {} |
| |
| typedef Map<String> StringMap; |
| |
| |
| // Handy function to delete all pointers in a map |
| template<class T> void clearPtrMap(Map<T*>* map_) |
| { |
| for(typename Map<T*>::Iterator it = map_->begin(); it != map_->end(); ++it) |
| { |
| T* temp_T = it->second; |
| delete temp_T; |
| } |
| map_->clear(); |
| return; |
| } |
| |
| // Handy function to delete all pointers in a map and the map itself |
| template<class T> void deletePtrMap(Map<T*>* map_) |
| { |
| clearPtrMap<T>(map_); |
| delete map_; |
| return; |
| } |
| |
| // Handy function to clone all pointers in a map |
| template<class T> Map<T*>* clonePtrMap(const Map<T*>* map_) |
| { |
| Map<T*>* new_T_map = new Map<T*>; |
| for(typename Map<T*>::ConstIterator it = map_->begin(); it != map_->end(); ++it) |
| { |
| const String& temp_name = it->first; |
| const T* temp_T = it->second; |
| new_T_map->set(temp_name, temp_T->clone()); |
| } |
| return new_T_map; |
| } |
| } |
| |
| #endif // __MAP_H__ |
| |