The Gaudi Framework  master (2112f010)
Loading...
Searching...
No Matches
MakeAndConsume.cpp
Go to the documentation of this file.
1/***********************************************************************************\
2* (c) Copyright 1998-2025 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#include <Gaudi/Accumulators.h>
19#include <GaudiKernel/AlgTool.h>
21#include <GaudiKernel/IBinder.h>
24#include <cmath>
25#include <numeric>
26#include <optional>
27
28namespace Gaudi::TestSuite {
29
30 struct IMyTool : extend_interfaces<IAlgTool> {
32 virtual void operator()() const = 0;
33 };
34
35 struct MyExampleTool : extends<AlgTool, IMyTool> {
36 using extends::extends;
37 void operator()() const override { always() << m_message.value() << endmsg; }
38 Gaudi::Property<std::string> m_message{ this, "Message", "Boring Default Message" };
39 };
40 DECLARE_COMPONENT( MyExampleTool )
41
42 struct MyConsumerTool final : Gaudi::Functional::ToolBinder<Gaudi::Interface::Bind::Box<IMyTool>( const int& )> {
43 MyConsumerTool( std::string type, std::string name, const IInterface* parent )
44 : ToolBinder{ std::move( type ), std::move( name ), parent, KeyValue{ "MyInt", "/Event/MyInt" },
45 construct<BoundInstance>( this ) } {}
46
47 class BoundInstance final : public Gaudi::Interface::Bind::Stub<IMyTool> {
49 int i;
50
51 public:
52 BoundInstance( MyConsumerTool const* parent, const int& i ) : parent{ parent }, i{ i } {}
53 void operator()() const override {
54 parent->always() << "BoundInstance - got: " << i << " from " << parent->inputLocation<int>() << endmsg;
55 }
56 };
57 };
58 DECLARE_COMPONENT( MyConsumerTool )
59
61
62 struct ToolConsumer final : Gaudi::Functional::Consumer<void( IMyTool const& ), BaseClass_t> {
63 ToolConsumer( const std::string& name, ISvcLocator* svcLoc )
64 : Consumer( name, svcLoc, KeyValue{ "MyTool", "MyExampleTool" } ) {}
65
66 void operator()( IMyTool const& tool ) const override { tool(); }
67 };
68 DECLARE_COMPONENT( ToolConsumer )
69
70 struct CountingConsumer final : Gaudi::Functional::Consumer<void(), BaseClass_t> {
71 using Gaudi::Functional::Consumer<void(), BaseClass_t>::Consumer;
72 mutable Gaudi::Accumulators::MsgCounter<MSG::ERROR> m_err{ this, "This is not an error...", 3 };
73 mutable Gaudi::Accumulators::MsgCounter<MSG::WARNING> m_warn{ this, "This is not a warning...", 2 };
74 mutable Gaudi::Accumulators::MsgCounter<MSG::INFO> m_info{ this, "This is not info...", 1 };
75
76 void operator()() const override {
77 always() << "CountingConsumer: incrementing \"This is not an error\" twice" << endmsg;
78 ++m_err;
79 m_err += true;
80 m_err += false; // should do nothing...
81 always() << "CountingConsumer: incrementing \"This is not a warning\" twice" << endmsg;
82 ++m_warn;
83 m_warn += true;
84 m_warn += false; // should do nothing...
85 always() << "CountingConsumer: incrementing \"This is not info\" twice" << endmsg;
86 ++m_info;
87 m_info += true;
88 m_info += false; // should do nothing...
89 }
90 };
91 DECLARE_COMPONENT( CountingConsumer )
92
93 struct IntDataProducer final : Gaudi::Functional::Producer<int(), BaseClass_t> {
94
95 IntDataProducer( const std::string& name, ISvcLocator* svcLoc )
96 : Producer( name, svcLoc, KeyValue( "OutputLocation", "/Event/MyInt" ) ) {}
97
98 int operator()() const override {
99 info() << "executing IntDataProducer, storing " << m_value.value() << " into " << outputLocation() << endmsg;
100 return m_value;
101 }
102
103 Gaudi::Property<int> m_value{ this, "Value", 7, "The integer value to produce." };
104 };
105
106 DECLARE_COMPONENT( IntDataProducer )
107
108 struct StringDataProducer final : Gaudi::Functional::Producer<std::string(), BaseClass_t> {
109
110 StringDataProducer( const std::string& name, ISvcLocator* svcLoc )
111 : Producer( name, svcLoc, KeyValue( "OutputLocation", "/Event/MyString" ) ) {}
112
113 std::string operator()() const override {
114 info() << "executing StringDataProducer, storing " << m_value.value() << " into " << outputLocation() << endmsg;
115 return m_value;
116 }
117
118 Gaudi::Property<std::string> m_value{ this, "Value", "Any value", "The string value to produce." };
119 };
120
121 DECLARE_COMPONENT( StringDataProducer )
122
123 struct VectorDataProducer final : Gaudi::Functional::Producer<std::vector<int>(), BaseClass_t> {
124
125 Gaudi::Property<std::vector<int>> m_data{ this, "Data", { 3, 3, 3, 3 } };
126
127 VectorDataProducer( const std::string& name, ISvcLocator* svcLoc )
128 : Producer( name, svcLoc, KeyValue( "OutputLocation", "/Event/MyVector" ) ) {}
129
130 std::vector<int> operator()() const override {
131 info() << "executing VectorDataProducer, storing " << m_data.value() << " into " << outputLocation() << endmsg;
132 return m_data;
133 }
134 };
135
136 DECLARE_COMPONENT( VectorDataProducer )
137
140
141 KeyedDataProducer( const std::string& name, ISvcLocator* svcLoc )
142 : Producer( name, svcLoc, KeyValue( "OutputLocation", "/Event/MyKeyed" ) ) {}
143
144 int_container operator()() const override {
145 int_container container;
146 auto a = new KeyedObject<int>{ 4 };
147 container.add( a );
148 auto b = new KeyedObject<int>{ 5 };
149 container.add( b );
150 info() << "executing KeyedDataProducer, storing [4,5] into " << outputLocation() << endmsg;
151 return container;
152 }
153 };
154
155 DECLARE_COMPONENT( KeyedDataProducer )
156
157 struct IntDataConsumer final : Gaudi::Functional::Consumer<void( const int& ), BaseClass_t> {
158
159 IntDataConsumer( const std::string& name, ISvcLocator* svcLoc )
160 : Consumer( name, svcLoc, KeyValue( "InputLocation", "/Event/MyInt" ) ) {}
161
162 void operator()( const int& input ) const override {
163 info() << "executing IntDataConsumer, consuming " << input << " from " << inputLocation() << endmsg;
164 }
165 };
166
167 DECLARE_COMPONENT( IntDataConsumer )
168
169 struct StringDataConsumer final : Gaudi::Functional::Consumer<void( const std::string& ), BaseClass_t> {
170
171 StringDataConsumer( const std::string& name, ISvcLocator* svcLoc )
172 : Consumer( name, svcLoc, KeyValue( "InputLocation", "/Event/MyString" ) ) {}
173
174 void operator()( const std::string& input ) const override {
175 info() << "executing StringDataConsumer, consuming " << input << " from " << inputLocation() << endmsg;
176 }
177 };
178
179 DECLARE_COMPONENT( StringDataConsumer )
180
181 struct IntToFloatData final : Gaudi::Functional::Transformer<float( const int& ), BaseClass_t> {
182
183 IntToFloatData( const std::string& name, ISvcLocator* svcLoc )
184 : Transformer( name, svcLoc, KeyValue( "InputLocation", "/Event/MyInt" ),
185 KeyValue( "OutputLocation", "/Event/MyFloat" ) ) {}
186
187 float operator()( const int& input ) const override {
188 info() << "Converting: " << input << " from " << inputLocation() << " and storing it into " << outputLocation()
189 << endmsg;
190 return input;
191 }
192 };
193
194 DECLARE_COMPONENT( IntToFloatData )
195
196 struct IntFloatToFloatData final : Gaudi::Functional::Transformer<float( const int&, const float& ), BaseClass_t> {
197
198 IntFloatToFloatData( const std::string& name, ISvcLocator* svcLoc )
199 : Transformer( name, svcLoc,
200 { KeyValue( "InputLocation", "/Event/MyInt" ), KeyValue{ "OtherInput", "/Event/MyOtherFloat" } },
201 KeyValue( "OutputLocation", "/Event/OtherFloat" ) ) {}
202
203 float operator()( const int& in1, const float& in2 ) const override {
204 info() << "Converting: " << in1 << " from " << inputLocation<int>() << " and " << in2 << " from "
205 << inputLocation<float>() << " and storing it into " << outputLocation() << endmsg;
206 return in1 + in2;
207 }
208 };
209
210 DECLARE_COMPONENT( IntFloatToFloatData )
211
213 : Gaudi::Functional::MultiTransformer<std::tuple<float, float>( const int&, const int& ), BaseClass_t> {
214 IntIntToFloatFloatData( const std::string& name, ISvcLocator* svcLoc )
215 : MultiTransformer( name, svcLoc,
216 { KeyValue( "InputLocation1", { "/Event/MyInt" } ),
217 KeyValue( "InputLocation2", { "/Event/MyOtherInt" } ) },
218 { KeyValue( "OutputLocation1", { "/Event/MyMultiFloat1" } ),
219 KeyValue( "OutputLocation2", { "/Event/MyMultiFloat2" } ) } ) {}
220
221 std::tuple<float, float> operator()( const int& input1, const int& input2 ) const override {
222 info() << "Number of inputs : " << inputLocationSize() << ", number of outputs : " << outputLocationSize()
223 << endmsg;
224 info() << "Converting " << input1 << " from " << inputLocation<0>() << " and " << input2 << " from "
225 << inputLocation<1>() << endmsg;
226 info() << "Storing results into " << outputLocation<0>() << " and " << outputLocation<1>() << endmsg;
227 return std::tuple<float, float>{ input1, input2 };
228 }
229 };
230
231 DECLARE_COMPONENT( IntIntToFloatFloatData )
232
233
236 : public Gaudi::Functional::MergingTransformer<
237 std::vector<int>( const Gaudi::Functional::vector_of_const_<std::vector<int>>& ), BaseClass_t> {
238
239 IntVectorsToIntVector( const std::string& name, ISvcLocator* svcLoc )
240 : MergingTransformer( name, svcLoc, { "InputLocations", {} },
241 { "OutputLocation", "/Event/MyConcatenatedIntVector" } ) {}
242
243 std::vector<int>
244 operator()( const Gaudi::Functional::vector_of_const_<std::vector<int>>& intVectors ) const override {
245 // Create a vector and pre-allocate enough space for the number of integers we have
246 auto nelements = std::accumulate( intVectors.begin(), intVectors.end(), 0,
247 []( const auto a, const auto b ) { return a + b.size(); } );
248 std::vector<int> out;
249 out.reserve( nelements );
250 // Concatenate the input vectors to form the output
251 for ( auto& intVector : intVectors ) {
252 info() << "Concatening vector " << intVector << endmsg;
253 out.insert( out.end(), intVector.begin(), intVector.end() );
254 // intVector.clear(); // should not be possible!!! and does indeed not compile ;-)
255 }
256 info() << "Storing output vector " << out << " to " << outputLocation() << endmsg;
257 return out;
258 }
259 };
260
261 DECLARE_COMPONENT( IntVectorsToIntVector )
262
264 : public Gaudi::Functional::MergingTransformer<
265 std::vector<int>( const Gaudi::Functional::vector_of_const_<std::vector<int>*>& ), BaseClass_t> {
266
267 PIntVectorsToIntVector( const std::string& name, ISvcLocator* svcLoc )
268 : MergingTransformer( name, svcLoc, { "InputLocations", {} },
269 { "OutputLocation", "/Event/MyConcatenatedIntVector" } ) {}
270
271 std::vector<int>
272 operator()( const Gaudi::Functional::vector_of_const_<std::vector<int>*>& intVectors ) const override {
273 // Create a vector and pre-allocate enough space for the number of integers we have
274 auto nelements = std::accumulate( intVectors.begin(), intVectors.end(), 0,
275 []( const auto a, const auto b ) { return a + ( b ? b->size() : 0 ); } );
276 std::vector<int> out;
277 out.reserve( nelements );
278 // Concatenate the input vectors to form the output
279 for ( auto& intVector : intVectors ) {
280 info() << "Concatening vector " << intVector << endmsg;
281 if ( intVector ) {
282 out.insert( out.end(), intVector->begin(), intVector->end() );
283 // intVector->clear(); // should not be possible!!! and does indeed not compile ;-)
284 }
285 }
286 info() << "Storing output vector " << out << " to " << outputLocation() << endmsg;
287 return out;
288 }
289 };
290
291 DECLARE_COMPONENT( PIntVectorsToIntVector )
292
293 struct FloatDataConsumer final : Gaudi::Functional::Consumer<void( const float& ), BaseClass_t> {
294
295 FloatDataConsumer( const std::string& name, ISvcLocator* svcLoc )
296 : Consumer( name, svcLoc, KeyValue( "InputLocation", "/Event/MyFloat" ) ) {}
297
298 void operator()( const float& input ) const override {
299 info() << "executing FloatDataConsumer: " << input << endmsg;
300 }
301 };
302
303 DECLARE_COMPONENT( FloatDataConsumer )
304
305 struct ContextConsumer final : Gaudi::Functional::Consumer<void( const EventContext& ), BaseClass_t> {
306
307 using Gaudi::Functional::Consumer<void( const EventContext& ), BaseClass_t>::Consumer;
308
309 void operator()( const EventContext& ctx ) const override {
310 info() << "executing ContextConsumer, got " << ctx << endmsg;
311 }
312 };
313
314 DECLARE_COMPONENT( ContextConsumer )
315
316 struct ContextTransformer final : Gaudi::Functional::Transformer<int( const EventContext& ), BaseClass_t> {
317
318 ContextTransformer( const std::string& name, ISvcLocator* svcLoc )
319 : Transformer( name, svcLoc, KeyValue{ "OutputLoc", "/Event/SomeOtherInt" } ) {}
320
321 int operator()( const EventContext& ctx ) const override {
322 info() << "executing ContextConsumer, got " << ctx << endmsg;
323 return 9;
324 }
325 };
326
327 DECLARE_COMPONENT( ContextTransformer )
328
329 struct ContextIntConsumer final : Gaudi::Functional::Consumer<void( const EventContext&, const int& ), BaseClass_t> {
330
331 ContextIntConsumer( const std::string& name, ISvcLocator* svcLoc )
332 : Consumer( name, svcLoc, KeyValue( "InputLocation", "/Event/MyInt" ) ) {}
333
334 void operator()( const EventContext& ctx, const int& i ) const override {
335 info() << "executing ContextIntConsumer, got context = " << ctx << ", int = " << i << endmsg;
336 }
337 };
338
339 DECLARE_COMPONENT( ContextIntConsumer )
340
341 struct VectorDoubleProducer final : Gaudi::Functional::Producer<std::vector<double>(), BaseClass_t> {
342
343 VectorDoubleProducer( const std::string& name, ISvcLocator* svcLoc )
344 : Producer( name, svcLoc, KeyValue( "OutputLocation", "/Event/MyVectorOfDoubles" ) ) {}
345
346 std::vector<double> operator()() const override {
347 info() << "storing vector<double> into " << outputLocation() << endmsg;
348 return { 12.34, 56.78, 90.12, 34.56, 78.90 };
349 }
350 };
351
352 DECLARE_COMPONENT( VectorDoubleProducer )
353
354 struct FrExpTransformer final
355 : Gaudi::Functional::MultiScalarTransformer<
356 FrExpTransformer, std::tuple<std::vector<double>, std::vector<int>>( const std::vector<double>& ),
357 BaseClass_t> {
358 FrExpTransformer( const std::string& name, ISvcLocator* svcLoc )
359 : MultiScalarTransformer( name, svcLoc, KeyValue{ "InputDoubles", { "/Event/MyVectorOfDoubles" } },
360 { KeyValue{ "OutputFractions", { "/Event/MyVectorOfFractions" } },
361 KeyValue{ "OutputIntegers", { "/Event/MyVectorOfIntegers" } } } ) {}
362
363 using MultiScalarTransformer::operator();
364
365 std::tuple<double, int> operator()( const double& d ) const {
366 int i;
367 double frac = std::frexp( d, &i );
368 info() << "Converting " << d << " -> " << frac << ", " << i << endmsg;
369 return { frac, i };
370 }
371 };
372 DECLARE_COMPONENT( FrExpTransformer )
373
375 : Gaudi::Functional::MultiScalarTransformer<
376 OptFrExpTransformer, std::tuple<std::vector<double>, std::vector<int>>( const std::vector<double>& ),
377 BaseClass_t> {
378 OptFrExpTransformer( const std::string& name, ISvcLocator* svcLoc )
379 : MultiScalarTransformer( name, svcLoc, KeyValue{ "InputDoubles", { "/Event/MyVectorOfDoubles" } },
380 { KeyValue{ "OutputFractions", { "/Event/OptMyVectorOfFractions" } },
381 KeyValue{ "OutputIntegers", { "/Event/OptMyVectorOfIntegers" } } } ) {}
382
383 using MultiScalarTransformer::operator();
384
385 std::optional<std::tuple<double, int>> operator()( const double& d ) const {
386 if ( d < 30. ) {
387 info() << "Skipping " << d << endmsg;
388 return {};
389 }
390 int i;
391 double frac = std::frexp( d, &i );
392 info() << "Converting " << d << " -> " << frac << ", " << i << endmsg;
393 return std::make_tuple( frac, i );
394 }
395 };
396 DECLARE_COMPONENT( OptFrExpTransformer )
397
398 struct LdExpTransformer final
399 : Gaudi::Functional::ScalarTransformer<
400 LdExpTransformer, std::vector<double>( const std::vector<double>&, const std::vector<int>& ), BaseClass_t> {
401 LdExpTransformer( const std::string& name, ISvcLocator* svcLoc )
402 : ScalarTransformer( name, svcLoc,
403 { KeyValue{ "InputFractions", { "/Event/MyVectorOfFractions" } },
404 KeyValue{ "InputIntegers", { "/Event/MyVectorOfIntegers" } } },
405 { KeyValue{ "OutputDoubles", { "/Event/MyNewVectorOfDoubles" } } } ) {}
406
407 using ScalarTransformer::operator();
408
409 double operator()( double frac, int i ) const {
410 double d = std::ldexp( frac, i );
411 info() << "Converting " << i << ", " << frac << " -> " << d << endmsg;
412 return d;
413 }
414 };
415 DECLARE_COMPONENT( LdExpTransformer )
416
418 : Gaudi::Functional::ScalarTransformer<OptLdExpTransformer,
419 std::vector<double>( const std::vector<double>&, const std::vector<int>& ),
420 BaseClass_t> {
421 OptLdExpTransformer( const std::string& name, ISvcLocator* svcLoc )
422 : ScalarTransformer( name, svcLoc,
423 { KeyValue{ "InputFractions", { "/Event/MyVectorOfFractions" } },
424 KeyValue{ "InputIntegers", { "/Event/MyVectorOfIntegers" } } },
425 { KeyValue{ "OutputDoubles", { "/Event/MyOptVectorOfDoubles" } } } ) {}
426
427 using ScalarTransformer::operator();
428
429 std::optional<double> operator()( const double& frac, const int& i ) const {
430 double d = std::ldexp( frac, i );
431 if ( i > 6 ) {
432 info() << "Skipping " << d << endmsg;
433 return {};
434 }
435 info() << "Converting " << i << ", " << frac << " -> " << d << endmsg;
436 return d;
437 }
438 };
439 DECLARE_COMPONENT( OptLdExpTransformer )
440
441 struct VoidConsumer final : Gaudi::Functional::Consumer<void(), BaseClass_t> {
442
443 using Consumer::Consumer;
444
445 void operator()() const override { info() << "executing VoidConsumer" << endmsg; }
446 };
447
448 DECLARE_COMPONENT( VoidConsumer )
449
450 struct S : public KeyedObject<int> {
452 int a;
453 using ConstVector = std::vector<S const*>;
456 };
457
458 struct SDataProducer final : Gaudi::Functional::Producer<S::Container(), BaseClass_t> {
459
460 SDataProducer( const std::string& name, ISvcLocator* svcLoc )
461 : Producer( name, svcLoc, KeyValue( "OutputLocation", "/Event/MyS" ) ) {}
462
463 S::Container operator()() const override {
464 S::Container out{};
465 for ( int i = 0; i < j; ++i ) out.insert( new S{} );
466 info() << "storing KeyedContainer of size " << out.size() << " into " << outputLocation() << endmsg;
467 return out;
468 }
469 Gaudi::Property<int> j{ this, "j", 5 };
470 };
471
472 DECLARE_COMPONENT( SDataProducer )
473
475 : public Gaudi::Functional::MergingTransformer<
476 std::vector<int>( const Gaudi::Functional::vector_of_const_<Gaudi::Range_<std::vector<S const*>>>& ),
477 BaseClass_t> {
478
479 SRangesToIntVector( const std::string& name, ISvcLocator* svcLoc )
480 : MergingTransformer( name, svcLoc, { "InputRanges", {} },
481 { "OutputLocation", "/Event/MyConcatenatedIntFromSVector" } ) {}
482
483 std::vector<int> operator()(
484 const Gaudi::Functional::vector_of_const_<Gaudi::Range_<std::vector<S const*>>>& SVectors ) const override {
485 std::vector<int> out;
486 // Concatenate the input vectors to form the output
487 for ( const auto& SVector : SVectors ) {
488 info() << "Concatening range of size " << SVector.size() << endmsg;
489 for ( auto* s : SVector ) { out.push_back( s->a ); }
490 }
491 info() << "Storing output vector " << out << " to " << outputLocation() << endmsg;
492 return out;
493 }
494 };
495 DECLARE_COMPONENT( SRangesToIntVector )
496
498 : public Gaudi::Functional::MergingTransformer<void( const Gaudi::Functional::vector_of_const_<
499 std::optional<Gaudi::NamedRange_<std::vector<S const*>>>>& ),
500 BaseClass_t> {
501
502 OptionalSRangesMerger( const std::string& name, ISvcLocator* svcLoc )
503 : MergingTransformer( name, svcLoc, { "InputRanges", {} } ) {}
504
505 void
506 operator()( const Gaudi::Functional::vector_of_const_<std::optional<Gaudi::NamedRange_<std::vector<S const*>>>>&
507 OptSVectors ) const override {
508 // Loop over the optional ranges checking if the opt has a value
509 for ( const auto& OptSVector : OptSVectors ) {
510 if ( OptSVector.has_value() ) {
511 auto SVector = OptSVector.value();
512 info() << "Consuming vector of size: " << SVector.size() << endmsg;
513 } else {
514 info() << "Skipping empty optional range" << endmsg;
515 }
516 }
517 }
518 };
519 DECLARE_COMPONENT( OptionalSRangesMerger )
520
521 struct IntVectorsMerger final
522 : public Gaudi::Functional::MergingTransformer<
523 void( const Gaudi::Functional::vector_of_const_<std::vector<int>>& ), BaseClass_t> {
524
525 IntVectorsMerger( const std::string& name, ISvcLocator* svcLoc )
526 : MergingTransformer( name, svcLoc, { "InputLocations", {} } ) {}
527
528 void operator()( const Gaudi::Functional::vector_of_const_<std::vector<int>>& intVectors ) const override {
529 // Create a vector and pre-allocate enough space for the number of integers we have
530 auto nelements = std::accumulate( intVectors.begin(), intVectors.end(), 0,
531 []( const auto a, const auto b ) { return a + b.size(); } );
532 info() << "sum of input sizes: " << nelements << endmsg;
533 // Concatenate the input vectors to form the output
534 for ( const auto& intVector : intVectors ) { info() << "Consuming vector " << intVector << endmsg; }
535 }
536 };
537
538 DECLARE_COMPONENT( IntVectorsMerger )
539
541 : public Gaudi::Functional::MergingConsumer<void( Gaudi::Functional::vector_of_const_<std::vector<int>> const& ),
542 BaseClass_t> {
543 using Base =
546
547 IntVectorsMergingConsumer( const std::string& name, ISvcLocator* svcLoc )
548 : Base( name, svcLoc, { "InputLocations", {} } ) {}
549
550 void operator()( Gaudi::Functional::vector_of_const_<std::vector<int>> const& intVectors ) const override {
551 // Create a vector and pre-allocate enough space for the number of integers we have
552 auto nelements = std::accumulate( intVectors.begin(), intVectors.end(), 0,
553 []( const auto a, const auto b ) { return a + b.size(); } );
554 info() << "sum of input sizes: " << nelements << endmsg;
555 // Concatenate the input vectors to form the output
556 for ( const auto& intVector : intVectors ) { info() << "Consuming vector " << intVector << endmsg; }
557 }
558 };
559
560 DECLARE_COMPONENT( IntVectorsMergingConsumer )
561
562 struct MyData {
563 using ConstVector = std::vector<const MyData*>;
564 };
566
568
569 RangeProducer( const std::string& name, ISvcLocator* pSvcLocator )
570 : Producer( name, pSvcLocator, KeyValue{ "TrackLocation", "" } ){};
571
572 MyDataRange operator()() const override { return {}; }
573 };
574 DECLARE_COMPONENT( RangeProducer )
575
576
578 struct TwoDMerger final : public Gaudi::Functional::MergingMultiTransformer<
579 std::tuple<std::vector<int>, std::vector<double>>(
580 const Gaudi::Functional::vector_of_const_<std::vector<int>>&,
581 const Gaudi::Functional::vector_of_const_<std::vector<double>>& ),
582 BaseClass_t> {
583
584 TwoDMerger( const std::string& name, ISvcLocator* svcLoc )
585 : MergingMultiTransformer{ name,
586 svcLoc,
587 { KeyValues{ "InputInts", {} }, KeyValues{ "InputDoubles", {} } },
588 { KeyValue{ "OutputInts", "/Event/MySummedInts" },
589 KeyValue{ "OutputDoubles", "/Event/MySummedDoubles" } } } {}
590
591 std::tuple<std::vector<int>, std::vector<double>>
592 operator()( const Gaudi::Functional::vector_of_const_<std::vector<int>>& intVectors,
593 const Gaudi::Functional::vector_of_const_<std::vector<double>>& doubleVectors ) const override {
594 auto r = std::tuple{ std::vector<int>{}, std::vector<double>{} };
595 auto& [is, ds] = r;
596 std::transform( begin( intVectors ), end( intVectors ), std::back_inserter( is ),
597 []( const std::vector<int>& vi ) { return std::accumulate( begin( vi ), end( vi ), 0 ); } );
598 always() << " accumulated: " << is << endmsg;
599 std::transform( begin( doubleVectors ), end( doubleVectors ), std::back_inserter( ds ),
600 []( const std::vector<double>& vd ) { return std::accumulate( begin( vd ), end( vd ), 0. ); } );
601 always() << " accumulated: " << ds << endmsg;
602 return r;
603 }
604 };
605
606 DECLARE_COMPONENT( TwoDMerger )
607
608 struct Foo {
609 int i;
610
611 Foo( int i ) : i{ i } {}
612 Foo( Foo&& ) = delete;
613 Foo& operator=( Foo&& ) = delete;
614 Foo( const Foo& ) = delete;
615 Foo& operator=( const Foo& ) = delete;
616 ~Foo(){};
617 };
618
619 struct ShrdPtrProducer final : Gaudi::Functional::Producer<std::shared_ptr<Foo>(), BaseClass_t> {
620
621 ShrdPtrProducer( const std::string& name, ISvcLocator* svcLoc )
622 : Producer( name, svcLoc, KeyValue( "OutputLocation", "/Event/MySharedFoo" ) ) {}
623
624 std::shared_ptr<Foo> operator()() const override {
625 auto foo = std::make_shared<Foo>( m_value.value() );
626 info() << "executing ShrdPtrProducer, storing shared_ptr<Foo> with payload at " << foo.get() << " and value "
627 << foo->i << " into " << outputLocation() << endmsg;
628 return foo;
629 }
630
631 Gaudi::Property<int> m_value{ this, "Value", 7, "The integer value to produce." };
632 };
633
634 DECLARE_COMPONENT( ShrdPtrProducer )
635
636 struct ShrdPtrConsumer final : Gaudi::Functional::Consumer<void( std::shared_ptr<Foo> const& ), BaseClass_t> {
637
638 ShrdPtrConsumer( const std::string& name, ISvcLocator* svcLoc )
639 : Consumer( name, svcLoc, KeyValue( "InputLocation", "/Event/MySharedFoo" ) ) {}
640
641 void operator()( const std::shared_ptr<Foo>& foo ) const override {
642 info() << "executing ShrdPtrConsumer, got shared_ptr<Foo> with payload at " << foo.get() << " with value "
643 << foo->i << " from " << inputLocation() << endmsg;
644 }
645 };
646
647 DECLARE_COMPONENT( ShrdPtrConsumer )
648
649
652 struct IntVectorsToInts final
653 : public Gaudi::Functional::SplittingMergingTransformer<
654 std::vector<int>( const Gaudi::Functional::vector_of_const_<std::vector<int>>& ), BaseClass_t> {
655
657
658 IntVectorsToInts( const std::string& name, ISvcLocator* svcLoc )
659 : SplittingMergingTransformer( name, svcLoc, { "InputLocations", {} }, { "OutputLocations", {} } ) {}
660
661 std::vector<int>
662 operator()( const Gaudi::Functional::vector_of_const_<std::vector<int>>& intVectors ) const override {
663 int l = 0;
664 for ( const auto& iv : intVectors ) { info() << "loaded " << iv << " from " << inputLocation( l++ ) << endmsg; }
665 std::vector<int> out( outputLocationSize(), 0 );
666 for ( const auto& [l, r] : m_mapping.value() ) {
667 out[l] = std::accumulate( intVectors.at( r ).begin(), intVectors.at( r ).end(), out[l] );
668 }
669 l = 0;
670 for ( const auto& o : out ) { info() << "storing " << o << " in " << outputLocation( l++ ) << endmsg; }
671 return out;
672 }
673 };
674 DECLARE_COMPONENT( IntVectorsToInts )
675
676 struct Eventually {
677 Gaudi::Algorithm const* parent = nullptr;
678 void ( *action )( Gaudi::Algorithm const* ) = nullptr;
679 Eventually( Gaudi::Algorithm const* p, void ( *a )( Gaudi::Algorithm const* ) ) : parent{ p }, action{ a } {}
680 Eventually( Eventually const& ) = delete;
681 Eventually& operator=( Eventually const& ) = delete;
683 : parent{ std::exchange( other.parent, nullptr ) }, action{ std::exchange( other.action, nullptr ) } {}
685 parent = std::exchange( other.parent, nullptr );
686 action = std::exchange( other.action, nullptr );
687 return *this;
688 }
690 if ( action ) action( parent );
691 }
692 };
693
694 struct OpaqueProducer final
696 Eventually(),
697 Gaudi::Functional::Traits::use_<BaseClass_t, Gaudi::Functional::Traits::WriteOpaqueFor<Eventually>>> {
698
699 OpaqueProducer( const std::string& name, ISvcLocator* svcLoc )
700 : Producer( name, svcLoc, KeyValue( "OutputLocation", "/Event/Eventually" ) ) {}
701
702 Eventually operator()() const override {
703 always() << "creating Eventually" << endmsg;
704 return Eventually{ this, []( Gaudi::Algorithm const* me ) {
705 me->always() << "My Eventually is about to be destroyed" << endmsg;
706 } };
707 }
708 };
709
710 DECLARE_COMPONENT( OpaqueProducer )
711
712 static_assert( std::ranges::forward_range<Gaudi::Functional::vector_of_const_<void*>> );
713 static_assert( std::ranges::forward_range<Gaudi::Functional::vector_of_const_<int>> );
714 static_assert( std::ranges::forward_range<Gaudi::Functional::vector_of_const_<std::vector<int>*>> );
715 static_assert( std::ranges::forward_range<Gaudi::Functional::vector_of_const_<std::vector<int>>> );
716 static_assert( std::same_as<typename Gaudi::Functional::vector_of_const_<std::vector<int>*>::value_type,
717 std::vector<int> const*> );
718 static_assert( std::same_as<typename Gaudi::Functional::vector_of_const_<std::vector<int>>::value_type,
719 std::vector<int> const> );
720 static_assert(
721 std::same_as<typename Gaudi::Functional::vector_of_const_<Gaudi::Range_<std::vector<void*>>>::value_type,
723
724} // namespace Gaudi::TestSuite
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition MsgStream.h:198
#define DECLARE_COMPONENT(type)
MsgStream & always() const
shortcut for the method msgStream(MSG::ALWAYS)
This class represents an entry point to all the event specific data.
Base class from which all concrete algorithm classes should be derived.
Definition Algorithm.h:87
Implementation of property with value of concrete type.
Definition PropertyFwd.h:27
Useful class for representation of "sequence" of the objects through the range of valid iterators.
Definition Range.h:81
BoundInstance(MyConsumerTool const *parent, const int &i)
Definition of the basic interface.
Definition IInterface.h:225
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition ISvcLocator.h:42
template class KeyedContainer, KeyedContainer.h
long add(ContainedObject *pObject) override
ObjectContainerBase overload: Add an object to the container.
Definition of the templated KeyedObject class.
Definition KeyedObject.h:37
KeyedObject()=default
Standard Constructor. The object key is preset to the invalid value.
Very simple class to represent the container of objects which are not owned by this container.
Base class used to extend a class implementing other interfaces.
Definition extends.h:19
STL class.
details::Consumer< Signature, Traits_, details::isLegacy< Traits_ > > Consumer
Definition Consumer.h:69
details::MergingTransformer< Signature, Traits_, details::isLegacy< Traits_ > > MergingConsumer
details::Producer< Signature, Traits_, details::isLegacy< Traits_ > > Producer
Definition Producer.h:37
Gaudi::Range_< MyData::ConstVector > MyDataRange
KeyedContainer< KeyedObject< int >, Containers::HashMap > int_container
Gaudi::Functional::Traits::BaseClass_t< Gaudi::Algorithm > BaseClass_t
This file provides a Grammar for the type Gaudi::Accumulators::Axis It allows to use that type from p...
Definition __init__.py:1
STL namespace.
void operator()(const EventContext &ctx) const override
void operator()(const EventContext &ctx, const int &i) const override
ContextIntConsumer(const std::string &name, ISvcLocator *svcLoc)
int operator()(const EventContext &ctx) const override
ContextTransformer(const std::string &name, ISvcLocator *svcLoc)
Gaudi::Accumulators::MsgCounter< MSG::INFO > m_info
Gaudi::Accumulators::MsgCounter< MSG::ERROR > m_err
Gaudi::Accumulators::MsgCounter< MSG::WARNING > m_warn
Eventually & operator=(Eventually const &)=delete
void(* action)(Gaudi::Algorithm const *)
Eventually(Gaudi::Algorithm const *p, void(*a)(Gaudi::Algorithm const *))
Eventually(Eventually const &)=delete
Eventually & operator=(Eventually &&other)
Gaudi::Algorithm const * parent
void operator()(const float &input) const override
FloatDataConsumer(const std::string &name, ISvcLocator *svcLoc)
Foo(Foo &&)=delete
Foo & operator=(Foo &&)=delete
Foo & operator=(const Foo &)=delete
Foo(const Foo &)=delete
FrExpTransformer(const std::string &name, ISvcLocator *svcLoc)
std::tuple< double, int > operator()(const double &d) const
DeclareInterfaceID(IMyTool, 1, 0)
virtual void operator()() const =0
IntDataConsumer(const std::string &name, ISvcLocator *svcLoc)
void operator()(const int &input) const override
IntDataProducer(const std::string &name, ISvcLocator *svcLoc)
float operator()(const int &in1, const float &in2) const override
IntFloatToFloatData(const std::string &name, ISvcLocator *svcLoc)
IntIntToFloatFloatData(const std::string &name, ISvcLocator *svcLoc)
std::tuple< float, float > operator()(const int &input1, const int &input2) const override
IntToFloatData(const std::string &name, ISvcLocator *svcLoc)
float operator()(const int &input) const override
IntVectorsMerger(const std::string &name, ISvcLocator *svcLoc)
void operator()(const Gaudi::Functional::vector_of_const_< std::vector< int > > &intVectors) const override
Gaudi::Functional::MergingConsumer< void(Gaudi::Functional::vector_of_const_< std::vector< int > > const &), BaseClass_t > Base
void operator()(Gaudi::Functional::vector_of_const_< std::vector< int > > const &intVectors) const override
IntVectorsMergingConsumer(const std::string &name, ISvcLocator *svcLoc)
IntVectorsToIntVector(const std::string &name, ISvcLocator *svcLoc)
std::vector< int > operator()(const Gaudi::Functional::vector_of_const_< std::vector< int > > &intVectors) const override
IntVectorsToInts(const std::string &name, ISvcLocator *svcLoc)
std::vector< int > operator()(const Gaudi::Functional::vector_of_const_< std::vector< int > > &intVectors) const override
Gaudi::Property< std::vector< std::pair< int, int > > > m_mapping
KeyedDataProducer(const std::string &name, ISvcLocator *svcLoc)
int_container operator()() const override
LdExpTransformer(const std::string &name, ISvcLocator *svcLoc)
double operator()(double frac, int i) const
MyConsumerTool(std::string type, std::string name, const IInterface *parent)
std::vector< const MyData * > ConstVector
void operator()() const override
Gaudi::Property< std::string > m_message
OpaqueProducer(const std::string &name, ISvcLocator *svcLoc)
Eventually operator()() const override
std::optional< std::tuple< double, int > > operator()(const double &d) const
OptFrExpTransformer(const std::string &name, ISvcLocator *svcLoc)
OptLdExpTransformer(const std::string &name, ISvcLocator *svcLoc)
std::optional< double > operator()(const double &frac, const int &i) const
void operator()(const Gaudi::Functional::vector_of_const_< std::optional< Gaudi::NamedRange_< std::vector< S const * > > > > &OptSVectors) const override
OptionalSRangesMerger(const std::string &name, ISvcLocator *svcLoc)
std::vector< int > operator()(const Gaudi::Functional::vector_of_const_< std::vector< int > * > &intVectors) const override
PIntVectorsToIntVector(const std::string &name, ISvcLocator *svcLoc)
MyDataRange operator()() const override
RangeProducer(const std::string &name, ISvcLocator *pSvcLocator)
SDataProducer(const std::string &name, ISvcLocator *svcLoc)
S::Container operator()() const override
KeyedObject()=default
Standard Constructor. The object key is preset to the invalid value.
KeyedContainer< S, Containers::HashMap > Container
SharedObjectsContainer< S > Selection
std::vector< S const * > ConstVector
std::vector< int > operator()(const Gaudi::Functional::vector_of_const_< Gaudi::Range_< std::vector< S const * > > > &SVectors) const override
SRangesToIntVector(const std::string &name, ISvcLocator *svcLoc)
ShrdPtrConsumer(const std::string &name, ISvcLocator *svcLoc)
void operator()(const std::shared_ptr< Foo > &foo) const override
ShrdPtrProducer(const std::string &name, ISvcLocator *svcLoc)
std::shared_ptr< Foo > operator()() const override
void operator()(const std::string &input) const override
StringDataConsumer(const std::string &name, ISvcLocator *svcLoc)
std::string operator()() const override
Gaudi::Property< std::string > m_value
StringDataProducer(const std::string &name, ISvcLocator *svcLoc)
ToolConsumer(const std::string &name, ISvcLocator *svcLoc)
void operator()(IMyTool const &tool) const override
TwoDMerger(const std::string &name, ISvcLocator *svcLoc)
std::tuple< std::vector< int >, std::vector< double > > operator()(const Gaudi::Functional::vector_of_const_< std::vector< int > > &intVectors, const Gaudi::Functional::vector_of_const_< std::vector< double > > &doubleVectors) const override
VectorDataProducer(const std::string &name, ISvcLocator *svcLoc)
std::vector< int > operator()() const override
Gaudi::Property< std::vector< int > > m_data
std::vector< double > operator()() const override
VectorDoubleProducer(const std::string &name, ISvcLocator *svcLoc)
void operator()() const override
Base class to be used to extend an interface.