File indexing completed on 2025-01-18 09:57:30
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #pragma once
0012
0013 #include "details.h"
0014 #include "utilities.h"
0015 #include <GaudiKernel/FunctionalFilterDecision.h>
0016 #include <functional>
0017 #include <optional>
0018 #include <string>
0019 #include <vector>
0020
0021 namespace Gaudi::Functional {
0022 template <typename Container>
0023 using vector_of_ = std::vector<Container>;
0024 template <typename Container>
0025 using vector_of_optional_ = std::vector<std::optional<Container>>;
0026 using details::vector_of_const_;
0027
0028 namespace details {
0029
0030 template <typename Signature, typename Traits_, bool isLegacy>
0031 class SplittingMergingTransformer;
0032
0033 template <typename Out, typename In, typename Traits_>
0034 class SplittingMergingTransformer<vector_of_<Out>( const vector_of_const_<In>& ), Traits_, false>
0035 : public BaseClass_t<Traits_> {
0036 using base_class = BaseClass_t<Traits_>;
0037 static_assert( std::is_base_of_v<Algorithm, base_class>, "BaseClass must inherit from Algorithm" );
0038
0039 public:
0040 using KeyValues = std::pair<std::string, std::vector<std::string>>;
0041
0042 SplittingMergingTransformer( std::string name, ISvcLocator* locator, const KeyValues& inputs,
0043 const KeyValues& outputs )
0044 : base_class( std::move( name ), locator )
0045 , m_inputLocations{ this, inputs.first, details::to_DataObjID( inputs.second ),
0046 [this]( Gaudi::Details::PropertyBase& ) {
0047 this->m_inputs =
0048 make_vector_of_handles<decltype( this->m_inputs )>( this, m_inputLocations );
0049 if ( std::is_pointer_v<In> ) {
0050
0051
0052 std::for_each( this->m_inputs.begin(), this->m_inputs.end(),
0053 []( auto& h ) { h.setOptional( true ); } );
0054 }
0055 },
0056 Gaudi::Details::Property::ImmediatelyInvokeHandler{ true } }
0057 , m_outputLocations(
0058 this, outputs.first, details::to_DataObjID( outputs.second ),
0059 [this]( Gaudi::Details::PropertyBase& ) {
0060 this->m_outputs =
0061 details::make_vector_of_handles<decltype( this->m_outputs )>( this, m_outputLocations );
0062 if constexpr ( details::is_optional_v<Out> ) {
0063
0064
0065 std::for_each( this->m_outputs.begin(), this->m_outputs.end(),
0066 []( auto& h ) { h.setOptional( true ); } );
0067 }
0068 },
0069 Gaudi::Details::Property::ImmediatelyInvokeHandler{ true } ) {}
0070
0071
0072 const std::string& outputLocation( unsigned int n ) const { return m_outputLocations.value()[n].key(); }
0073 unsigned int outputLocationSize() const { return m_outputLocations.value().size(); }
0074
0075
0076 const std::string& inputLocation( unsigned int n ) const { return m_inputLocations.value()[n].key(); }
0077 unsigned int inputLocationSize() const { return m_inputLocations.value().size(); }
0078
0079
0080 StatusCode execute( const EventContext& ) const override final {
0081 try {
0082 vector_of_const_<In> ins;
0083 ins.reserve( m_inputs.size() );
0084 std::transform( m_inputs.begin(), m_inputs.end(), std::back_inserter( ins ),
0085 details2::get_from_handle<In>{} );
0086
0087 auto out = ( *this )( std::as_const( ins ) );
0088 if ( out.size() != m_outputs.size() ) {
0089 throw GaudiException( "Error during transform: expected " + std::to_string( m_outputs.size() ) +
0090 " containers, got " + std::to_string( out.size() ) + " instead",
0091 this->name(), StatusCode::FAILURE );
0092 }
0093 for ( unsigned i = 0; i != out.size(); ++i ) details::put( m_outputs[i], std::move( out[i] ) );
0094 return FilterDecision::PASSED;
0095 } catch ( GaudiException& e ) {
0096 if ( e.code().isFailure() ) this->error() << e.tag() << " : " << e.message() << endmsg;
0097 return e.code();
0098 }
0099 }
0100
0101
0102
0103
0104 virtual vector_of_<Out> operator()( const vector_of_const_<In>& ) const = 0;
0105
0106 private:
0107
0108 template <typename T>
0109 using InputHandle_t = InputHandle_t<Traits_, std::remove_pointer_t<T>>;
0110 std::vector<InputHandle_t<In>> m_inputs;
0111 Gaudi::Property<std::vector<DataObjID>> m_inputLocations;
0112
0113
0114 template <typename T>
0115 using OutputHandle = details::OutputHandle_t<Traits_, details::remove_optional_t<T>>;
0116 std::vector<OutputHandle<Out>> m_outputs;
0117 Gaudi::Property<std::vector<DataObjID>> m_outputLocations;
0118
0119 };
0120
0121 }
0122
0123 template <typename Signature, typename Traits_ = Traits::useDefaults>
0124 using SplittingMergingTransformer =
0125 details::SplittingMergingTransformer<Signature, Traits_, false>;
0126
0127 }