110448Snilay@cs.wisc.edu/* Copyright (c) 2012 Massachusetts Institute of Technology
210448Snilay@cs.wisc.edu *
310448Snilay@cs.wisc.edu * Permission is hereby granted, free of charge, to any person obtaining a copy
410448Snilay@cs.wisc.edu * of this software and associated documentation files (the "Software"), to deal
510448Snilay@cs.wisc.edu * in the Software without restriction, including without limitation the rights
610448Snilay@cs.wisc.edu * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
710448Snilay@cs.wisc.edu * copies of the Software, and to permit persons to whom the Software is
810448Snilay@cs.wisc.edu * furnished to do so, subject to the following conditions:
910448Snilay@cs.wisc.edu *
1010448Snilay@cs.wisc.edu * The above copyright notice and this permission notice shall be included in
1110448Snilay@cs.wisc.edu * all copies or substantial portions of the Software.
1210448Snilay@cs.wisc.edu *
1310448Snilay@cs.wisc.edu * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1410448Snilay@cs.wisc.edu * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1510448Snilay@cs.wisc.edu * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1610448Snilay@cs.wisc.edu * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1710448Snilay@cs.wisc.edu * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1810448Snilay@cs.wisc.edu * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1910448Snilay@cs.wisc.edu * THE SOFTWARE.
2010448Snilay@cs.wisc.edu */
2110448Snilay@cs.wisc.edu
2210447Snilay@cs.wisc.edu#ifndef __MAP_H__
2310447Snilay@cs.wisc.edu#define __MAP_H__
2410447Snilay@cs.wisc.edu
2510447Snilay@cs.wisc.edu#include <iostream>
2610447Snilay@cs.wisc.edu#include <map>
2710447Snilay@cs.wisc.edu
2810447Snilay@cs.wisc.edu#include "String.h"
2910447Snilay@cs.wisc.edu#include "Assert.h"
3010447Snilay@cs.wisc.edu
3110447Snilay@cs.wisc.edunamespace LibUtil
3210447Snilay@cs.wisc.edu{
3310447Snilay@cs.wisc.edu    using std::map;
3410447Snilay@cs.wisc.edu
3510447Snilay@cs.wisc.edu    template<class T> class Map
3610447Snilay@cs.wisc.edu    {
3710447Snilay@cs.wisc.edu        public:
3810447Snilay@cs.wisc.edu            typedef typename map<String, T>::iterator       Iterator;
3910447Snilay@cs.wisc.edu            typedef typename map<String, T>::const_iterator ConstIterator;
4010447Snilay@cs.wisc.edu            typedef typename map<String, T>::size_type      SizeType;
4110447Snilay@cs.wisc.edu
4210447Snilay@cs.wisc.edu        public:
4310447Snilay@cs.wisc.edu            Map();
4410447Snilay@cs.wisc.edu            virtual ~Map();
4510447Snilay@cs.wisc.edu
4610447Snilay@cs.wisc.edu        public:
4710447Snilay@cs.wisc.edu            // Return a new copy of this Map instance
4810447Snilay@cs.wisc.edu            Map* clone() const;
4910447Snilay@cs.wisc.edu            // Copy map_ to this instance
5010447Snilay@cs.wisc.edu            void copyFrom(const Map<T>* map_);
5110447Snilay@cs.wisc.edu            // Return the size of the map
5210447Snilay@cs.wisc.edu            SizeType size() const;
5310447Snilay@cs.wisc.edu            // Check if the map is empty
5410447Snilay@cs.wisc.edu            bool isEmpty() const;
5510447Snilay@cs.wisc.edu            // Check if the key exists
5610447Snilay@cs.wisc.edu            bool keyExist(const String& key_) const;
5710447Snilay@cs.wisc.edu            // Get the value_ corresponding to the key_
5810447Snilay@cs.wisc.edu            const T& get(const String& key_) const;
5910447Snilay@cs.wisc.edu            // Get the value_ corresponding to the key_ if the key_ exist, otherwise, the default_value_is returned
6010447Snilay@cs.wisc.edu            const T& getIfKeyExist(const String& key_, const T& default_value_ = T()) const;
6110447Snilay@cs.wisc.edu            // Add/Update a <key_, value_> entry
6210447Snilay@cs.wisc.edu            void set(const String& key_, const T& value_);
6310447Snilay@cs.wisc.edu            // Get iterator to the element
6410447Snilay@cs.wisc.edu            Iterator find(const String& key_);
6510447Snilay@cs.wisc.edu            ConstIterator find(const String& key_) const;
6610447Snilay@cs.wisc.edu            // Remove an entry corresponding to key_
6710447Snilay@cs.wisc.edu            void remove(const String& key_);
6810447Snilay@cs.wisc.edu            // Remove an entry at 'it'
6910447Snilay@cs.wisc.edu            void remove(Iterator it);
7010447Snilay@cs.wisc.edu            // Remove all keys
7110447Snilay@cs.wisc.edu            void clear();
7210447Snilay@cs.wisc.edu            // Merge a map. Values with same key will be overwritten.
7310447Snilay@cs.wisc.edu            void merge(const Map<T>* map_);
7410447Snilay@cs.wisc.edu            // Returns a MapIterator referring to the first element in the map
7510447Snilay@cs.wisc.edu            Iterator begin();
7610447Snilay@cs.wisc.edu            ConstIterator begin() const;
7710447Snilay@cs.wisc.edu            // Returns a MapIterator referring to the past-the-end element in the map
7810447Snilay@cs.wisc.edu            Iterator end();
7910447Snilay@cs.wisc.edu            ConstIterator end() const;
8010447Snilay@cs.wisc.edu
8110447Snilay@cs.wisc.edu        protected:
8210447Snilay@cs.wisc.edu            Map(const Map& map_);
8310447Snilay@cs.wisc.edu
8410447Snilay@cs.wisc.edu        protected:
8510447Snilay@cs.wisc.edu            map<String, T> mMap;
8610447Snilay@cs.wisc.edu    };
8710447Snilay@cs.wisc.edu
8810447Snilay@cs.wisc.edu    template<class T> Map<T>::Map()
8910447Snilay@cs.wisc.edu    {}
9010447Snilay@cs.wisc.edu
9110447Snilay@cs.wisc.edu    template<class T> Map<T>::~Map()
9210447Snilay@cs.wisc.edu    {}
9310447Snilay@cs.wisc.edu
9410447Snilay@cs.wisc.edu    template<class T> Map<T>* Map<T>::clone() const
9510447Snilay@cs.wisc.edu    {
9610447Snilay@cs.wisc.edu        return new Map<T>(*this);
9710447Snilay@cs.wisc.edu    }
9810447Snilay@cs.wisc.edu
9910447Snilay@cs.wisc.edu    template<class T> void Map<T>::copyFrom(const Map<T>* map_)
10010447Snilay@cs.wisc.edu    {
10110447Snilay@cs.wisc.edu        // Remove all keys (it won't free the content if T is a pointer)
10210447Snilay@cs.wisc.edu        mMap.clear();
10310447Snilay@cs.wisc.edu
10410447Snilay@cs.wisc.edu        // Copy the contents
10510447Snilay@cs.wisc.edu        mMap = map_->mMap;
10610447Snilay@cs.wisc.edu    }
10710447Snilay@cs.wisc.edu
10810447Snilay@cs.wisc.edu    template<class T> typename Map<T>::SizeType Map<T>::size() const
10910447Snilay@cs.wisc.edu    {
11010447Snilay@cs.wisc.edu        return mMap.size();
11110447Snilay@cs.wisc.edu    }
11210447Snilay@cs.wisc.edu
11310447Snilay@cs.wisc.edu    template<class T> bool Map<T>::isEmpty() const
11410447Snilay@cs.wisc.edu    {
11510447Snilay@cs.wisc.edu        return (mMap.empty());
11610447Snilay@cs.wisc.edu    }
11710447Snilay@cs.wisc.edu
11810447Snilay@cs.wisc.edu    template<class T> bool Map<T>::keyExist(const String& key_) const
11910447Snilay@cs.wisc.edu    {
12010447Snilay@cs.wisc.edu        ConstIterator it = mMap.find(key_);
12110447Snilay@cs.wisc.edu        return (it != mMap.end());
12210447Snilay@cs.wisc.edu    }
12310447Snilay@cs.wisc.edu
12410447Snilay@cs.wisc.edu    template<class T> const T& Map<T>::get(const String& key_) const
12510447Snilay@cs.wisc.edu    {
12610447Snilay@cs.wisc.edu        ConstIterator it;
12710447Snilay@cs.wisc.edu
12810447Snilay@cs.wisc.edu        it = mMap.find(key_);
12910447Snilay@cs.wisc.edu        ASSERT((it != mMap.end()), "Key not found: " + key_);
13010447Snilay@cs.wisc.edu        return (it->second);
13110447Snilay@cs.wisc.edu    }
13210447Snilay@cs.wisc.edu
13310447Snilay@cs.wisc.edu    template<class T> const T& Map<T>::getIfKeyExist(const String& key_, const T& default_value_) const
13410447Snilay@cs.wisc.edu    {
13510447Snilay@cs.wisc.edu        if(keyExist(key_))
13610447Snilay@cs.wisc.edu        {
13710447Snilay@cs.wisc.edu            return get(key_);
13810447Snilay@cs.wisc.edu        }
13910447Snilay@cs.wisc.edu        else
14010447Snilay@cs.wisc.edu        {
14110447Snilay@cs.wisc.edu            return default_value_;
14210447Snilay@cs.wisc.edu        }
14310447Snilay@cs.wisc.edu    }
14410447Snilay@cs.wisc.edu
14510447Snilay@cs.wisc.edu    template<class T> void Map<T>::set(const String& key_, const T& value_)
14610447Snilay@cs.wisc.edu    {
14710447Snilay@cs.wisc.edu        mMap[key_] = value_;
14810447Snilay@cs.wisc.edu        return;
14910447Snilay@cs.wisc.edu    }
15010447Snilay@cs.wisc.edu
15110447Snilay@cs.wisc.edu    template<class T> typename Map<T>::Iterator Map<T>::find(const String& key_)
15210447Snilay@cs.wisc.edu    {
15310447Snilay@cs.wisc.edu        return mMap.find(key_);
15410447Snilay@cs.wisc.edu    }
15510447Snilay@cs.wisc.edu
15610447Snilay@cs.wisc.edu    template<class T> typename Map<T>::ConstIterator Map<T>::find(const String& key_) const
15710447Snilay@cs.wisc.edu    {
15810447Snilay@cs.wisc.edu        return mMap.find(key_);
15910447Snilay@cs.wisc.edu    }
16010447Snilay@cs.wisc.edu
16110447Snilay@cs.wisc.edu    template<class T> void Map<T>::remove(const String& key_)
16210447Snilay@cs.wisc.edu    {
16310447Snilay@cs.wisc.edu        mMap.erase(key_);
16410447Snilay@cs.wisc.edu        return;
16510447Snilay@cs.wisc.edu    }
16610447Snilay@cs.wisc.edu
16710447Snilay@cs.wisc.edu    template<class T> void Map<T>::remove(Iterator it)
16810447Snilay@cs.wisc.edu    {
16910447Snilay@cs.wisc.edu        mMap.erase(it);
17010447Snilay@cs.wisc.edu        return;
17110447Snilay@cs.wisc.edu    }
17210447Snilay@cs.wisc.edu
17310447Snilay@cs.wisc.edu    template<class T> void Map<T>::clear()
17410447Snilay@cs.wisc.edu    {
17510447Snilay@cs.wisc.edu        mMap.clear();
17610447Snilay@cs.wisc.edu        return;
17710447Snilay@cs.wisc.edu    }
17810447Snilay@cs.wisc.edu
17910447Snilay@cs.wisc.edu    template<class T> void Map<T>::merge(const Map<T>* map_)
18010447Snilay@cs.wisc.edu    {
18110447Snilay@cs.wisc.edu        ConstIterator it;
18210447Snilay@cs.wisc.edu        for(it = map_->begin(); it != map_->end(); it++)
18310447Snilay@cs.wisc.edu        {
18410447Snilay@cs.wisc.edu            const String& key = it->first;
18510447Snilay@cs.wisc.edu            const T& value = it->second;
18610447Snilay@cs.wisc.edu            set(key, value);
18710447Snilay@cs.wisc.edu        }
18810447Snilay@cs.wisc.edu        return;
18910447Snilay@cs.wisc.edu    }
19010447Snilay@cs.wisc.edu
19110447Snilay@cs.wisc.edu    template<class T> typename Map<T>::Iterator Map<T>::begin()
19210447Snilay@cs.wisc.edu    {
19310447Snilay@cs.wisc.edu        return mMap.begin();
19410447Snilay@cs.wisc.edu    }
19510447Snilay@cs.wisc.edu
19610447Snilay@cs.wisc.edu    template<class T> typename Map<T>::ConstIterator Map<T>::begin() const
19710447Snilay@cs.wisc.edu    {
19810447Snilay@cs.wisc.edu        return mMap.begin();
19910447Snilay@cs.wisc.edu    }
20010447Snilay@cs.wisc.edu
20110447Snilay@cs.wisc.edu    template<class T> typename Map<T>::Iterator Map<T>::end()
20210447Snilay@cs.wisc.edu    {
20310447Snilay@cs.wisc.edu        return mMap.end();
20410447Snilay@cs.wisc.edu    }
20510447Snilay@cs.wisc.edu
20610447Snilay@cs.wisc.edu    template<class T> typename Map<T>::ConstIterator Map<T>::end() const
20710447Snilay@cs.wisc.edu    {
20810447Snilay@cs.wisc.edu        return mMap.end();
20910447Snilay@cs.wisc.edu    }
21010447Snilay@cs.wisc.edu
21110447Snilay@cs.wisc.edu    inline std::ostream& operator<<(std::ostream& ost_, const Map<String>& map_)
21210447Snilay@cs.wisc.edu    {
21310447Snilay@cs.wisc.edu        Map<String>::ConstIterator it;
21410447Snilay@cs.wisc.edu        for(it = map_.begin(); it != map_.end(); it++)
21510447Snilay@cs.wisc.edu        {
21610447Snilay@cs.wisc.edu            ost_ << it->first << " = " << it->second << std::endl;
21710447Snilay@cs.wisc.edu        }
21810447Snilay@cs.wisc.edu        return ost_;
21910447Snilay@cs.wisc.edu    }
22010447Snilay@cs.wisc.edu
22110447Snilay@cs.wisc.edu    template<class T> Map<T>::Map(const Map<T>& map_)
22210447Snilay@cs.wisc.edu        : mMap(map_.mMap)
22310447Snilay@cs.wisc.edu    {}
22410447Snilay@cs.wisc.edu
22510447Snilay@cs.wisc.edu    typedef Map<String> StringMap;
22610447Snilay@cs.wisc.edu
22710447Snilay@cs.wisc.edu
22810447Snilay@cs.wisc.edu    // Handy function to delete all pointers in a map
22910447Snilay@cs.wisc.edu    template<class T> void clearPtrMap(Map<T*>* map_)
23010447Snilay@cs.wisc.edu    {
23110447Snilay@cs.wisc.edu        for(typename Map<T*>::Iterator it = map_->begin(); it != map_->end(); ++it)
23210447Snilay@cs.wisc.edu        {
23310447Snilay@cs.wisc.edu            T* temp_T = it->second;
23410447Snilay@cs.wisc.edu            delete temp_T;
23510447Snilay@cs.wisc.edu        }
23610447Snilay@cs.wisc.edu        map_->clear();
23710447Snilay@cs.wisc.edu        return;
23810447Snilay@cs.wisc.edu    }
23910447Snilay@cs.wisc.edu
24010447Snilay@cs.wisc.edu    // Handy function to delete all pointers in a map and the map itself
24110447Snilay@cs.wisc.edu    template<class T> void deletePtrMap(Map<T*>* map_)
24210447Snilay@cs.wisc.edu    {
24310447Snilay@cs.wisc.edu        clearPtrMap<T>(map_);
24410447Snilay@cs.wisc.edu        delete map_;
24510447Snilay@cs.wisc.edu        return;
24610447Snilay@cs.wisc.edu    }
24710447Snilay@cs.wisc.edu
24810447Snilay@cs.wisc.edu    // Handy function to clone all pointers in a map
24910447Snilay@cs.wisc.edu    template<class T> Map<T*>* clonePtrMap(const Map<T*>* map_)
25010447Snilay@cs.wisc.edu    {
25110447Snilay@cs.wisc.edu        Map<T*>* new_T_map = new Map<T*>;
25210447Snilay@cs.wisc.edu        for(typename Map<T*>::ConstIterator it = map_->begin(); it != map_->end(); ++it)
25310447Snilay@cs.wisc.edu        {
25410447Snilay@cs.wisc.edu            const String& temp_name = it->first;
25510447Snilay@cs.wisc.edu            const T* temp_T = it->second;
25610447Snilay@cs.wisc.edu            new_T_map->set(temp_name, temp_T->clone());
25710447Snilay@cs.wisc.edu        }
25810447Snilay@cs.wisc.edu        return new_T_map;
25910447Snilay@cs.wisc.edu    }
26010447Snilay@cs.wisc.edu}
26110447Snilay@cs.wisc.edu
26210447Snilay@cs.wisc.edu#endif // __MAP_H__
26310447Snilay@cs.wisc.edu
264