All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
Transformer.h
Go to the documentation of this file.
1 #ifndef TRANSFORMER_H
2 #define TRANSFORMER_H
3 
4 #include <utility>
5 #include <type_traits>
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 { namespace Functional {
17 
18  template <typename Signature,typename Traits_= Traits::useDefaults> class Transformer;
19 
20  // general N -> 1 algorithms
21  template <typename Out, typename... In, typename Traits_>
22  class Transformer<Out(const In&...),Traits_>
24  {
25  public:
26  using details::DataHandleMixin<std::tuple<Out>,std::tuple<In...>,Traits_>::DataHandleMixin;
27 
28  // derived classes can NOT implement execute
29  StatusCode execute() override final
30  { return invoke(std::index_sequence_for<In...>{}); }
31 
32  // instead they MUST implement this operator
33  virtual Out operator()(const In&...) const = 0;
34 
35  private:
36  template <std::size_t... I>
37  StatusCode invoke(std::index_sequence<I...>) {
38  using details::as_const; using details::put;
39  try {
40  put( std::get<0>(this->m_outputs), as_const(*this)( as_const(*std::get<I>(this->m_inputs).get())... ) );
41  } catch ( GaudiException& e ) {
42  (e.code() ? this->warning() : this->error() )
43  << e.message() << endmsg;
44  return e.code();
45  }
46  return StatusCode::SUCCESS;
47  }
48  };
49 
50 //
51 // general N -> M algorithms
52 //
53  template <typename Signature,typename Traits_=Traits::useDefaults> class MultiTransformer;
54 
55  template <typename ... Out, typename... In, typename Traits_>
56  class MultiTransformer<std::tuple<Out...>(const In&...),Traits_>
57  : public details::DataHandleMixin<std::tuple<Out...>, std::tuple<In...>,Traits_>
58  {
59  public:
60  using details::DataHandleMixin<std::tuple<Out...>, std::tuple<In...>,Traits_>::DataHandleMixin;
61 
62  // derived classes can NOT implement execute
63  StatusCode execute() override final
64  { return invoke(std::index_sequence_for<In...>{},std::index_sequence_for<Out...>{}); }
65 
66  // instead they MUST implement this operator
67  virtual std::tuple<Out...> operator()(const In&...) const = 0;
68 
69  private:
70  template <std::size_t... I, std::size_t... O>
71  StatusCode invoke(std::index_sequence<I...>,std::index_sequence<O...>) {
72  using details::as_const; using details::put;
73  try {
74  auto out = as_const(*this)( as_const(*std::get<I>(this->m_inputs).get())... );
76  (put(std::get<O>(this->m_outputs),std::move(std::get<O>(out))),0)...
77  };
78  } catch ( GaudiException& e ) {
79  (e.code() ? this->warning() : this->error() )
80  << e.message() << endmsg;
81  return e.code();
82  }
83  return StatusCode::SUCCESS;
84  }
85  };
86 
87 //
88 // general N -> M algorithms with filter functionality
89 //
90  template <typename Signature,typename Traits_=Traits::useDefaults> class MultiTransformerFilter;
91 
92  template <typename ... Out, typename... In, typename Traits_>
93  class MultiTransformerFilter<std::tuple<Out...>(const In&...),Traits_>
94  : public details::DataHandleMixin<std::tuple<Out...>, std::tuple<In...>,Traits_>
95  {
96  public:
97  using details::DataHandleMixin<std::tuple<Out...>, std::tuple<In...>,Traits_>::DataHandleMixin;
98 
99  // derived classes can NOT implement execute
100  StatusCode execute() override final
101  { return invoke(std::index_sequence_for<In...>{},std::index_sequence_for<Out...>{}); }
102 
103  // instead they MUST implement this operator
104  virtual std::tuple<bool, Out...> operator()(const In&...) const = 0;
105 
106  private:
107  template <std::size_t... I, std::size_t... O>
108  StatusCode invoke(std::index_sequence<I...>,std::index_sequence<O...>) {
109  using details::as_const; using details::put;
110  try {
111  auto out = as_const(*this)( as_const(*std::get<I>(this->m_inputs).get())... );
112  this->setFilterPassed(std::get<0>(out));
114  (put(std::get<O>(this->m_outputs),std::move(std::get<O+1>(out))),0)...
115  };
116  } catch ( GaudiException& e ) {
117  (e.code() ? this->warning() : this->error() )
118  << e.message() << endmsg;
119  return e.code();
120  }
121  return StatusCode::SUCCESS;
122  }
123  };
124 
125 }}
126 
127 #endif
virtual const std::string & message() const
error message to be printed
constexpr std::add_const< T >::type & as_const(T &t) noexcept
Define general base for Gaudi exception.
StatusCode invoke(std::index_sequence< I... >, std::index_sequence< O... >)
Definition: Transformer.h:108
STL namespace.
class MergingTransformer< Out(const vector_of_const_< In > void
virtual const StatusCode & code() const
StatusCode for Exception.
StatusCode invoke(std::index_sequence< I... >)
Definition: Transformer.h:37
class MergingTransformer< Out(const vector_of_const_< In > Traits_
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
T move(T...args)
StatusCode invoke(std::index_sequence< I... >, std::index_sequence< O... >)
Definition: Transformer.h:71
std::vector< InputHandle_t< In > > m_inputs
virtual Out operator()(const vector_of_const_< In > &inputs) const =0
Helper functions to set/get the application return code.
Definition: __init__.py:1
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
Out1 * put(DataObjectHandle< Out1 > &out_handle, Out2 &&out)