Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:12:01

0001 #ifndef FWCore_Framework_ESConsumesCollector_h
0002 #define FWCore_Framework_ESConsumesCollector_h
0003 // -*- C++ -*-
0004 //
0005 // Package:     FWCore/Framework
0006 // Class  :     edm::ConsumesCollector
0007 //
0008 /**\class edm::ESConsumesCollector ESConsumesCollector.h "FWCore/Framework/interface/ESConsumesCollector.h"
0009 
0010  Description: Helper class to gather consumes information for the EventSetup.
0011 
0012  Usage: The constructor of an ESProducer module can get an instance of
0013         edm::ESConsumesCollector by calling consumesCollector()
0014         method. This instance can then be passed to helper classes in
0015         order to register the event-setup data the helper will request
0016         from an Event, LuminosityBlock or Run on behalf of the module.
0017 
0018  Caveat: The ESConsumesCollector should be used during the time that
0019          modules are being constructed. It should not be saved and
0020          used later. It will not work if it is used to call the
0021          consumes function during beginJob, beginRun, beginLuminosity
0022          block, event processing or at any later time. As of now, an
0023          ESConsumesCollector is provided for only ESProducer
0024          subclasses--i.e. those that call setWhatProduced(this, ...).
0025 */
0026 //
0027 // Original Author:  Kyle Knoepfel
0028 //         Created:  Fri, 02 Oct 2018 12:44:47 GMT
0029 //
0030 
0031 #include "FWCore/Framework/interface/EventSetupRecordKey.h"
0032 #include "FWCore/Framework/interface/DataKey.h"
0033 #include "FWCore/Framework/interface/es_impl/MayConsumeChooser.h"
0034 #include "FWCore/Utilities/interface/ESGetToken.h"
0035 #include "FWCore/Utilities/interface/ESInputTag.h"
0036 #include "FWCore/Utilities/interface/propagate_const.h"
0037 #include "FWCore/Utilities/interface/Transition.h"
0038 
0039 #include <vector>
0040 #include <memory>
0041 
0042 class testEventsetupRecord;
0043 
0044 namespace edm {
0045   class ESConsumesCollectorAdaptor;
0046   class ESConsumesCollectorWithTagAdaptor;
0047 
0048   struct ESConsumesInfoEntry {
0049     ESConsumesInfoEntry(edm::eventsetup::EventSetupRecordKey const& iRecord,
0050                         edm::eventsetup::DataKey const& iProduct,
0051                         std::string moduleLabel,
0052                         std::unique_ptr<edm::eventsetup::impl::MayConsumeChooserCore> chooser)
0053         : recordKey_{iRecord},
0054           productKey_{iProduct},
0055           moduleLabel_{std::move(moduleLabel)},
0056           chooser_{std::move(chooser)} {}
0057     edm::eventsetup::EventSetupRecordKey recordKey_;
0058     edm::eventsetup::DataKey productKey_;
0059     std::string moduleLabel_;
0060     std::unique_ptr<edm::eventsetup::impl::MayConsumeChooserCore> chooser_;
0061   };
0062   using ESConsumesInfo = std::vector<ESConsumesInfoEntry>;
0063 
0064   class ESConsumesCollector {
0065   public:
0066     ESConsumesCollector() = delete;
0067     ESConsumesCollector(ESConsumesCollector const&) = delete;
0068     ESConsumesCollector(ESConsumesCollector&&) = default;
0069     ESConsumesCollector& operator=(ESConsumesCollector const&) = delete;
0070     ESConsumesCollector& operator=(ESConsumesCollector&&) = default;
0071 
0072     // ---------- member functions ---------------------------
0073     template <typename Product, typename Record>
0074     auto consumesFrom(ESInputTag const& tag) {
0075       using namespace edm::eventsetup;
0076       ESTokenIndex index{static_cast<ESTokenIndex::Value_t>(m_consumer->size())};
0077       m_consumer->emplace_back(EventSetupRecordKey::makeKey<Record>(),
0078                                DataKey(DataKey::makeTypeTag<Product>(), tag.data().c_str()),
0079                                tag.module(),
0080                                nullptr);
0081       //even though m_consumer may expand, the address for
0082       // name().value() remains the same since it is 'moved'.
0083       return ESGetToken<Product, Record>{m_transitionID, index, m_consumer->back().productKey_.name().value()};
0084     }
0085 
0086     template <typename Product, typename Record>
0087     auto consumesFrom() {
0088       using namespace edm::eventsetup;
0089       ESTokenIndex index{static_cast<ESTokenIndex::Value_t>(m_consumer->size())};
0090       m_consumer->emplace_back(
0091           EventSetupRecordKey::makeKey<Record>(), DataKey(DataKey::makeTypeTag<Product>(), ""), "", nullptr);
0092       //even though m_consumer may expand, the address for
0093       // name().value() remains the same since it is 'moved'.
0094       return ESGetToken<Product, Record>{m_transitionID, index, m_consumer->back().productKey_.name().value()};
0095     }
0096 
0097     ESConsumesCollectorAdaptor consumes();
0098     ESConsumesCollectorWithTagAdaptor consumes(ESInputTag tag);
0099 
0100   protected:
0101     explicit ESConsumesCollector(ESConsumesInfo* const iConsumer, unsigned int iTransitionID)
0102         : m_consumer{iConsumer}, m_transitionID{iTransitionID} {}
0103 
0104     template <typename Product, typename Record, typename Collector, typename PTag>
0105     auto registerMayConsume(std::unique_ptr<Collector> iCollector, PTag const& productTag) {
0106       //NOTE: for now, just treat like standard consumes request for the product needed to
0107       // do the decision
0108       iCollector->token() = consumes(productTag.inputTag());
0109 
0110       using namespace edm::eventsetup;
0111       ESTokenIndex index{static_cast<ESTokenIndex::Value_t>(m_consumer->size())};
0112       m_consumer->emplace_back(EventSetupRecordKey::makeKey<Record>(),
0113                                DataKey(DataKey::makeTypeTag<Product>(), "@mayConsume"),
0114                                "@mayConsume",
0115                                std::move(iCollector));
0116       //even though m_consumer may expand, the address for
0117       // name().value() remains the same since it is 'moved'.
0118       return ESGetToken<Product, Record>{m_transitionID, index, m_consumer->back().productKey_.name().value()};
0119     }
0120 
0121   private:
0122     // ---------- member data --------------------------------
0123     edm::propagate_const<ESConsumesInfo*> m_consumer{nullptr};
0124     unsigned int m_transitionID{0};
0125   };
0126 
0127   template <typename RECORD>
0128   class ESConsumesCollectorT : public ESConsumesCollector {
0129   public:
0130     ESConsumesCollectorT() = delete;
0131     ESConsumesCollectorT(ESConsumesCollectorT<RECORD> const&) = default;
0132     ESConsumesCollectorT(ESConsumesCollectorT<RECORD>&&) = default;
0133     ESConsumesCollectorT<RECORD>& operator=(ESConsumesCollectorT<RECORD> const&) = default;
0134     ESConsumesCollectorT<RECORD>& operator=(ESConsumesCollectorT<RECORD>&&) = default;
0135 
0136     // ---------- member functions ---------------------------
0137 
0138     using ESConsumesCollector::consumes;
0139     template <typename Product>
0140     auto consumes(ESInputTag const& tag) {
0141       return consumesFrom<Product, RECORD>(tag);
0142     }
0143 
0144     template <typename Product>
0145     auto consumes() {
0146       return consumesFrom<Product, RECORD>();
0147     }
0148 
0149     template <typename Product, typename FromRecord, typename Func, typename PTag>
0150     auto mayConsumeFrom(Func&& func, PTag const& productTag) {
0151       return registerMayConsume<Product, FromRecord>(
0152           std::make_unique<eventsetup::impl::MayConsumeChooser<RECORD, Product, FromRecord, Func, PTag>>(
0153               std::forward<Func>(func)),
0154           productTag);
0155     }
0156 
0157     template <typename Product, typename FromRecord, typename Func, typename PTag>
0158     ESConsumesCollector& setMayConsume(ESGetToken<Product, FromRecord>& token, Func&& func, PTag const& productTag) {
0159       token = mayConsumeFrom<Product, FromRecord>(std::forward<Func>(func), productTag);
0160       return *this;
0161     }
0162 
0163   private:
0164     //only ESProducer is allowed to make an instance of this class
0165     friend class ESProducer;
0166     friend class ESProducerExternalWork;
0167     friend class ::testEventsetupRecord;
0168 
0169     explicit ESConsumesCollectorT(ESConsumesInfo* const iConsumer, unsigned int iTransitionID)
0170         : ESConsumesCollector(iConsumer, iTransitionID) {}
0171   };
0172 
0173   class ESConsumesCollectorAdaptor {
0174   public:
0175     template <typename TYPE, typename REC>
0176     ESGetToken<TYPE, REC> consumes() {
0177       return m_consumer->template consumesFrom<TYPE, REC>();
0178     }
0179 
0180   private:
0181     //only ESConsumesCollector is allowed to make an instance of this class
0182     friend class ESConsumesCollector;
0183     explicit ESConsumesCollectorAdaptor(ESConsumesCollector* iBase) : m_consumer(iBase) {}
0184 
0185     ESConsumesCollector* m_consumer;
0186   };
0187 
0188   class ESConsumesCollectorWithTagAdaptor {
0189   public:
0190     template <typename TYPE, typename REC>
0191     ESGetToken<TYPE, REC> consumes() {
0192       return m_consumer->template consumesFrom<TYPE, REC>(m_tag);
0193     }
0194 
0195   private:
0196     //only ESConsumesCollector is allowed to make an instance of this class
0197     friend class ESConsumesCollector;
0198     ESConsumesCollectorWithTagAdaptor(ESConsumesCollector* iBase, ESInputTag iTag)
0199         : m_consumer(iBase), m_tag(std::move(iTag)) {}
0200 
0201     ESConsumesCollector* m_consumer;
0202     ESInputTag const m_tag;
0203   };
0204 
0205   inline ESConsumesCollectorAdaptor ESConsumesCollector::consumes() { return ESConsumesCollectorAdaptor(this); }
0206   inline ESConsumesCollectorWithTagAdaptor ESConsumesCollector::consumes(ESInputTag tag) {
0207     return ESConsumesCollectorWithTagAdaptor(this, std::move(tag));
0208   }
0209 
0210 }  // namespace edm
0211 
0212 #endif