# multimap.hpp

Go to the documentation of this file.

    00001 /* $Id$ */
    00002
    00003 /*
    00004  * This file is part of OpenTTD.
    00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
    00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
    00008  */
    00009
    00012 #ifndef MULTIMAP_HPP_
    00013 #define MULTIMAP_HPP_
    00014
    00015 #include <map>
    00016 #include <list>
    00017
    00018 template<typename KEY, typename VALUE, typename COMPARE>
    00019 class MultiMap;
    00020
    00021 template<class MAP_ITER, class LIST_ITER, class KEY, class VALUE, class COMPARE>
    00022 class MultiMapIterator {
    00023 protected:
    00024   friend class MultiMap<KEY, VALUE, COMPARE>;
    00025   typedef MultiMapIterator<MAP_ITER, LIST_ITER, KEY, VALUE, COMPARE> Self;
    00026   LIST_ITER list_iter;
    00027   MAP_ITER map_iter;
    00028   bool list_valid;
    00029
    00030 public:
    00031   MultiMapIterator() : list_valid(false) {}
    00032   template<class NONCONST>
    00033   MultiMapIterator(NONCONST mi) : map_iter(mi), list_valid(false) {}
    00034   MultiMapIterator(MAP_ITER mi, LIST_ITER li) : list_iter(li), map_iter(mi)
    00035   {
    00036     list_valid = (list_iter != map_iter->second.begin());
    00037   }
    00038
    00039   template<class NONCONST>
    00040   Self &operator=(NONCONST mi)
    00041   {
    00042     map_iter = mi;
    00043     list_valid = false;
    00044   }
    00045
    00046   VALUE &operator*() const
    00047   {
    00048     assert(!map_iter->second.empty());
    00049     if (list_valid) {
    00050       return list_iter.operator*();
    00051     } else {
    00052       return map_iter->second.begin().operator*();
    00053     }
    00054   }
    00055
    00056   VALUE *operator->() const
    00057   {
    00058     assert(!map_iter->second.empty());
    00059     if (list_valid) {
    00060       return list_iter.operator->();
    00061     } else {
    00062       return map_iter->second.begin().operator->();
    00063     }
    00064   }
    00065
    00066   FORCEINLINE const MAP_ITER &GetMapIter() const {return map_iter;}
    00067   FORCEINLINE const LIST_ITER &GetListIter() const {return list_iter;}
    00068   FORCEINLINE bool ListValid() const {return list_valid;}
    00069
    00070   const KEY &GetKey() const {return map_iter->first;}
    00071
    00072   Self &operator++()
    00073   {
    00074     assert(!map_iter->second.empty());
    00075     if (list_valid) {
    00076       if(++list_iter == map_iter->second.end()) {
    00077         ++map_iter;
    00078         list_valid = false;
    00079       }
    00080     } else {
    00081       list_iter = ++(map_iter->second.begin());
    00082       if (list_iter == map_iter->second.end()) {
    00083         ++map_iter;
    00084       } else {
    00085         list_valid = true;
    00086       }
    00087     }
    00088     return *this;
    00089   }
    00090
    00091   Self operator++(int)
    00092   {
    00093     Self tmp = *this;
    00094     this->operator++();
    00095     return tmp;
    00096   }
    00097
    00098   Self &operator--()
    00099   {
    00100     assert(!map_iter->second.empty());
    00101     if (!list_valid) {
    00102       --map_iter;
    00103       list_iter = map_iter->second.end();
    00104       assert(!map_iter->second.empty());
    00105     }
    00106
    00107     if(--list_iter == map_iter->second.begin()) {
    00108       list_valid = false;
    00109     } else {
    00110       list_valid = true;
    00111     }
    00112
    00113     return *this;
    00114   }
    00115
    00116   Self operator--(int)
    00117   {
    00118     Self tmp = *this;
    00119     this->operator--();
    00120     return tmp;
    00121   }
    00122 };
    00123
    00124 /* generic comparison functions for const/non-const multimap iterators and map iterators */
    00125
    00126 template<class MAP_ITER1, class LIST_ITER1, class MAP_ITER2, class LIST_ITER2, class KEY, class VALUE1, class VALUE2, class COMPARE>
    00127 bool operator==(const MultiMapIterator<MAP_ITER1, LIST_ITER1, KEY, VALUE1, COMPARE> &iter1, const MultiMapIterator<MAP_ITER2, LIST_ITER2, KEY, VALUE2, COMPARE> &iter2)
    00128 {
    00129   if (iter1.ListValid()) {
    00130     if (!iter2.ListValid()) {
    00131       return false;
    00132     } else if (iter1.GetListIter() != iter2.GetListIter()) {
    00133       return false;
    00134     }
    00135   } else if (iter2.ListValid()) {
    00136     return false;
    00137   }
    00138   return (iter1.GetMapIter() == iter2.GetMapIter());
    00139 }
    00140
    00141 template<class MAP_ITER1, class LIST_ITER1, class MAP_ITER2, class LIST_ITER2, class KEY, class VALUE1, class VALUE2, class COMPARE>
    00142 bool operator!=(const MultiMapIterator<MAP_ITER1, LIST_ITER1, KEY, VALUE1, COMPARE> &iter1, const MultiMapIterator<MAP_ITER2, LIST_ITER2, KEY, VALUE2, COMPARE> &iter2)
    00143 {
    00144   return !(iter1 == iter2);
    00145 }
    00146
    00147 template<class MAP_ITER1, class LIST_ITER1, class MAP_ITER2, class KEY, class VALUE, class COMPARE >
    00148 bool operator==(const MultiMapIterator<MAP_ITER1, LIST_ITER1, KEY, VALUE, COMPARE> &iter1, const MAP_ITER2 &iter2)
    00149 {
    00150   return !iter1.ListValid() && iter1.GetMapIter() == iter2;
    00151 }
    00152
    00153 template<class MAP_ITER1, class LIST_ITER1, class MAP_ITER2, class KEY, class VALUE, class COMPARE >
    00154 bool operator!=(const MultiMapIterator<MAP_ITER1, LIST_ITER1, KEY, VALUE, COMPARE> &iter1, const MAP_ITER2 &iter2)
    00155 {
    00156   return iter1.ListValid() || iter1.GetMapIter() != iter2;
    00157 }
    00158
    00159 template<class MAP_ITER1, class LIST_ITER1, class MAP_ITER2, class KEY, class VALUE, class COMPARE >
    00160 bool operator==(const MAP_ITER2 &iter2, const MultiMapIterator<MAP_ITER1, LIST_ITER1, KEY, VALUE, COMPARE> &iter1)
    00161 {
    00162   return !iter1.ListValid() && iter1.GetMapIter() == iter2;
    00163 }
    00164
    00165 template<class MAP_ITER1, class LIST_ITER1, class MAP_ITER2, class KEY, class VALUE, class COMPARE >
    00166 bool operator!=(const MAP_ITER2 &iter2, const MultiMapIterator<MAP_ITER1, LIST_ITER1, KEY, VALUE, COMPARE> &iter1)
    00167 {
    00168   return iter1.ListValid() || iter1.GetMapIter() != iter2;
    00169 }
    00170
    00171
    00176 template<typename KEY, typename VALUE, typename COMPARE = std::less<KEY> >
    00177 class MultiMap : public std::map<KEY, std::list<VALUE>, COMPARE > {
    00178 public:
    00179   typedef typename std::list<VALUE> List;
    00180   typedef typename List::iterator ListIterator;
    00181   typedef typename List::const_iterator ConstListIterator;
    00182
    00183   typedef typename std::map<KEY, List, COMPARE > Map;
    00184   typedef typename Map::iterator MapIterator;
    00185   typedef typename Map::const_iterator ConstMapIterator;
    00186
    00187   typedef MultiMapIterator<MapIterator, ListIterator, KEY, VALUE, COMPARE> iterator;
    00188   typedef MultiMapIterator<ConstMapIterator, ConstListIterator, KEY, const VALUE, COMPARE> const_iterator;
    00189
    00190   void erase(iterator it)
    00191   {
    00192     List &list = it.map_iter->second;
    00193     assert(!list.empty());
    00194     if (it.ListValid()) {
    00195       list.erase(it.list_iter);
    00196     } else {
    00197       list.erase(list.begin());
    00198     }
    00199
    00200     if (list.empty()) {
    00201       Map::erase(it.map_iter);
    00202     }
    00203   }
    00204
    00205   void Insert(const KEY &key, const VALUE &val)
    00206   {
    00207     List &list = (*this)[key];
    00208     list.push_back(val);
    00209     assert(!list.empty());
    00210   }
    00211
    00212   size_t size() const
    00213   {
    00214     size_t ret = 0;
    00215     for(ConstMapIterator it = Map::begin(); it != Map::end(); ++it) {
    00216       ret += it->second.size();
    00217     }
    00218     return ret;
    00219   }
    00220
    00221   size_t MapSize() const
    00222   {
    00223     return Map::size();
    00224   }
    00225
    00226   std::pair<iterator, iterator> equal_range(const KEY &key)
    00227   {
    00228     MapIterator begin(lower_bound(key));
    00229     if (begin != Map::end() && begin->first == key) {
    00230       MapIterator end = begin;
    00231       return std::make_pair(begin, ++end);
    00232     } else {
    00233       return std::make_pair(begin, begin);
    00234     }
    00235   }
    00236
    00237   std::pair<const_iterator, const_iterator> equal_range(const KEY &key) const
    00238   {
    00239     ConstMapIterator begin(lower_bound(key));
    00240     if (begin != Map::end() && begin->first == key) {
    00241       ConstMapIterator end = begin;
    00242       return std::make_pair(begin, ++end);
    00243     } else {
    00244       return std::make_pair(begin, begin);
    00245     }
    00246   }
    00247 };
    00248
    00249 #endif /* MULTIMAP_HPP_ */