The Gaudi Framework  master (37c0b60a)
SplittingMergingTransformer.h
Go to the documentation of this file.
1 /*****************************************************************************\
2 * (c) Copyright 2022-2023 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 
21 namespace Gaudi::Functional {
22  template <typename Container>
24  template <typename 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:
41 
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 ),
59  [this]( Gaudi::Details::PropertyBase& ) {
60  this->m_outputs =
61  details::make_vector_of_handles<decltype( this->m_outputs )>( this, m_outputLocations );
62  if constexpr ( details::is_optional_v<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)
104  virtual vector_of_<Out> operator()( const vector_of_const_<In>& ) const = 0;
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>
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
Gaudi::Details::PropertyBase
PropertyBase base class allowing PropertyBase* collections to be "homogeneous".
Definition: PropertyBase.h:35
Gaudi::Functional::details::SplittingMergingTransformer< vector_of_< Out >(const vector_of_const_< In > &), Traits_, false >::outputLocation
const std::string & outputLocation(unsigned int n) const
Definition: SplittingMergingTransformer.h:72
Gaudi::Functional::details::SplittingMergingTransformer< vector_of_< Out >(const vector_of_const_< In > &), Traits_, false >::m_outputLocations
Gaudi::Property< std::vector< DataObjID > > m_outputLocations
Definition: SplittingMergingTransformer.h:117
std::for_each
T for_each(T... args)
Gaudi::Functional::details::SplittingMergingTransformer< vector_of_< Out >(const vector_of_const_< In > &), Traits_, false >::base_class
BaseClass_t< Traits_ > base_class
Definition: SplittingMergingTransformer.h:36
std::string
STL class.
std::move
T move(T... args)
std::pair
std::vector
STL class.
ISvcLocator
Definition: ISvcLocator.h:46
std::back_inserter
T back_inserter(T... args)
Gaudi::Functional::details::SplittingMergingTransformer< vector_of_< Out >(const vector_of_const_< In > &), Traits_, false >::InputHandle_t
InputHandle_t< Traits_, std::remove_pointer_t< T > > InputHandle_t
Definition: SplittingMergingTransformer.h:109
GaudiException
Definition: GaudiException.h:31
Gaudi::Functional::details::SplittingMergingTransformer< vector_of_< Out >(const vector_of_const_< In > &), Traits_, false >::outputLocationSize
unsigned int outputLocationSize() const
Definition: SplittingMergingTransformer.h:73
Gaudi::Functional::details::vector_of_const_::reserve
void reserve(size_type size)
Definition: details.h:344
Gaudi::Functional::details::vector_of_const_
Definition: details.h:296
Gaudi::Functional::details::SplittingMergingTransformer< vector_of_< Out >(const vector_of_const_< In > &), Traits_, false >::SplittingMergingTransformer
SplittingMergingTransformer(std::string name, ISvcLocator *locator, const KeyValues &inputs, const KeyValues &outputs)
Definition: SplittingMergingTransformer.h:42
Gaudi::Functional::details::to_DataObjID
std::vector< DataObjID > to_DataObjID(const std::vector< std::string > &in)
Definition: details.h:114
GaudiException::message
virtual const std::string & message() const
error message to be printed
Definition: GaudiException.h:68
Gaudi::Functional::details::SplittingMergingTransformer< vector_of_< Out >(const vector_of_const_< In > &), Traits_, false >::m_inputs
std::vector< InputHandle_t< In > > m_inputs
Definition: SplittingMergingTransformer.h:110
Gaudi::Functional::details::SplittingMergingTransformer< vector_of_< Out >(const vector_of_const_< In > &), Traits_, false >::execute
StatusCode execute(const EventContext &) const override final
Definition: SplittingMergingTransformer.h:80
Gaudi::Functional::details::make_vector_of_handles
Handles make_vector_of_handles(IDataHandleHolder *owner, const std::vector< DataObjID > &init)
Definition: details.h:435
Gaudi::Functional::details::SplittingMergingTransformer< vector_of_< Out >(const vector_of_const_< In > &), Traits_, false >::OutputHandle
details::OutputHandle_t< Traits_, details::remove_optional_t< T > > OutputHandle
Definition: SplittingMergingTransformer.h:115
Gaudi::Functional::details::SplittingMergingTransformer< vector_of_< Out >(const vector_of_const_< In > &), Traits_, false >::m_inputLocations
Gaudi::Property< std::vector< DataObjID > > m_inputLocations
Definition: SplittingMergingTransformer.h:111
StatusCode
Definition: StatusCode.h:65
Gaudi::tagged_bool_ns::tagged_bool
Definition: TaggedBool.h:16
details
Definition: AnyDataWrapper.h:19
AlgSequencer.h
h
Definition: AlgSequencer.py:31
Gaudi::Functional::details::SplittingMergingTransformer< vector_of_< Out >(const vector_of_const_< In > &), Traits_, false >::operator()
virtual vector_of_< Out > operator()(const vector_of_const_< In > &) const =0
std::to_string
T to_string(T... args)
Gaudi::Functional::FilterDecision::PASSED
@ PASSED
Gaudi::Functional
Definition: Consumer.h:19
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:202
GaudiException::tag
virtual const std::string & tag() const
name tag for the exception, or exception type
Definition: GaudiException.h:77
Gaudi::Functional::details::SplittingMergingTransformer
Definition: SplittingMergingTransformer.h:31
utilities.h
std::transform
T transform(T... args)
Gaudi::Functional::details::SplittingMergingTransformer< vector_of_< Out >(const vector_of_const_< In > &), Traits_, false >::inputLocationSize
unsigned int inputLocationSize() const
Definition: SplittingMergingTransformer.h:77
cpluginsvc.n
n
Definition: cpluginsvc.py:234
GaudiException::code
virtual const StatusCode & code() const
StatusCode for Exception.
Definition: GaudiException.h:86
StatusCode::isFailure
bool isFailure() const
Definition: StatusCode.h:129
ConditionsStallTest.name
name
Definition: ConditionsStallTest.py:77
Gaudi::Functional::details::details2::get_from_handle
Definition: details.h:261
std
STL namespace.
EventContext
Definition: EventContext.h:34
details.h
Gaudi::Functional::details::BaseClass_t
Gaudi::cpp17::detected_or_t< Base, detail2::BaseClass_t, Tr > BaseClass_t
Definition: details.h:416
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:101
Gaudi::Functional::details::SplittingMergingTransformer< vector_of_< Out >(const vector_of_const_< In > &), Traits_, false >::m_outputs
std::vector< OutputHandle< Out > > m_outputs
Definition: SplittingMergingTransformer.h:116
FunctionalFilterDecision.h
Gaudi::Functional::details::OutputHandle_t
Gaudi::cpp17::detected_or_t< DataObjectWriteHandle< T >, detail2::OutputHandle_t, Tr, T > OutputHandle_t
Definition: details.h:423
Gaudi::Property
Implementation of property with value of concrete type.
Definition: Property.h:37
Gaudi::Functional::details::SplittingMergingTransformer< vector_of_< Out >(const vector_of_const_< In > &), Traits_, false >::inputLocation
const std::string & inputLocation(unsigned int n) const
Definition: SplittingMergingTransformer.h:76
Gaudi::Functional::details::put
auto put(const DataObjectHandle< Out1 > &out_handle, Out2 &&out)
Definition: details.h:168
PrepareBase.out
out
Definition: PrepareBase.py:20