The Gaudi Framework  v32r2 (46d42edc)
MergingTransformer.h
Go to the documentation of this file.
1 #ifndef MERGING_TRANSFORMER_H
2 #define MERGING_TRANSFORMER_H
3 
4 #include <functional>
5 #include <string>
6 #include <vector>
7 
8 #include "Gaudi/Algorithm.h"
11 
12 namespace Gaudi::Functional {
13 
14  using details::vector_of_const_;
15 
16  namespace details {
17 
18  template <typename Signature, typename Traits_, bool isLegacy>
20 
22  template <typename Out, typename In, typename Traits_>
23  struct MergingTransformer<Out( const vector_of_const_<In>& ), Traits_, true>
24  : DataHandleMixin<std::tuple<Out>, void, Traits_> {
25  private:
26  using base_class = DataHandleMixin<std::tuple<Out>, void, Traits_>;
27 
28  public:
29  using KeyValue = typename base_class::KeyValue;
30  using KeyValues = typename base_class::KeyValues;
31 
32  MergingTransformer( const std::string& name, ISvcLocator* locator, const KeyValues& inputs,
33  const KeyValue& output )
34  : base_class( name, locator, output )
35  , m_inputLocations{this, inputs.first, inputs.second,
37  this->m_inputs =
38  make_vector_of_handles<decltype( this->m_inputs )>( this, m_inputLocations );
39  if ( std::is_pointer_v<In> ) { // handle constructor does not (yet) allow to set
40  // optional flag... so do it
41  // explicitly here...
42  std::for_each( this->m_inputs.begin(), this->m_inputs.end(),
43  []( auto& h ) { h.setOptional( true ); } );
44  }
45  },
47 
48  // accessor to input Locations
49  const std::string& inputLocation( unsigned int n ) const { return m_inputLocations.value()[n]; }
50  unsigned int inputLocationSize() const { return m_inputLocations.value().size(); }
51 
52  // derived classes can NOT implement execute
53  StatusCode execute() override final {
54  vector_of_const_<In> ins;
55  ins.reserve( m_inputs.size() );
56  std::transform( m_inputs.begin(), m_inputs.end(), std::back_inserter( ins ), details2::get_from_handle<In>{} );
57  try {
58  put( std::get<0>( this->m_outputs ), std::as_const( *this )( std::as_const( ins ) ) );
59  return StatusCode::SUCCESS;
60  } catch ( GaudiException& e ) {
61  ( e.code() ? this->warning() : this->error() ) << e.message() << endmsg;
62  return e.code();
63  }
64  }
65 
66  virtual Out operator()( const vector_of_const_<In>& inputs ) const = 0;
67 
68  private:
69  // if In is a pointer, it signals optional (as opposed to mandatory) input
70  template <typename T>
72  std::vector<InputHandle_t<In>> m_inputs; // and make the handles properties instead...
73  Gaudi::Property<std::vector<std::string>> m_inputLocations; // TODO/FIXME: remove this duplication...
74  // TODO/FIXME: replace vector of string property + call-back with a
75  // vector<handle> property ... as soon as declareProperty can deal with that.
76  };
77 
78  template <typename Out, typename In, typename Traits_>
79  struct MergingTransformer<Out( const vector_of_const_<In>& ), Traits_, false>
80  : DataHandleMixin<std::tuple<Out>, void, Traits_> {
81  private:
82  using base_class = DataHandleMixin<std::tuple<Out>, void, Traits_>;
83 
84  public:
85  using KeyValue = typename base_class::KeyValue;
86  using KeyValues = typename base_class::KeyValues;
87 
88  MergingTransformer( const std::string& name, ISvcLocator* locator, const KeyValues& inputs,
89  const KeyValue& output )
90  : base_class( name, locator, output )
91  , m_inputLocations{this, inputs.first, inputs.second,
93  this->m_inputs =
94  make_vector_of_handles<decltype( this->m_inputs )>( this, m_inputLocations );
95  if ( std::is_pointer_v<In> ) { // handle constructor does not (yet) allow to set
96  // optional flag... so do it
97  // explicitly here...
98  std::for_each( this->m_inputs.begin(), this->m_inputs.end(),
99  []( auto& h ) { h.setOptional( true ); } );
100  }
101  },
103 
104  // accessor to input Locations
105  const std::string& inputLocation( unsigned int n ) const { return m_inputLocations.value()[n]; }
106  unsigned int inputLocationSize() const { return m_inputLocations.value().size(); }
107 
108  // derived classes can NOT implement execute
109  StatusCode execute( const EventContext& ) const override final {
110  vector_of_const_<In> ins;
111  ins.reserve( m_inputs.size() );
112  std::transform( m_inputs.begin(), m_inputs.end(), std::back_inserter( ins ), details2::get_from_handle<In>{} );
113  try {
114  put( std::get<0>( this->m_outputs ), ( *this )( std::as_const( ins ) ) );
115  return StatusCode::SUCCESS;
116  } catch ( GaudiException& e ) {
117  ( e.code() ? this->warning() : this->error() ) << e.message() << endmsg;
118  return e.code();
119  }
120  }
121 
122  virtual Out operator()( const vector_of_const_<In>& inputs ) const = 0;
123 
124  private:
125  // if In is a pointer, it signals optional (as opposed to mandatory) input
126  template <typename T>
128  std::vector<InputHandle_t<In>> m_inputs; // and make the handles properties instead...
129  Gaudi::Property<std::vector<std::string>> m_inputLocations; // TODO/FIXME: remove this duplication...
130  // TODO/FIXME: replace vector of string property + call-back with a
131  // vector<handle> property ... as soon as declareProperty can deal with that.
132  };
133 
134  } // namespace details
135 
136  template <typename Signature, typename Traits_ = Traits::useDefaults>
138 
139  // Many of the same -> N
140  template <typename Signature, typename Traits_ = Traits::BaseClass_t<Gaudi::Algorithm>>
142 
143  template <typename... Outs, typename In, typename Traits_>
144  struct MergingMultiTransformer<std::tuple<Outs...>( vector_of_const_<In> const& ), Traits_>
145  : details::DataHandleMixin<std::tuple<Outs...>, void, Traits_> {
146 
147  private:
148  using base_class = details::DataHandleMixin<std::tuple<Outs...>, void, Traits_>;
149 
150  public:
151  using KeyValue = typename base_class::KeyValue;
152  using KeyValues = typename base_class::KeyValues;
153  using OutKeys = std::array<KeyValue, sizeof...( Outs )>;
154 
155  MergingMultiTransformer( std::string const& name, ISvcLocator* locator, KeyValues const& inputs,
156  OutKeys const& outputs );
157 
158  // accessor to input Locations
159  std::string const& inputLocation( unsigned int n ) const { return m_inputLocations.value()[n]; }
160  unsigned int inputLocationSize() const { return m_inputLocations.value().size(); }
161 
162  // derived classes can NOT implement execute
163  StatusCode execute( EventContext const& ) const override final {
164  vector_of_const_<In> ins;
165  ins.reserve( m_inputs.size() );
166  std::transform( m_inputs.begin(), m_inputs.end(), std::back_inserter( ins ),
167  details::details2::get_from_handle<In>{} );
168  try {
169  std::apply(
170  [&]( auto&... outhandle ) {
172  std::apply(
173  [&outhandle...]( auto&&... data ) {
174  ( details::put( outhandle, std::forward<decltype( data )>( data ) ), ... );
175  },
176  std::as_const( *this )( std::as_const( ins ) ) );
178  },
179  this->m_outputs );
180  } catch ( GaudiException& e ) {
181  ( e.code() ? this->warning() : this->error() ) << e.message() << endmsg;
182  return e.code();
183  }
184  return StatusCode::SUCCESS;
185  }
186 
187  virtual std::tuple<Outs...> operator()( const vector_of_const_<In>& inputs ) const = 0;
188 
189  private:
190  // if In is a pointer, it signals optional (as opposed to mandatory) input
191  template <typename T>
193  std::vector<InputHandle_t<In>> m_inputs; // and make the handles properties instead...
194  Gaudi::Property<std::vector<std::string>> m_inputLocations; // TODO/FIXME: remove this duplication...
195  // TODO/FIXME: replace vector of string property + call-back with a
196  // vector<handle> property ... as soon as declareProperty can deal with that.
197  };
198 
199  template <typename... Outs, typename In, typename Traits_>
200  MergingMultiTransformer<std::tuple<Outs...>( const vector_of_const_<In>& ), Traits_>::MergingMultiTransformer(
201  std::string const& name, ISvcLocator* pSvcLocator, KeyValues const& inputs, OutKeys const& outputs )
202  : base_class( name, pSvcLocator, outputs )
203  , m_inputLocations{
204  this, inputs.first, inputs.second,
206  this->m_inputs = details::make_vector_of_handles<decltype( this->m_inputs )>( this, m_inputLocations );
207  if ( std::is_pointer_v<In> ) { // handle constructor does not (yet) allow to set
208  // optional flag... so do it
209  // explicitly here...
210  std::for_each( this->m_inputs.begin(), this->m_inputs.end(), []( auto& h ) { h.setOptional( true ); } );
211  }
212  },
214 
215 } // namespace Gaudi::Functional
216 
217 #endif
Out1 * put(const DataObjectHandle< Out1 > &out_handle, Out2 &&out)
Define general base for Gaudi exception.
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition: ISvcLocator.h:25
Implementation of property with value of concrete type.
Definition: Property.h:352
#define GF_SUPPRESS_SPURIOUS_CLANG_WARNING_BEGIN
Gaudi::tagged_bool< class ImmediatelyInvokeHandler_tag > ImmediatelyInvokeHandler
Definition: Property.h:141
virtual const std::string & message() const
error message to be printed
constexpr static const auto SUCCESS
Definition: StatusCode.h:85
STL namespace.
details::InputHandle_t< Traits_, typename std::remove_pointer< T >::type > InputHandle_t
This class represents an entry point to all the event specific data.
Definition: EventContext.h:24
STL class.
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:50
PropertyBase base class allowing PropertyBase* collections to be "homogeneous".
Definition: Property.h:32
MergingTransformer(const std::string &name, ISvcLocator *locator, const KeyValues &inputs, const KeyValue &output)
virtual const StatusCode & code() const
StatusCode for Exception.
STL class.
T back_inserter(T... args)
STL class.
MergingTransformer(const std::string &name, ISvcLocator *locator, const KeyValues &inputs, const KeyValue &output)
Handles make_vector_of_handles(IDataHandleHolder *owner, const std::vector< std::string > &init)
T transform(T... args)
#define GF_SUPPRESS_SPURIOUS_CLANG_WARNING_END
T for_each(T... args)
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:192