The Gaudi Framework  v40r6 (777c37dd)
Loading...
Searching...
No Matches
MergingTransformer.h
Go to the documentation of this file.
1/***********************************************************************************\
2* (c) Copyright 1998-2026 CERN for the benefit of the LHCb and ATLAS collaborations *
3* *
4* This software is distributed under the terms of the Apache version 2 licence, *
5* copied verbatim in the file "LICENSE". *
6* *
7* In applying this licence, CERN does not waive the privileges and immunities *
8* granted to it by virtue of its status as an Intergovernmental Organization *
9* or submit itself to any jurisdiction. *
10\***********************************************************************************/
11#pragma once
12#include "details.h"
13#include "utilities.h"
14#include <Gaudi/Algorithm.h>
16#include <string>
17
18namespace Gaudi::Functional {
19
20 namespace details {
21
22 template <typename Sig>
23 constexpr bool is_void_fun_v = false;
24 template <typename... Args>
25 constexpr bool is_void_fun_v<void( Args... )> = true;
26 template <typename Sig>
28
29 template <typename Signature, typename Traits_, bool isLegacy>
31
33 template <typename Out, typename... Ins, typename Traits_>
34 struct MergingTransformer<Out( const vector_of_const_<Ins>&... ), Traits_, true>
35 : DataHandleMixin<std::tuple<Out>, std::tuple<>, Traits_> {
36
37 using base_class = DataHandleMixin<std::tuple<Out>, std::tuple<>, Traits_>;
38 using KeyValue = typename base_class::KeyValue;
39 using KeyValues = typename base_class::KeyValues;
40 using InKeys = details::RepeatValues_<KeyValues, sizeof...( Ins )>;
41
42 // if In is a pointer, it signals optional (as opposed to mandatory) input
43 template <typename T>
45 std::tuple<HandleVector<InputHandle, Ins>...> m_ins;
46
47 public:
48 MergingTransformer( std::string name, ISvcLocator* locator, InKeys inputs )
49 requires std::is_void_v<Out>
50 : base_class( std::move( name ), locator )
51 , m_ins{ make_HandleVectorTuple<InputHandle, Ins...>( this, inputs ) } {}
52
53 MergingTransformer( std::string name, ISvcLocator* locator, const KeyValues& inputs )
54 requires( std::is_void_v<Out> && sizeof...( Ins ) == 1 )
55 : MergingTransformer{ std::move( name ), locator, InKeys{ inputs } } {}
56
57 MergingTransformer( std::string name, ISvcLocator* locator, InKeys inputs, const KeyValue& output )
58 requires( !std::is_void_v<Out> )
59 : base_class( std::move( name ), locator, output )
60 , m_ins{ make_HandleVectorTuple<InputHandle, Ins...>( this, inputs ) } {}
61
62 MergingTransformer( std::string name, ISvcLocator* locator, const KeyValues& inputs, const KeyValue& output )
63 requires( !std::is_void_v<Out> && sizeof...( Ins ) == 1 )
64 : MergingTransformer{ std::move( name ), locator, InKeys{ inputs }, output } {}
65
66 // accessor to input Locations
67 const std::string& inputLocation( unsigned int i, unsigned int j ) const {
68 return getLocations( m_ins, i ).at( j ).key();
69 }
70
71 const std::string& inputLocation( unsigned int i ) const
72 requires( sizeof...( Ins ) == 1 )
73 {
74 return inputLocation( 0, i );
75 }
76
77 unsigned int inputLocationSize( int i = 0 ) const { return getLocations( m_ins, i ).size(); }
78
79 // derived classes can NOT implement execute
80 StatusCode execute() override final {
81 return details::execute( *this, [&] {
82 const auto& ctx = Gaudi::Hive::currentContext();
83 if constexpr ( std::is_void_v<Out> ) {
84 std::apply( [&]( auto&&... handle ) { ( *this )( handle.get( ctx )... ); }, m_ins );
85 } else {
86 put( std::get<0>( this->m_outputs ),
87 std::apply( [&]( auto&&... handle ) { return ( *this )( handle.get( ctx )... ); }, m_ins ) );
88 }
90 } );
91 }
92
93 virtual Out operator()( const vector_of_const_<Ins>&... inputs ) const = 0;
94 };
95
97 template <typename Out, typename... Ins, typename Traits_>
98 struct MergingTransformer<Out( const vector_of_const_<Ins>&... ), Traits_, false>
99 : DataHandleMixin<std::tuple<Out>, std::tuple<>, Traits_> {
100
101 using base_class = DataHandleMixin<std::tuple<Out>, std::tuple<>, Traits_>;
102 using KeyValue = typename base_class::KeyValue;
103 using KeyValues = typename base_class::KeyValues;
104 using InKeys = details::RepeatValues_<KeyValues, sizeof...( Ins )>;
105
106 // if In is a pointer, it signals optional (as opposed to mandatory) input
107 template <typename T>
109 std::tuple<HandleVector<InputHandle, Ins>...> m_ins;
110
111 public:
112 MergingTransformer( std::string name, ISvcLocator* locator, InKeys inputs )
113 requires std::is_void_v<Out>
114 : base_class( std::move( name ), locator )
115 , m_ins{ make_HandleVectorTuple<InputHandle, Ins...>( this, inputs ) } {}
116
117 MergingTransformer( std::string name, ISvcLocator* locator, const KeyValues& inputs )
118 requires( std::is_void_v<Out> && sizeof...( Ins ) == 1 )
119 : MergingTransformer{ std::move( name ), locator, InKeys{ inputs } } {}
120
121 MergingTransformer( std::string name, ISvcLocator* locator, InKeys inputs, const KeyValue& output )
122 requires( !std::is_void_v<Out> )
123 : base_class( std::move( name ), locator, output )
124 , m_ins{ make_HandleVectorTuple<InputHandle, Ins...>( this, inputs ) } {}
125
126 MergingTransformer( std::string name, ISvcLocator* locator, const KeyValues& inputs, const KeyValue& output )
127 requires( !std::is_void_v<Out> && sizeof...( Ins ) == 1 )
128 : MergingTransformer{ std::move( name ), locator, InKeys{ inputs }, output } {}
129
130 // accessor to input Locations
131 const std::string& inputLocation( unsigned int i, unsigned int j ) const {
132 return getLocations( m_ins, i ).at( j ).key();
133 }
134
135 const std::string& inputLocation( unsigned int i ) const
136 requires( sizeof...( Ins ) == 1 )
137 {
138 return inputLocation( 0, i );
139 }
140
141 unsigned int inputLocationSize( int i = 0 ) const { return getLocations( m_ins, i ).size(); }
142
143 // derived classes can NOT implement execute
144 StatusCode execute( const EventContext& ctx ) const override final {
145 return details::execute( *this, [&] {
146 if constexpr ( std::is_void_v<Out> ) {
147 std::apply( [&]( auto&&... handle ) { ( *this )( handle.get( ctx )... ); }, m_ins );
148 } else {
149 put( std::get<0>( this->m_outputs ),
150 std::apply( [&]( auto&&... handle ) { return ( *this )( handle.get( ctx )... ); }, m_ins ) );
151 }
153 } );
154 }
155
156 virtual Out operator()( const vector_of_const_<Ins>&... inputs ) const = 0;
157 };
158
159 } // namespace details
160
161 template <typename Signature, typename Traits_ = Traits::useDefaults>
163
164 // more meaningful alias for cases where the return type in Signature is void
165 template <details::is_void_fun Signature, typename Traits_ = Traits::useDefaults>
167
169
170 // M vectors of the same -> N
171 template <typename Signature, typename Traits_ = Traits::BaseClass_t<Gaudi::Algorithm>>
173
174 template <typename... Outs, typename... Ins, typename Traits_>
175 struct MergingMultiTransformer<std::tuple<Outs...>( details::vector_of_const_<Ins> const&... ), Traits_>
176 : details::DataHandleMixin<std::tuple<Outs...>, std::tuple<>, Traits_> {
177
178 using base_class = details::DataHandleMixin<std::tuple<Outs...>, std::tuple<>, Traits_>;
179 // if In is a pointer, it signals optional (as opposed to mandatory) input
180 template <typename T>
182 std::tuple<details::HandleVector<InputHandle, Ins>...> m_ins;
183
184 public:
185 using KeyValue = typename base_class::KeyValue;
186 using KeyValues = typename base_class::KeyValues;
187 using InKeys = details::RepeatValues_<KeyValues, sizeof...( Ins )>;
188 using OutKeys = details::RepeatValues_<KeyValue, sizeof...( Outs )>;
189 static constexpr size_t n_args = sizeof...( Ins );
190
191 MergingMultiTransformer( std::string const& name, ISvcLocator* pSvcLocator, InKeys inputs, OutKeys outputs )
192 : base_class{ name, pSvcLocator, std::move( outputs ) }
193 , m_ins{ details::make_HandleVectorTuple<InputHandle, Ins...>( this, inputs ) } {}
194
195 MergingMultiTransformer( std::string const& name, ISvcLocator* pSvcLocator, KeyValues inputs, OutKeys outputs )
196 requires( sizeof...( Ins ) == 1 )
197 : MergingMultiTransformer{ name, pSvcLocator, InKeys{ std::move( inputs ) }, std::move( outputs ) } {}
198
199 // accessor to input Locations
200 std::string const& inputLocation( unsigned int i, unsigned int j ) const {
201 return getLocations( m_ins, i ).at( j ).key();
202 }
203 std::string const& inputLocation( unsigned int j ) const
204 requires( n_args == 1 )
205 {
206 return inputLocation( 0, j );
207 }
208 unsigned int inputLocationSize( int i = 0 ) const { return getLocations( m_ins, i ).size(); }
209
210 // derived classes can NOT implement execute
211 StatusCode execute( EventContext const& ctx ) const override final {
212 return details::execute( *this, [&] {
213 std::apply(
214 [&]( auto&... outhandle ) {
215 std::apply(
216 [&outhandle...]( auto&&... data ) {
217 ( details::put( outhandle, std::forward<decltype( data )>( data ) ), ... );
218 },
219 std::apply( [&]( auto&&... in ) { return ( *this )( in.get( ctx )... ); }, this->m_ins ) );
220 },
221 this->m_outputs );
223 } );
224 }
225
226 virtual std::tuple<Outs...> operator()( const vector_of_const_<Ins>&... inputs ) const = 0;
227 };
228
229 // Many of the same -> N with filter functionality
230 template <typename Signature, typename Traits_ = Traits::BaseClass_t<Gaudi::Algorithm>>
232
233 template <typename... Outs, typename In, typename Traits_>
234 struct MergingMultiTransformerFilter<std::tuple<Outs...>( vector_of_const_<In> const& ), Traits_>
235 : details::DataHandleMixin<std::tuple<Outs...>, std::tuple<>, Traits_> {
236
237 private:
238 using base_class = details::DataHandleMixin<std::tuple<Outs...>, std::tuple<>, Traits_>;
239
240 // if In is a pointer, it signals optional (as opposed to mandatory) input
241 template <typename T>
244
245 public:
246 using KeyValue = typename base_class::KeyValue;
247 using KeyValues = typename base_class::KeyValues;
248 using OutKeys = details::RepeatValues_<KeyValue, sizeof...( Outs )>;
249
250 MergingMultiTransformerFilter( std::string const& name, ISvcLocator* locator, KeyValues const& inputs,
251 OutKeys const& outputs )
252 : base_class( name, locator, outputs ), m_ins{ this, inputs } {}
253
254 // accessor to input Locations
255 std::string const& inputLocation( unsigned int n ) const { return m_ins.at( n ).key(); }
256 unsigned int inputLocationSize() const { return m_ins.size(); }
257
258 // derived classes can NOT implement execute
259 StatusCode execute( EventContext const& ctx ) const override final {
260 return details::execute( *this, [&] {
261 return std::apply(
262 [&]( auto&... outhandle ) {
263 return std::apply(
264 [&outhandle...]( bool passed, auto&&... data ) {
265 ( details::put( outhandle, std::forward<decltype( data )>( data ) ), ... );
266 return passed;
267 },
268 ( *this )( this->m_ins.get( ctx ) ) );
269 },
270 this->m_outputs )
273 } );
274 }
275
276 virtual std::tuple<bool, Outs...> operator()( const vector_of_const_<In>& inputs ) const = 0;
277 };
278
279} // namespace Gaudi::Functional
This class represents an entry point to all the event specific data.
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition ISvcLocator.h:42
This class is used for returning status codes from appropriate routines.
Definition StatusCode.h:64
typename detail2::InputHandle< T, Tr, detail2::DefaultInputHandle >::type InputHandle_t
Definition details.h:494
auto put(const DataObjectHandle< Out1 > &out_handle, Out2 &&out)
Definition details.h:103
auto make_HandleVectorTuple(Algorithm *parent, InKeys const &keys)
Definition details.h:412
decltype(get_values_helper< Value >(std::make_index_sequence< N >())) RepeatValues_
Definition details.h:98
decltype(auto) getLocations(std::tuple< HandleVector< Handle, I >... > const &vectors, unsigned int i)
Definition details.h:422
StatusCode execute(CommonMessagingBase const &alg, F &&f)
Definition details.h:429
details::MergingTransformer< Signature, Traits_, details::isLegacy< Traits_ > > MergingTransformer
details::MergingTransformer< Signature, Traits_, details::isLegacy< Traits_ > > MergingConsumer
GAUDI_API const EventContext & currentContext()
STL namespace.
virtual std::tuple< bool, Outs... > operator()(const vector_of_const_< In > &inputs) const =0
MergingMultiTransformerFilter(std::string const &name, ISvcLocator *locator, KeyValues const &inputs, OutKeys const &outputs)
MergingMultiTransformer(std::string const &name, ISvcLocator *pSvcLocator, InKeys inputs, OutKeys outputs)
virtual std::tuple< Outs... > operator()(const vector_of_const_< Ins > &... inputs) const =0
MergingMultiTransformer(std::string const &name, ISvcLocator *pSvcLocator, KeyValues inputs, OutKeys outputs)
MergingTransformer(std::string name, ISvcLocator *locator, const KeyValues &inputs, const KeyValue &output)
MergingTransformer(std::string name, ISvcLocator *locator, InKeys inputs, const KeyValue &output)
MergingTransformer(std::string name, ISvcLocator *locator, InKeys inputs, const KeyValue &output)
MergingTransformer(std::string name, ISvcLocator *locator, const KeyValues &inputs, const KeyValue &output)