Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-08-23 03:25:06

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 { 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       Transition transition_;
0048       TypeID typeID_;
0049       std::string productInstanceName_;
0050       std::string branchAlias_;
0051       AliasType aliasType_;
0052     };
0053 
0054     struct BranchAliasSetter {
0055       BranchAliasSetter(TypeLabelItem& iItem, EDPutToken iToken) : value_(iItem), token_(iToken) {}
0056 
0057       BranchAliasSetter& setBranchAlias(std::string alias) {
0058         value_.branchAlias_ = std::move(alias);
0059         return *this;
0060       }
0061       BranchAliasSetter& setSwitchAlias(std::string moduleLabel) {
0062         value_.branchAlias_ = std::move(moduleLabel);
0063         value_.aliasType_ = TypeLabelItem::AliasType::kSwitchAlias;
0064         return *this;
0065       }
0066       TypeLabelItem& value_;
0067       EDPutToken token_;
0068 
0069       operator EDPutToken() { return token_; }
0070     };
0071 
0072     template <typename T>
0073     struct BranchAliasSetterT {
0074       BranchAliasSetterT(TypeLabelItem& iItem, EDPutTokenT<T> iToken) : value_(iItem), token_(std::move(iToken)) {}
0075 
0076       BranchAliasSetterT(BranchAliasSetter&& iS) : value_(iS.value_), token_(iS.token_.index()) {}
0077 
0078       BranchAliasSetterT<T>& setBranchAlias(std::string alias) {
0079         value_.branchAlias_ = std::move(alias);
0080         return *this;
0081       }
0082       TypeLabelItem& value_;
0083       EDPutTokenT<T> token_;
0084 
0085       template <typename U>
0086       EDPutTokenT<T> produces() {
0087         static_assert(std::is_same_v<T, U>);
0088         return token_;
0089       }
0090 
0091       operator EDPutTokenT<T>() { return token_; }
0092       operator EDPutToken() { return EDPutToken(token_.index()); }
0093     };
0094 
0095     typedef std::vector<TypeLabelItem> TypeLabelList;
0096 
0097     /// used by the fwk to register the list of products of this module
0098     TypeLabelList const& typeLabelList() const;
0099 
0100     std::vector<bool> const& recordProvenanceList() const { return recordProvenanceList_; }
0101 
0102     static void addToRegistry(TypeLabelList::const_iterator const& iBegin,
0103                               TypeLabelList::const_iterator const& iEnd,
0104                               ModuleDescription const& iDesc,
0105                               ProductRegistry& iReg,
0106                               ProductRegistryHelper* iProd,
0107                               bool iIsListener = false);
0108 
0109     /// declare what type of product will make and with which optional label
0110     /** the statement
0111         \code
0112            produces<ProductType>("optlabel");
0113         \endcode
0114         should be added to the producer ctor for every product */
0115 
0116     template <Transition Tr = Transition::Event>
0117     [[nodiscard]] auto produces(std::string instanceName) noexcept {
0118       return ProductRegistryHelperAdaptor<Tr>(*this, std::move(instanceName));
0119     }
0120     template <Transition Tr = Transition::Event>
0121     [[nodiscard]] auto produces() noexcept {
0122       return ProductRegistryHelperAdaptor<Tr>(*this);
0123     }
0124 
0125     template <class ProductType>
0126     BranchAliasSetterT<ProductType> produces() {
0127       return produces<ProductType, InEvent>(std::string());
0128     }
0129 
0130     template <class ProductType>
0131     BranchAliasSetterT<ProductType> produces(std::string instanceName) {
0132       return produces<ProductType, InEvent>(std::move(instanceName));
0133     }
0134 
0135     template <typename ProductType, BranchType B>
0136     BranchAliasSetterT<ProductType> produces() {
0137       return produces<ProductType, B>(std::string());
0138     }
0139 
0140     template <typename ProductType, BranchType B>
0141     BranchAliasSetterT<ProductType> produces(std::string instanceName) {
0142       TypeID tid(typeid(ProductType));
0143       return BranchAliasSetterT<ProductType>{
0144           produces<B>(tid, std::move(instanceName), (not has_donotrecordparents<ProductType>::value) and B == InEvent)};
0145     }
0146 
0147     template <typename ProductType, Transition B>
0148     BranchAliasSetterT<ProductType> produces() {
0149       return produces<ProductType, B>(std::string());
0150     }
0151 
0152     template <typename ProductType, Transition B>
0153     BranchAliasSetterT<ProductType> produces(std::string instanceName) {
0154       TypeID tid(typeid(ProductType));
0155       return BranchAliasSetterT<ProductType>{produces<B>(
0156           tid, std::move(instanceName), (not has_donotrecordparents<ProductType>::value) and B == Transition::Event)};
0157     }
0158 
0159     BranchAliasSetter produces(const TypeID& id,
0160                                std::string instanceName = std::string(),
0161                                bool recordProvenance = true) {
0162       return produces<Transition::Event>(id, std::move(instanceName), recordProvenance);
0163     }
0164 
0165     template <BranchType B>
0166     BranchAliasSetter produces(const TypeID& id,
0167                                std::string instanceName = std::string(),
0168                                bool recordProvenance = true) {
0169       unsigned int index = typeLabelList_.size();
0170       typeLabelList_.emplace_back(convertToTransition(B), id, std::move(instanceName));
0171       recordProvenanceList_.push_back(recordProvenance and B == InEvent);
0172       return BranchAliasSetter{typeLabelList_.back(), EDPutToken{static_cast<unsigned int>(index)}};
0173     }
0174     template <Transition B>
0175     BranchAliasSetter produces(const TypeID& id,
0176                                std::string instanceName = std::string(),
0177                                bool recordProvenance = true) {
0178       unsigned int index = typeLabelList_.size();
0179       typeLabelList_.emplace_back(B, id, std::move(instanceName));
0180       recordProvenanceList_.push_back(recordProvenance and B == Transition::Event);
0181       return BranchAliasSetter{typeLabelList_.back(), EDPutToken{index}};
0182     }
0183 
0184     virtual bool hasAbilityToProduceInBeginProcessBlocks() const { return false; }
0185     virtual bool hasAbilityToProduceInEndProcessBlocks() const { return false; }
0186 
0187     virtual bool hasAbilityToProduceInBeginRuns() const { return false; }
0188     virtual bool hasAbilityToProduceInEndRuns() const { return false; }
0189 
0190     virtual bool hasAbilityToProduceInBeginLumis() const { return false; }
0191     virtual bool hasAbilityToProduceInEndLumis() const { return false; }
0192 
0193   private:
0194     TypeLabelList typeLabelList_;
0195     std::vector<bool> recordProvenanceList_;
0196   };
0197 
0198   template <Transition B>
0199   class ProductRegistryHelperAdaptor {
0200   public:
0201     template <typename TYPE>
0202     EDPutTokenT<TYPE> produces() {
0203       return m_helper.template produces<TYPE, B>(m_label);
0204     }
0205 
0206   private:
0207     //only ProductRegistryHelper is allowed to make an instance of this class
0208     friend class ProductRegistryHelper;
0209 
0210     ProductRegistryHelperAdaptor(ProductRegistryHelper& iBase, std::string iLabel)
0211         : m_helper(iBase), m_label(std::move(iLabel)) {}
0212     explicit ProductRegistryHelperAdaptor(ProductRegistryHelper& iBase) : m_helper(iBase), m_label() {}
0213 
0214     ProductRegistryHelper& m_helper;
0215     std::string const m_label;
0216   };
0217 
0218 }  // namespace edm
0219 
0220 #endif