00001 #ifndef DataFormats_Common_OneToManyWithQualityGeneric_h
00002 #define DataFormats_Common_OneToManyWithQualityGeneric_h
00003 #include "DataFormats/Common/interface/AssociationMapHelpers.h"
00004 #include "DataFormats/Common/interface/Ref.h"
00005 #include "DataFormats/Common/interface/RefProd.h"
00006 #include <map>
00007 #include <vector>
00008 #include <algorithm>
00009 #include <boost/bind.hpp>
00010
00011 #include "DataFormats/Common/interface/MapRefViewTrait.h"
00012
00013 namespace edm {
00014 template<typename CKey, typename CVal, typename Q, typename index = unsigned int,
00015 typename KeyRefProd = typename helper::MapRefViewTrait<CKey>::refprod_type,
00016 typename ValRefProd = typename helper::MapRefViewTrait<CVal>::refprod_type,
00017 typename KeyRef = typename helper::MapRefViewTrait<CKey>::ref_type,
00018 typename ValRef = typename helper::MapRefViewTrait<CVal>::ref_type >
00019 class OneToManyWithQualityGeneric {
00021 typedef KeyRefProd keyrefprod_type;
00023 typedef ValRefProd valrefprod_type;
00025 typedef std::vector<std::pair<index, Q> > map_assoc;
00026
00027 public:
00029 typedef std::vector<std::pair<ValRef, Q> > val_type;
00031 typedef KeyRef key_type;
00033 typedef std::pair<ValRef, Q> data_type;
00035 typedef index index_type;
00037 typedef std::map<index_type, map_assoc> map_type;
00039 typedef helpers::KeyVal<keyrefprod_type, valrefprod_type> ref_type;
00041 typedef std::map<const typename CKey::value_type *,
00042 std::vector<std::pair<const typename CVal::value_type *, Q > >
00043 > transient_map_type;
00045 typedef std::vector<const typename CKey::value_type *> transient_key_vector;
00047 typedef std::vector<std::vector<std::pair<const typename CVal::value_type *, Q > >
00048 > transient_val_vector;
00050 static void insert(ref_type & ref, map_type & m,
00051 const key_type & k, const data_type & v) {
00052 const ValRef & vref = v.first;
00053 if (k.isNull() || vref.isNull())
00054 Exception::throwThis(errors::InvalidReference,
00055 "can't insert null references in AssociationMap");
00056 if (ref.key.isNull()) {
00057 ref.key = keyrefprod_type(k);
00058 ref.val = valrefprod_type(vref);
00059 }
00060 helpers::checkRef(ref.key, k); helpers::checkRef(ref.val, vref);
00061 index_type ik = index_type(k.key()), iv = index_type(vref.key());
00062 m[ik].push_back(std::make_pair(iv, v.second));
00063 }
00064 static void insert(ref_type & ref, map_type & m, const key_type & k, const val_type & v) {
00065 for(typename val_type::const_iterator i = v.begin(), iEnd = v.end(); i != iEnd; ++i)
00066 insert(ref, m, k, *i);
00067 }
00069 static val_type val(const ref_type & ref, const map_assoc & iv) {
00070 val_type v;
00071 for(typename map_assoc::const_iterator idx = iv.begin(), idxEnd = iv.end(); idx != idxEnd; ++idx)
00072 v.push_back(std::make_pair(ValRef(ref.val, idx->first), idx->second));
00073 return v;
00074 }
00076 static typename map_type::size_type size(const map_assoc & v) { return v.size(); }
00078 static void sort(map_type & m) {
00079
00080 for(typename map_type::iterator i = m.begin(), iEnd = m.end(); i != iEnd; ++i) {
00081 map_assoc & v = i->second;
00082
00083
00084
00085 std::sort(v.begin(), v.end(),
00086 boost::bind(std::less<Q>(),
00087 boost::bind(&std::pair<index, Q>::second,_2), boost::bind( &std::pair<index, Q>::second,_1)
00088 )
00089 );
00090
00091 }
00092 }
00094 static transient_map_type transientMap(const ref_type & ref, const map_type & map) {
00095 transient_map_type m;
00096 const CKey & ckey = * ref.key;
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 const typename CKey::value_type * k = & ckey[i->first];
00101 std::vector<std::pair<const typename CVal::value_type *, Q> > v;
00102 for(typename map_assoc::const_iterator j = a.begin(); j != a.end(); ++j) {
00103 const typename CVal::value_type * val = & cval[j->first];
00104 v.push_back(std::make_pair(val, j->second));
00105 }
00106 m.insert(std::make_pair(k, v));
00107 }
00108 return m;
00109 }
00111 static transient_key_vector transientKeyVector(const ref_type & ref, const map_type & map) {
00112 transient_key_vector m;
00113 const CKey & ckey = * ref.key;
00114 for(typename map_type::const_iterator i = map.begin(); i != map.end(); ++ i)
00115 m.push_back(& ckey[i->first]);
00116 return m;
00117 }
00119 static transient_val_vector transientValVector(const ref_type & ref, const map_type & map) {
00120 transient_val_vector m;
00121 const CVal & cval = * ref.val;
00122 for(typename map_type::const_iterator i = map.begin(); i != map.end(); ++ i) {
00123 const map_assoc & a = i->second;
00124 std::vector<std::pair<const typename CVal::value_type *, Q> > v;
00125 m.push_back(v);
00126 for(typename map_assoc::const_iterator j = a.begin(); j != a.end(); ++j)
00127 m.back().push_back(std::make_pair(& cval[ j->first ], j->second));
00128 }
00129 return m;
00130 }
00131 };
00132 }
00133
00134 #endif