The Gaudi Framework  v29r0 (ff2e7097)
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
17 {
18  namespace Functional
19  {
20 
21  template <typename Signature, typename Traits_ = Traits::useDefaults>
22  class Transformer;
23 
24  // general N -> 1 algorithms
25  template <typename Out, typename... In, typename Traits_>
26  class Transformer<Out( const In&... ), Traits_>
28  {
29  public:
30  using details::DataHandleMixin<std::tuple<Out>, std::tuple<In...>, Traits_>::DataHandleMixin;
31 
32  // derived classes can NOT implement execute
33  StatusCode execute() override final { return invoke( std::index_sequence_for<In...>{} ); }
34 
35  // instead they MUST implement this operator
36  virtual Out operator()( const In&... ) const = 0;
37 
38  private:
39  template <std::size_t... I>
40  StatusCode invoke( std::index_sequence<I...> )
41  {
42  using details::as_const;
43  using details::put;
44  try {
45  put( std::get<0>( this->m_outputs ),
46  as_const( *this )( as_const( *std::get<I>( this->m_inputs ).get() )... ) );
47  } catch ( GaudiException& e ) {
48  ( e.code() ? this->warning() : this->error() ) << e.message() << endmsg;
49  return e.code();
50  }
51  return StatusCode::SUCCESS;
52  }
53  };
54 
55  //
56  // general N -> M algorithms
57  //
58  template <typename Signature, typename Traits_ = Traits::useDefaults>
60 
61  template <typename... Out, typename... In, typename Traits_>
62  class MultiTransformer<std::tuple<Out...>( const In&... ), Traits_>
63  : public details::DataHandleMixin<std::tuple<Out...>, std::tuple<In...>, Traits_>
64  {
65  public:
66  using details::DataHandleMixin<std::tuple<Out...>, std::tuple<In...>, Traits_>::DataHandleMixin;
67 
68  // derived classes can NOT implement execute
69  StatusCode execute() override final
70  {
71  return invoke( std::index_sequence_for<In...>{}, std::index_sequence_for<Out...>{} );
72  }
73 
74  // instead they MUST implement this operator
75  virtual std::tuple<Out...> operator()( const In&... ) const = 0;
76 
77  private:
78  template <std::size_t... I, std::size_t... O>
79  StatusCode invoke( std::index_sequence<I...>, std::index_sequence<O...> )
80  {
81  using details::as_const;
82  using details::put;
83  try {
84  auto out = as_const( *this )( as_const( *std::get<I>( this->m_inputs ).get() )... );
86  ( put( std::get<O>( this->m_outputs ), std::move( std::get<O>( out ) ) ), 0 )...};
87  } catch ( GaudiException& e ) {
88  ( e.code() ? this->warning() : this->error() ) << e.message() << endmsg;
89  return e.code();
90  }
91  return StatusCode::SUCCESS;
92  }
93  };
94 
95  //
96  // general N -> M algorithms with filter functionality
97  //
98  template <typename Signature, typename Traits_ = Traits::useDefaults>
100 
101  template <typename... Out, typename... In, typename Traits_>
102  class MultiTransformerFilter<std::tuple<Out...>( const In&... ), Traits_>
103  : public details::DataHandleMixin<std::tuple<Out...>, std::tuple<In...>, Traits_>
104  {
105  public:
106  using details::DataHandleMixin<std::tuple<Out...>, std::tuple<In...>, Traits_>::DataHandleMixin;
107 
108  // derived classes can NOT implement execute
109  StatusCode execute() override final
110  {
111  return invoke( std::index_sequence_for<In...>{}, std::index_sequence_for<Out...>{} );
112  }
113 
114  // instead they MUST implement this operator
115  virtual std::tuple<bool, Out...> operator()( const In&... ) const = 0;
116 
117  private:
118  template <std::size_t... I, std::size_t... O>
119  StatusCode invoke( std::index_sequence<I...>, std::index_sequence<O...> )
120  {
121  using details::as_const;
122  using details::put;
123  try {
124  auto out = as_const( *this )( as_const( *std::get<I>( this->m_inputs ).get() )... );
125  this->setFilterPassed( std::get<0>( out ) );
127  ( put( std::get<O>( this->m_outputs ), std::move( std::get<O + 1>( out ) ) ), 0 )...};
128  } catch ( GaudiException& e ) {
129  ( e.code() ? this->warning() : this->error() ) << e.message() << endmsg;
130  return e.code();
131  }
132  return StatusCode::SUCCESS;
133  }
134  };
135  }
136 }
137 
138 #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:119
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:40
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:28
T move(T...args)
StatusCode invoke(std::index_sequence< I... >, std::index_sequence< O... >)
Definition: Transformer.h:79
std::vector< InputHandle_t< In > > m_inputs
virtual Out operator()(const vector_of_const_< In > &inputs) const =0
struct[[deprecated("use MergingTransformer instead")]] Traits_
auto invoke(F &&f, ArgTypes &&...args) noexcept(noexcept(detail2::INVOKE(std::forward< F >(f), std::forward< ArgTypes >(args)...))) -> decltype(detail2::INVOKE(std::forward< F >(f), std::forward< ArgTypes >(args)...))
Definition: invoke.h:83
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:209
Out1 * put(DataObjectHandle< Out1 > &out_handle, Out2 &&out)