The Gaudi Framework  v30r2 (9eca68f7)
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
34  {
35  try {
36  invoke( std::index_sequence_for<In...>{} );
37  return StatusCode::SUCCESS;
38  } catch ( GaudiException& e ) {
39  ( e.code() ? this->warning() : this->error() ) << e.message() << endmsg;
40  return e.code();
41  }
42  }
43 
44  // instead they MUST implement this operator
45  virtual Out operator()( const In&... ) const = 0;
46 
47  private:
48  template <std::size_t... I>
49  void invoke( std::index_sequence<I...> )
50  {
51  details::put( std::get<0>( this->m_outputs ),
52  details::as_const( *this )( details::deref( std::get<I>( this->m_inputs ).get() )... ) );
53  }
54  };
55 
56  //
57  // general N -> M algorithms
58  //
59  template <typename Signature, typename Traits_ = Traits::useDefaults>
61 
62  template <typename... Out, typename... In, typename Traits_>
63  class MultiTransformer<std::tuple<Out...>( const In&... ), Traits_>
64  : public details::DataHandleMixin<std::tuple<Out...>, std::tuple<In...>, Traits_>
65  {
66  public:
67  using details::DataHandleMixin<std::tuple<Out...>, std::tuple<In...>, Traits_>::DataHandleMixin;
68 
69  // derived classes can NOT implement execute
70  StatusCode execute() override final
71  {
72  try {
73  invoke( std::index_sequence_for<In...>{}, std::index_sequence_for<Out...>{} );
74  return StatusCode::SUCCESS;
75  } catch ( GaudiException& e ) {
76  ( e.code() ? this->warning() : this->error() ) << e.message() << endmsg;
77  return e.code();
78  }
79  }
80 
81  // instead they MUST implement this operator
82  virtual std::tuple<Out...> operator()( const In&... ) const = 0;
83 
84  private:
85  template <std::size_t... I, std::size_t... O>
86  void invoke( std::index_sequence<I...>, std::index_sequence<O...> )
87  {
88  auto out = details::as_const( *this )( details::deref( std::get<I>( this->m_inputs ).get() )... );
89 #if __cplusplus < 201703L
91  ( details::put( std::get<O>( this->m_outputs ), std::get<O>( std::move( out ) ) ), 0 )...};
92 #else
93  ( details::put( std::get<O>( this->m_outputs ), std::get<O>( std::move( out ) ) ), ... );
94 #endif
95  }
96  };
97 
98  //
99  // general N -> M algorithms with filter functionality
100  //
101  template <typename Signature, typename Traits_ = Traits::useDefaults>
103 
104  template <typename... Out, typename... In, typename Traits_>
105  class MultiTransformerFilter<std::tuple<Out...>( const In&... ), Traits_>
106  : public details::DataHandleMixin<std::tuple<Out...>, std::tuple<In...>, Traits_>
107  {
108  public:
109  using details::DataHandleMixin<std::tuple<Out...>, std::tuple<In...>, Traits_>::DataHandleMixin;
110 
111  // derived classes can NOT implement execute
112  StatusCode execute() override final
113  {
114  try {
115  invoke( std::index_sequence_for<In...>{}, std::index_sequence_for<Out...>{} );
116  return StatusCode::SUCCESS;
117  } catch ( GaudiException& e ) {
118  ( e.code() ? this->warning() : this->error() ) << e.message() << endmsg;
119  return e.code();
120  }
121  }
122 
123  // instead they MUST implement this operator
124  virtual std::tuple<bool, Out...> operator()( const In&... ) const = 0;
125 
126  private:
127  template <std::size_t... I, std::size_t... O>
128  void invoke( std::index_sequence<I...>, std::index_sequence<O...> )
129  {
130  auto out = details::as_const( *this )( details::deref( std::get<I>( this->m_inputs ).get() )... );
131  this->setFilterPassed( std::get<0>( out ) );
133  ( details::put( std::get<O>( this->m_outputs ), std::get<O + 1>( std::move( out ) ) ), 0 )...};
134  }
135  };
136  }
137 }
138 
139 #endif
virtual const std::string & message() const
error message to be printed
Define general base for Gaudi exception.
STL namespace.
class MergingTransformer< Out(const vector_of_const_< In > void
void invoke(std::index_sequence< I... >, std::index_sequence< O... >)
Definition: Transformer.h:86
constexpr struct Gaudi::Functional::details::deref_t deref
virtual const StatusCode & code() const
StatusCode for Exception.
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:51
void invoke(std::index_sequence< I... >, std::index_sequence< O... >)
Definition: Transformer.h:128
T move(T...args)
constexpr static const auto SUCCESS
Definition: StatusCode.h:87
constexpr std::add_const_t< T > & as_const(T &t) noexcept
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:85
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)