Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #ifndef FWCore_Framework_EventSetup_h
0002 #define FWCore_Framework_EventSetup_h
0003 // -*- C++ -*-
0004 //
0005 // Package:     Framework
0006 // Class:      EventSetup
0007 //
0008 /**\class edm::EventSetup
0009 
0010  Description: Container for all Records dealing with non-RunState info
0011 
0012  Usage:
0013     <usage>
0014 
0015 */
0016 //
0017 // Author:      Chris Jones
0018 // Created:     Thu Mar 24 13:50:04 EST 2005
0019 //
0020 
0021 // system include files
0022 #include <cassert>
0023 #include <map>
0024 #include <optional>
0025 #include <type_traits>
0026 #include <vector>
0027 
0028 // user include files
0029 #include "FWCore/Framework/interface/ESHandle.h"
0030 #include "FWCore/Framework/interface/ESTransientHandle.h"
0031 #include "FWCore/Framework/interface/EventSetupRecordKey.h"
0032 #include "FWCore/Framework/interface/EventSetupRecord.h"
0033 #include "FWCore/Framework/interface/EventSetupImpl.h"
0034 #include "FWCore/Framework/interface/HCMethods.h"
0035 #include "FWCore/Framework/interface/NoRecordException.h"
0036 #include "FWCore/Framework/interface/IOVSyncValue.h"
0037 #include "FWCore/Framework/interface/data_default_record_trait.h"
0038 #include "FWCore/Utilities/interface/Transition.h"
0039 #include "FWCore/Utilities/interface/ESIndices.h"
0040 
0041 // forward declarations
0042 
0043 namespace edm {
0044 
0045   template <class T, class R>
0046   class ESGetToken;
0047   class PileUp;
0048   class ESParentContext;
0049 
0050   namespace eventsetup {
0051     class EventSetupProvider;
0052     class EventSetupRecord;
0053     class EventSetupRecordImpl;
0054   }  // namespace eventsetup
0055 
0056   class EventSetup {
0057     ///Needed until a better solution can be found
0058     friend class edm::PileUp;
0059 
0060   public:
0061     template <typename T>
0062     explicit EventSetup(T const& info,
0063                         unsigned int iTransitionID,
0064                         ESResolverIndex const* iGetTokenIndices,
0065                         ESParentContext const& iContext)
0066         : EventSetup(info.eventSetupImpl(), iTransitionID, iGetTokenIndices, iContext) {}
0067 
0068     explicit EventSetup(EventSetupImpl const& iSetup,
0069                         unsigned int iTransitionID,
0070                         ESResolverIndex const* iGetTokenIndices,
0071                         ESParentContext const& iContext)
0072         : m_setup{iSetup}, m_getTokenIndices{iGetTokenIndices}, m_context(&iContext), m_id{iTransitionID} {}
0073     EventSetup(EventSetup const&) = delete;
0074     EventSetup& operator=(EventSetup const&) = delete;
0075 
0076     /** returns the Record of type T.  If no such record available
0077           a eventsetup::NoRecordException<T> is thrown */
0078     template <typename T>
0079     T get() const {
0080       using namespace eventsetup;
0081       using namespace eventsetup::heterocontainer;
0082       //NOTE: this will catch the case where T does not inherit from EventSetupRecord
0083       //  HOWEVER the error message under gcc 3.x is awful
0084       static_assert(std::is_base_of_v<edm::eventsetup::EventSetupRecord, T>,
0085                     "Trying to get a class that is not a Record from EventSetup");
0086 
0087       auto const temp = m_setup.findImpl(makeKey<typename type_from_itemtype<eventsetup::EventSetupRecordKey, T>::Type,
0088                                                  eventsetup::EventSetupRecordKey>());
0089       if (nullptr == temp) {
0090         throw eventsetup::NoRecordException<T>(recordDoesExist(m_setup, eventsetup::EventSetupRecordKey::makeKey<T>()));
0091       }
0092       T returnValue;
0093       returnValue.setImpl(temp, m_id, m_getTokenIndices, &m_setup, m_context);
0094       return returnValue;
0095     }
0096 
0097     /** returns the Record of type T.  If no such record available
0098        a null optional is returned */
0099     template <typename T>
0100     std::optional<T> tryToGet() const {
0101       using namespace eventsetup;
0102       using namespace eventsetup::heterocontainer;
0103 
0104       //NOTE: this will catch the case where T does not inherit from EventSetupRecord
0105       static_assert(std::is_base_of_v<edm::eventsetup::EventSetupRecord, T>,
0106                     "Trying to get a class that is not a Record from EventSetup");
0107       auto const temp = impl().findImpl(makeKey<typename type_from_itemtype<eventsetup::EventSetupRecordKey, T>::Type,
0108                                                 eventsetup::EventSetupRecordKey>());
0109       if (temp != nullptr) {
0110         T rec;
0111         rec.setImpl(temp, m_id, m_getTokenIndices, &m_setup, m_context);
0112         return rec;
0113       }
0114       return std::nullopt;
0115     }
0116 
0117     /** can directly access data if data_default_record_trait<> is defined for this data type **/
0118     template <typename T, typename R>
0119     T const& getData(const ESGetToken<T, R>& iToken) const noexcept(false) {
0120       return this
0121           ->get<std::conditional_t<std::is_same_v<R, edm::DefaultRecord>, eventsetup::default_record_t<ESHandle<T>>, R>>()
0122           .get(iToken);
0123     }
0124     template <typename T, typename R>
0125     T const& getData(ESGetToken<T, R>& iToken) const noexcept(false) {
0126       return this->getData(const_cast<const ESGetToken<T, R>&>(iToken));
0127     }
0128 
0129     template <typename T, typename R>
0130     ESHandle<T> getHandle(const ESGetToken<T, R>& iToken) const {
0131       if constexpr (std::is_same_v<R, edm::DefaultRecord>) {
0132         auto const& rec = this->get<eventsetup::default_record_t<ESHandle<T>>>();
0133         return rec.getHandle(iToken);
0134       } else {
0135         auto const& rec = this->get<R>();
0136         return rec.getHandle(iToken);
0137       }
0138     }
0139 
0140     template <typename T, typename R>
0141     ESTransientHandle<T> getTransientHandle(const ESGetToken<T, R>& iToken) const {
0142       if constexpr (std::is_same_v<R, edm::DefaultRecord>) {
0143         auto const& rec = this->get<eventsetup::default_record_t<ESTransientHandle<T>>>();
0144         return rec.getTransientHandle(iToken);
0145       } else {
0146         auto const& rec = this->get<R>();
0147         return rec.getTransientHandle(iToken);
0148       }
0149     }
0150 
0151     std::optional<eventsetup::EventSetupRecordGeneric> find(const eventsetup::EventSetupRecordKey& iKey) const {
0152       return m_setup.find(iKey, m_id, m_getTokenIndices, *m_context);
0153     }
0154 
0155     ///clears the oToFill vector and then fills it with the keys for all available records
0156     void fillAvailableRecordKeys(std::vector<eventsetup::EventSetupRecordKey>& oToFill) const {
0157       m_setup.fillAvailableRecordKeys(oToFill);
0158     }
0159     ///returns true if the Record is provided by a Source or a Producer
0160     /// a value of true does not mean this EventSetup object holds such a record
0161     bool recordIsProvidedByAModule(eventsetup::EventSetupRecordKey const& iKey) const {
0162       return m_setup.recordIsProvidedByAModule(iKey);
0163     }
0164     // ---------- static member functions --------------------
0165 
0166   private:
0167     edm::EventSetupImpl const& impl() const { return m_setup; }
0168 
0169     // ---------- member data --------------------------------
0170     edm::EventSetupImpl const& m_setup;
0171     ESResolverIndex const* m_getTokenIndices;
0172     ESParentContext const* m_context;
0173     unsigned int m_id;
0174   };
0175 }  // namespace edm
0176 
0177 #endif  // FWCore_Framework_EventSetup_h