Loading [MathJax]/extensions/tex2jax.js
The Gaudi Framework  v36r16 (ea80daf8)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
Transformer.h
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations *
3 * *
4 * This software is distributed under the terms of the Apache version 2 licence, *
5 * copied verbatim in the file "LICENSE". *
6 * *
7 * In applying this licence, CERN does not waive the privileges and immunities *
8 * granted to it by virtue of its status as an Intergovernmental Organization *
9 * or submit itself to any jurisdiction. *
10 \***********************************************************************************/
11 
12 #pragma once
13 
18 #include <type_traits>
19 #include <utility>
20 
21 // Adapt an Algorithm (by default, GaudiAlgorithm) so that derived classes
22 // a) do not need to access the event store, and have to explicitly
23 // state their data dependencies
24 // b) are encouraged not to have state which depends on the events
25 // (eg. histograms, counters will have to be mutable)
26 
27 namespace Gaudi ::Functional {
28 
29  namespace details {
30 
31  template <typename Signature, typename Traits_, bool isLegacy>
32  struct Transformer;
33 
34  // general N -> 1 algorithms
35  template <typename Out, typename... In, typename Traits_>
36  struct Transformer<Out( const In&... ), Traits_, true>
37  : DataHandleMixin<std::tuple<Out>, filter_evtcontext<In...>, Traits_> {
38  using DataHandleMixin<std::tuple<Out>, filter_evtcontext<In...>, Traits_>::DataHandleMixin;
39 
40  // derived classes can NOT implement execute
41  StatusCode execute() override final {
42  try {
43  if constexpr ( sizeof...( In ) == 0 ) {
44  put( std::get<0>( this->m_outputs ), ( *this )() );
45  } else if constexpr ( std::tuple_size_v<filter_evtcontext<In...>> == 0 ) {
46  put( std::get<0>( this->m_outputs ), ( *this )( Gaudi::Hive::currentContext() ) );
47  } else {
48  put( std::get<0>( this->m_outputs ), filter_evtcontext_t<In...>::apply( *this, this->m_inputs ) );
49  }
50  return FilterDecision::PASSED;
51  } catch ( GaudiException& e ) {
52  ( e.code() ? this->warning() : this->error() ) << e.tag() << " : " << e.message() << endmsg;
53  return e.code();
54  }
55  }
56 
57  // instead they MUST implement this operator
58  virtual Out operator()( const In&... ) const = 0;
59  };
60 
61  template <typename Out, typename... In, typename Traits_>
62  struct Transformer<Out( const In&... ), Traits_, false>
63  : DataHandleMixin<std::tuple<Out>, filter_evtcontext<In...>, Traits_> {
64  using DataHandleMixin<std::tuple<Out>, filter_evtcontext<In...>, Traits_>::DataHandleMixin;
65 
66  // derived classes can NOT implement execute
67  StatusCode execute( const EventContext& ctx ) const override final {
68  try {
69  if constexpr ( sizeof...( In ) == 0 ) {
70  put( std::get<0>( this->m_outputs ), ( *this )() );
71  } else if constexpr ( std::tuple_size_v<filter_evtcontext<In...>> == 0 ) {
72  put( std::get<0>( this->m_outputs ), ( *this )( ctx ) );
73  } else {
74  put( std::get<0>( this->m_outputs ), filter_evtcontext_t<In...>::apply( *this, ctx, this->m_inputs ) );
75  }
76  return FilterDecision::PASSED;
77  } catch ( GaudiException& e ) {
78  ( e.code() ? this->warning() : this->error() ) << e.tag() << " : " << e.message() << endmsg;
79  return e.code();
80  }
81  }
82 
83  // instead they MUST implement this operator
84  virtual Out operator()( const In&... ) const = 0;
85  };
86 
87  //
88  // general N -> M algorithms
89  //
90  template <typename Signature, typename Traits_, bool isLegacy>
92 
93  template <typename... Out, typename... In, typename Traits_>
94  struct MultiTransformer<std::tuple<Out...>( const In&... ), Traits_, true>
95  : DataHandleMixin<std::tuple<Out...>, filter_evtcontext<In...>, Traits_> {
96  using DataHandleMixin<std::tuple<Out...>, filter_evtcontext<In...>, Traits_>::DataHandleMixin;
97 
98  // derived classes can NOT implement execute
99  StatusCode execute() override final {
100  try {
101  std::apply(
102  [this]( auto&... ohandle ) {
104 
105  if constexpr ( sizeof...( In ) == 0 ) {
106  std::apply( [&ohandle...](
107  auto&&... data ) { ( put( ohandle, std::forward<decltype( data )>( data ) ), ... ); },
108  std::as_const( *this )() );
109  } else {
110  std::apply( [&ohandle...](
111  auto&&... data ) { ( put( ohandle, std::forward<decltype( data )>( data ) ), ... ); },
112  filter_evtcontext_t<In...>::apply( std::as_const( *this ), this->m_inputs ) );
113  }
115  },
116  this->m_outputs );
117  return FilterDecision::PASSED;
118  } catch ( GaudiException& e ) {
119  ( e.code() ? this->warning() : this->error() ) << e.tag() << " : " << e.message() << endmsg;
120  return e.code();
121  }
122  }
123 
124  // instead they MUST implement this operator
125  virtual std::tuple<Out...> operator()( const In&... ) const = 0;
126  };
127 
128  template <typename... Out, typename... In, typename Traits_>
129  struct MultiTransformer<std::tuple<Out...>( const In&... ), Traits_, false>
130  : DataHandleMixin<std::tuple<Out...>, filter_evtcontext<In...>, Traits_> {
131  using DataHandleMixin<std::tuple<Out...>, filter_evtcontext<In...>, Traits_>::DataHandleMixin;
132 
133  // derived classes can NOT implement execute
134  StatusCode execute( const EventContext& ctx ) const override final {
135  try {
137  std::apply(
138  [this, &ctx]( auto&... ohandle ) {
139  if constexpr ( sizeof...( In ) == 0 ) {
140  std::apply( [&ohandle...](
141  auto&&... data ) { ( put( ohandle, std::forward<decltype( data )>( data ) ), ... ); },
142  ( *this )() );
143  } else if constexpr ( std::tuple_size_v<filter_evtcontext<In...>> == 0 ) {
144  std::apply( [&ohandle...](
145  auto&&... data ) { ( put( ohandle, std::forward<decltype( data )>( data ) ), ... ); },
146  ( *this )( ctx ) );
147  } else {
148  std::apply( [&ohandle...](
149  auto&&... data ) { ( put( ohandle, std::forward<decltype( data )>( data ) ), ... ); },
150  filter_evtcontext_t<In...>::apply( *this, ctx, this->m_inputs ) );
151  }
152  },
153  this->m_outputs );
155  return FilterDecision::PASSED;
156  } catch ( GaudiException& e ) {
157  ( e.code() ? this->warning() : this->error() ) << e.tag() << " : " << e.message() << endmsg;
158  return e.code();
159  }
160  }
161 
162  // instead they MUST implement this operator
163  virtual std::tuple<Out...> operator()( const In&... ) const = 0;
164  };
165 
166  //
167  // general N -> M algorithms with filter functionality
168  //
169  template <typename Signature, typename Traits_, bool isLegacy>
171 
172  template <typename... Out, typename... In, typename Traits_>
173  struct MultiTransformerFilter<std::tuple<Out...>( const In&... ), Traits_, true>
174  : DataHandleMixin<std::tuple<Out...>, filter_evtcontext<In...>, Traits_> {
175  using DataHandleMixin<std::tuple<Out...>, filter_evtcontext<In...>, Traits_>::DataHandleMixin;
176 
177  // derived classes can NOT implement execute
178  StatusCode execute() override final {
179  try {
180  return std::apply(
181  [&]( auto&... ohandle ) {
183  return std::apply(
184  [&ohandle...]( bool passed, auto&&... data ) {
185  ( put( ohandle, std::forward<decltype( data )>( data ) ), ... );
186  return passed;
187  },
188  filter_evtcontext_t<In...>::apply( *this, this->m_inputs ) );
190  },
191  this->m_outputs )
192  ? FilterDecision::PASSED
193  : FilterDecision::FAILED;
194  } catch ( GaudiException& e ) {
195  ( e.code() ? this->warning() : this->error() ) << e.tag() << " : " << e.message() << endmsg;
196  return e.code();
197  }
198  }
199 
200  // instead they MUST implement this operator
201  virtual std::tuple<bool, Out...> operator()( const In&... ) const = 0;
202  };
203 
204  template <typename... Out, typename... In, typename Traits_>
205  struct MultiTransformerFilter<std::tuple<Out...>( const In&... ), Traits_, false>
206  : DataHandleMixin<std::tuple<Out...>, filter_evtcontext<In...>, Traits_> {
207  using DataHandleMixin<std::tuple<Out...>, filter_evtcontext<In...>, Traits_>::DataHandleMixin;
208 
209  // derived classes can NOT implement execute
210  StatusCode execute( const EventContext& ctx ) const override final {
211  try {
212  return std::apply(
213  GF_SUPPRESS_SPURIOUS_CLANG_WARNING_BEGIN[&]( auto&... ohandle ) {
214  return std::apply(
215  [&ohandle...]( bool passed, auto&&... data ) {
216  ( put( ohandle, std::forward<decltype( data )>( data ) ), ... );
217  return passed;
218  },
219  filter_evtcontext_t<In...>::apply( *this, ctx, this->m_inputs ) );
220  },
222 
223  this->m_outputs )
224  ? FilterDecision::PASSED
225  : FilterDecision::FAILED;
226  } catch ( GaudiException& e ) {
227  ( e.code() ? this->warning() : this->error() ) << e.tag() << " : " << e.message() << endmsg;
228  return e.code();
229  }
230  }
231 
232  // instead they MUST implement this operator
233  virtual std::tuple<bool, Out...> operator()( const In&... ) const = 0;
234  };
235  } // namespace details
236 
237  template <typename Signature, typename Traits_ = Traits::useDefaults>
239 
240  template <typename Signature, typename Traits_ = Traits::useDefaults>
242 
243  template <typename Signature, typename Traits_ = Traits::useDefaults>
245 
246 } // namespace Gaudi::Functional
Gaudi ::Functional::details::MultiTransformerFilter< std::tuple< Out... >(const In &...), Traits_, false >::execute
StatusCode execute(const EventContext &ctx) const override final
Definition: Transformer.h:210
Gaudi ::Functional::details::MultiTransformer< std::tuple< Out... >(const In &...), Traits_, true >::execute
StatusCode execute() override final
Definition: Transformer.h:99
GF_SUPPRESS_SPURIOUS_CLANG_WARNING_BEGIN
#define GF_SUPPRESS_SPURIOUS_CLANG_WARNING_BEGIN
Definition: FunctionalDetails.h:44
Gaudi::Hive::currentContext
GAUDI_API const EventContext & currentContext()
Definition: ThreadLocalContext.cpp:30
Gaudi ::Functional::details::MultiTransformerFilter< std::tuple< Out... >(const In &...), Traits_, false >::operator()
virtual std::tuple< bool, Out... > operator()(const In &...) const =0
GaudiException.h
Gaudi ::Functional::details::MultiTransformerFilter< std::tuple< Out... >(const In &...), Traits_, true >::operator()
virtual std::tuple< bool, Out... > operator()(const In &...) const =0
GaudiException
Definition: GaudiException.h:31
std::tuple
Gaudi ::Functional::details::MultiTransformerFilter< std::tuple< Out... >(const In &...), Traits_, true >::execute
StatusCode execute() override final
Definition: Transformer.h:178
Gaudi ::Functional::details::Transformer< Out(const In &...), Traits_, true >::operator()
virtual Out operator()(const In &...) const =0
Gaudi ::Functional::details::MultiTransformerFilter
Definition: Transformer.h:170
GaudiException::message
virtual const std::string & message() const
error message to be printed
Definition: GaudiException.h:68
GaudiPython.Pythonizations.ctx
ctx
Definition: Pythonizations.py:588
StatusCode
Definition: StatusCode.h:65
details
Definition: AnyDataWrapper.h:18
Gaudi ::Functional::details::Transformer< Out(const In &...), Traits_, true >::execute
StatusCode execute() override final
Definition: Transformer.h:41
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:203
GaudiException::tag
virtual const std::string & tag() const
name tag for the exception, or exception type
Definition: GaudiException.h:77
Gaudi ::Functional::details::MultiTransformer< std::tuple< Out... >(const In &...), Traits_, false >::operator()
virtual std::tuple< Out... > operator()(const In &...) const =0
Gaudi
Header file for std:chrono::duration-based Counters.
Definition: __init__.py:1
FunctionalUtilities.h
GaudiException::code
virtual const StatusCode & code() const
StatusCode for Exception.
Definition: GaudiException.h:86
Gaudi ::Functional::details::MultiTransformer< std::tuple< Out... >(const In &...), Traits_, true >::operator()
virtual std::tuple< Out... > operator()(const In &...) const =0
std
STL namespace.
Gaudi ::Functional::details::MultiTransformer
Definition: Transformer.h:91
EventContext
Definition: EventContext.h:34
Gaudi ::Functional::details::Transformer
Definition: Transformer.h:32
GF_SUPPRESS_SPURIOUS_CLANG_WARNING_END
#define GF_SUPPRESS_SPURIOUS_CLANG_WARNING_END
Definition: FunctionalDetails.h:45
Gaudi ::Functional::details::Transformer< Out(const In &...), Traits_, false >::operator()
virtual Out operator()(const In &...) const =0
FunctionalDetails.h
Gaudi ::Functional::details::MultiTransformer< std::tuple< Out... >(const In &...), Traits_, false >::execute
StatusCode execute(const EventContext &ctx) const override final
Definition: Transformer.h:134
Gaudi ::Functional::details::Transformer< Out(const In &...), Traits_, false >::execute
StatusCode execute(const EventContext &ctx) const override final
Definition: Transformer.h:67
FunctionalFilterDecision.h
Gaudi::Functional::details::filter_evtcontext
typename filter_evtcontext_t< In... >::type filter_evtcontext
Definition: FunctionalDetails.h:501
Gaudi::Functional::details::put
auto put(const DataObjectHandle< Out1 > &out_handle, Out2 &&out)
Definition: FunctionalDetails.h:173