File indexing completed on 2023-03-17 11:05:43
0001 #ifndef HeterogeneousCore_CUDACore_interface_ConvertingESProducerWithDependenciesT_h
0002 #define HeterogeneousCore_CUDACore_interface_ConvertingESProducerWithDependenciesT_h
0003
0004 #include <tuple>
0005 #include <utility>
0006
0007 #include "FWCore/Framework/interface/ESProducer.h"
0008 #include "FWCore/Framework/interface/ESHandle.h"
0009 #include "FWCore/Framework/interface/MakerMacros.h"
0010 #include "FWCore/Framework/interface/ModuleFactory.h"
0011 #include "FWCore/Framework/interface/eventsetuprecord_registration_macro.h"
0012 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0013 #include "FWCore/Utilities/interface/typelookup.h"
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023 namespace detail {
0024
0025
0026
0027
0028 template <template <typename, typename> class Gen, typename Tuple1, typename Tuple2>
0029 struct TypeZipper;
0030
0031 template <template <typename, typename> class Gen, typename Tuple1, typename Tuple2, std::size_t... Is>
0032 auto TypeZipperImpl(Tuple1 const& t1, Tuple2 const& t2, std::index_sequence<Is...>) {
0033 return std::make_tuple(
0034 Gen<typename std::tuple_element<Is, Tuple1>::type, typename std::tuple_element<Is, Tuple2>::type>{}...);
0035 }
0036
0037 template <template <typename, typename> class Gen, typename... Ts1, typename... Ts2>
0038 struct TypeZipper<Gen, std::tuple<Ts1...>, std::tuple<Ts2...>> {
0039 static_assert(sizeof...(Ts1) == sizeof...(Ts2));
0040 using type = typename std::decay<decltype(TypeZipperImpl<Gen>(
0041 std::tuple<Ts1...>{}, std::tuple<Ts2...>{}, std::index_sequence_for<Ts1...>{}))>::type;
0042 };
0043
0044 }
0045
0046 template <typename CombinedRecord, typename Target, typename... Dependencies>
0047 class ConvertingESProducerWithDependenciesT;
0048
0049 template <template <typename...> typename CombinedRecord,
0050 typename... DepsRecords,
0051 typename Target,
0052 typename... Dependencies>
0053 class ConvertingESProducerWithDependenciesT<CombinedRecord<DepsRecords...>, Target, Dependencies...>
0054 : public edm::ESProducer {
0055 public:
0056 static constexpr std::size_t nsources = sizeof...(Dependencies);
0057 static_assert(sizeof...(Dependencies) == sizeof...(DepsRecords));
0058
0059 explicit ConvertingESProducerWithDependenciesT(edm::ParameterSet const& ps) {
0060 std::vector<edm::ESInputTag> tags(nsources);
0061 for (std::size_t i = 0; i < nsources; i++)
0062 tags[i] = edm::ESInputTag{"", ps.getParameter<std::string>("label" + std::to_string(i))};
0063
0064 std::string const& name = ps.getParameter<std::string>("ComponentName");
0065 edm::ESConsumesCollectorT<CombinedRecord<DepsRecords...>> cc = setWhatProduced(this, name);
0066 WalkConsumes<nsources - 1>::iterate(cc, tokens_, tags);
0067 }
0068
0069 std::unique_ptr<Target> produce(CombinedRecord<DepsRecords...> const& record) {
0070 auto handles = std::tuple<edm::ESHandle<Dependencies>...>{};
0071 WalkAndCall<nsources - 1, edm::ESHandle<Dependencies>...>::iterate(record, handles, tokens_);
0072
0073 return std::apply([](auto const&... handles) { return std::make_unique<Target>((*handles)...); }, handles);
0074 }
0075
0076 static void fillDescriptions(edm::ConfigurationDescriptions& confDesc) {
0077 edm::ParameterSetDescription desc;
0078
0079 desc.add<std::string>("ComponentName", "");
0080 for (std::size_t i = 0; i < nsources; i++)
0081 desc.add<std::string>("label" + std::to_string(i), "")->setComment("Product Label");
0082 confDesc.addWithDefaultLabel(desc);
0083 }
0084
0085 private:
0086 using TokenType =
0087 typename detail::TypeZipper<edm::ESGetToken, std::tuple<Dependencies...>, std::tuple<DepsRecords...>>::type;
0088 TokenType tokens_;
0089
0090 private:
0091 template <std::size_t N>
0092 struct WalkConsumes {
0093 static void iterate(edm::ESConsumesCollectorT<CombinedRecord<DepsRecords...>>& cc,
0094 TokenType& tokens,
0095 std::vector<edm::ESInputTag> const& tags) {
0096 if constexpr (N > 0)
0097 WalkConsumes<N - 1>::iterate(cc, tokens, tags);
0098 std::get<N>(tokens) = cc.consumes(tags[N]);
0099 }
0100 };
0101
0102 template <std::size_t N, typename... Types>
0103 struct WalkAndCall {
0104 static void iterate(CombinedRecord<DepsRecords...> const& containingRecord,
0105 std::tuple<Types...>& ts,
0106 TokenType const& tokens) {
0107 using Record = typename std::tuple_element<N, std::tuple<DepsRecords...>>::type;
0108 if constexpr (N > 0)
0109 WalkAndCall<N - 1, Types...>::iterate(containingRecord, ts, tokens);
0110
0111 auto const& record = containingRecord.template getRecord<Record>();
0112
0113 std::get<N>(ts) = record.getHandle(std::get<N>(tokens));
0114 }
0115 };
0116 };
0117
0118 #endif