CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/DataFormats/Common/interface/IDVectorMap.h

Go to the documentation of this file.
00001 #ifndef DataFormats_Common_IDVectorMap_h
00002 #define DataFormats_Common_IDVectorMap_h
00003 // $Id: IDVectorMap.h,v 1.12 2008/03/31 21:12:11 wmtan Exp $
00004 #include <map>
00005 
00006 namespace edm {
00007 
00008   template<typename ID, typename C, typename P>
00009   class IDVectorMap {
00010   public:
00011     typedef typename C::value_type value_type;
00012     typedef typename C::const_iterator container_iterator;
00013     typedef std::map<ID, C> map;
00014     typedef typename map::const_iterator map_iterator;
00015     struct const_iterator {
00016       typedef typename IDVectorMap::value_type value_type;
00017       typedef value_type * pointer;
00018       typedef value_type & reference;
00019       typedef typename map_iterator::iterator_category iterator_category;
00020       const_iterator() { }
00021       const_iterator(const map_iterator & e, const map_iterator & m, const container_iterator & c) : 
00022         im(m), em(e), ic(c) {
00023       }
00024       const_iterator(const map_iterator & e) : 
00025         im(e), em(e) {
00026       }
00027       const_iterator & operator=(const const_iterator & it) { 
00028         im = it.im; em = it.em; ic = it.ic;
00029         return *this; 
00030       }
00031       const_iterator& operator++() { 
00032         ++ic;
00033         while (ic == im->second.end()) {
00034           ++im; 
00035           if (im == em) return *this;
00036           ic = im->second.begin();
00037         }
00038         return *this; 
00039       }
00040       const_iterator operator++(int) { const_iterator ci = *this; operator++(); return ci; }
00041       const_iterator& operator--() { 
00042         if (im == em) { --im; ic = im->second.end(); }
00043         while (ic == im->second.begin()) {
00044           --im; 
00045           ic = im->second.end();
00046         }
00047         --ic;
00048         return *this; 
00049       }
00050       const_iterator operator--(int) { const_iterator ci = *this; operator--(); return ci; }
00051       bool operator==(const const_iterator& ci) const { 
00052         if (im == em && ci.im == im && ci.em == em) return true;
00053         return im == ci.im && ic == ci.ic; 
00054       }
00055       bool operator!=(const const_iterator& ci) const { return ! operator==(ci); }
00056       const value_type & operator *() const { return *ic; }
00057     private:
00058       map_iterator im, em;
00059       container_iterator ic;
00060     };
00061 
00062     IDVectorMap() { }
00063     const_iterator begin() const {
00064       return const_iterator(map_.end(), map_.begin(), map_.begin()->second.begin());
00065     }
00066     const_iterator end() const {
00067       return const_iterator(map_.end());
00068     }
00069     void insert(ID id, const value_type & t) {
00070       map_[ id ].push_back(P::clone(t));
00071     }
00072     template<typename CI>
00073     void insert(ID id, CI begin, CI end) {
00074       C & c = map_[ id ];
00075       for(CI i = begin; i != end; ++i)
00076         c.push_back(P::clone(*i));
00077     }
00078 
00079     struct range {
00080       range (const container_iterator & b, const container_iterator & e) :
00081         begin(b), end(e) { }
00082       container_iterator begin, end;
00083     };
00084     range get(ID id) const {
00085       container_iterator begin, end;
00086       map_iterator i = map_.find(id);
00087       if (i != map_.end()) { 
00088         begin = i->second.begin();
00089         end = i->second.end();
00090       } else {
00091         begin = end;
00092       }
00093       return range(begin, end);
00094     }
00095 
00096     template<typename M>
00097     struct match_iterator {
00098       typedef typename IDVectorMap::value_type value_type;
00099       typedef value_type * pointer;
00100       typedef value_type & reference;
00101       typedef typename map_iterator::iterator_category iterator_category;
00102       match_iterator() { }
00103       match_iterator(const M & ma, const map_iterator & e, const map_iterator & m, const container_iterator & c) : 
00104         match(ma), im(m), em(e), ic(c) {
00105       }
00106       match_iterator(const M & ma, const map_iterator & e) : 
00107         match(ma), im(e), em(e) {
00108       }
00109       match_iterator & operator=(const match_iterator & it) { 
00110         match = it.match; im = it.im; em = it.em; ic = it.ic;
00111         return *this; 
00112       }
00113       match_iterator& operator++() { 
00114         ++ic;
00115         while (ic == im->second.end()) {
00116           do { ++im; } while (! match(im->first) && im != em);
00117           if (im == em) return *this;
00118           ic = im->second.begin();
00119         }
00120         return *this; 
00121       }
00122       match_iterator operator++(int) { match_iterator ci = *this; operator++(); return ci; }
00123       bool operator==(const match_iterator& ci) const { 
00124         if (im == em && ci.im == im && ci.em == em) return true;
00125         return im == ci.im && ic == ci.ic; 
00126       }
00127       bool operator!=(const match_iterator& ci) const { return ! operator==(ci); }
00128       const value_type & operator * () const { return *ic; }
00129     private:
00130       M match;
00131       map_iterator im, em;
00132       container_iterator ic;
00133     };
00134 
00135     template<typename M>
00136     match_iterator<M> begin(const M & m) const {
00137       return match_iterator<M>(m, map_.end(), map_.begin(), map_.begin()->second.begin());
00138     }
00139     template<typename M>
00140     match_iterator<M> end(const M & m) const {
00141       return match_iterator<M>(m, map_.end());
00142     }
00143 
00144     struct id_iterator {
00145       typedef ID value_type;
00146       typedef ID * pointer;
00147       typedef ID & reference;
00148       typedef typename map_iterator::iterator_category iterator_category;
00149       id_iterator() { }
00150       id_iterator(map_iterator o) : i(o) { }
00151       id_iterator & operator=(const id_iterator & it) { i = it.i; return *this; }
00152       id_iterator& operator++() { ++i; return *this; }
00153       id_iterator operator++(int) { id_iterator ci = *this; ++i; return ci; }
00154       id_iterator& operator--() { --i; return *this; }
00155       id_iterator operator--(int) { id_iterator ci = *this; --i; return ci; }
00156       bool operator==(const id_iterator& ci) const { return i == ci.i; }
00157       bool operator!=(const id_iterator& ci) const { return i != ci.i; }
00158       const ID operator *() const { return i->first; }
00159     private:
00160       map_iterator i;
00161     };
00162     id_iterator id_begin() const { return id_iterator(map_.begin()); }
00163     id_iterator id_end() const { return id_iterator(map_.end()); }
00164     size_t id_size() const { return map_.size(); }
00165     void swap (IDVectorMap & other);
00166     IDVectorMap& operator=(IDVectorMap const& rhs);
00167   private:
00168     C collection_;
00169     map map_;
00170   };
00171   
00172   template <typename ID, typename C, typename P>
00173   inline
00174   void
00175   IDVectorMap<ID, C, P>::swap(IDVectorMap<ID, C, P> & other) {
00176     collection_.swap(other.collection_);
00177     map_.swap(other.map_);
00178   }
00179 
00180   template <typename ID, typename C, typename P>
00181   inline
00182   IDVectorMap<ID, C, P>&
00183   IDVectorMap<ID, C, P>::operator=(IDVectorMap<ID, C, P> const& rhs) {
00184     IDVectorMap<ID, C, P> temp(rhs);
00185     this->swap(temp);
00186     return *this;
00187   }
00188 
00189   // free swap function
00190   template <typename ID, typename C, typename P>
00191   inline
00192   void
00193   swap(IDVectorMap<ID, C, P> & a, IDVectorMap<ID, C, P> & b) {
00194     a.swap(b);
00195   }
00196 
00197 }
00198 
00199 #endif