The Gaudi Framework  v29r3 (fa547fc2)
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() )... );
85 #if __cplusplus < 201703L
87  ( put( std::get<O>( this->m_outputs ), std::move( std::get<O>( out ) ) ), 0 )...};
88 #else
89  ( put( std::get<O>( this->m_outputs ), std::move( std::get<O>( out ) ) ), ... );
90 #endif
91  } catch ( GaudiException& e ) {
92  ( e.code() ? this->warning() : this->error() ) << e.message() << endmsg;
93  return e.code();
94  }
95  return StatusCode::SUCCESS;
96  }
97  };
98 
99  //
100  // general N -> M algorithms with filter functionality
101  //
102  template <typename Signature, typename Traits_ = Traits::useDefaults>
104 
105  template <typename... Out, typename... In, typename Traits_>
106  class MultiTransformerFilter<std::tuple<Out...>( const In&... ), Traits_>
107  : public details::DataHandleMixin<std::tuple<Out...>, std::tuple<In...>, Traits_>
108  {
109  public:
110  using details::DataHandleMixin<std::tuple<Out...>, std::tuple<In...>, Traits_>::DataHandleMixin;
111 
112  // derived classes can NOT implement execute
113  StatusCode execute() override final
114  {
115  return invoke( std::index_sequence_for<In...>{}, std::index_sequence_for<Out...>{} );
116  }
117 
118  // instead they MUST implement this operator
119  virtual std::tuple<bool, Out...> operator()( const In&... ) const = 0;
120 
121  private:
122  template <std::size_t... I, std::size_t... O>
123  StatusCode invoke( std::index_sequence<I...>, std::index_sequence<O...> )
124  {
125  using details::as_const;
126  using details::put;
127  try {
128  auto out = as_const( *this )( as_const( *std::get<I>( this->m_inputs ).get() )... );
129  this->setFilterPassed( std::get<0>( out ) );
131  ( put( std::get<O>( this->m_outputs ), std::move( std::get<O + 1>( out ) ) ), 0 )...};
132  } catch ( GaudiException& e ) {
133  ( e.code() ? this->warning() : this->error() ) << e.message() << endmsg;
134  return e.code();
135  }
136  return StatusCode::SUCCESS;
137  }
138  };
139  }
140 }
141 
142 #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:123
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:26
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: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)