Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:53:00

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