Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-05-11 03:34:10

0001 #ifndef FWCore_Framework_limited_implementors_h
0002 #define FWCore_Framework_limited_implementors_h
0003 // -*- C++ -*-
0004 //
0005 // Package:     FWCore/Framework
0006 // Class  :     implementors
0007 //
0008 /**\file implementors.h "FWCore/Framework/interface/limited/implementors.h"
0009 
0010  Description: Base classes used to implement the interfaces for the edm::limited::* module  abilities
0011 
0012  Usage:
0013     <usage>
0014 
0015 */
0016 //
0017 // Original Author:  Chris Jones
0018 //         Created:  Thu, 18 Jul 2013 11:52:34 GMT
0019 //
0020 
0021 // system include files
0022 #include <memory>
0023 #include <mutex>
0024 #include <string>
0025 #include <tuple>
0026 #include <utility>
0027 #include <vector>
0028 
0029 // user include files
0030 #include "FWCore/Common/interface/FWCoreCommonFwd.h"
0031 #include "FWCore/Concurrency/interface/WaitingTaskHolder.h"
0032 #include "FWCore/Concurrency/interface/WaitingTaskWithArenaHolder.h"
0033 #include "FWCore/Framework/interface/CacheHandle.h"
0034 #include "FWCore/Framework/interface/Frameworkfwd.h"
0035 #include "FWCore/Framework/interface/InputProcessBlockCacheImpl.h"
0036 #include "FWCore/Framework/interface/LuminosityBlock.h"
0037 #include "FWCore/Framework/interface/TransformerBase.h"
0038 #include "FWCore/Framework/interface/ProductRegistryHelper.h"
0039 #include "FWCore/Utilities/interface/EDGetToken.h"
0040 #include "FWCore/Utilities/interface/StreamID.h"
0041 #include "FWCore/Utilities/interface/ProcessBlockIndex.h"
0042 #include "FWCore/Utilities/interface/RunIndex.h"
0043 #include "FWCore/Utilities/interface/LuminosityBlockIndex.h"
0044 #include "FWCore/Utilities/interface/propagate_const.h"
0045 #include "DataFormats/Common/interface/Wrapper.h"
0046 
0047 // forward declarations
0048 namespace edm {
0049   class ServiceWeakToken;
0050   class ActivityRegistry;
0051 
0052   namespace limited {
0053     namespace impl {
0054       class EmptyType {
0055       public:
0056         EmptyType(edm::ParameterSet const&) {}
0057       };
0058 
0059       template <typename T, typename C>
0060       class StreamCacheHolder : public virtual T {
0061       public:
0062         StreamCacheHolder(edm::ParameterSet const& iPSet) : T(iPSet) {}
0063         StreamCacheHolder(StreamCacheHolder<T, C> const&) = delete;
0064         StreamCacheHolder<T, C>& operator=(StreamCacheHolder<T, C> const&) = delete;
0065         ~StreamCacheHolder() override {
0066           for (auto c : caches_) {
0067             delete c;
0068           }
0069         }
0070 
0071       protected:
0072         C* streamCache(edm::StreamID iID) const { return caches_[iID.value()]; }
0073 
0074       private:
0075         void preallocStreams(unsigned int iNStreams) final { caches_.resize(iNStreams, static_cast<C*>(nullptr)); }
0076         void doBeginStream_(StreamID id) final { caches_[id.value()] = beginStream(id).release(); }
0077         void doEndStream_(StreamID id) final {
0078           endStream(id);
0079           delete caches_[id.value()];
0080           caches_[id.value()] = nullptr;
0081         }
0082         void doStreamBeginRun_(StreamID id, Run const& rp, EventSetup const& c) final { streamBeginRun(id, rp, c); }
0083         void doStreamEndRun_(StreamID id, Run const& rp, EventSetup const& c) final { streamEndRun(id, rp, c); }
0084         void doStreamBeginLuminosityBlock_(StreamID id, LuminosityBlock const& lbp, EventSetup const& c) final {
0085           streamBeginLuminosityBlock(id, lbp, c);
0086         }
0087         void doStreamEndLuminosityBlock_(StreamID id, LuminosityBlock const& lbp, EventSetup const& c) final {
0088           streamEndLuminosityBlock(id, lbp, c);
0089         }
0090 
0091         virtual std::unique_ptr<C> beginStream(edm::StreamID) const = 0;
0092         virtual void streamBeginRun(edm::StreamID, edm::Run const&, edm::EventSetup const&) const {}
0093         virtual void streamBeginLuminosityBlock(edm::StreamID,
0094                                                 edm::LuminosityBlock const&,
0095                                                 edm::EventSetup const&) const {}
0096         virtual void streamEndLuminosityBlock(edm::StreamID,
0097                                               edm::LuminosityBlock const&,
0098                                               edm::EventSetup const&) const {}
0099         virtual void streamEndRun(edm::StreamID, edm::Run const&, edm::EventSetup const&) const {}
0100         virtual void endStream(edm::StreamID) const {}
0101 
0102         //When threaded we will have a container for N items whre N is # of streams
0103         std::vector<C*> caches_;
0104       };
0105 
0106       template <typename T, typename... CacheTypes>
0107       class InputProcessBlockCacheHolder : public virtual T {
0108       public:
0109         InputProcessBlockCacheHolder(edm::ParameterSet const& iPSet) : T(iPSet) {}
0110         InputProcessBlockCacheHolder(InputProcessBlockCacheHolder const&) = delete;
0111         InputProcessBlockCacheHolder& operator=(InputProcessBlockCacheHolder const&) = delete;
0112         ~InputProcessBlockCacheHolder() noexcept(false) override {}
0113 
0114         std::tuple<CacheHandle<CacheTypes>...> processBlockCaches(Event const& event) const {
0115           return cacheImpl_.processBlockCaches(event);
0116         }
0117 
0118         template <std::size_t ICacheType, typename DataType, typename Func>
0119         void registerProcessBlockCacheFiller(EDGetTokenT<DataType> const& token, Func&& func) {
0120           cacheImpl_.template registerProcessBlockCacheFiller<ICacheType, DataType, Func>(token,
0121                                                                                           std::forward<Func>(func));
0122         }
0123 
0124         template <typename CacheType, typename DataType, typename Func>
0125         void registerProcessBlockCacheFiller(EDGetTokenT<DataType> const& token, Func&& func) {
0126           cacheImpl_.template registerProcessBlockCacheFiller<CacheType, DataType, Func>(token,
0127                                                                                          std::forward<Func>(func));
0128         }
0129 
0130         // This is intended for use by Framework unit tests only
0131         unsigned int cacheSize() const { return cacheImpl_.cacheSize(); }
0132 
0133       private:
0134         void doSelectInputProcessBlocks(ProductRegistry const& productRegistry,
0135                                         ProcessBlockHelperBase const& processBlockHelperBase) final {
0136           cacheImpl_.selectInputProcessBlocks(productRegistry, processBlockHelperBase, *this);
0137         }
0138 
0139         void doAccessInputProcessBlock_(ProcessBlock const& pb) final {
0140           cacheImpl_.accessInputProcessBlock(pb);
0141           accessInputProcessBlock(pb);
0142         }
0143 
0144         // Alternate method to access ProcessBlocks without using the caches
0145         // Mostly intended for unit testing, but might have other uses...
0146         virtual void accessInputProcessBlock(ProcessBlock const&) {}
0147 
0148         void clearInputProcessBlockCaches() final { cacheImpl_.clearCaches(); }
0149 
0150         edm::impl::InputProcessBlockCacheImpl<CacheTypes...> cacheImpl_;
0151       };
0152 
0153       template <typename T, typename C>
0154       class RunCacheHolder : public virtual T {
0155       public:
0156         RunCacheHolder(edm::ParameterSet const& iPSet) : T(iPSet) {}
0157         RunCacheHolder(RunCacheHolder<T, C> const&) = delete;
0158         RunCacheHolder<T, C>& operator=(RunCacheHolder<T, C> const&) = delete;
0159         ~RunCacheHolder() noexcept(false) override{};
0160 
0161       protected:
0162         void preallocRuns(unsigned int iNRuns) final { caches_.reset(new std::shared_ptr<C>[iNRuns]); }
0163 
0164         C const* runCache(edm::RunIndex iID) const { return caches_[iID].get(); }
0165 
0166       private:
0167         void doBeginRun_(Run const& rp, EventSetup const& c) final { caches_[rp.index()] = globalBeginRun(rp, c); }
0168         void doEndRun_(Run const& rp, EventSetup const& c) final {
0169           globalEndRun(rp, c);
0170           caches_[rp.index()].reset();
0171         }
0172 
0173         virtual std::shared_ptr<C> globalBeginRun(edm::Run const&, edm::EventSetup const&) const = 0;
0174         virtual void globalEndRun(edm::Run const&, edm::EventSetup const&) const = 0;
0175 
0176         std::unique_ptr<std::shared_ptr<C>[]> caches_;
0177       };
0178 
0179       template <typename T, typename C>
0180       class LuminosityBlockCacheHolder : public virtual T {
0181       public:
0182         LuminosityBlockCacheHolder(edm::ParameterSet const& iPSet) : T(iPSet) {}
0183         LuminosityBlockCacheHolder(LuminosityBlockCacheHolder<T, C> const&) = delete;
0184         LuminosityBlockCacheHolder<T, C>& operator=(LuminosityBlockCacheHolder<T, C> const&) = delete;
0185         ~LuminosityBlockCacheHolder() noexcept(false) override{};
0186 
0187       protected:
0188         C const* luminosityBlockCache(edm::LuminosityBlockIndex iID) const { return caches_[iID].get(); }
0189 
0190       private:
0191         void preallocLumis(unsigned int iNLumis) final { caches_.reset(new std::shared_ptr<C>[iNLumis]); }
0192 
0193         void doBeginLuminosityBlock_(LuminosityBlock const& lp, EventSetup const& c) final {
0194           caches_[lp.index()] = globalBeginLuminosityBlock(lp, c);
0195         }
0196         void doEndLuminosityBlock_(LuminosityBlock const& lp, EventSetup const& c) final {
0197           globalEndLuminosityBlock(lp, c);
0198           caches_[lp.index()].reset();
0199         }
0200 
0201         virtual std::shared_ptr<C> globalBeginLuminosityBlock(edm::LuminosityBlock const&,
0202                                                               edm::EventSetup const&) const = 0;
0203         virtual void globalEndLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) const = 0;
0204 
0205         std::unique_ptr<std::shared_ptr<C>[]> caches_;
0206       };
0207 
0208       template <typename T, typename C>
0209       class EndRunSummaryProducer;
0210 
0211       template <typename T, typename C>
0212       class RunSummaryCacheHolder : public virtual T {
0213       public:
0214         RunSummaryCacheHolder(edm::ParameterSet const& iPSet) : T(iPSet) {}
0215         RunSummaryCacheHolder(RunSummaryCacheHolder<T, C> const&) = delete;
0216         RunSummaryCacheHolder<T, C>& operator=(RunSummaryCacheHolder<T, C> const&) = delete;
0217         ~RunSummaryCacheHolder() noexcept(false) override{};
0218 
0219       private:
0220         void preallocRunsSummary(unsigned int iNRuns) final { caches_.reset(new std::shared_ptr<C>[iNRuns]); }
0221 
0222         friend class EndRunSummaryProducer<T, C>;
0223         void doBeginRunSummary_(edm::Run const& rp, EventSetup const& c) final {
0224           caches_[rp.index()] = globalBeginRunSummary(rp, c);
0225         }
0226         void doStreamEndRunSummary_(StreamID id, Run const& rp, EventSetup const& c) final {
0227           //NOTE: in future this will need to be serialized
0228           std::lock_guard<std::mutex> guard(mutex_);
0229           streamEndRunSummary(id, rp, c, caches_[rp.index()].get());
0230         }
0231         void doEndRunSummary_(Run const& rp, EventSetup const& c) final {
0232           globalEndRunSummary(rp, c, caches_[rp.index()].get());
0233           maybeClearCache(rp);
0234         }
0235 
0236         virtual std::shared_ptr<C> globalBeginRunSummary(edm::Run const&, edm::EventSetup const&) const = 0;
0237         virtual void streamEndRunSummary(StreamID, edm::Run const&, edm::EventSetup const&, C*) const = 0;
0238 
0239         virtual void globalEndRunSummary(edm::Run const&, edm::EventSetup const&, C*) const = 0;
0240 
0241         virtual void maybeClearCache(Run const& rp) { caches_[rp.index()].reset(); }
0242 
0243         std::unique_ptr<std::shared_ptr<C>[]> caches_;
0244         std::mutex mutex_;
0245       };
0246 
0247       template <typename T, typename C>
0248       class EndLuminosityBlockSummaryProducer;
0249 
0250       template <typename T, typename C>
0251       class LuminosityBlockSummaryCacheHolder : public virtual T {
0252       public:
0253         LuminosityBlockSummaryCacheHolder(edm::ParameterSet const& iPSet) : T(iPSet) {}
0254         LuminosityBlockSummaryCacheHolder(LuminosityBlockSummaryCacheHolder<T, C> const&) = delete;
0255         LuminosityBlockSummaryCacheHolder<T, C>& operator=(LuminosityBlockSummaryCacheHolder<T, C> const&) = delete;
0256         ~LuminosityBlockSummaryCacheHolder() noexcept(false) override{};
0257 
0258       private:
0259         void preallocLumisSummary(unsigned int iNLumis) final { caches_.reset(new std::shared_ptr<C>[iNLumis]); }
0260 
0261         friend class EndLuminosityBlockSummaryProducer<T, C>;
0262 
0263         void doBeginLuminosityBlockSummary_(edm::LuminosityBlock const& lb, EventSetup const& c) final {
0264           caches_[lb.index()] = globalBeginLuminosityBlockSummary(lb, c);
0265         }
0266 
0267         void doStreamEndLuminosityBlockSummary_(StreamID id, LuminosityBlock const& lb, EventSetup const& c) final {
0268           std::lock_guard<std::mutex> guard(mutex_);
0269           streamEndLuminosityBlockSummary(id, lb, c, caches_[lb.index()].get());
0270         }
0271         void doEndLuminosityBlockSummary_(LuminosityBlock const& lb, EventSetup const& c) final {
0272           globalEndLuminosityBlockSummary(lb, c, caches_[lb.index()].get());
0273           maybeClearCache(lb);
0274         }
0275 
0276         virtual std::shared_ptr<C> globalBeginLuminosityBlockSummary(edm::LuminosityBlock const&,
0277                                                                      edm::EventSetup const&) const = 0;
0278         virtual void streamEndLuminosityBlockSummary(StreamID,
0279                                                      edm::LuminosityBlock const&,
0280                                                      edm::EventSetup const&,
0281                                                      C*) const = 0;
0282 
0283         virtual void globalEndLuminosityBlockSummary(edm::LuminosityBlock const&, edm::EventSetup const&, C*) const = 0;
0284 
0285         virtual void maybeClearCache(LuminosityBlock const& lb) { caches_[lb.index()].reset(); }
0286 
0287         std::unique_ptr<std::shared_ptr<C>[]> caches_;
0288         std::mutex mutex_;
0289       };
0290 
0291       template <typename T>
0292       class WatchProcessBlock : public virtual T {
0293       public:
0294         WatchProcessBlock(edm::ParameterSet const& iPSet) : T(iPSet) {}
0295         WatchProcessBlock(WatchProcessBlock const&) = delete;
0296         WatchProcessBlock& operator=(WatchProcessBlock const&) = delete;
0297         ~WatchProcessBlock() noexcept(false) override{};
0298 
0299       private:
0300         void doBeginProcessBlock_(ProcessBlock const&) final;
0301         void doEndProcessBlock_(ProcessBlock const&) final;
0302 
0303         virtual void beginProcessBlock(ProcessBlock const&) {}
0304         virtual void endProcessBlock(ProcessBlock const&) {}
0305       };
0306 
0307       template <typename T>
0308       class BeginProcessBlockProducer : public virtual T {
0309       public:
0310         BeginProcessBlockProducer(edm::ParameterSet const& iPSet) : T(iPSet) {}
0311         BeginProcessBlockProducer(BeginProcessBlockProducer const&) = delete;
0312         BeginProcessBlockProducer& operator=(BeginProcessBlockProducer const&) = delete;
0313         ~BeginProcessBlockProducer() noexcept(false) override{};
0314 
0315       private:
0316         void doBeginProcessBlockProduce_(ProcessBlock&) final;
0317 
0318         virtual void beginProcessBlockProduce(edm::ProcessBlock&) = 0;
0319       };
0320 
0321       template <typename T>
0322       class EndProcessBlockProducer : public virtual T {
0323       public:
0324         EndProcessBlockProducer(edm::ParameterSet const& iPSet) : T(iPSet) {}
0325         EndProcessBlockProducer(EndProcessBlockProducer const&) = delete;
0326         EndProcessBlockProducer& operator=(EndProcessBlockProducer const&) = delete;
0327         ~EndProcessBlockProducer() noexcept(false) override{};
0328 
0329       private:
0330         void doEndProcessBlockProduce_(ProcessBlock&) final;
0331 
0332         virtual void endProcessBlockProduce(edm::ProcessBlock&) = 0;
0333       };
0334 
0335       template <typename T>
0336       class BeginRunProducer : public virtual T {
0337       public:
0338         BeginRunProducer(edm::ParameterSet const& iPSet) : T(iPSet) {}
0339         BeginRunProducer(BeginRunProducer const&) = delete;
0340         BeginRunProducer& operator=(BeginRunProducer const&) = delete;
0341         ~BeginRunProducer() noexcept(false) override{};
0342 
0343       private:
0344         void doBeginRunProduce_(Run& rp, EventSetup const& c) final;
0345 
0346         virtual void globalBeginRunProduce(edm::Run&, edm::EventSetup const&) const = 0;
0347       };
0348 
0349       template <typename T>
0350       class EndRunProducer : public virtual T {
0351       public:
0352         EndRunProducer(edm::ParameterSet const& iPSet) : T(iPSet) {}
0353         EndRunProducer(EndRunProducer const&) = delete;
0354         EndRunProducer& operator=(EndRunProducer const&) = delete;
0355         ~EndRunProducer() noexcept(false) override{};
0356 
0357       private:
0358         void doEndRunProduce_(Run& rp, EventSetup const& c) final;
0359 
0360         virtual void globalEndRunProduce(edm::Run&, edm::EventSetup const&) const = 0;
0361       };
0362 
0363       template <typename T, typename C>
0364       class EndRunSummaryProducer : public RunSummaryCacheHolder<T, C> {
0365       public:
0366         EndRunSummaryProducer(edm::ParameterSet const& iPSet) : T(iPSet), RunSummaryCacheHolder<T, C>(iPSet) {}
0367         EndRunSummaryProducer(EndRunSummaryProducer const&) = delete;
0368         EndRunSummaryProducer& operator=(EndRunSummaryProducer const&) = delete;
0369         ~EndRunSummaryProducer() noexcept(false) override{};
0370 
0371       private:
0372         void doEndRunProduce_(Run& rp, EventSetup const& c) final {
0373           globalEndRunProduce(rp, c, RunSummaryCacheHolder<T, C>::caches_[rp.index()].get());
0374           RunSummaryCacheHolder<T, C>::caches_[rp.index()].reset();
0375         }
0376 
0377         virtual void globalEndRunProduce(edm::Run&, edm::EventSetup const&, C const*) const = 0;
0378 
0379         // Do nothing because the cache is cleared in doEndRunProduce_
0380         void maybeClearCache(Run const&) final {}
0381       };
0382 
0383       template <typename T>
0384       class BeginLuminosityBlockProducer : public virtual T {
0385       public:
0386         BeginLuminosityBlockProducer(edm::ParameterSet const& iPSet) : T(iPSet) {}
0387         BeginLuminosityBlockProducer(BeginLuminosityBlockProducer const&) = delete;
0388         BeginLuminosityBlockProducer& operator=(BeginLuminosityBlockProducer const&) = delete;
0389         ~BeginLuminosityBlockProducer() noexcept(false) override{};
0390 
0391       private:
0392         void doBeginLuminosityBlockProduce_(LuminosityBlock& lb, EventSetup const& c) final;
0393         virtual void globalBeginLuminosityBlockProduce(edm::LuminosityBlock&, edm::EventSetup const&) const = 0;
0394       };
0395 
0396       template <typename T>
0397       class EndLuminosityBlockProducer : public virtual T {
0398       public:
0399         EndLuminosityBlockProducer(edm::ParameterSet const& iPSet) : T(iPSet) {}
0400         EndLuminosityBlockProducer(EndLuminosityBlockProducer const&) = delete;
0401         EndLuminosityBlockProducer& operator=(EndLuminosityBlockProducer const&) = delete;
0402         ~EndLuminosityBlockProducer() noexcept(false) override{};
0403 
0404       private:
0405         void doEndLuminosityBlockProduce_(LuminosityBlock& lb, EventSetup const& c) final;
0406         virtual void globalEndLuminosityBlockProduce(edm::LuminosityBlock&, edm::EventSetup const&) const = 0;
0407       };
0408 
0409       template <typename T, typename S>
0410       class EndLuminosityBlockSummaryProducer : public LuminosityBlockSummaryCacheHolder<T, S> {
0411       public:
0412         EndLuminosityBlockSummaryProducer(edm::ParameterSet const& iPSet)
0413             : T(iPSet), LuminosityBlockSummaryCacheHolder<T, S>(iPSet) {}
0414         EndLuminosityBlockSummaryProducer(EndLuminosityBlockSummaryProducer const&) = delete;
0415         EndLuminosityBlockSummaryProducer& operator=(EndLuminosityBlockSummaryProducer const&) = delete;
0416         ~EndLuminosityBlockSummaryProducer() noexcept(false) override{};
0417 
0418       private:
0419         void doEndLuminosityBlockProduce_(LuminosityBlock& lb, EventSetup const& c) final {
0420           globalEndLuminosityBlockProduce(lb, c, LuminosityBlockSummaryCacheHolder<T, S>::caches_[lb.index()].get());
0421           LuminosityBlockSummaryCacheHolder<T, S>::caches_[lb.index()].reset();
0422         }
0423 
0424         virtual void globalEndLuminosityBlockProduce(edm::LuminosityBlock&, edm::EventSetup const&, S const*) const = 0;
0425 
0426         // Do nothing because the cache is cleared in doEndLuminosityBlockProduce_
0427         void maybeClearCache(LuminosityBlock const&) final {}
0428       };
0429 
0430       template <typename T>
0431       class Accumulator : public virtual T {
0432       public:
0433         Accumulator(edm::ParameterSet const& iPSet) : T(iPSet) {}
0434         Accumulator() = default;
0435         Accumulator(Accumulator const&) = delete;
0436         Accumulator& operator=(Accumulator const&) = delete;
0437         ~Accumulator() noexcept(false) override{};
0438 
0439       private:
0440         bool hasAccumulator() const noexcept override { return true; }
0441 
0442         void produce(StreamID streamID, Event& ev, EventSetup const& es) const final { accumulate(streamID, ev, es); }
0443 
0444         virtual void accumulate(StreamID streamID, Event const& ev, EventSetup const& es) const = 0;
0445       };
0446 
0447       template <typename T>
0448       class Transformer : public virtual T, private TransformerBase {
0449       public:
0450         Transformer(edm::ParameterSet const& iPSet) : T(iPSet) {}
0451         Transformer() = default;
0452         Transformer(Transformer const&) = delete;
0453         Transformer& operator=(Transformer const&) = delete;
0454         ~Transformer() noexcept(false) override{};
0455 
0456         template <typename G, typename F>
0457         void registerTransform(ProductRegistryHelper::BranchAliasSetterT<G> iSetter,
0458                                F&& iF,
0459                                std::string productInstance = std::string()) {
0460           registerTransform(edm::EDPutTokenT<G>(iSetter), std::forward<F>(iF), std::move(productInstance));
0461         }
0462 
0463         template <typename G, typename F>
0464         void registerTransform(edm::EDPutTokenT<G> iToken, F iF, std::string productInstance = std::string()) {
0465           using ReturnTypeT = decltype(iF(std::declval<G>()));
0466           TypeID returnType(typeid(ReturnTypeT));
0467           TransformerBase::registerTransformImp(
0468               *this,
0469               EDPutToken(iToken),
0470               returnType,
0471               std::move(productInstance),
0472               [f = std::move(iF)](std::any const& iGotProduct) {
0473                 auto pGotProduct = std::any_cast<edm::WrapperBase const*>(iGotProduct);
0474                 return std::make_unique<edm::Wrapper<ReturnTypeT>>(
0475                     WrapperBase::Emplace{}, f(*static_cast<edm::Wrapper<G> const*>(pGotProduct)->product()));
0476               });
0477         }
0478 
0479         template <typename G, typename P, typename F>
0480         void registerTransformAsync(edm::EDPutTokenT<G> iToken,
0481                                     P iPre,
0482                                     F iF,
0483                                     std::string productInstance = std::string()) {
0484           using CacheTypeT = decltype(iPre(std::declval<G>(), WaitingTaskWithArenaHolder()));
0485           using ReturnTypeT = decltype(iF(std::declval<CacheTypeT>()));
0486           TypeID returnType(typeid(ReturnTypeT));
0487           TransformerBase::registerTransformAsyncImp(
0488               *this,
0489               EDPutToken(iToken),
0490               returnType,
0491               std::move(productInstance),
0492               [p = std::move(iPre)](edm::WrapperBase const& iGotProduct, WaitingTaskWithArenaHolder iHolder) {
0493                 return std::any(p(*static_cast<edm::Wrapper<G> const&>(iGotProduct).product(), std::move(iHolder)));
0494               },
0495               [f = std::move(iF)](std::any const& iCache) {
0496                 auto cache = std::any_cast<CacheTypeT>(iCache);
0497                 return std::make_unique<edm::Wrapper<ReturnTypeT>>(WrapperBase::Emplace{}, f(cache));
0498               });
0499         }
0500 
0501       private:
0502         size_t transformIndex_(edm::BranchDescription const& iBranch) const noexcept final {
0503           return TransformerBase::findMatchingIndex(*this, iBranch);
0504         }
0505         ProductResolverIndex transformPrefetch_(std::size_t iIndex) const noexcept final {
0506           return TransformerBase::prefetchImp(iIndex);
0507         }
0508         void transformAsync_(WaitingTaskHolder iTask,
0509                              std::size_t iIndex,
0510                              edm::EventForTransformer& iEvent,
0511                              edm::ActivityRegistry* iAct,
0512                              ServiceWeakToken const& iToken) const noexcept final {
0513           return TransformerBase::transformImpAsync(std::move(iTask), iIndex, iAct, *this, iEvent);
0514         }
0515         void extendUpdateLookup(BranchType iBranchType, ProductResolverIndexHelper const& iHelper) override {
0516           if (iBranchType == InEvent) {
0517             TransformerBase::extendUpdateLookup(*this, this->moduleDescription(), iHelper);
0518           }
0519         }
0520       };
0521     }  // namespace impl
0522   }    // namespace limited
0523 }  // namespace edm
0524 
0525 #endif