CMS 3D CMS Logo

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

Go to the documentation of this file.
00001 #ifndef DataFormats_Common_OneToMany_h
00002 #define DataFormats_Common_OneToMany_h
00003 #include "DataFormats/Common/interface/AssociationMapHelpers.h"
00004 #include "DataFormats/Common/interface/Ref.h"
00005 #include "DataFormats/Common/interface/RefVector.h"
00006 #include "DataFormats/Common/interface/RefProd.h"
00007 #include <map>
00008 #include <vector>
00009 
00010 namespace edm {
00011   template<typename CKey, typename CVal, typename index = unsigned int>
00012   class OneToMany {
00014     typedef edm::RefProd<CKey> KeyRefProd;
00016     typedef edm::RefProd<CVal> ValRefProd;
00018     typedef std::vector<index> map_assoc;
00019   public:
00021     typedef edm::RefVector<CVal> val_type;
00023     typedef edm::Ref<CKey> key_type;
00025     typedef edm::Ref<CVal> data_type;
00027     typedef index index_type;
00029     typedef std::map<index_type, map_assoc > map_type;
00031     typedef helpers::KeyVal<KeyRefProd, ValRefProd> ref_type;
00033     typedef std::map<const typename CKey::value_type *,
00034                      std::vector<const typename CVal::value_type *> 
00035                     > transient_map_type;
00037     typedef std::vector<const typename CKey::value_type *> transient_key_vector;
00039     typedef std::vector<std::vector<const typename CVal::value_type *> > transient_val_vector;
00041     static void insert(ref_type & ref, map_type & m,
00042                         const key_type & k, const data_type & v) {
00043       if (k.isNull() || v.isNull())
00044         Exception::throwThis(errors::InvalidReference,
00045           "can't insert null references in AssociationMap");
00046       if (ref.key.isNull()) {
00047         ref.key = KeyRefProd(k);
00048         ref.val = ValRefProd(v);
00049       }
00050       helpers::checkRef(ref.key, k); helpers::checkRef(ref.val, v);
00051       index_type ik = index_type(k.key()), iv = index_type(v.key());
00052       m[ ik ].push_back(iv);
00053     }
00054     static void insert(ref_type & ref, map_type & m, const key_type & k, const val_type & v) {
00055       for(typename val_type::const_iterator i = v.begin(), iEnd = v.end(); i != iEnd; ++i)
00056       insert(ref, m, k, *i);
00057     }
00059     static val_type val(const ref_type & ref, const map_assoc & iv) {
00060       val_type v;
00061       for(typename map_assoc::const_iterator idx = iv.begin(), idxEnd = iv.end(); idx != idxEnd; ++idx)
00062         v.push_back(edm::Ref<CVal>(ref.val, *idx));
00063       return v;
00064     }
00066     static typename map_type::size_type size(const map_assoc & v) { return v.size(); }
00068     static void sort(map_type &) { }
00070     static transient_map_type transientMap(const ref_type & ref, const map_type & map) {
00071       transient_map_type m;
00072       const CKey & ckey = * ref.key;
00073       const CVal & cval = * ref.val;
00074       for(typename map_type::const_iterator i = map.begin(); i != map.end(); ++ i) {
00075         const map_assoc & a = i->second;
00076         const typename CKey::value_type * k = & ckey[ i->first ];
00077         std::vector<const typename CVal::value_type *> v;
00078         for(typename map_assoc::const_iterator j = a.begin(); j != a.end(); ++j) {
00079           const typename CVal::value_type * val = & cval[ *j ];
00080           v.push_back(val);
00081         }
00082         m.insert(std::make_pair(k, v));
00083       }
00084       return m;
00085     }
00087     static transient_key_vector transientKeyVector(const ref_type & ref, const map_type & map) {
00088       transient_key_vector m;
00089       const CKey & ckey = * ref.key;
00090       for(typename map_type::const_iterator i = map.begin(); i != map.end(); ++ i)
00091         m.push_back(& ckey[i->first]);
00092       return m;
00093     }
00095     static transient_val_vector transientValVector(const ref_type & ref, const map_type & map) {
00096       transient_val_vector m;
00097       const CVal & cval = * ref.val;
00098       for(typename map_type::const_iterator i = map.begin(); i != map.end(); ++ i) {
00099         const map_assoc & a = i->second;
00100         std::vector<const typename CVal::value_type *> v;
00101         m.push_back(v);
00102         for(typename map_assoc::const_iterator j = a.begin(); j != a.end(); ++j)
00103           m.back().push_back(& cval[ *j ]);
00104       }
00105       return m;
00106     }
00107   };
00108 }
00109 
00110 #endif