File indexing completed on 2025-12-16 10:19:17
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #ifndef FWCORE_CONSUMER_H
0020 #define FWCORE_CONSUMER_H
0021
0022 #include "Gaudi/Functional/details.h"
0023 #include "Gaudi/Functional/utilities.h"
0024 #include "GaudiKernel/FunctionalFilterDecision.h"
0025
0026
0027
0028 #include "k4FWCore/FunctionalUtils.h"
0029
0030 #include <ranges>
0031 #include <stdexcept>
0032 #include <type_traits>
0033 #include <utility>
0034
0035 namespace k4FWCore {
0036
0037 namespace details {
0038
0039 template <typename Signature, typename Traits_>
0040 struct Consumer;
0041
0042 template <typename... In, typename Traits_>
0043 struct Consumer<void(const In&...), Traits_>
0044 : Gaudi::Functional::details::DataHandleMixin<std::tuple<>, std::tuple<>, Traits_> {
0045 using Gaudi::Functional::details::DataHandleMixin<std::tuple<>, std::tuple<>, Traits_>::DataHandleMixin;
0046
0047 static_assert(((std::is_base_of_v<podio::CollectionBase, In> || isVectorLike_v<In>)&&...),
0048 "Consumer input types must be EDM4hep collections or vectors of collection pointers");
0049
0050 template <typename T>
0051 using InputHandle_t = Gaudi::Functional::details::InputHandle_t<Traits_, T>;
0052
0053 std::tuple<std::vector<InputHandle_t<typename EventStoreType<In>::type>>...> m_inputs;
0054 std::array<Gaudi::Property<std::vector<DataObjID>>, sizeof...(In)> m_inputLocations{};
0055
0056 using base_class = Gaudi::Functional::details::DataHandleMixin<std::tuple<>, std::tuple<>, Traits_>;
0057
0058 using KeyValues = typename base_class::KeyValues;
0059
0060 template <typename IArgs, std::size_t... I>
0061 Consumer(std::string name, ISvcLocator* locator, const IArgs& inputs, std::index_sequence<I...>)
0062 : base_class(std::move(name), locator),
0063
0064
0065
0066
0067 m_inputLocations{Gaudi::Property<std::vector<DataObjID>>{
0068 this, std::get<I>(inputs).first, to_DataObjID(std::get<I>(inputs).second),
0069 [this](Gaudi::Details::PropertyBase&) {
0070 std::vector<InputHandle_t<EventStoreType_t>> handles;
0071 for (auto& value : this->m_inputLocations[I].value()) {
0072 auto handle = InputHandle_t<EventStoreType_t>(value, this);
0073 handles.push_back(std::move(handle));
0074 }
0075 std::get<I>(m_inputs) = std::move(handles);
0076 },
0077 Gaudi::Details::Property::ImmediatelyInvokeHandler{true}}...} {}
0078
0079 Consumer(std::string name, ISvcLocator* locator,
0080 Gaudi::Functional::details::RepeatValues_<KeyValues, sizeof...(In)> const& inputs)
0081 : Consumer(std::move(name), locator, inputs, std::index_sequence_for<In...>{}) {}
0082
0083
0084 StatusCode execute(const EventContext& ctx) const final {
0085 try {
0086 filter_evtcontext_tt<In...>::apply(*this, ctx, m_inputs);
0087 return Gaudi::Functional::FilterDecision::PASSED;
0088 } catch (GaudiException& e) {
0089 (e.code() ? this->warning() : this->error()) << e.tag() << " : " << e.message() << endmsg;
0090 return e.code();
0091 }
0092 }
0093
0094
0095 virtual void operator()(const In&...) const = 0;
0096
0097
0098
0099
0100
0101
0102 auto inputLocations(size_t i) const {
0103 if (i >= sizeof...(In)) {
0104 throw std::out_of_range("Called inputLocations with an index out of range, index: " + std::to_string(i) +
0105 ", number of inputs: " + std::to_string(sizeof...(In)));
0106 }
0107 return m_inputLocations[i] | std::views::transform([](const DataObjID& id) -> const auto& { return id.key(); });
0108 }
0109
0110
0111
0112
0113
0114 auto inputLocations(std::string_view name) const {
0115 auto it = std::ranges::find_if(m_inputLocations, [&name](const auto& prop) { return prop.name() == name; });
0116 if (it == m_inputLocations.end()) {
0117 throw std::runtime_error("Called inputLocations with an unknown name");
0118 }
0119 return it->value() | std::views::transform([](const DataObjID& id) -> const auto& { return id.key(); });
0120 }
0121 static constexpr std::size_t inputLocationsSize() { return sizeof...(In); }
0122 };
0123
0124 }
0125
0126 template <typename Signature, typename Traits_ = Gaudi::Functional::Traits::useDefaults>
0127 using Consumer = details::Consumer<Signature, Traits_>;
0128
0129 }
0130
0131 #endif