The Gaudi Framework  v32r0 (3325bb39)
Transformer.h
Go to the documentation of this file.
1 #ifndef TRANSFORMER_H
2 #define TRANSFORMER_H
3 
7 #include <type_traits>
8 #include <utility>
9 
10 // Adapt an Algorithm (by default, GaudiAlgorithm) so that derived classes
11 // a) do not need to access the event store, and have to explicitly
12 // state their data dependencies
13 // b) are encouraged not to have state which depends on the events
14 // (eg. histograms, counters will have to be mutable)
15 
16 namespace Gaudi ::Functional {
17 
18  namespace details {
19 
20  template <typename Signature, typename Traits_, bool isLegacy>
21  struct Transformer;
22 
23  // general N -> 1 algorithms
24  template <typename Out, typename... In, typename Traits_>
25  struct Transformer<Out( const In&... ), Traits_, true>
28 
29  // derived classes can NOT implement execute
30  StatusCode execute() override final {
31  try {
32  details::put( std::get<0>( this->m_outputs ),
34  return StatusCode::SUCCESS;
35  } catch ( GaudiException& e ) {
36  ( e.code() ? this->warning() : this->error() ) << e.message() << endmsg;
37  return e.code();
38  }
39  }
40 
41  // instead they MUST implement this operator
42  virtual Out operator()( const In&... ) const = 0;
43  };
44 
45  template <typename Out, typename... In, typename Traits_>
46  struct Transformer<Out( const In&... ), Traits_, false>
49 
50  // derived classes can NOT implement execute
51  StatusCode execute( const EventContext& ctx ) const override final {
52  try {
53  details::put( std::get<0>( this->m_outputs ),
55  return StatusCode::SUCCESS;
56  } catch ( GaudiException& e ) {
57  ( e.code() ? this->warning() : this->error() ) << e.message() << endmsg;
58  return e.code();
59  }
60  }
61 
62  // instead they MUST implement this operator
63  virtual Out operator()( const In&... ) const = 0;
64  };
65 
66  //
67  // general N -> M algorithms
68  //
69  template <typename Signature, typename Traits_, bool isLegacy>
71 
72  template <typename... Out, typename... In, typename Traits_>
73  struct MultiTransformer<std::tuple<Out...>( const In&... ), Traits_, true>
74  : details::DataHandleMixin<std::tuple<Out...>, details::filter_evtcontext<In...>, Traits_> {
76 
77  // derived classes can NOT implement execute
78  StatusCode execute() override final {
79  try {
80  std::apply(
81  [this]( auto&... ohandle ) {
82 
83 #if defined( __clang__ ) && ( __clang_major__ < 6 )
84 // clang-5 gives a spurious warning about not using the captured `ohandle`
85 # pragma clang diagnostic push
86 # pragma clang diagnostic ignored "-Wunused-lambda-capture"
87 #endif
88  std::apply(
89  [&ohandle...]( auto&&... data ) {
90  ( details::put( ohandle, std::forward<decltype( data )>( data ) ), ... );
91  },
92  details::filter_evtcontext_t<In...>::apply( *this, this->m_inputs ) );
93 
94 #if defined( __clang__ ) && ( __clang_major__ < 6 )
95 # pragma clang diagnostic pop
96 #endif
97  },
98  this->m_outputs );
99  return StatusCode::SUCCESS;
100  } catch ( GaudiException& e ) {
101  ( e.code() ? this->warning() : this->error() ) << e.message() << endmsg;
102  return e.code();
103  }
104  }
105 
106  // instead they MUST implement this operator
107  virtual std::tuple<Out...> operator()( const In&... ) const = 0;
108  };
109 
110  template <typename... Out, typename... In, typename Traits_>
111  struct MultiTransformer<std::tuple<Out...>( const In&... ), Traits_, false>
112  : details::DataHandleMixin<std::tuple<Out...>, details::filter_evtcontext<In...>, Traits_> {
114 
115  // derived classes can NOT implement execute
116  StatusCode execute( const EventContext& ctx ) const override final {
117  try {
118  std::apply(
119  [this, &ctx]( auto&... ohandle ) {
120 
121 #if defined( __clang__ ) && ( __clang_major__ < 6 )
122 // clang-5 gives a spurious warning about not using the captured `ohandle`
123 # pragma clang diagnostic push
124 # pragma clang diagnostic ignored "-Wunused-lambda-capture"
125 #endif
126  std::apply(
127  [&ohandle...]( auto&&... data ) {
128  ( details::put( ohandle, std::forward<decltype( data )>( data ) ), ... );
129  },
130  details::filter_evtcontext_t<In...>::apply( *this, ctx, this->m_inputs ) );
131 
132 #if defined( __clang__ ) && ( __clang_major__ < 6 )
133 # pragma clang diagnostic pop
134 #endif
135  },
136  this->m_outputs );
137  return StatusCode::SUCCESS;
138  } catch ( GaudiException& e ) {
139  ( e.code() ? this->warning() : this->error() ) << e.message() << endmsg;
140  return e.code();
141  }
142  }
143 
144  // instead they MUST implement this operator
145  virtual std::tuple<Out...> operator()( const In&... ) const = 0;
146  };
147 
148  //
149  // general N -> M algorithms with filter functionality
150  //
151  template <typename Signature, typename Traits_, bool isLegacy>
153 
154  template <typename... Out, typename... In, typename Traits_>
155  struct MultiTransformerFilter<std::tuple<Out...>( const In&... ), Traits_, true>
156  : details::DataHandleMixin<std::tuple<Out...>, std::tuple<In...>, Traits_> {
158 
159  // derived classes can NOT implement execute
160  StatusCode execute() override final {
161  try {
162  std::apply(
163  [&]( auto&... ohandle ) {
164  std::apply(
165  [&ohandle..., this]( bool passed, auto&&... data ) {
166  this->setFilterPassed( passed );
167  ( details::put( ohandle, std::forward<decltype( data )>( data ) ), ... );
168  },
169  details::filter_evtcontext_t<In...>::apply( *this, this->m_inputs ) );
170  },
171  this->m_outputs );
172  return StatusCode::SUCCESS;
173  } catch ( GaudiException& e ) {
174  ( e.code() ? this->warning() : this->error() ) << e.message() << endmsg;
175  return e.code();
176  }
177  }
178 
179  // instead they MUST implement this operator
180  virtual std::tuple<bool, Out...> operator()( const In&... ) const = 0;
181  };
182 
183  template <typename... Out, typename... In, typename Traits_>
184  struct MultiTransformerFilter<std::tuple<Out...>( const In&... ), Traits_, false>
185  : details::DataHandleMixin<std::tuple<Out...>, std::tuple<In...>, Traits_> {
187 
188  // derived classes can NOT implement execute
189  StatusCode execute( const EventContext& ctx ) const override final {
190  try {
191  std::apply(
192  [&]( auto&... ohandle ) {
193  std::apply(
194  [&ohandle..., &ctx, this]( bool passed, auto&&... data ) {
195  this->execState( ctx ).setFilterPassed( passed );
196  ( details::put( ohandle, std::forward<decltype( data )>( data ) ), ... );
197  },
198  details::filter_evtcontext_t<In...>::apply( *this, ctx, this->m_inputs ) );
199  },
200  this->m_outputs );
201  return StatusCode::SUCCESS;
202  } catch ( GaudiException& e ) {
203  ( e.code() ? this->warning() : this->error() ) << e.message() << endmsg;
204  return e.code();
205  }
206  }
207 
208  // instead they MUST implement this operator
209  virtual std::tuple<bool, Out...> operator()( const In&... ) const = 0;
210  };
211  } // namespace details
212 
213  template <typename Signature, typename Traits_ = Traits::useDefaults>
215 
216  template <typename Signature, typename Traits_ = Traits::useDefaults>
218 
219  template <typename Signature, typename Traits_ = Traits::useDefaults>
221 
222 } // namespace Gaudi::Functional
223 
224 #endif
class MergingTransformer< Out(const vector_of_const_< In > true
virtual const std::string & message() const
error message to be printed
Define general base for Gaudi exception.
virtual Out operator()(const vector_of_const_< In > &inputs) const =0
constexpr static const auto SUCCESS
Definition: StatusCode.h:85
STL namespace.
typename filter_evtcontext_t< In... >::type filter_evtcontext
This class represents an entry point to all the event specific data.
Definition: EventContext.h:24
virtual const StatusCode & code() const
StatusCode for Exception.
StatusCode execute(const EventContext &ctx) const override final
Definition: Transformer.h:51
std::vector< InputHandle_t< In > > m_inputs
class MergingTransformer< Out(const vector_of_const_< In > Traits_
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:50
Out1 * put(const DataObjectHandle< Out1 > &out_handle, Out2 &&out)
class MergingTransformer< Out(const vector_of_const_< In > false
Header file for std:chrono::duration-based Counters.
Definition: __init__.py:1
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:192