Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-08-22 04:57:37

0001 #ifndef FWCore_Framework_PrincipalGetAdapter_h
0002 #define FWCore_Framework_PrincipalGetAdapter_h
0003 
0004 // -*- C++ -*-
0005 //
0006 
0007 // Class  :     PrincipalGetAdapter
0008 //
0009 /**\class PrincipalGetAdapter PrincipalGetAdapter.h FWCore/Framework/interface/PrincipalGetAdapter.h
0010 
0011 Description: This is the implementation for accessing EDProducts and 
0012 inserting new EDProducts.
0013 
0014 Usage:
0015 
0016 Getting Data
0017 
0018 The edm::PrincipalGetAdapter class provides many 'get*" methods for getting data
0019 it contains.  
0020 
0021 The primary method for getting data is to use getByLabel(). The labels are
0022 the label of the module assigned in the configuration file and the 'product
0023 instance label' (which can be omitted in the case the 'product instance label'
0024 is the default value).  The C++ type of the product plus the two labels
0025 uniquely identify a product in the PrincipalGetAdapter.
0026 
0027 We use an event in the examples, but a run or a luminosity block can also
0028 hold products.
0029 
0030 \code
0031 edm::Handle<AppleCollection> apples;
0032 event.getByLabel("tree",apples);
0033 \endcode
0034 
0035 \code
0036 edm::Handle<FruitCollection> fruits;
0037 event.getByLabel("market", "apple", fruits);
0038 \endcode
0039 
0040 
0041 Putting Data
0042 
0043 \code
0044   
0045 //fill the collection
0046 ...
0047 event.put(std::make_unique<AppleCollection>());
0048 \endcode
0049 
0050 \code
0051 
0052 //fill the collection
0053 ...
0054 event.put(std::make_unique<FruitCollection>());
0055 \endcode
0056 
0057 
0058 Getting a reference to a product before that product is put into the
0059 event/lumiBlock/run.
0060 NOTE: The edm::RefProd returned will not work until after the
0061 edm::PrincipalGetAdapter has been committed (which happens after the
0062 EDProducer::produce method has ended)
0063 \code
0064 auto pApples = std::make_unique<AppleCollection>();
0065 
0066 edm::RefProd<AppleCollection> refApples = event.getRefBeforePut<AppleCollection>();
0067 
0068 //do loop and fill collection
0069 for(unsigned int index = 0; .....) {
0070 ....
0071 apples->push_back(Apple(...));
0072   
0073 //create an edm::Ref to the new object
0074 edm::Ref<AppleCollection> ref(refApples, index);
0075 ....
0076 }
0077 \endcode
0078 
0079 */
0080 /*----------------------------------------------------------------------
0081 
0082 ----------------------------------------------------------------------*/
0083 #include <cassert>
0084 #include <typeinfo>
0085 #include <string>
0086 #include <vector>
0087 #include <type_traits>
0088 
0089 #include "DataFormats/Common/interface/EDProductfwd.h"
0090 #include "DataFormats/Provenance/interface/ProvenanceFwd.h"
0091 #include "FWCore/Framework/interface/Frameworkfwd.h"
0092 
0093 #include "DataFormats/Common/interface/traits.h"
0094 
0095 #include "DataFormats/Common/interface/BasicHandle.h"
0096 
0097 #include "DataFormats/Common/interface/ConvertHandle.h"
0098 
0099 #include "DataFormats/Common/interface/Handle.h"
0100 
0101 #include "DataFormats/Common/interface/Wrapper.h"
0102 
0103 #include "FWCore/Utilities/interface/InputTag.h"
0104 #include "FWCore/Utilities/interface/EDGetToken.h"
0105 #include "FWCore/Utilities/interface/EDPutToken.h"
0106 #include "FWCore/Utilities/interface/ProductKindOfType.h"
0107 #include "FWCore/Utilities/interface/ProductLabels.h"
0108 #include "FWCore/Utilities/interface/propagate_const.h"
0109 #include "FWCore/Utilities/interface/Transition.h"
0110 
0111 namespace edm {
0112 
0113   class ModuleCallingContext;
0114   class SharedResourcesAcquirer;
0115   class ProducerBase;
0116 
0117   namespace principal_get_adapter_detail {
0118     void throwOnPutOfNullProduct(char const* principalType,
0119                                  TypeID const& productType,
0120                                  std::string const& productInstanceName);
0121     void throwOnPutOfUninitializedToken(char const* principalType, std::type_info const& productType);
0122     void throwOnPutOfWrongType(std::type_info const& wrongType, TypeID const& rightType);
0123     void throwOnPrematureRead(char const* principalType,
0124                               TypeID const& productType,
0125                               std::string const& moduleLabel,
0126                               std::string const& productInstanceName);
0127 
0128     void throwOnPrematureRead(char const* principalType, TypeID const& productType, EDGetToken);
0129 
0130   }  // namespace principal_get_adapter_detail
0131   class PrincipalGetAdapter {
0132   public:
0133     PrincipalGetAdapter(Principal const& pcpl, ModuleDescription const& md, bool isComplete);
0134 
0135     ~PrincipalGetAdapter();
0136 
0137     PrincipalGetAdapter(PrincipalGetAdapter const&) = delete;             // Disallow copying and moving
0138     PrincipalGetAdapter& operator=(PrincipalGetAdapter const&) = delete;  // Disallow copying and moving
0139 
0140     //size_t size() const;
0141 
0142     void setConsumer(EDConsumerBase const* iConsumer) { consumer_ = iConsumer; }
0143     EDConsumerBase const* getConsumer() const { return consumer_; }
0144 
0145     void setSharedResourcesAcquirer(SharedResourcesAcquirer* iSra) { resourcesAcquirer_ = iSra; }
0146     SharedResourcesAcquirer* getSharedResourcesAcquirer() const { return resourcesAcquirer_; }
0147 
0148     void setProducer(ProducerBase const* iProd) { prodBase_ = iProd; }
0149 
0150     size_t numberOfProductsConsumed() const;
0151 
0152     bool isComplete() const { return isComplete_; }
0153 
0154     template <typename PROD>
0155     bool checkIfComplete() const;
0156 
0157     Transition transition() const;
0158 
0159     ProcessHistory const& processHistory() const;
0160 
0161     Principal const& principal() const { return principal_; }
0162 
0163     BranchDescription const& getBranchDescription(TypeID const& type, std::string const& productInstanceName) const;
0164 
0165     EDPutToken::value_type getPutTokenIndex(TypeID const& type, std::string const& productInstanceName) const;
0166 
0167     TypeID const& getTypeIDForPutTokenIndex(EDPutToken::value_type index) const;
0168     std::string const& productInstanceLabel(EDPutToken) const;
0169     typedef std::vector<BasicHandle> BasicHandleVec;
0170 
0171     BranchDescription const& getBranchDescription(unsigned int iPutTokenIndex) const;
0172     ProductID const& getProductID(unsigned int iPutTokenIndex) const;
0173     ModuleDescription const& moduleDescription() const { return md_; }
0174 
0175     std::vector<edm::ProductResolverIndex> const& putTokenIndexToProductResolverIndex() const;
0176 
0177     //uses the EDPutToken index
0178     std::vector<bool> const& recordProvenanceList() const;
0179     //------------------------------------------------------------
0180     // Protected functions.
0181     //
0182 
0183     // The following 'get' functions serve to isolate the PrincipalGetAdapter class
0184     // from the Principal class.
0185 
0186     BasicHandle getByLabel_(TypeID const& tid, InputTag const& tag, ModuleCallingContext const* mcc) const;
0187 
0188     BasicHandle getByLabel_(TypeID const& tid,
0189                             std::string const& label,
0190                             std::string const& instance,
0191                             std::string const& process,
0192                             ModuleCallingContext const* mcc) const;
0193 
0194     BasicHandle getByToken_(TypeID const& id,
0195                             KindOfType kindOfType,
0196                             EDGetToken token,
0197                             ModuleCallingContext const* mcc) const;
0198 
0199     BasicHandle getMatchingSequenceByLabel_(TypeID const& typeID,
0200                                             InputTag const& tag,
0201                                             ModuleCallingContext const* mcc) const;
0202 
0203     BasicHandle getMatchingSequenceByLabel_(TypeID const& typeID,
0204                                             std::string const& label,
0205                                             std::string const& instance,
0206                                             std::string const& process,
0207                                             ModuleCallingContext const* mcc) const;
0208 
0209     // Also isolates the PrincipalGetAdapter class
0210     // from the Principal class.
0211     EDProductGetter const* prodGetter() const;
0212 
0213     void labelsForToken(EDGetToken const& iToken, ProductLabels& oLabels) const;
0214 
0215     unsigned int processBlockIndex(std::string const& processName) const;
0216 
0217   private:
0218     template <typename T>
0219     static constexpr bool hasMergeProductFunction() {
0220       if constexpr (requires(T& a, T const& b) { a.mergeProduct(b); }) {
0221         return true;
0222       }
0223       return false;
0224     }
0225     // Is this an Event, a LuminosityBlock, or a Run.
0226     BranchType const& branchType() const;
0227 
0228     BasicHandle makeFailToGetException(KindOfType, TypeID const&, EDGetToken) const;
0229 
0230     void throwAmbiguousException(TypeID const& productType, EDGetToken token) const;
0231 
0232     void throwUnregisteredPutException(TypeID const& type, std::string const& productInstanceLabel) const;
0233 
0234   private:
0235     //------------------------------------------------------------
0236     // Data members
0237     //
0238 
0239     // Each PrincipalGetAdapter must have an associated Principal, used as the
0240     // source of all 'gets' and the target of 'puts'.
0241     Principal const& principal_;
0242 
0243     // Each PrincipalGetAdapter must have a description of the module executing the
0244     // "transaction" which the PrincipalGetAdapter represents.
0245     ModuleDescription const& md_;
0246 
0247     EDConsumerBase const* consumer_;
0248     SharedResourcesAcquirer* resourcesAcquirer_;  // We do not use propagate_const because the acquirer is itself mutable.
0249     ProducerBase const* prodBase_ = nullptr;
0250     bool isComplete_;
0251   };
0252 
0253   template <typename PROD>
0254   inline std::ostream& operator<<(std::ostream& os, Handle<PROD> const& h) {
0255     os << h.product() << " " << h.provenance() << " " << h.id();
0256     return os;
0257   }
0258 
0259   //------------------------------------------------------------
0260   // Metafunction support for compile-time selection of code used in
0261   // PrincipalGetAdapter::put member template.
0262   //
0263 
0264   namespace detail {
0265     template <typename T>
0266     void do_post_insert_if_available(T& iProduct) {
0267       if constexpr (not std::derived_from<T, DoNotSortUponInsertion> and requires(T& p) { p.post_insert(); }) {
0268         iProduct.post_insert();
0269       }
0270     }
0271   }  // namespace detail
0272 
0273   // Implementation of  PrincipalGetAdapter  member templates. See  PrincipalGetAdapter.cc for the
0274   // implementation of non-template members.
0275   //
0276 
0277   template <typename PROD>
0278   inline bool PrincipalGetAdapter::checkIfComplete() const {
0279     return isComplete() || !hasMergeProductFunction<PROD>();
0280   }
0281 
0282 }  // namespace edm
0283 #endif