The Gaudi Framework  v33r0 (d5ea422b)
MergingTransformer.h
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2019 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 #ifndef MERGING_TRANSFORMER_H
12 #define MERGING_TRANSFORMER_H
13 
14 #include <functional>
15 #include <string>
16 #include <vector>
17 
18 #include "Gaudi/Algorithm.h"
22 
23 namespace Gaudi::Functional {
24 
25  using details::vector_of_const_;
26 
27  namespace details {
28 
29  template <typename Signature, typename Traits_, bool isLegacy>
31 
33  template <typename Out, typename In, typename Traits_>
34  struct MergingTransformer<Out( const vector_of_const_<In>& ), Traits_, true>
35  : DataHandleMixin<std::tuple<Out>, std::tuple<>, Traits_> {
36  private:
37  using base_class = DataHandleMixin<std::tuple<Out>, std::tuple<>, Traits_>;
38 
39  public:
40  using KeyValue = typename base_class::KeyValue;
41  using KeyValues = typename base_class::KeyValues;
42 
43  MergingTransformer( const std::string& name, ISvcLocator* locator, const KeyValues& inputs,
44  const KeyValue& output )
45  : base_class( name, locator, output )
46  , m_inputLocations{this, inputs.first, inputs.second,
48  this->m_inputs =
49  make_vector_of_handles<decltype( this->m_inputs )>( this, m_inputLocations );
50  if ( std::is_pointer_v<In> ) { // handle constructor does not (yet) allow to set
51  // optional flag... so do it
52  // explicitly here...
53  std::for_each( this->m_inputs.begin(), this->m_inputs.end(),
54  []( auto& h ) { h.setOptional( true ); } );
55  }
56  },
58 
59  // accessor to input Locations
60  const std::string& inputLocation( unsigned int n ) const { return m_inputLocations.value()[n]; }
61  unsigned int inputLocationSize() const { return m_inputLocations.value().size(); }
62 
63  // derived classes can NOT implement execute
64  StatusCode execute() override final {
65  vector_of_const_<In> ins;
66  ins.reserve( m_inputs.size() );
67  std::transform( m_inputs.begin(), m_inputs.end(), std::back_inserter( ins ), details2::get_from_handle<In>{} );
68  try {
69  put( std::get<0>( this->m_outputs ), std::as_const( *this )( std::as_const( ins ) ) );
71  } catch ( GaudiException& e ) {
72  ( e.code() ? this->warning() : this->error() ) << e.message() << endmsg;
73  return e.code();
74  }
75  }
76 
77  virtual Out operator()( const vector_of_const_<In>& inputs ) const = 0;
78 
79  private:
80  // if In is a pointer, it signals optional (as opposed to mandatory) input
81  template <typename T>
83  std::vector<InputHandle_t<In>> m_inputs; // and make the handles properties instead...
84  Gaudi::Property<std::vector<std::string>> m_inputLocations; // TODO/FIXME: remove this duplication...
85  // TODO/FIXME: replace vector of string property + call-back with a
86  // vector<handle> property ... as soon as declareProperty can deal with that.
87  };
88 
89  template <typename Out, typename In, typename Traits_>
90  struct MergingTransformer<Out( const vector_of_const_<In>& ), Traits_, false>
91  : DataHandleMixin<std::tuple<Out>, std::tuple<>, Traits_> {
92  private:
93  using base_class = DataHandleMixin<std::tuple<Out>, std::tuple<>, Traits_>;
94 
95  public:
96  using KeyValue = typename base_class::KeyValue;
97  using KeyValues = typename base_class::KeyValues;
98 
99  MergingTransformer( const std::string& name, ISvcLocator* locator, const KeyValues& inputs,
100  const KeyValue& output )
101  : base_class( name, locator, output )
102  , m_inputLocations{this, inputs.first, inputs.second,
104  this->m_inputs =
105  make_vector_of_handles<decltype( this->m_inputs )>( this, m_inputLocations );
106  if ( std::is_pointer_v<In> ) { // handle constructor does not (yet) allow to set
107  // optional flag... so do it
108  // explicitly here...
109  std::for_each( this->m_inputs.begin(), this->m_inputs.end(),
110  []( auto& h ) { h.setOptional( true ); } );
111  }
112  },
114 
115  // accessor to input Locations
116  const std::string& inputLocation( unsigned int n ) const { return m_inputLocations.value()[n]; }
117  unsigned int inputLocationSize() const { return m_inputLocations.value().size(); }
118 
119  // derived classes can NOT implement execute
120  StatusCode execute( const EventContext& ) const override final {
121  vector_of_const_<In> ins;
122  ins.reserve( m_inputs.size() );
123  std::transform( m_inputs.begin(), m_inputs.end(), std::back_inserter( ins ), details2::get_from_handle<In>{} );
124  try {
125  put( std::get<0>( this->m_outputs ), ( *this )( std::as_const( ins ) ) );
126  return FilterDecision::PASSED;
127  } catch ( GaudiException& e ) {
128  ( e.code() ? this->warning() : this->error() ) << e.message() << endmsg;
129  return e.code();
130  }
131  }
132 
133  virtual Out operator()( const vector_of_const_<In>& inputs ) const = 0;
134 
135  private:
136  // if In is a pointer, it signals optional (as opposed to mandatory) input
137  template <typename T>
139  std::vector<InputHandle_t<In>> m_inputs; // and make the handles properties instead...
140  Gaudi::Property<std::vector<std::string>> m_inputLocations; // TODO/FIXME: remove this duplication...
141  // TODO/FIXME: replace vector of string property + call-back with a
142  // vector<handle> property ... as soon as declareProperty can deal with that.
143  };
144 
145  } // namespace details
146 
147  template <typename Signature, typename Traits_ = Traits::useDefaults>
149 
150  // Many of the same -> N
151  template <typename Signature, typename Traits_ = Traits::BaseClass_t<Gaudi::Algorithm>>
153 
154  template <typename... Outs, typename In, typename Traits_>
155  struct MergingMultiTransformer<std::tuple<Outs...>( vector_of_const_<In> const& ), Traits_>
156  : details::DataHandleMixin<std::tuple<Outs...>, std::tuple<>, Traits_> {
157 
158  private:
159  using base_class = details::DataHandleMixin<std::tuple<Outs...>, std::tuple<>, Traits_>;
160 
161  public:
162  using KeyValue = typename base_class::KeyValue;
163  using KeyValues = typename base_class::KeyValues;
164  using OutKeys = std::array<KeyValue, sizeof...( Outs )>;
165 
166  MergingMultiTransformer( std::string const& name, ISvcLocator* locator, KeyValues const& inputs,
167  OutKeys const& outputs );
168 
169  // accessor to input Locations
170  std::string const& inputLocation( unsigned int n ) const { return m_inputLocations.value()[n]; }
171  unsigned int inputLocationSize() const { return m_inputLocations.value().size(); }
172 
173  // derived classes can NOT implement execute
174  StatusCode execute( EventContext const& ) const override final {
175  vector_of_const_<In> ins;
176  ins.reserve( m_inputs.size() );
177  std::transform( m_inputs.begin(), m_inputs.end(), std::back_inserter( ins ),
178  details::details2::get_from_handle<In>{} );
179  try {
180  std::apply(
181  [&]( auto&... outhandle ) {
183  std::apply(
184  [&outhandle...]( auto&&... data ) {
185  ( details::put( outhandle, std::forward<decltype( data )>( data ) ), ... );
186  },
187  std::as_const( *this )( std::as_const( ins ) ) );
189  },
190  this->m_outputs );
191  return FilterDecision::PASSED;
192  } catch ( GaudiException& e ) {
193  ( e.code() ? this->warning() : this->error() ) << e.message() << endmsg;
194  return e.code();
195  }
196  }
197 
198  virtual std::tuple<Outs...> operator()( const vector_of_const_<In>& inputs ) const = 0;
199 
200  private:
201  // if In is a pointer, it signals optional (as opposed to mandatory) input
202  template <typename T>
204  std::vector<InputHandle_t<In>> m_inputs; // and make the handles properties instead...
205  Gaudi::Property<std::vector<std::string>> m_inputLocations; // TODO/FIXME: remove this duplication...
206  // TODO/FIXME: replace vector of string property + call-back with a
207  // vector<handle> property ... as soon as declareProperty can deal with that.
208  };
209 
210  template <typename... Outs, typename In, typename Traits_>
211  MergingMultiTransformer<std::tuple<Outs...>( const vector_of_const_<In>& ), Traits_>::MergingMultiTransformer(
212  std::string const& name, ISvcLocator* pSvcLocator, KeyValues const& inputs, OutKeys const& outputs )
213  : base_class( name, pSvcLocator, outputs )
214  , m_inputLocations{
215  this, inputs.first, inputs.second,
217  this->m_inputs = details::make_vector_of_handles<decltype( this->m_inputs )>( this, m_inputLocations );
218  if ( std::is_pointer_v<In> ) { // handle constructor does not (yet) allow to set
219  // optional flag... so do it
220  // explicitly here...
221  std::for_each( this->m_inputs.begin(), this->m_inputs.end(), []( auto& h ) { h.setOptional( true ); } );
222  }
223  },
225 
226 } // namespace Gaudi::Functional
227 
228 #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:35
Implementation of property with value of concrete type.
Definition: Property.h:370
#define GF_SUPPRESS_SPURIOUS_CLANG_WARNING_BEGIN
Gaudi::tagged_bool< class ImmediatelyInvokeHandler_tag > ImmediatelyInvokeHandler
Definition: Property.h:159
virtual const std::string & message() const
error message to be printed
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:34
STL class.
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:61
PropertyBase base class allowing PropertyBase* collections to be "homogeneous".
Definition: Property.h:42
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:202