Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #ifndef FWCore_Framework_ProductRegistryHelper_h
0002 #define FWCore_Framework_ProductRegistryHelper_h
0003 
0004 /*----------------------------------------------------------------------
0005 
0006 ProductRegistryHelper:
0007 
0008 ----------------------------------------------------------------------*/
0009 
0010 #include "FWCore/Utilities/interface/TypeID.h"
0011 #include "FWCore/Utilities/interface/Transition.h"
0012 #include "FWCore/Utilities/interface/EDPutToken.h"
0013 #include "DataFormats/Provenance/interface/BranchType.h"
0014 #include <string>
0015 #include <vector>
0016 #include <type_traits>
0017 
0018 namespace edm {
0019   class ModuleDescription;
0020   class ProductRegistry;
0021   struct DoNotRecordParents;
0022 
0023   template <Transition B>
0024   class ProductRegistryHelperAdaptor;
0025 
0026   class ProductRegistryHelper {
0027   public:
0028     virtual ~ProductRegistryHelper() noexcept(false);
0029     ProductRegistryHelper() : typeLabelList_() {}
0030 
0031     // has_donotrecordparents<T>::value is true if we should not
0032     // record parentage for type T, and false otherwise.
0033     template <typename T>
0034     struct has_donotrecordparents {
0035       static constexpr bool value = std::is_base_of<DoNotRecordParents, T>::value;
0036     };
0037 
0038     struct TypeLabelItem {
0039       enum class AliasType : char { kBranchAlias, kSwitchAlias };
0040 
0041       TypeLabelItem(Transition const& transition, TypeID const& tid, std::string pin)
0042           : transition_(transition),
0043             typeID_(tid),
0044             productInstanceName_(std::move(pin)),
0045             branchAlias_(),
0046             aliasType_(AliasType::kBranchAlias),
0047             isTransform_(false) {}
0048       Transition transition_;
0049       TypeID typeID_;
0050       std::string productInstanceName_;
0051       std::string branchAlias_;
0052       AliasType aliasType_;
0053       bool isTransform_;
0054     };
0055 
0056     struct BranchAliasSetter {
0057       BranchAliasSetter(TypeLabelItem& iItem, EDPutToken iToken) : value_(iItem), token_(iToken) {}
0058 
0059       BranchAliasSetter& setBranchAlias(std::string alias) {
0060         value_.branchAlias_ = std::move(alias);
0061         return *this;
0062       }
0063       BranchAliasSetter& setSwitchAlias(std::string moduleLabel) {
0064         value_.branchAlias_ = std::move(moduleLabel);
0065         value_.aliasType_ = TypeLabelItem::AliasType::kSwitchAlias;
0066         return *this;
0067       }
0068       TypeLabelItem& value_;
0069       EDPutToken token_;
0070 
0071       operator EDPutToken() { return token_; }
0072     };
0073 
0074     template <typename T>
0075     struct BranchAliasSetterT {
0076       BranchAliasSetterT(TypeLabelItem& iItem, EDPutTokenT<T> iToken) : value_(iItem), token_(std::move(iToken)) {}
0077 
0078       BranchAliasSetterT(BranchAliasSetter&& iS) : value_(iS.value_), token_(iS.token_.index()) {}
0079 
0080       BranchAliasSetterT<T>& setBranchAlias(std::string alias) {
0081         value_.branchAlias_ = std::move(alias);
0082         return *this;
0083       }
0084       TypeLabelItem& value_;
0085       EDPutTokenT<T> token_;
0086 
0087       template <typename U>
0088       EDPutTokenT<T> produces() {
0089         static_assert(std::is_same_v<T, U>);
0090         return token_;
0091       }
0092 
0093       operator EDPutTokenT<T>() { return token_; }
0094       operator EDPutToken() { return EDPutToken(token_.index()); }
0095     };
0096 
0097     typedef std::vector<TypeLabelItem> TypeLabelList;
0098 
0099     /// used by the fwk to register the list of products of this module
0100     TypeLabelList const& typeLabelList() const;
0101 
0102     std::vector<bool> const& recordProvenanceList() const { return recordProvenanceList_; }
0103 
0104     static void addToRegistry(TypeLabelList::const_iterator const& iBegin,
0105                               TypeLabelList::const_iterator const& iEnd,
0106                               ModuleDescription const& iDesc,
0107                               ProductRegistry& iReg,
0108                               ProductRegistryHelper* iProd,
0109                               bool iIsListener = false);
0110 
0111     /// declare what type of product will make and with which optional label
0112     /** the statement
0113         \code
0114            produces<ProductType>("optlabel");
0115         \endcode
0116         should be added to the producer ctor for every product */
0117 
0118     template <Transition Tr = Transition::Event>
0119     [[nodiscard]] auto produces(std::string instanceName) noexcept {
0120       return ProductRegistryHelperAdaptor<Tr>(*this, std::move(instanceName));
0121     }
0122     template <Transition Tr = Transition::Event>
0123     [[nodiscard]] auto produces() noexcept {
0124       return ProductRegistryHelperAdaptor<Tr>(*this);
0125     }
0126 
0127     template <class ProductType>
0128     BranchAliasSetterT<ProductType> produces() {
0129       return produces<ProductType, InEvent>(std::string());
0130     }
0131 
0132     template <class ProductType>
0133     BranchAliasSetterT<ProductType> produces(std::string instanceName) {
0134       return produces<ProductType, InEvent>(std::move(instanceName));
0135     }
0136 
0137     template <typename ProductType, BranchType B>
0138     BranchAliasSetterT<ProductType> produces() {
0139       return produces<ProductType, B>(std::string());
0140     }
0141 
0142     template <typename ProductType, BranchType B>
0143     BranchAliasSetterT<ProductType> produces(std::string instanceName) {
0144       TypeID tid(typeid(ProductType));
0145       return BranchAliasSetterT<ProductType>{
0146           produces<B>(tid, std::move(instanceName), (not has_donotrecordparents<ProductType>::value) and B == InEvent)};
0147     }
0148 
0149     template <typename ProductType, Transition B>
0150     BranchAliasSetterT<ProductType> produces() {
0151       return produces<ProductType, B>(std::string());
0152     }
0153 
0154     template <typename ProductType, Transition B>
0155     BranchAliasSetterT<ProductType> produces(std::string instanceName) {
0156       TypeID tid(typeid(ProductType));
0157       return BranchAliasSetterT<ProductType>{produces<B>(
0158           tid, std::move(instanceName), (not has_donotrecordparents<ProductType>::value) and B == Transition::Event)};
0159     }
0160 
0161     BranchAliasSetter produces(const TypeID& id,
0162                                std::string instanceName = std::string(),
0163                                bool recordProvenance = true) {
0164       return produces<Transition::Event>(id, std::move(instanceName), recordProvenance);
0165     }
0166 
0167     template <BranchType B>
0168     BranchAliasSetter produces(const TypeID& id,
0169                                std::string instanceName = std::string(),
0170                                bool recordProvenance = true) {
0171       unsigned int index = typeLabelList_.size();
0172       typeLabelList_.emplace_back(convertToTransition(B), id, std::move(instanceName));
0173       recordProvenanceList_.push_back(recordProvenance and B == InEvent);
0174       return BranchAliasSetter{typeLabelList_.back(), EDPutToken{static_cast<unsigned int>(index)}};
0175     }
0176     template <Transition B>
0177     BranchAliasSetter produces(const TypeID& id,
0178                                std::string instanceName = std::string(),
0179                                bool recordProvenance = true) {
0180       unsigned int index = typeLabelList_.size();
0181       typeLabelList_.emplace_back(B, id, std::move(instanceName));
0182       recordProvenanceList_.push_back(recordProvenance and B == Transition::Event);
0183       return BranchAliasSetter{typeLabelList_.back(), EDPutToken{index}};
0184     }
0185 
0186     EDPutToken transforms(const TypeID& id, std::string instanceName) {
0187       unsigned int index = typeLabelList_.size();
0188       typeLabelList_.emplace_back(Transition::Event, id, std::move(instanceName));
0189       typeLabelList_.back().isTransform_ = true;
0190       recordProvenanceList_.push_back(true);
0191       return EDPutToken{index};
0192     }
0193 
0194     virtual bool hasAbilityToProduceInBeginProcessBlocks() const { return false; }
0195     virtual bool hasAbilityToProduceInEndProcessBlocks() const { return false; }
0196 
0197     virtual bool hasAbilityToProduceInBeginRuns() const { return false; }
0198     virtual bool hasAbilityToProduceInEndRuns() const { return false; }
0199 
0200     virtual bool hasAbilityToProduceInBeginLumis() const { return false; }
0201     virtual bool hasAbilityToProduceInEndLumis() const { return false; }
0202 
0203   private:
0204     TypeLabelList typeLabelList_;
0205     std::vector<bool> recordProvenanceList_;
0206   };
0207 
0208   template <Transition B>
0209   class ProductRegistryHelperAdaptor {
0210   public:
0211     template <typename TYPE>
0212     EDPutTokenT<TYPE> produces() {
0213       return m_helper.template produces<TYPE, B>(m_label);
0214     }
0215 
0216   private:
0217     //only ProductRegistryHelper is allowed to make an instance of this class
0218     friend class ProductRegistryHelper;
0219 
0220     ProductRegistryHelperAdaptor(ProductRegistryHelper& iBase, std::string iLabel)
0221         : m_helper(iBase), m_label(std::move(iLabel)) {}
0222     explicit ProductRegistryHelperAdaptor(ProductRegistryHelper& iBase) : m_helper(iBase), m_label() {}
0223 
0224     ProductRegistryHelper& m_helper;
0225     std::string const m_label;
0226   };
0227 
0228 }  // namespace edm
0229 
0230 #endif