File indexing completed on 2024-04-06 12:03:52
0001 #ifndef DataFormats_Common_OneToManyWithQualityGeneric_h
0002 #define DataFormats_Common_OneToManyWithQualityGeneric_h
0003 #include "DataFormats/Common/interface/AssociationMapHelpers.h"
0004 #include "DataFormats/Common/interface/Ref.h"
0005 #include "DataFormats/Common/interface/RefProd.h"
0006 #include <functional>
0007 #include <map>
0008 #include <vector>
0009 #include <algorithm>
0010 #include "DataFormats/Common/interface/MapRefViewTrait.h"
0011
0012 namespace edm {
0013 template <typename CKey,
0014 typename CVal,
0015 typename Q,
0016 typename index = unsigned int,
0017 typename KeyRefProd = typename helper::MapRefViewTrait<CKey>::refprod_type,
0018 typename ValRefProd = typename helper::MapRefViewTrait<CVal>::refprod_type,
0019 typename KeyRef = typename helper::MapRefViewTrait<CKey>::ref_type,
0020 typename ValRef = typename helper::MapRefViewTrait<CVal>::ref_type>
0021 class OneToManyWithQualityGeneric {
0022
0023 typedef KeyRefProd keyrefprod_type;
0024
0025 typedef ValRefProd valrefprod_type;
0026
0027 typedef std::vector<std::pair<index, Q> > map_assoc;
0028
0029 public:
0030
0031 typedef std::vector<std::pair<ValRef, Q> > val_type;
0032
0033 typedef KeyRef key_type;
0034
0035 typedef std::pair<ValRef, Q> data_type;
0036
0037 typedef Q quality_type;
0038
0039 typedef index index_type;
0040
0041 typedef std::map<index_type, map_assoc> map_type;
0042
0043 typedef helpers::KeyVal<keyrefprod_type, valrefprod_type> ref_type;
0044
0045 typedef std::map<const typename CKey::value_type *, std::vector<std::pair<const typename CVal::value_type *, Q> > >
0046 transient_map_type;
0047
0048 typedef std::vector<const typename CKey::value_type *> transient_key_vector;
0049
0050 typedef std::vector<std::vector<std::pair<const typename CVal::value_type *, Q> > > transient_val_vector;
0051
0052 static void insert(ref_type &ref, map_type &m, const key_type &k, const data_type &v) {
0053 const ValRef &vref = v.first;
0054 if (k.isNull() || vref.isNull())
0055 Exception::throwThis(errors::InvalidReference, "can't insert null references in AssociationMap");
0056 if (ref.key.isNull()) {
0057 if (k.isTransient() || vref.isTransient()) {
0058 Exception::throwThis(errors::InvalidReference,
0059 "can't insert transient references in uninitialized AssociationMap");
0060 }
0061
0062 EDProductGetter const *getter = ref.key.productGetter();
0063 if (getter == nullptr) {
0064 Exception::throwThis(errors::LogicError,
0065 "Can't insert into AssociationMap unless it was properly initialized.\n"
0066 "The most common fix for this is to add arguments to the call to the\n"
0067 "AssociationMap constructor that are valid Handle's to the containers.\n"
0068 "If you don't have valid handles or either template parameter to the\n"
0069 "AssociationMap is a View, then see the comments in AssociationMap.h.\n"
0070 "(note this was a new requirement added in the 7_5_X release series)\n");
0071 }
0072 ref.key = KeyRefProd(k.id(), getter);
0073 ref.val = ValRefProd(vref.id(), ref.val.productGetter());
0074 }
0075 helpers::checkRef(ref.key, k);
0076 helpers::checkRef(ref.val, vref);
0077 index_type ik = index_type(k.key()), iv = index_type(vref.key());
0078 m[ik].push_back(std::make_pair(iv, v.second));
0079 }
0080 static void insert(ref_type &ref, map_type &m, const key_type &k, const val_type &v) {
0081 for (typename val_type::const_iterator i = v.begin(), iEnd = v.end(); i != iEnd; ++i)
0082 insert(ref, m, k, *i);
0083 }
0084
0085 static val_type val(const ref_type &ref, const map_assoc &iv) {
0086 val_type v;
0087 for (typename map_assoc::const_iterator idx = iv.begin(), idxEnd = iv.end(); idx != idxEnd; ++idx)
0088 v.push_back(std::make_pair(ValRef(ref.val, idx->first), idx->second));
0089 return v;
0090 }
0091
0092 static typename map_type::size_type size(const map_assoc &v) { return v.size(); }
0093
0094
0095
0096
0097
0098 static void sort(map_type &m) {
0099
0100 for (typename map_type::iterator i = m.begin(), iEnd = m.end(); i != iEnd; ++i) {
0101 using std::placeholders::_1;
0102 using std::placeholders::_2;
0103 map_assoc &v = i->second;
0104
0105
0106
0107 std::sort(v.begin(),
0108 v.end(),
0109 std::bind(std::less<Q>(),
0110 std::bind(&std::pair<index, Q>::second, _2),
0111 std::bind(&std::pair<index, Q>::second, _1)));
0112 }
0113 }
0114
0115 static transient_map_type transientMap(const ref_type &ref, const map_type &map) {
0116 transient_map_type m;
0117 if (!map.empty()) {
0118 const CKey &ckey = *ref.key;
0119 const CVal &cval = *ref.val;
0120 for (typename map_type::const_iterator i = map.begin(); i != map.end(); ++i) {
0121 const map_assoc &a = i->second;
0122 const typename CKey::value_type *k = &ckey[i->first];
0123 std::vector<std::pair<const typename CVal::value_type *, Q> > v;
0124 for (typename map_assoc::const_iterator j = a.begin(); j != a.end(); ++j) {
0125 const typename CVal::value_type *val = &cval[j->first];
0126 v.push_back(std::make_pair(val, j->second));
0127 }
0128 m.insert(std::make_pair(k, v));
0129 }
0130 }
0131 return m;
0132 }
0133
0134 static transient_key_vector transientKeyVector(const ref_type &ref, const map_type &map) {
0135 transient_key_vector m;
0136 if (!map.empty()) {
0137 const CKey &ckey = *ref.key;
0138 for (typename map_type::const_iterator i = map.begin(); i != map.end(); ++i)
0139 m.push_back(&ckey[i->first]);
0140 }
0141 return m;
0142 }
0143
0144 static transient_val_vector transientValVector(const ref_type &ref, const map_type &map) {
0145 transient_val_vector m;
0146 if (!map.empty()) {
0147 const CVal &cval = *ref.val;
0148 for (typename map_type::const_iterator i = map.begin(); i != map.end(); ++i) {
0149 const map_assoc &a = i->second;
0150 std::vector<std::pair<const typename CVal::value_type *, Q> > v;
0151 m.push_back(v);
0152 for (typename map_assoc::const_iterator j = a.begin(); j != a.end(); ++j)
0153 m.back().push_back(std::make_pair(&cval[j->first], j->second));
0154 }
0155 }
0156 return m;
0157 }
0158 };
0159 }
0160
0161 #endif