Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-10-25 09:46:52

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     // Is this an Event, a LuminosityBlock, or a Run.
0219     BranchType const& branchType() const;
0220 
0221     BasicHandle makeFailToGetException(KindOfType, TypeID const&, EDGetToken) const;
0222 
0223     void throwAmbiguousException(TypeID const& productType, EDGetToken token) const;
0224 
0225     void throwUnregisteredPutException(TypeID const& type, std::string const& productInstanceLabel) const;
0226 
0227   private:
0228     //------------------------------------------------------------
0229     // Data members
0230     //
0231 
0232     // Each PrincipalGetAdapter must have an associated Principal, used as the
0233     // source of all 'gets' and the target of 'puts'.
0234     Principal const& principal_;
0235 
0236     // Each PrincipalGetAdapter must have a description of the module executing the
0237     // "transaction" which the PrincipalGetAdapter represents.
0238     ModuleDescription const& md_;
0239 
0240     EDConsumerBase const* consumer_;
0241     SharedResourcesAcquirer* resourcesAcquirer_;  // We do not use propagate_const because the acquirer is itself mutable.
0242     ProducerBase const* prodBase_ = nullptr;
0243     bool isComplete_;
0244   };
0245 
0246   template <typename PROD>
0247   inline std::ostream& operator<<(std::ostream& os, Handle<PROD> const& h) {
0248     os << h.product() << " " << h.provenance() << " " << h.id();
0249     return os;
0250   }
0251 
0252   //------------------------------------------------------------
0253   // Metafunction support for compile-time selection of code used in
0254   // PrincipalGetAdapter::put member template.
0255   //
0256 
0257   // has_postinsert is a metafunction of one argument, the type T.  As
0258   // with many metafunctions, it is implemented as a class with a data
0259   // member 'value', which contains the value 'returned' by the
0260   // metafunction.
0261   //
0262   // has_postinsert<T>::value is 'true' if T has the post_insert
0263   // member function (with the right signature), and 'false' if T has
0264   // no such member function.
0265 
0266   namespace detail {
0267     using no_tag = std::false_type;  // type indicating FALSE
0268     using yes_tag = std::true_type;  // type indicating TRUE
0269 
0270     // Definitions forthe following struct and function templates are
0271     // not needed; we only require the declarations.
0272     template <typename T, void (T::*)()>
0273     struct postinsert_function;
0274     template <typename T>
0275     no_tag has_postinsert_helper(...);
0276     template <typename T>
0277     yes_tag has_postinsert_helper(postinsert_function<T, &T::post_insert>* p);
0278 
0279     template <typename T>
0280     struct has_postinsert {
0281       static constexpr bool value = std::is_same<decltype(has_postinsert_helper<T>(nullptr)), yes_tag>::value &&
0282                                     !std::is_base_of<DoNotSortUponInsertion, T>::value;
0283     };
0284 
0285   }  // namespace detail
0286 
0287   //------------------------------------------------------------
0288 
0289   // The following function objects are used by Event::put, under the
0290   // control of a metafunction if, to either call the given object's
0291   // post_insert function (if it has one), or to do nothing (if it
0292   // does not have a post_insert function).
0293   template <typename T>
0294   struct DoPostInsert {
0295     void operator()(T* p) const { p->post_insert(); }
0296   };
0297 
0298   template <typename T>
0299   struct DoNotPostInsert {
0300     void operator()(T*) const {}
0301   };
0302 
0303   // Implementation of  PrincipalGetAdapter  member templates. See  PrincipalGetAdapter.cc for the
0304   // implementation of non-template members.
0305   //
0306 
0307   template <typename PROD>
0308   inline bool PrincipalGetAdapter::checkIfComplete() const {
0309     return isComplete() || !detail::has_mergeProduct_function<PROD>::value;
0310   }
0311 
0312 }  // namespace edm
0313 #endif