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
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 : 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
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
0112
0113
0114
0115
0116
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
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 }
0229
0230 #endif