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