File indexing completed on 2022-08-30 04:05:52
0001 #ifndef FWCore_Framework_ESProducer_h
0002 #define FWCore_Framework_ESProducer_h
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072 #include <memory>
0073 #include <string>
0074 #include <optional>
0075
0076
0077 #include "FWCore/Framework/interface/ESConsumesCollector.h"
0078 #include "FWCore/Framework/interface/es_impl/MayConsumeChooserBase.h"
0079 #include "FWCore/Framework/interface/es_impl/ReturnArgumentTypes.h"
0080 #include "FWCore/Framework/interface/ESProxyFactoryProducer.h"
0081 #include "FWCore/Framework/interface/ProxyArgumentFactoryTemplate.h"
0082
0083 #include "FWCore/Framework/interface/CallbackProxy.h"
0084 #include "FWCore/Framework/interface/Callback.h"
0085 #include "FWCore/Framework/interface/produce_helpers.h"
0086 #include "FWCore/Framework/interface/eventsetup_dependsOn.h"
0087 #include "FWCore/Framework/interface/es_Label.h"
0088
0089 #include "FWCore/Framework/interface/SharedResourcesAcquirer.h"
0090
0091
0092 namespace edm {
0093 namespace eventsetup {
0094 class ESRecordsToProxyIndices;
0095
0096
0097
0098 template <typename T, typename TRecord, typename TDecorator>
0099 inline const TDecorator& createDecoratorFrom(T*, const TRecord*, const TDecorator& iDec) {
0100 return iDec;
0101 }
0102 }
0103
0104 class ESProducer : public ESProxyFactoryProducer {
0105 public:
0106 ESProducer();
0107 ~ESProducer() noexcept(false) override;
0108 ESProducer(const ESProducer&) = delete;
0109 ESProducer const& operator=(const ESProducer&) = delete;
0110
0111 void updateLookup(eventsetup::ESRecordsToProxyIndices const&) final;
0112 ESProxyIndex const* getTokenIndices(unsigned int iIndex) const {
0113 if (itemsToGetFromRecords_.empty()) {
0114 return nullptr;
0115 }
0116 return (itemsToGetFromRecords_[iIndex].empty()) ? static_cast<ESProxyIndex const*>(nullptr)
0117 : &(itemsToGetFromRecords_[iIndex].front());
0118 }
0119 ESRecordIndex const* getTokenRecordIndices(unsigned int iIndex) const {
0120 if (recordsUsedDuringGet_.empty()) {
0121 return nullptr;
0122 }
0123 return (recordsUsedDuringGet_[iIndex].empty()) ? static_cast<ESRecordIndex const*>(nullptr)
0124 : &(recordsUsedDuringGet_[iIndex].front());
0125 }
0126 size_t numberOfTokenIndices(unsigned int iIndex) const {
0127 if (itemsToGetFromRecords_.empty()) {
0128 return 0;
0129 }
0130 return itemsToGetFromRecords_[iIndex].size();
0131 }
0132
0133 bool hasMayConsumes() const noexcept { return hasMayConsumes_; }
0134
0135 template <typename Record>
0136 std::optional<std::vector<ESProxyIndex>> updateFromMayConsumes(unsigned int iIndex, const Record& iRecord) const {
0137 if (not hasMayConsumes()) {
0138 return {};
0139 }
0140 std::vector<ESProxyIndex> ret = itemsToGetFromRecords_[iIndex];
0141 auto const info = consumesInfos_[iIndex].get();
0142 for (size_t i = 0; i < info->size(); ++i) {
0143 auto chooserBase = (*info)[i].chooser_.get();
0144 if (chooserBase) {
0145 auto chooser = static_cast<eventsetup::impl::MayConsumeChooserBase<Record>*>(chooserBase);
0146 ret[i] = chooser->makeChoice(iRecord);
0147 }
0148 }
0149 return ret;
0150 }
0151
0152 SerialTaskQueueChain& queue() { return acquirer_.serialQueueChain(); }
0153
0154 protected:
0155
0156 void usesResources(std::vector<std::string> const&);
0157
0158
0159
0160
0161
0162 template <typename T>
0163 auto setWhatProduced(T* iThis, const es::Label& iLabel = {}) {
0164 return setWhatProduced(iThis, &T::produce, iLabel);
0165 }
0166
0167 template <typename T>
0168 auto setWhatProduced(T* iThis, const char* iLabel) {
0169 return setWhatProduced(iThis, es::Label(iLabel));
0170 }
0171 template <typename T>
0172 auto setWhatProduced(T* iThis, const std::string& iLabel) {
0173 return setWhatProduced(iThis, es::Label(iLabel));
0174 }
0175
0176 template <typename T, typename TDecorator>
0177 auto setWhatProduced(T* iThis, const TDecorator& iDec, const es::Label& iLabel = {}) {
0178 return setWhatProduced(iThis, &T::produce, iDec, iLabel);
0179 }
0180
0181
0182
0183
0184
0185 template <typename T, typename TReturn, typename TRecord>
0186 auto setWhatProduced(T* iThis, TReturn (T ::*iMethod)(const TRecord&), const es::Label& iLabel = {}) {
0187 return setWhatProduced(iThis, iMethod, eventsetup::CallbackSimpleDecorator<TRecord>(), iLabel);
0188 }
0189
0190
0191
0192
0193
0194
0195 template <typename T, typename TReturn, typename TRecord, typename TArg>
0196 auto setWhatProduced(T* iThis,
0197 TReturn (T ::*iMethod)(const TRecord&),
0198 const TArg& iDec,
0199 const es::Label& iLabel = {}) {
0200 return setWhatProduced<TReturn, TRecord>(
0201 [iThis, iMethod](TRecord const& iRecord) { return (iThis->*iMethod)(iRecord); },
0202 createDecoratorFrom(iThis, static_cast<const TRecord*>(nullptr), iDec),
0203 iLabel);
0204 }
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219 template <typename TFunc>
0220 auto setWhatProduced(TFunc&& func, const es::Label& iLabel = {}) {
0221 using Types = eventsetup::impl::ReturnArgumentTypes<TFunc>;
0222 using TReturn = typename Types::return_type;
0223 using TRecord = typename Types::argument_type;
0224 using DecoratorType = eventsetup::CallbackSimpleDecorator<TRecord>;
0225 return setWhatProduced<TReturn, TRecord>(std::forward<TFunc>(func), DecoratorType(), iLabel);
0226 }
0227
0228 template <typename TReturn, typename TRecord, typename TFunc, typename TDecorator>
0229 ESConsumesCollectorT<TRecord> setWhatProduced(TFunc&& func, TDecorator&& iDec, const es::Label& iLabel = {}) {
0230 const auto id = consumesInfos_.size();
0231 using DecoratorType = std::decay_t<TDecorator>;
0232 using CallbackType = eventsetup::Callback<ESProducer, TFunc, TReturn, TRecord, DecoratorType>;
0233 unsigned int iovIndex = 0;
0234 auto temp = std::make_shared<CallbackType>(this, std::forward<TFunc>(func), id, std::forward<TDecorator>(iDec));
0235 auto callback =
0236 std::make_shared<std::pair<unsigned int, std::shared_ptr<CallbackType>>>(iovIndex, std::move(temp));
0237 registerProducts(std::move(callback),
0238 static_cast<const typename eventsetup::produce::product_traits<TReturn>::type*>(nullptr),
0239 static_cast<const TRecord*>(nullptr),
0240 iLabel);
0241 consumesInfos_.push_back(std::make_unique<ESConsumesInfo>());
0242 return ESConsumesCollectorT<TRecord>(consumesInfos_.back().get(), id);
0243 }
0244
0245 private:
0246 template <typename CallbackT, typename TList, typename TRecord>
0247 void registerProducts(std::shared_ptr<std::pair<unsigned int, std::shared_ptr<CallbackT>>> iCallback,
0248 const TList*,
0249 const TRecord* iRecord,
0250 const es::Label& iLabel) {
0251 registerProduct(iCallback, static_cast<const typename TList::tail_type*>(nullptr), iRecord, iLabel);
0252 registerProducts(std::move(iCallback), static_cast<const typename TList::head_type*>(nullptr), iRecord, iLabel);
0253 }
0254
0255 template <typename CallbackT, typename TRecord>
0256 void registerProducts(std::shared_ptr<std::pair<unsigned int, std::shared_ptr<CallbackT>>>,
0257 const eventsetup::produce::Null*,
0258 const TRecord*,
0259 const es::Label&) {
0260
0261 }
0262
0263 template <typename CallbackT, typename TProduct, typename TRecord>
0264 void registerProduct(std::shared_ptr<std::pair<unsigned int, std::shared_ptr<CallbackT>>> iCallback,
0265 const TProduct*,
0266 const TRecord*,
0267 const es::Label& iLabel) {
0268 using ProxyType = eventsetup::CallbackProxy<CallbackT, TRecord, TProduct>;
0269 using FactoryType = eventsetup::ProxyArgumentFactoryTemplate<ProxyType, CallbackT>;
0270 registerFactory(std::make_unique<FactoryType>(std::move(iCallback)), iLabel.default_);
0271 }
0272
0273 template <typename CallbackT, typename TProduct, typename TRecord, int IIndex>
0274 void registerProduct(std::shared_ptr<std::pair<unsigned int, std::shared_ptr<CallbackT>>> iCallback,
0275 const es::L<TProduct, IIndex>*,
0276 const TRecord*,
0277 const es::Label& iLabel) {
0278 if (iLabel.labels_.size() <= IIndex || iLabel.labels_[IIndex] == es::Label::def()) {
0279 Exception::throwThis(errors::Configuration,
0280 "Unnamed Label\nthe index ",
0281 IIndex,
0282 " was never assigned a name in the 'setWhatProduced' method");
0283 }
0284 using ProxyType = eventsetup::CallbackProxy<CallbackT, TRecord, es::L<TProduct, IIndex>>;
0285 using FactoryType = eventsetup::ProxyArgumentFactoryTemplate<ProxyType, CallbackT>;
0286 registerFactory(std::make_unique<FactoryType>(std::move(iCallback)), iLabel.labels_[IIndex]);
0287 }
0288
0289 std::vector<std::unique_ptr<ESConsumesInfo>> consumesInfos_;
0290 std::vector<std::vector<ESProxyIndex>> itemsToGetFromRecords_;
0291
0292
0293 std::vector<std::vector<ESRecordIndex>> recordsUsedDuringGet_;
0294
0295 SharedResourcesAcquirer acquirer_;
0296 std::unique_ptr<std::vector<std::string>> sharedResourceNames_;
0297 bool hasMayConsumes_ = false;
0298 };
0299 }
0300 #endif