Back to home page

Project CMSSW displayed by LXR

 
 

    


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

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