00001 #ifndef DataFormats_Common_IDVectorMap_h
00002 #define DataFormats_Common_IDVectorMap_h
00003
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
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