The Gaudi Framework  master (181af51f)
Loading...
Searching...
No Matches
SplittingMergingTransformer.h
Go to the documentation of this file.
1/*****************************************************************************\
2* (c) Copyright 2022-2025 CERN for the benefit of the LHCb Collaboration *
3* *
4* This software is distributed under the terms of the GNU General Public *
5* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". *
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
13#include "details.h"
14#include "utilities.h"
16#include <functional>
17#include <optional>
18#include <string>
19#include <vector>
20
21namespace Gaudi::Functional {
22 template <typename Container>
23 using vector_of_ = std::vector<Container>;
24 template <typename Container>
25 using vector_of_optional_ = std::vector<std::optional<Container>>;
27
28 namespace details {
29
30 template <typename Signature, typename Traits_, bool isLegacy>
32
33 template <typename Out, typename In, typename Traits_>
34 class SplittingMergingTransformer<vector_of_<Out>( const vector_of_const_<In>& ), Traits_, false>
35 : public BaseClass_t<Traits_> {
37 static_assert( std::is_base_of_v<Algorithm, base_class>, "BaseClass must inherit from Algorithm" );
38
39 public:
40 using KeyValues = std::pair<std::string, std::vector<std::string>>;
41
42 SplittingMergingTransformer( std::string name, ISvcLocator* locator, const KeyValues& inputs,
43 const KeyValues& outputs )
44 : base_class( std::move( name ), locator )
45 , m_inputLocations{ this, inputs.first, details::to_DataObjID( inputs.second ),
46 [this]( Gaudi::Details::PropertyBase& ) {
47 this->m_inputs =
48 make_vector_of_handles<decltype( this->m_inputs )>( this, m_inputLocations );
49 if ( std::is_pointer_v<In> ) { // handle constructor does not (yet) allow to set
50 // optional flag... so do it
51 // explicitly here...
52 std::for_each( this->m_inputs.begin(), this->m_inputs.end(),
53 []( auto& h ) { h.setOptional( true ); } );
54 }
55 },
57 , m_outputLocations(
58 this, outputs.first, details::to_DataObjID( outputs.second ),
60 this->m_outputs =
61 details::make_vector_of_handles<decltype( this->m_outputs )>( this, m_outputLocations );
62 if constexpr ( details::is_optional<Out> ) { // handle constructor does not (yet) allow to
63 // set optional flag... so
64 // do it explicitly here...
65 std::for_each( this->m_outputs.begin(), this->m_outputs.end(),
66 []( auto& h ) { h.setOptional( true ); } );
67 }
68 },
70
71 // accessor to output Locations
72 const std::string& outputLocation( unsigned int n ) const { return m_outputLocations.value()[n].key(); }
73 unsigned int outputLocationSize() const { return m_outputLocations.value().size(); }
74
75 // accessor to input Locations
76 const std::string& inputLocation( unsigned int n ) const { return m_inputLocations.value()[n].key(); }
77 unsigned int inputLocationSize() const { return m_inputLocations.value().size(); }
78
79 // derived classes can NOT implement execute
80 StatusCode execute( const EventContext& ) const override final {
81 try {
83 ins.reserve( m_inputs.size() );
84 std::transform( m_inputs.begin(), m_inputs.end(), std::back_inserter( ins ),
86 // TODO:FIXME: how does operator() know the number and order of expected outputs?
87 auto out = ( *this )( std::as_const( ins ) );
88 if ( out.size() != m_outputs.size() ) {
89 throw GaudiException( "Error during transform: expected " + std::to_string( m_outputs.size() ) +
90 " containers, got " + std::to_string( out.size() ) + " instead",
91 this->name(), StatusCode::FAILURE );
92 }
93 for ( unsigned i = 0; i != out.size(); ++i ) details::put( m_outputs[i], std::move( out[i] ) );
95 } catch ( GaudiException& e ) {
96 if ( e.code().isFailure() ) this->error() << e.tag() << " : " << e.message() << endmsg;
97 return e.code();
98 }
99 }
100
101 // TODO/FIXME: how does the callee know in which order to produce the outputs?
102 // (note: 'missing' items can be specified by making Out an std::optional<Out>,
103 // and only those entries which contain an Out are stored)
105
106 private:
107 // if In is a pointer, it signals optional (as opposed to mandatory) input
108 template <typename T>
110 std::vector<InputHandle_t<In>> m_inputs; // and make the handles properties instead...
111 Gaudi::Property<std::vector<DataObjID>> m_inputLocations; // TODO/FIXME: remove this duplication...
112 // TODO/FIXME: replace vector of DataObjID property + call-back with a
113 // vector<handle> property ... as soon as declareProperty can deal with that.
114 template <typename T>
116 std::vector<OutputHandle<Out>> m_outputs;
117 Gaudi::Property<std::vector<DataObjID>> m_outputLocations; // TODO/FIXME for now: use a call-back to update the
118 // actual handles!
119 };
120
121 } // namespace details
122
123 template <typename Signature, typename Traits_ = Traits::useDefaults>
126
127} // namespace Gaudi::Functional
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition MsgStream.h:198
This class represents an entry point to all the event specific data.
PropertyBase base class allowing PropertyBase* collections to be "homogeneous".
SplittingMergingTransformer(std::string name, ISvcLocator *locator, const KeyValues &inputs, const KeyValues &outputs)
Implementation of property with value of concrete type.
Definition PropertyFwd.h:27
Define general base for Gaudi exception.
virtual const std::string & message() const
error message to be printed
virtual const StatusCode & code() const
StatusCode for Exception.
virtual const std::string & tag() const
name tag for the exception, or exception type
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition ISvcLocator.h:42
PropertyBase base class allowing PropertyBase* collections to be "homogeneous".
This class is used for returning status codes from appropriate routines.
Definition StatusCode.h:64
bool isFailure() const
Definition StatusCode.h:129
constexpr static const auto FAILURE
Definition StatusCode.h:100
Gaudi::tagged_bool< class ImmediatelyInvokeHandler_tag > ImmediatelyInvokeHandler
Definition Property.h:23
std::vector< DataObjID > to_DataObjID(const std::vector< std::string > &in)
Definition details.h:106
auto put(const DataObjectHandle< Out1 > &out_handle, Out2 &&out)
Definition details.h:162
Handles make_vector_of_handles(IDataHandleHolder *owner, const std::vector< DataObjID > &init)
Definition details.h:467
typename detail2::OutputHandle< T, Tr, DataObjectWriteHandle >::type OutputHandle_t
Definition details.h:455
detail2::BaseClass< Tr, Default >::type BaseClass_t
Definition details.h:449
std::vector< Container > vector_of_
details::SplittingMergingTransformer< Signature, Traits_, false > SplittingMergingTransformer
std::vector< std::optional< Container > > vector_of_optional_
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.