blob: 7a990fc99a7580fe4fb8fc243909b2ce42d5103d [file] [log] [blame]
/* 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__