Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-11-04 01:57:05

0001 #ifndef FWCore_Framework_Event_h
0002 #define FWCore_Framework_Event_h
0003 
0004 // -*- C++ -*-
0005 //
0006 // Package:     Framework
0007 // Class  :     Event
0008 //
0009 /**\class Event Event.h FWCore/Framework/interface/Event.h
0010 
0011 Description: This is the primary interface for accessing EDProducts
0012 from a single collision and inserting new derived products.
0013 
0014 For its usage, see "FWCore/Framework/interface/PrincipalGetAdapter.h"
0015 
0016 */
0017 /*----------------------------------------------------------------------
0018 ----------------------------------------------------------------------*/
0019 
0020 #include "DataFormats/Common/interface/BasicHandle.h"
0021 #include "DataFormats/Common/interface/ConvertHandle.h"
0022 #include "DataFormats/Common/interface/Handle.h"
0023 #include "DataFormats/Common/interface/OrphanHandle.h"
0024 #include "DataFormats/Common/interface/Wrapper.h"
0025 #include "DataFormats/Common/interface/FillViewHelperVector.h"
0026 #include "DataFormats/Common/interface/FunctorHandleExceptionFactory.h"
0027 
0028 #include "DataFormats/Provenance/interface/EventID.h"
0029 #include "DataFormats/Provenance/interface/EventSelectionID.h"
0030 #include "DataFormats/Provenance/interface/ProductID.h"
0031 #include "DataFormats/Provenance/interface/RunID.h"
0032 
0033 #include "FWCore/Common/interface/EventBase.h"
0034 #include "FWCore/Framework/interface/Frameworkfwd.h"
0035 #include "FWCore/Framework/interface/PrincipalGetAdapter.h"
0036 #include "FWCore/Framework/interface/LuminosityBlock.h"
0037 #include "FWCore/Utilities/interface/TypeID.h"
0038 #include "FWCore/Utilities/interface/EDGetToken.h"
0039 #include "FWCore/Utilities/interface/EDPutToken.h"
0040 #include "FWCore/Utilities/interface/ProductKindOfType.h"
0041 #include "FWCore/Utilities/interface/StreamID.h"
0042 #include "FWCore/Utilities/interface/propagate_const.h"
0043 #include "FWCore/Utilities/interface/Likely.h"
0044 #include "FWCore/Utilities/interface/thread_safety_macros.h"
0045 
0046 #include <memory>
0047 #include <string>
0048 #include <unordered_set>
0049 #include <typeinfo>
0050 #include <type_traits>
0051 #include <vector>
0052 
0053 class testEventGetRefBeforePut;
0054 class testEvent;
0055 
0056 namespace edm {
0057 
0058   class BranchDescription;
0059   class ModuleCallingContext;
0060   class TriggerResultsByName;
0061   class TriggerResults;
0062   class TriggerNames;
0063   class EDConsumerBase;
0064   class EDProductGetter;
0065   class ProducerBase;
0066   class SharedResourcesAcquirer;
0067 
0068   namespace stream {
0069     template <typename T>
0070     class ProducingModuleAdaptorBase;
0071   }
0072 
0073   class Event : public EventBase {
0074   public:
0075     Event(EventTransitionInfo const&, ModuleDescription const&, ModuleCallingContext const*);
0076     Event(EventPrincipal const&, ModuleDescription const&, ModuleCallingContext const*);
0077     ~Event() override;
0078 
0079     //Used in conjunction with EDGetToken
0080     void setConsumer(EDConsumerBase const* iConsumer);
0081 
0082     void setSharedResourcesAcquirer(SharedResourcesAcquirer* iResourceAcquirer);
0083 
0084     void setProducerCommon(ProducerBase const* iProd, std::vector<BranchID>* previousParentage);
0085 
0086     void setProducer(ProducerBase const* iProd,
0087                      std::vector<BranchID>* previousParentage,
0088                      std::vector<BranchID>* gotBranchIDsFromAcquire = nullptr);
0089 
0090     void setProducerForAcquire(ProducerBase const* iProd,
0091                                std::vector<BranchID>* previousParentage,
0092                                std::vector<BranchID>& gotBranchIDsFromAcquire);
0093 
0094     // AUX functions are defined in EventBase
0095     EventAuxiliary const& eventAuxiliary() const override { return aux_; }
0096 
0097     ///\return The id for the particular Stream processing the Event
0098     StreamID streamID() const { return streamID_; }
0099 
0100     LuminosityBlock const& getLuminosityBlock() const {
0101       if (not luminosityBlock_) {
0102         fillLuminosityBlock();
0103       }
0104       return *luminosityBlock_;
0105     }
0106 
0107     Run const& getRun() const;
0108 
0109     RunNumber_t run() const { return id().run(); }
0110 
0111     /**If you are caching data from the Event, you should also keep
0112      this number.  If this number changes then you know that
0113      the data you have cached is invalid.
0114      The value of '0' will never be returned so you can use that to
0115      denote that you have not yet checked the value.
0116      */
0117     typedef unsigned long CacheIdentifier_t;
0118     CacheIdentifier_t cacheIdentifier() const;
0119 
0120     template <typename PROD>
0121     bool get(ProductID const& oid, Handle<PROD>& result) const;
0122 
0123     // Template member overload to deal with Views.
0124     template <typename ELEMENT>
0125     bool get(ProductID const& oid, Handle<View<ELEMENT>>& result) const;
0126 
0127     EventSelectionIDVector const& eventSelectionIDs() const;
0128 
0129     ProcessHistoryID const& processHistoryID() const;
0130 
0131     ///Put a new product.
0132     template <typename PROD>
0133     OrphanHandle<PROD> put(std::unique_ptr<PROD> product) {
0134       return put<PROD>(std::move(product), std::string());
0135     }
0136 
0137     ///Put a new product with a 'product instance name'
0138     template <typename PROD>
0139     OrphanHandle<PROD> put(std::unique_ptr<PROD> product, std::string const& productInstanceName);
0140 
0141     template <typename PROD>
0142     OrphanHandle<PROD> put(EDPutToken token, std::unique_ptr<PROD> product);
0143 
0144     template <typename PROD>
0145     OrphanHandle<PROD> put(EDPutTokenT<PROD> token, std::unique_ptr<PROD> product);
0146 
0147     ///puts a new product
0148     template <typename PROD, typename... Args>
0149     OrphanHandle<PROD> emplace(EDPutTokenT<PROD> token, Args&&... args);
0150 
0151     template <typename PROD, typename... Args>
0152     OrphanHandle<PROD> emplace(EDPutToken token, Args&&... args);
0153 
0154     ///Returns a RefProd to a product before that product has been placed into the Event.
0155     /// The RefProd (and any Ref's made from it) will no work properly until after the
0156     /// Event has been committed (which happens after leaving the EDProducer::produce method)
0157     template <typename PROD>
0158     RefProd<PROD> getRefBeforePut() {
0159       return getRefBeforePut<PROD>(std::string());
0160     }
0161 
0162     template <typename PROD>
0163     RefProd<PROD> getRefBeforePut(std::string const& productInstanceName);
0164 
0165     template <typename PROD>
0166     RefProd<PROD> getRefBeforePut(EDPutTokenT<PROD>);
0167 
0168     template <typename PROD>
0169     RefProd<PROD> getRefBeforePut(EDPutToken);
0170 
0171     template <typename PROD>
0172     bool getByLabel(InputTag const& tag, Handle<PROD>& result) const;
0173 
0174     template <typename PROD>
0175     bool getByLabel(std::string const& label, Handle<PROD>& result) const;
0176 
0177     template <typename PROD>
0178     bool getByLabel(std::string const& label, std::string const& productInstanceName, Handle<PROD>& result) const;
0179 
0180     template <typename PROD>
0181     void getManyByType(std::vector<Handle<PROD>>& results) const;
0182 
0183     template <typename PROD>
0184     bool getByToken(EDGetToken token, Handle<PROD>& result) const;
0185 
0186     template <typename PROD>
0187     bool getByToken(EDGetTokenT<PROD> token, Handle<PROD>& result) const;
0188 
0189     template <typename PROD>
0190     Handle<PROD> getHandle(EDGetTokenT<PROD> token) const;
0191 
0192     template <typename PROD>
0193     PROD const& get(EDGetTokenT<PROD> token) const noexcept(false);
0194 
0195     // Template member overload to deal with Views.
0196     template <typename ELEMENT>
0197     bool getByLabel(std::string const& label, Handle<View<ELEMENT>>& result) const;
0198 
0199     template <typename ELEMENT>
0200     bool getByLabel(std::string const& label,
0201                     std::string const& productInstanceName,
0202                     Handle<View<ELEMENT>>& result) const;
0203 
0204     template <typename ELEMENT>
0205     bool getByLabel(InputTag const& tag, Handle<View<ELEMENT>>& result) const;
0206 
0207     template <typename ELEMENT>
0208     bool getByToken(EDGetToken token, Handle<View<ELEMENT>>& result) const;
0209 
0210     template <typename ELEMENT>
0211     bool getByToken(EDGetTokenT<View<ELEMENT>> token, Handle<View<ELEMENT>>& result) const;
0212 
0213     template <typename ELEMENT>
0214     Handle<View<ELEMENT>> getHandle(EDGetTokenT<View<ELEMENT>> token) const;
0215 
0216     template <typename ELEMENT>
0217     View<ELEMENT> const& get(EDGetTokenT<View<ELEMENT>> token) const noexcept(false);
0218 
0219     template <typename ELEMENT>
0220     Handle<View<ELEMENT>> fillView_(BasicHandle& bh) const;
0221 
0222     Provenance const& getProvenance(BranchID const& theID) const;
0223 
0224     Provenance const& getProvenance(ProductID const& theID) const;
0225 
0226     StableProvenance const& getStableProvenance(BranchID const& theID) const;
0227 
0228     StableProvenance const& getStableProvenance(ProductID const& theID) const;
0229 
0230     // Get the provenance for all products that may be in the event
0231     void getAllProvenance(std::vector<Provenance const*>& provenances) const;
0232 
0233     // Get the provenance for all products that may be in the event,
0234     // excluding the per-event provenance (the parentage information).
0235     // The excluded information may change from event to event.
0236     void getAllStableProvenance(std::vector<StableProvenance const*>& provenances) const;
0237 
0238     // Return true if this Event has been subjected to a process with
0239     // the given processName, and false otherwise.
0240     // If true is returned, then ps is filled with the ParameterSet
0241     // used to configure the identified process.
0242     bool getProcessParameterSet(std::string const& processName, ParameterSet& ps) const;
0243 
0244     ProcessHistory const& processHistory() const override;
0245 
0246     edm::ParameterSet const* parameterSet(edm::ParameterSetID const& psID) const override;
0247 
0248     size_t size() const;
0249 
0250     edm::TriggerNames const& triggerNames(edm::TriggerResults const& triggerResults) const override;
0251     TriggerResultsByName triggerResultsByName(edm::TriggerResults const& triggerResults) const override;
0252 
0253     ModuleCallingContext const* moduleCallingContext() const { return moduleCallingContext_; }
0254 
0255     void labelsForToken(EDGetToken const& iToken, ProductLabels& oLabels) const {
0256       provRecorder_.labelsForToken(iToken, oLabels);
0257     }
0258 
0259     typedef std::vector<edm::propagate_const<std::unique_ptr<WrapperBase>>> ProductPtrVec;
0260 
0261     EDProductGetter const& productGetter() const;
0262 
0263     unsigned int processBlockIndex(std::string const& processName) const {
0264       return provRecorder_.processBlockIndex(processName);
0265     }
0266 
0267   private:
0268     //for testing
0269     friend class ::testEventGetRefBeforePut;
0270     friend class ::testEvent;
0271 
0272     EventPrincipal const& eventPrincipal() const;
0273 
0274     void fillLuminosityBlock() const;
0275 
0276     ProductID makeProductID(BranchDescription const& desc) const;
0277 
0278     //override used by EventBase class
0279     BasicHandle getByLabelImpl(std::type_info const& iWrapperType,
0280                                std::type_info const& iProductType,
0281                                InputTag const& iTag) const override;
0282     BasicHandle getByTokenImpl(std::type_info const& iProductType, EDGetToken iToken) const override;
0283 
0284     //override used by EventBase class
0285     BasicHandle getImpl(std::type_info const& iProductType, ProductID const& pid) const override;
0286 
0287     template <typename PROD>
0288     OrphanHandle<PROD> putImpl(EDPutToken::value_type token, std::unique_ptr<PROD> product);
0289 
0290     template <typename PROD, typename... Args>
0291     OrphanHandle<PROD> emplaceImpl(EDPutToken::value_type token, Args&&... args);
0292 
0293     // commit_() is called to complete the transaction represented by
0294     // this PrincipalGetAdapter. The friendships required seems gross, but any
0295     // alternative is not great either.  Putting it into the
0296     // public interface is asking for trouble
0297     friend class ProducerSourceBase;
0298     friend class InputSource;
0299     friend class RawInputSource;
0300     friend class ProducerBase;
0301     template <typename T>
0302     friend class stream::ProducingModuleAdaptorBase;
0303 
0304     void commit_(std::vector<edm::ProductResolverIndex> const& iShouldPut, ParentageID* previousParentageId = nullptr);
0305     void commit_aux(ProductPtrVec& products, ParentageID* previousParentageId = nullptr);
0306 
0307     BasicHandle getByProductID_(ProductID const& oid) const;
0308 
0309     ProductPtrVec& putProducts() { return putProducts_; }
0310     ProductPtrVec const& putProducts() const { return putProducts_; }
0311 
0312     PrincipalGetAdapter provRecorder_;
0313 
0314     // putProducts_ is a holding pen for EDProducts inserted into this
0315     // PrincipalGetAdapter.
0316     //
0317     ProductPtrVec putProducts_;
0318 
0319     EventAuxiliary const& aux_;
0320     // measurable performance gain by only creating LuminosityBlock when needed
0321     // mutables are allowed in this case because edm::Event is only accessed by one thread
0322     CMS_SA_ALLOW mutable std::optional<LuminosityBlock> luminosityBlock_;
0323 
0324     // gotBranchIDs_ must be mutable because it records all 'gets',
0325     // which do not logically modify the PrincipalGetAdapter. gotBranchIDs_ is
0326     // merely a cache reflecting what has been retrieved from the
0327     // Principal class.
0328     typedef std::unordered_set<BranchID::value_type> BranchIDSet;
0329     CMS_SA_ALLOW mutable BranchIDSet gotBranchIDs_;
0330     CMS_SA_ALLOW mutable std::vector<bool> gotBranchIDsFromPrevious_;
0331     std::vector<BranchID>* previousBranchIDs_ = nullptr;
0332     std::vector<BranchID>* gotBranchIDsFromAcquire_ = nullptr;
0333 
0334     void addToGotBranchIDs(Provenance const& prov) const;
0335     void addToGotBranchIDs(BranchID const& branchID) const;
0336 
0337     // We own the retrieved Views, and have to destroy them.
0338     CMS_SA_ALLOW mutable std::vector<std::shared_ptr<ViewBase>> gotViews_;
0339 
0340     StreamID streamID_;
0341     ModuleCallingContext const* moduleCallingContext_;
0342 
0343     static const std::string emptyString_;
0344   };
0345 
0346   template <typename PROD>
0347   bool Event::get(ProductID const& oid, Handle<PROD>& result) const {
0348     result.clear();
0349     BasicHandle bh = this->getByProductID_(oid);
0350     result = convert_handle_check_type<PROD>(std::move(bh));  // throws on conversion error
0351     if (result.failedToGet()) {
0352       return false;
0353     }
0354     addToGotBranchIDs(*bh.provenance());
0355     return true;
0356   }
0357 
0358   template <typename ELEMENT>
0359   bool Event::get(ProductID const& oid, Handle<View<ELEMENT>>& result) const {
0360     result.clear();
0361     BasicHandle bh = this->getByProductID_(oid);
0362 
0363     if (bh.failedToGet()) {
0364       result = Handle<View<ELEMENT>>(makeHandleExceptionFactory([oid]() -> std::shared_ptr<cms::Exception> {
0365         std::shared_ptr<cms::Exception> whyFailed = std::make_shared<edm::Exception>(edm::errors::ProductNotFound);
0366         *whyFailed << "get View by ID failed: no product with ID = " << oid << "\n";
0367         return whyFailed;
0368       }));
0369       return false;
0370     }
0371 
0372     result = fillView_<ELEMENT>(bh);
0373     return true;
0374   }
0375 
0376   template <typename PROD>
0377   OrphanHandle<PROD> Event::putImpl(EDPutToken::value_type index, std::unique_ptr<PROD> product) {
0378     // The following will call post_insert if T has such a function,
0379     // and do nothing if T has no such function.
0380     std::conditional_t<detail::has_postinsert<PROD>::value, DoPostInsert<PROD>, DoNotPostInsert<PROD>> maybe_inserter;
0381     maybe_inserter(product.get());
0382 
0383     assert(index < putProducts().size());
0384 
0385     std::unique_ptr<Wrapper<PROD>> wp(new Wrapper<PROD>(std::move(product)));
0386     PROD const* prod = wp->product();
0387 
0388     putProducts()[index] = std::move(wp);
0389     auto const& prodID = provRecorder_.getProductID(index);
0390     return (OrphanHandle<PROD>(prod, prodID));
0391   }
0392 
0393   template <typename PROD>
0394   OrphanHandle<PROD> Event::put(std::unique_ptr<PROD> product, std::string const& productInstanceName) {
0395     if (UNLIKELY(product.get() == nullptr)) {  // null pointer is illegal
0396       TypeID typeID(typeid(PROD));
0397       principal_get_adapter_detail::throwOnPutOfNullProduct("Event", typeID, productInstanceName);
0398     }
0399 
0400     auto index = provRecorder_.getPutTokenIndex(TypeID(*product), productInstanceName);
0401     return putImpl(index, std::move(product));
0402   }
0403 
0404   template <typename PROD>
0405   OrphanHandle<PROD> Event::put(EDPutTokenT<PROD> token, std::unique_ptr<PROD> product) {
0406     if (UNLIKELY(product.get() == nullptr)) {  // null pointer is illegal
0407       TypeID typeID(typeid(PROD));
0408       principal_get_adapter_detail::throwOnPutOfNullProduct("Event", typeID, provRecorder_.productInstanceLabel(token));
0409     }
0410     if (UNLIKELY(token.isUninitialized())) {
0411       principal_get_adapter_detail::throwOnPutOfUninitializedToken("Event", typeid(PROD));
0412     }
0413     return putImpl(token.index(), std::move(product));
0414   }
0415 
0416   template <typename PROD>
0417   OrphanHandle<PROD> Event::put(EDPutToken token, std::unique_ptr<PROD> product) {
0418     if (UNLIKELY(product.get() == nullptr)) {  // null pointer is illegal
0419       TypeID typeID(typeid(PROD));
0420       principal_get_adapter_detail::throwOnPutOfNullProduct("Event", typeID, provRecorder_.productInstanceLabel(token));
0421     }
0422     if (UNLIKELY(token.isUninitialized())) {
0423       principal_get_adapter_detail::throwOnPutOfUninitializedToken("Event", typeid(PROD));
0424     }
0425     if (UNLIKELY(provRecorder_.getTypeIDForPutTokenIndex(token.index()) != TypeID{typeid(PROD)})) {
0426       principal_get_adapter_detail::throwOnPutOfWrongType(typeid(PROD),
0427                                                           provRecorder_.getTypeIDForPutTokenIndex(token.index()));
0428     }
0429 
0430     return putImpl(token.index(), std::move(product));
0431   }
0432 
0433   template <typename PROD, typename... Args>
0434   OrphanHandle<PROD> Event::emplace(EDPutTokenT<PROD> token, Args&&... args) {
0435     if (UNLIKELY(token.isUninitialized())) {
0436       principal_get_adapter_detail::throwOnPutOfUninitializedToken("Event", typeid(PROD));
0437     }
0438     return emplaceImpl<PROD>(token.index(), std::forward<Args>(args)...);
0439   }
0440 
0441   template <typename PROD, typename... Args>
0442   OrphanHandle<PROD> Event::emplace(EDPutToken token, Args&&... args) {
0443     if (UNLIKELY(token.isUninitialized())) {
0444       principal_get_adapter_detail::throwOnPutOfUninitializedToken("Event", typeid(PROD));
0445     }
0446     if (UNLIKELY(provRecorder_.getTypeIDForPutTokenIndex(token.index()) != TypeID{typeid(PROD)})) {
0447       principal_get_adapter_detail::throwOnPutOfWrongType(typeid(PROD),
0448                                                           provRecorder_.getTypeIDForPutTokenIndex(token.index()));
0449     }
0450 
0451     return emplaceImpl(token.index(), std::forward<Args>(args)...);
0452   }
0453 
0454   template <typename PROD, typename... Args>
0455   OrphanHandle<PROD> Event::emplaceImpl(EDPutToken::value_type index, Args&&... args) {
0456     assert(index < putProducts().size());
0457 
0458     std::unique_ptr<Wrapper<PROD>> wp(new Wrapper<PROD>(WrapperBase::Emplace{}, std::forward<Args>(args)...));
0459 
0460     // The following will call post_insert if T has such a function,
0461     // and do nothing if T has no such function.
0462     std::conditional_t<detail::has_postinsert<PROD>::value, DoPostInsert<PROD>, DoNotPostInsert<PROD>> maybe_inserter;
0463     maybe_inserter(&(wp->bareProduct()));
0464 
0465     PROD const* prod = wp->product();
0466 
0467     putProducts()[index] = std::move(wp);
0468     auto const& prodID = provRecorder_.getProductID(index);
0469     return (OrphanHandle<PROD>(prod, prodID));
0470   }
0471 
0472   template <typename PROD>
0473   RefProd<PROD> Event::getRefBeforePut(std::string const& productInstanceName) {
0474     auto index = provRecorder_.getPutTokenIndex(TypeID{typeid(PROD)}, productInstanceName);
0475 
0476     //should keep track of what Ref's have been requested and make sure they are 'put'
0477     return RefProd<PROD>(provRecorder_.getProductID(index), provRecorder_.prodGetter());
0478   }
0479 
0480   template <typename PROD>
0481   RefProd<PROD> Event::getRefBeforePut(EDPutTokenT<PROD> token) {
0482     if (UNLIKELY(token.isUninitialized())) {
0483       principal_get_adapter_detail::throwOnPutOfUninitializedToken("Event", typeid(PROD));
0484     }
0485     return RefProd<PROD>(provRecorder_.getProductID(token.index()), provRecorder_.prodGetter());
0486   }
0487 
0488   template <typename PROD>
0489   RefProd<PROD> Event::getRefBeforePut(EDPutToken token) {
0490     if (UNLIKELY(token.isUninitialized())) {
0491       principal_get_adapter_detail::throwOnPutOfUninitializedToken("Event", typeid(PROD));
0492     }
0493     if (UNLIKELY(provRecorder_.getTypeIDForPutTokenIndex(token.index()) != TypeID{typeid(PROD)})) {
0494       principal_get_adapter_detail::throwOnPutOfWrongType(typeid(PROD),
0495                                                           provRecorder_.getTypeIDForPutTokenIndex(token.index()));
0496     }
0497     return RefProd<PROD>(provRecorder_.getProductID(token.index()), provRecorder_.prodGetter());
0498   }
0499 
0500   template <typename PROD>
0501   bool Event::getByLabel(InputTag const& tag, Handle<PROD>& result) const {
0502     result.clear();
0503     BasicHandle bh = provRecorder_.getByLabel_(TypeID(typeid(PROD)), tag, moduleCallingContext_);
0504     result = convert_handle<PROD>(std::move(bh));  // throws on conversion error
0505     if UNLIKELY (result.failedToGet()) {
0506       return false;
0507     }
0508     addToGotBranchIDs(*result.provenance());
0509     return true;
0510   }
0511 
0512   template <typename PROD>
0513   bool Event::getByLabel(std::string const& label, std::string const& productInstanceName, Handle<PROD>& result) const {
0514     result.clear();
0515     BasicHandle bh = provRecorder_.getByLabel_(
0516         TypeID(typeid(PROD)), label, productInstanceName, emptyString_, moduleCallingContext_);
0517     result = convert_handle<PROD>(std::move(bh));  // throws on conversion error
0518     if UNLIKELY (result.failedToGet()) {
0519       return false;
0520     }
0521     addToGotBranchIDs(*result.provenance());
0522     return true;
0523   }
0524 
0525   template <typename PROD>
0526   bool Event::getByLabel(std::string const& label, Handle<PROD>& result) const {
0527     return getByLabel(label, emptyString_, result);
0528   }
0529 
0530   template <typename PROD>
0531   void Event::getManyByType(std::vector<Handle<PROD>>& results) const {
0532     provRecorder_.getManyByType(results, moduleCallingContext_);
0533     for (typename std::vector<Handle<PROD>>::const_iterator it = results.begin(), itEnd = results.end(); it != itEnd;
0534          ++it) {
0535       addToGotBranchIDs(*it->provenance());
0536     }
0537   }
0538 
0539   template <typename PROD>
0540   bool Event::getByToken(EDGetToken token, Handle<PROD>& result) const {
0541     result.clear();
0542     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(PROD)), PRODUCT_TYPE, token, moduleCallingContext_);
0543     result = convert_handle<PROD>(std::move(bh));  // throws on conversion error
0544     if UNLIKELY (result.failedToGet()) {
0545       return false;
0546     }
0547     addToGotBranchIDs(*result.provenance());
0548     return true;
0549   }
0550 
0551   template <typename PROD>
0552   bool Event::getByToken(EDGetTokenT<PROD> token, Handle<PROD>& result) const {
0553     result.clear();
0554     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(PROD)), PRODUCT_TYPE, token, moduleCallingContext_);
0555     result = convert_handle<PROD>(std::move(bh));
0556     if UNLIKELY (result.failedToGet()) {
0557       return false;
0558     }
0559     addToGotBranchIDs(*result.provenance());
0560     return true;
0561   }
0562 
0563   template <typename PROD>
0564   Handle<PROD> Event::getHandle(EDGetTokenT<PROD> token) const {
0565     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(PROD)), PRODUCT_TYPE, token, moduleCallingContext_);
0566     auto result = convert_handle<PROD>(std::move(bh));
0567     if LIKELY (not result.failedToGet()) {
0568       addToGotBranchIDs(*result.provenance());
0569     }
0570     return result;
0571   }
0572 
0573   template <typename PROD>
0574   PROD const& Event::get(EDGetTokenT<PROD> token) const noexcept(false) {
0575     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(PROD)), PRODUCT_TYPE, token, moduleCallingContext_);
0576     auto result = convert_handle<PROD>(std::move(bh));
0577     if LIKELY (not result.failedToGet()) {
0578       addToGotBranchIDs(*result.provenance());
0579     }
0580     return *result;
0581   }
0582 
0583   template <typename ELEMENT>
0584   bool Event::getByLabel(InputTag const& tag, Handle<View<ELEMENT>>& result) const {
0585     result.clear();
0586     BasicHandle bh = provRecorder_.getMatchingSequenceByLabel_(TypeID(typeid(ELEMENT)), tag, moduleCallingContext_);
0587     if UNLIKELY (bh.failedToGet()) {
0588       Handle<View<ELEMENT>> h(std::move(bh.whyFailedFactory()));
0589       h.swap(result);
0590       return false;
0591     }
0592     result = fillView_<ELEMENT>(bh);
0593     return true;
0594   }
0595 
0596   template <typename ELEMENT>
0597   bool Event::getByLabel(std::string const& moduleLabel,
0598                          std::string const& productInstanceName,
0599                          Handle<View<ELEMENT>>& result) const {
0600     result.clear();
0601     BasicHandle bh = provRecorder_.getMatchingSequenceByLabel_(
0602         TypeID(typeid(ELEMENT)), moduleLabel, productInstanceName, emptyString_, moduleCallingContext_);
0603     if UNLIKELY (bh.failedToGet()) {
0604       Handle<View<ELEMENT>> h(std::move(bh.whyFailedFactory()));
0605       h.swap(result);
0606       return false;
0607     }
0608     result = fillView_<ELEMENT>(bh);
0609     return true;
0610   }
0611 
0612   template <typename ELEMENT>
0613   bool Event::getByLabel(std::string const& moduleLabel, Handle<View<ELEMENT>>& result) const {
0614     return getByLabel(moduleLabel, emptyString_, result);
0615   }
0616 
0617   template <typename ELEMENT>
0618   bool Event::getByToken(EDGetToken token, Handle<View<ELEMENT>>& result) const {
0619     result.clear();
0620     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(ELEMENT)), ELEMENT_TYPE, token, moduleCallingContext_);
0621     if UNLIKELY (bh.failedToGet()) {
0622       Handle<View<ELEMENT>> h(std::move(bh.whyFailedFactory()));
0623       h.swap(result);
0624       return false;
0625     }
0626     result = fillView_<ELEMENT>(bh);
0627     return true;
0628   }
0629 
0630   template <typename ELEMENT>
0631   bool Event::getByToken(EDGetTokenT<View<ELEMENT>> token, Handle<View<ELEMENT>>& result) const {
0632     result.clear();
0633     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(ELEMENT)), ELEMENT_TYPE, token, moduleCallingContext_);
0634     if UNLIKELY (bh.failedToGet()) {
0635       Handle<View<ELEMENT>> h(std::move(bh.whyFailedFactory()));
0636       h.swap(result);
0637       return false;
0638     }
0639     result = fillView_<ELEMENT>(bh);
0640     return true;
0641   }
0642 
0643   template <typename ELEMENT>
0644   Handle<View<ELEMENT>> Event::getHandle(EDGetTokenT<View<ELEMENT>> token) const {
0645     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(ELEMENT)), ELEMENT_TYPE, token, moduleCallingContext_);
0646     if UNLIKELY (bh.failedToGet()) {
0647       return Handle<View<ELEMENT>>(std::move(bh.whyFailedFactory()));
0648     }
0649     return fillView_<ELEMENT>(bh);
0650   }
0651 
0652   template <typename ELEMENT>
0653   View<ELEMENT> const& Event::get(EDGetTokenT<View<ELEMENT>> token) const noexcept(false) {
0654     BasicHandle bh = provRecorder_.getByToken_(TypeID(typeid(ELEMENT)), ELEMENT_TYPE, token, moduleCallingContext_);
0655     if UNLIKELY (bh.failedToGet()) {
0656       bh.whyFailedFactory()->make()->raise();
0657     }
0658     return *fillView_<ELEMENT>(bh);
0659   }
0660 
0661   template <typename ELEMENT>
0662   Handle<View<ELEMENT>> Event::fillView_(BasicHandle& bh) const {
0663     std::vector<void const*> pointersToElements;
0664     FillViewHelperVector helpers;
0665     // the following must initialize the
0666     //  fill the helper vector
0667     bh.wrapper()->fillView(bh.id(), pointersToElements, helpers);
0668 
0669     auto newview = std::make_shared<View<ELEMENT>>(pointersToElements, helpers, &(productGetter()));
0670 
0671     addToGotBranchIDs(*bh.provenance());
0672     gotViews_.push_back(newview);
0673     return Handle<View<ELEMENT>>(newview.get(), bh.provenance());
0674   }
0675 
0676   // Free functions to retrieve a collection from the Event.
0677   // Will throw an exception if the collection is not available.
0678 
0679   template <typename T>
0680   T const& get(Event const& event, InputTag const& tag) noexcept(false) {
0681     Handle<T> handle;
0682     event.getByLabel(tag, handle);
0683     // throw if the handle is not valid
0684     return *handle.product();
0685   }
0686 
0687   template <typename T>
0688   T const& get(Event const& event, EDGetToken const& token) noexcept(false) {
0689     Handle<T> handle;
0690     event.getByToken(token, handle);
0691     // throw if the handle is not valid
0692     return *handle.product();
0693   }
0694 
0695   template <typename T>
0696   T const& get(Event const& event, EDGetTokenT<T> const& token) noexcept(false) {
0697     return event.get(token);
0698   }
0699 
0700 }  // namespace edm
0701 
0702 #endif  // FWCore_Framework_Event_h