The Gaudi Framework  v32r2 (46d42edc)
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>
26  : DataHandleMixin<std::tuple<Out>, filter_evtcontext<In...>, Traits_> {
27  using DataHandleMixin<std::tuple<Out>, filter_evtcontext<In...>, Traits_>::DataHandleMixin;
28 
29  // derived classes can NOT implement execute
30  StatusCode execute() override final {
31  try {
32  put( std::get<0>( this->m_outputs ), filter_evtcontext_t<In...>::apply( *this, this->m_inputs ) );
33  return StatusCode::SUCCESS;
34  } catch ( GaudiException& e ) {
35  ( e.code() ? this->warning() : this->error() ) << e.message() << endmsg;
36  return e.code();
37  }
38  }
39 
40  // instead they MUST implement this operator
41  virtual Out operator()( const In&... ) const = 0;
42  };
43 
44  template <typename Out, typename... In, typename Traits_>
45  struct Transformer<Out( const In&... ), Traits_, false>
46  : DataHandleMixin<std::tuple<Out>, filter_evtcontext<In...>, Traits_> {
47  using DataHandleMixin<std::tuple<Out>, filter_evtcontext<In...>, Traits_>::DataHandleMixin;
48 
49  // derived classes can NOT implement execute
50  StatusCode execute( const EventContext& ctx ) const override final {
51  try {
52  put( std::get<0>( this->m_outputs ), filter_evtcontext_t<In...>::apply( *this, ctx, this->m_inputs ) );
53  return StatusCode::SUCCESS;
54  } catch ( GaudiException& e ) {
55  ( e.code() ? this->warning() : this->error() ) << e.message() << endmsg;
56  return e.code();
57  }
58  }
59 
60  // instead they MUST implement this operator
61  virtual Out operator()( const In&... ) const = 0;
62  };
63 
64  //
65  // general N -> M algorithms
66  //
67  template <typename Signature, typename Traits_, bool isLegacy>
69 
70  template <typename... Out, typename... In, typename Traits_>
71  struct MultiTransformer<std::tuple<Out...>( const In&... ), Traits_, true>
72  : DataHandleMixin<std::tuple<Out...>, filter_evtcontext<In...>, Traits_> {
73  using DataHandleMixin<std::tuple<Out...>, filter_evtcontext<In...>, Traits_>::DataHandleMixin;
74 
75  // derived classes can NOT implement execute
76  StatusCode execute() override final {
77  try {
78  std::apply(
79  [this]( auto&... ohandle ) {
81  std::apply( [&ohandle...](
82  auto&&... data ) { ( put( ohandle, std::forward<decltype( data )>( data ) ), ... ); },
83  filter_evtcontext_t<In...>::apply( *this, this->m_inputs ) );
85  },
86  this->m_outputs );
87  return StatusCode::SUCCESS;
88  } catch ( GaudiException& e ) {
89  ( e.code() ? this->warning() : this->error() ) << e.message() << endmsg;
90  return e.code();
91  }
92  }
93 
94  // instead they MUST implement this operator
95  virtual std::tuple<Out...> operator()( const In&... ) const = 0;
96  };
97 
98  template <typename... Out, typename... In, typename Traits_>
99  struct MultiTransformer<std::tuple<Out...>( const In&... ), Traits_, false>
100  : DataHandleMixin<std::tuple<Out...>, filter_evtcontext<In...>, Traits_> {
101  using DataHandleMixin<std::tuple<Out...>, filter_evtcontext<In...>, Traits_>::DataHandleMixin;
102 
103  // derived classes can NOT implement execute
104  StatusCode execute( const EventContext& ctx ) const override final {
105  try {
106  std::apply(
107  [this, &ctx]( auto&... ohandle ) {
109  std::apply( [&ohandle...](
110  auto&&... data ) { ( put( ohandle, std::forward<decltype( data )>( data ) ), ... ); },
111  filter_evtcontext_t<In...>::apply( *this, ctx, this->m_inputs ) );
113  },
114  this->m_outputs );
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  // instead they MUST implement this operator
123  virtual std::tuple<Out...> operator()( const In&... ) const = 0;
124  };
125 
126  //
127  // general N -> M algorithms with filter functionality
128  //
129  template <typename Signature, typename Traits_, bool isLegacy>
131 
132  template <typename... Out, typename... In, typename Traits_>
133  struct MultiTransformerFilter<std::tuple<Out...>( const In&... ), Traits_, true>
134  : DataHandleMixin<std::tuple<Out...>, std::tuple<In...>, Traits_> {
135  using DataHandleMixin<std::tuple<Out...>, std::tuple<In...>, Traits_>::DataHandleMixin;
136 
137  // derived classes can NOT implement execute
138  StatusCode execute() override final {
139  try {
140  std::apply(
141  [&]( auto&... ohandle ) {
143  std::apply(
144  [&ohandle..., this]( bool passed, auto&&... data ) {
145  this->setFilterPassed( passed );
146  ( put( ohandle, std::forward<decltype( data )>( data ) ), ... );
147  },
148  filter_evtcontext_t<In...>::apply( *this, this->m_inputs ) );
150  },
151  this->m_outputs );
152  return StatusCode::SUCCESS;
153  } catch ( GaudiException& e ) {
154  ( e.code() ? this->warning() : this->error() ) << e.message() << endmsg;
155  return e.code();
156  }
157  }
158 
159  // instead they MUST implement this operator
160  virtual std::tuple<bool, Out...> operator()( const In&... ) const = 0;
161  };
162 
163  template <typename... Out, typename... In, typename Traits_>
164  struct MultiTransformerFilter<std::tuple<Out...>( const In&... ), Traits_, false>
165  : DataHandleMixin<std::tuple<Out...>, std::tuple<In...>, Traits_> {
166  using DataHandleMixin<std::tuple<Out...>, std::tuple<In...>, Traits_>::DataHandleMixin;
167 
168  // derived classes can NOT implement execute
169  StatusCode execute( const EventContext& ctx ) const override final {
170  try {
171  std::apply(
173 
174  [&]( auto&... ohandle ) {
175  std::apply(
176  [&ohandle..., &ctx, this]( bool passed, auto&&... data ) {
177  this->execState( ctx ).setFilterPassed( passed );
178  ( put( ohandle, std::forward<decltype( data )>( data ) ), ... );
179  },
180  filter_evtcontext_t<In...>::apply( *this, ctx, this->m_inputs ) );
181  },
183 
184  this->m_outputs );
185  return StatusCode::SUCCESS;
186  } catch ( GaudiException& e ) {
187  ( e.code() ? this->warning() : this->error() ) << e.message() << endmsg;
188  return e.code();
189  }
190  }
191 
192  // instead they MUST implement this operator
193  virtual std::tuple<bool, Out...> operator()( const In&... ) const = 0;
194  };
195  } // namespace details
196 
197  template <typename Signature, typename Traits_ = Traits::useDefaults>
199 
200  template <typename Signature, typename Traits_ = Traits::useDefaults>
202 
203  template <typename Signature, typename Traits_ = Traits::useDefaults>
205 
206 } // namespace Gaudi::Functional
207 
208 #endif
Out1 * put(const DataObjectHandle< Out1 > &out_handle, Out2 &&out)
Define general base for Gaudi exception.
#define GF_SUPPRESS_SPURIOUS_CLANG_WARNING_BEGIN
virtual const std::string & message() const
error message to be printed
constexpr static const auto SUCCESS
Definition: StatusCode.h:85
STL namespace.
This class represents an entry point to all the event specific data.
Definition: EventContext.h:24
typename filter_evtcontext_t< In... >::type filter_evtcontext
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:50
virtual const StatusCode & code() const
StatusCode for Exception.
StatusCode execute(const EventContext &ctx) const override final
Definition: Transformer.h:50
#define GF_SUPPRESS_SPURIOUS_CLANG_WARNING_END
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