Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-10-18 04:13:15

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