| The Gaudi Framework v32r1 (f65d50dc)

Transformer.h
Go to the documentation of this file.
1 #ifndef TRANSFORMER_H
2 #define TRANSFORMER_H
3
4 #include "GaudiAlg/FunctionalDetails.h"
5 #include "GaudiAlg/FunctionalUtilities.h"
6 #include "GaudiKernel/GaudiException.h"
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 ::Functional {
17
18 namespace details {
19
20 template <typename Signature, typename Traits_, bool isLegacy>
21 struct Transformer;
22
23 // general N -> 1 algorithms
24 template <typename Out, typename... In, typename Traits_>
25 struct Transformer<Out( const In&... ), Traits_, true>
26 : details::DataHandleMixin<std::tuple<Out>, details::filter_evtcontext<In...>, Traits_> {
27 using details::DataHandleMixin<std::tuple<Out>, details::filter_evtcontext<In...>, Traits_>::DataHandleMixin;
28
29 // derived classes can NOT implement execute
30 StatusCode execute() override final {
31 try {
32 details::put( std::get<0>( this->m_outputs ),
33 details::filter_evtcontext_t<In...>::apply( *this, this->m_inputs ) );
34 return StatusCode::SUCCESS;
35 } catch ( GaudiException& e ) {
36 ( e.code() ? this->warning() : this->error() ) << e.message() << endmsg;
37 return e.code();
38 }
39 }
40
41 // instead they MUST implement this operator
42 virtual Out operator()( const In&... ) const = 0;
43 };
44
45 template <typename Out, typename... In, typename Traits_>
46 struct Transformer<Out( const In&... ), Traits_, false>
47 : details::DataHandleMixin<std::tuple<Out>, details::filter_evtcontext<In...>, Traits_> {
48 using details::DataHandleMixin<std::tuple<Out>, details::filter_evtcontext<In...>, Traits_>::DataHandleMixin;
49
50 // derived classes can NOT implement execute
51 StatusCode execute( const EventContext& ctx ) const override final {
52 try {
53 details::put( std::get<0>( this->m_outputs ),
54 details::filter_evtcontext_t<In...>::apply( *this, ctx, this->m_inputs ) );
55 return StatusCode::SUCCESS;
56 } catch ( GaudiException& e ) {
57 ( e.code() ? this->warning() : this->error() ) << e.message() << endmsg;
58 return e.code();
59 }
60 }
61
62 // instead they MUST implement this operator
63 virtual Out operator()( const In&... ) const = 0;
64 };
65
66 //
67 // general N -> M algorithms
68 //
69 template <typename Signature, typename Traits_, bool isLegacy>
70 struct MultiTransformer;
71
72 template <typename... Out, typename... In, typename Traits_>
73 struct MultiTransformer<std::tuple<Out...>( const In&... ), Traits_, true>
74 : details::DataHandleMixin<std::tuple<Out...>, details::filter_evtcontext<In...>, Traits_> {
75 using details::DataHandleMixin<std::tuple<Out...>, details::filter_evtcontext<In...>, Traits_>::DataHandleMixin;
76
77 // derived classes can NOT implement execute
78 StatusCode execute() override final {
79 try {
80 std::apply(
81 [this]( auto&... ohandle ) {
82
83 #if defined( __clang__ ) && ( __clang_major__ < 9 )
84 // clang-8 gives a spurious warning about not using the captured `ohandle`
85 # pragma clang diagnostic push
86 # pragma clang diagnostic ignored "-Wunused-lambda-capture"
87 #endif
88 std::apply(
89 [&ohandle...]( auto&&... data ) {
90 ( details::put( ohandle, std::forward<decltype( data )>( data ) ), ... );
91 },
92 details::filter_evtcontext_t<In...>::apply( *this, this->m_inputs ) );
93
94 #if defined( __clang__ ) && ( __clang_major__ < 9 )
95 # pragma clang diagnostic pop
96 #endif
97 },
98 this->m_outputs );
99 return StatusCode::SUCCESS;
100 } catch ( GaudiException& e ) {
101 ( e.code() ? this->warning() : this->error() ) << e.message() << endmsg;
102 return e.code();
103 }
104 }
105
106 // instead they MUST implement this operator
107 virtual std::tuple<Out...> operator()( const In&... ) const = 0;
108 };
109
110 template <typename... Out, typename... In, typename Traits_>
111 struct MultiTransformer<std::tuple<Out...>( const In&... ), Traits_, false>
112 : details::DataHandleMixin<std::tuple<Out...>, details::filter_evtcontext<In...>, Traits_> {
113 using details::DataHandleMixin<std::tuple<Out...>, details::filter_evtcontext<In...>, Traits_>::DataHandleMixin;
114
115 // derived classes can NOT implement execute
116 StatusCode execute( const EventContext& ctx ) const override final {
117 try {
118 std::apply(
119 [this, &ctx]( auto&... ohandle ) {
120
121 #if defined( __clang__ ) && ( __clang_major__ < 6 )
122 // clang-5 gives a spurious warning about not using the captured `ohandle`
123 # pragma clang diagnostic push
124 # pragma clang diagnostic ignored "-Wunused-lambda-capture"
125 #endif
126 std::apply(
127 [&ohandle...]( auto&&... data ) {
128 ( details::put( ohandle, std::forward<decltype( data )>( data ) ), ... );
129 },
130 details::filter_evtcontext_t<In...>::apply( *this, ctx, this->m_inputs ) );
131
132 #if defined( __clang__ ) && ( __clang_major__ < 6 )
133 # pragma clang diagnostic pop
134 #endif
135 },
136 this->m_outputs );
137 return StatusCode::SUCCESS;
138 } catch ( GaudiException& e ) {
139 ( e.code() ? this->warning() : this->error() ) << e.message() << endmsg;
140 return e.code();
141 }
142 }
143
144 // instead they MUST implement this operator
145 virtual std::tuple<Out...> operator()( const In&... ) const = 0;
146 };
147
148 //
149 // general N -> M algorithms with filter functionality
150 //
151 template <typename Signature, typename Traits_, bool isLegacy>
152 struct MultiTransformerFilter;
153
154 template <typename... Out, typename... In, typename Traits_>
155 struct MultiTransformerFilter<std::tuple<Out...>( const In&... ), Traits_, true>
156 : details::DataHandleMixin<std::tuple<Out...>, std::tuple<In...>, Traits_> {
157 using details::DataHandleMixin<std::tuple<Out...>, std::tuple<In...>, Traits_>::DataHandleMixin;
158
159 // derived classes can NOT implement execute
160 StatusCode execute() override final {
161 try {
162 std::apply(
163 [&]( auto&... ohandle ) {
164 std::apply(
165 [&ohandle..., this]( bool passed, auto&&... data ) {
166 this->setFilterPassed( passed );
167 ( details::put( ohandle, std::forward<decltype( data )>( data ) ), ... );
168 },
169 details::filter_evtcontext_t<In...>::apply( *this, this->m_inputs ) );
170 },
171 this->m_outputs );
172 return StatusCode::SUCCESS;
173 } catch ( GaudiException& e ) {
174 ( e.code() ? this->warning() : this->error() ) << e.message() << endmsg;
175 return e.code();
176 }
177 }
178
179 // instead they MUST implement this operator
180 virtual std::tuple<bool, Out...> operator()( const In&... ) const = 0;
181 };
182
183 template <typename... Out, typename... In, typename Traits_>
184 struct MultiTransformerFilter<std::tuple<Out...>( const In&... ), Traits_, false>
185 : details::DataHandleMixin<std::tuple<Out...>, std::tuple<In...>, Traits_> {
186 using details::DataHandleMixin<std::tuple<Out...>, std::tuple<In...>, Traits_>::DataHandleMixin;
187
188 // derived classes can NOT implement execute
189 StatusCode execute( const EventContext& ctx ) const override final {
190 try {
191 std::apply(
192 [&]( auto&... ohandle ) {
193 std::apply(
194 [&ohandle..., &ctx, this]( bool passed, auto&&... data ) {
195 this->execState( ctx ).setFilterPassed( passed );
196 ( details::put( ohandle, std::forward<decltype( data )>( data ) ), ... );
197 },
198 details::filter_evtcontext_t<In...>::apply( *this, ctx, this->m_inputs ) );
199 },
200 this->m_outputs );
201 return StatusCode::SUCCESS;
202 } catch ( GaudiException& e ) {
203 ( e.code() ? this->warning() : this->error() ) << e.message() << endmsg;
204 return e.code();
205 }
206 }
207
208 // instead they MUST implement this operator
209 virtual std::tuple<bool, Out...> operator()( const In&... ) const = 0;
210 };
211 } // namespace details
212
213 template <typename Signature, typename Traits_ = Traits::useDefaults>
214 using Transformer = details::Transformer<Signature, Traits_, details::isLegacy<Traits_>>;
215
216 template <typename Signature, typename Traits_ = Traits::useDefaults>
217 using MultiTransformer = details::MultiTransformer<Signature, Traits_, details::isLegacy<Traits_>>;
218
219 template <typename Signature, typename Traits_ = Traits::useDefaults>
220 using MultiTransformerFilter = details::MultiTransformerFilter<Signature, Traits_, details::isLegacy<Traits_>>;
221
222 } // namespace Gaudi::Functional
223
224 #endif
Gaudi ::Functional::details::MultiTransformerFilter< std::tuple< Out... >(const In &...), Traits_, false >::execute
StatusCode execute(const EventContext &ctx) const override final
Definition: Transformer.h:189
Gaudi ::Functional::details::MultiTransformer< std::tuple< Out... >(const In &...), Traits_, false >::execute
StatusCode execute(const EventContext &ctx) const override final
Definition: Transformer.h:116
GaudiException
Define general base for Gaudi exception.
Definition: GaudiException.h:21
GaudiException::message
virtual const std::string & message() const
error message to be printed
Definition: GaudiException.h:58
StatusCode::SUCCESS
constexpr static const auto SUCCESS
Definition: StatusCode.h:85
std
STL namespace.
Gaudi::Functional::details::filter_evtcontext
typename filter_evtcontext_t< In... >::type filter_evtcontext
Definition: FunctionalDetails.h:387
EventContext
This class represents an entry point to all the event specific data.
Definition: EventContext.h:24
Gaudi ::Functional::details::MultiTransformerFilter
Definition: Transformer.h:152
Gaudi ::Functional::details::MultiTransformerFilter< std::tuple< Out... >(const In &...), Traits_, true >::execute
StatusCode execute() override final
Definition: Transformer.h:160
details
Definition: AnyDataWrapper.h:10
StatusCode
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:50
GaudiException.h
FunctionalUtilities.h
std::tuple
GaudiException::code
virtual const StatusCode & code() const
StatusCode for Exception.
Definition: GaudiException.h:76
Gaudi ::Functional::details::MultiTransformer
Definition: Transformer.h:70
Gaudi ::Functional::details::Transformer< Out(const In &...), Traits_, true >::execute
StatusCode execute() override final
Definition: Transformer.h:30
Gaudi::Functional::details::put
Out1 * put(const DataObjectHandle< Out1 > &out_handle, Out2 &&out)
Definition: FunctionalDetails.h:121
Gaudi ::Functional::details::MultiTransformer< std::tuple< Out... >(const In &...), Traits_, true >::execute
StatusCode execute() override final
Definition: Transformer.h:78
Gaudi ::Functional::details::Transformer< Out(const In &...), Traits_, false >::execute
StatusCode execute(const EventContext &ctx) const override final
Definition: Transformer.h:51
Gaudi
Header file for std:chrono::duration-based Counters.
Definition: __init__.py:1
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:192
Gaudi ::Functional::details::Transformer
Definition: Transformer.h:21
FunctionalDetails.h