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
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
0032
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
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
0110
0111
0112
0113
0114
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
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 }
0219
0220 #endif