File indexing completed on 2025-01-30 10:07:03
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #pragma once
0012
0013 #include "details.h"
0014 #include "utilities.h"
0015 #include <GaudiKernel/FunctionalFilterDecision.h>
0016 #include <GaudiKernel/GaudiException.h>
0017 #include <type_traits>
0018 #include <utility>
0019
0020
0021
0022
0023
0024
0025
0026 namespace Gaudi ::Functional {
0027
0028 namespace details {
0029
0030 template <typename Signature, typename Traits_, bool isLegacy>
0031 struct Transformer;
0032
0033
0034 template <typename Out, typename... In, typename Traits_>
0035 struct Transformer<Out( const In&... ), Traits_, true>
0036 : DataHandleMixin<std::tuple<Out>, filter_evtcontext<In...>, Traits_> {
0037 using DataHandleMixin<std::tuple<Out>, filter_evtcontext<In...>, Traits_>::DataHandleMixin;
0038
0039
0040 StatusCode execute() override final {
0041 try {
0042 if constexpr ( sizeof...( In ) == 0 ) {
0043 put( std::get<0>( this->m_outputs ), ( *this )() );
0044 } else if constexpr ( std::tuple_size_v<filter_evtcontext<In...>> == 0 ) {
0045 put( std::get<0>( this->m_outputs ), ( *this )( Gaudi::Hive::currentContext() ) );
0046 } else {
0047 put( std::get<0>( this->m_outputs ), filter_evtcontext_t<In...>::apply( *this, this->m_inputs ) );
0048 }
0049 return FilterDecision::PASSED;
0050 } catch ( GaudiException& e ) {
0051 if ( e.code().isFailure() ) this->error() << e.tag() << " : " << e.message() << endmsg;
0052 return e.code();
0053 }
0054 }
0055
0056
0057 virtual Out operator()( const In&... ) const = 0;
0058 };
0059
0060 template <typename Out, typename... In, typename Traits_>
0061 struct Transformer<Out( const In&... ), Traits_, false>
0062 : DataHandleMixin<std::tuple<Out>, filter_evtcontext<In...>, Traits_> {
0063 using DataHandleMixin<std::tuple<Out>, filter_evtcontext<In...>, Traits_>::DataHandleMixin;
0064
0065
0066 StatusCode execute( const EventContext& ctx ) const override final {
0067 try {
0068 if constexpr ( sizeof...( In ) == 0 ) {
0069 put( std::get<0>( this->m_outputs ), ( *this )() );
0070 } else if constexpr ( std::tuple_size_v<filter_evtcontext<In...>> == 0 ) {
0071 put( std::get<0>( this->m_outputs ), ( *this )( ctx ) );
0072 } else {
0073 put( std::get<0>( this->m_outputs ), filter_evtcontext_t<In...>::apply( *this, ctx, this->m_inputs ) );
0074 }
0075 return FilterDecision::PASSED;
0076 } catch ( GaudiException& e ) {
0077 if ( e.code().isFailure() ) this->error() << e.tag() << " : " << e.message() << endmsg;
0078 return e.code();
0079 }
0080 }
0081
0082
0083 virtual Out operator()( const In&... ) const = 0;
0084 };
0085
0086
0087
0088
0089 template <typename Signature, typename Traits_, bool isLegacy>
0090 struct MultiTransformer;
0091
0092 template <typename... Out, typename... In, typename Traits_>
0093 struct MultiTransformer<std::tuple<Out...>( const In&... ), Traits_, true>
0094 : DataHandleMixin<std::tuple<Out...>, filter_evtcontext<In...>, Traits_> {
0095 using DataHandleMixin<std::tuple<Out...>, filter_evtcontext<In...>, Traits_>::DataHandleMixin;
0096
0097
0098 StatusCode execute() override final {
0099 try {
0100 std::apply(
0101 [this]( auto&... ohandle ) {
0102 GF_SUPPRESS_SPURIOUS_CLANG_WARNING_BEGIN
0103
0104 if constexpr ( sizeof...( In ) == 0 ) {
0105 std::apply( [&ohandle...](
0106 auto&&... data ) { ( put( ohandle, std::forward<decltype( data )>( data ) ), ... ); },
0107 std::as_const( *this )() );
0108 } else {
0109 std::apply( [&ohandle...](
0110 auto&&... data ) { ( put( ohandle, std::forward<decltype( data )>( data ) ), ... ); },
0111 filter_evtcontext_t<In...>::apply( std::as_const( *this ), this->m_inputs ) );
0112 }
0113 GF_SUPPRESS_SPURIOUS_CLANG_WARNING_END
0114 },
0115 this->m_outputs );
0116 return FilterDecision::PASSED;
0117 } catch ( GaudiException& e ) {
0118 if ( e.code().isFailure() ) this->error() << e.tag() << " : " << e.message() << endmsg;
0119 return e.code();
0120 }
0121 }
0122
0123
0124 virtual std::tuple<Out...> operator()( const In&... ) const = 0;
0125 };
0126
0127 template <typename... Out, typename... In, typename Traits_>
0128 struct MultiTransformer<std::tuple<Out...>( const In&... ), Traits_, false>
0129 : DataHandleMixin<std::tuple<Out...>, filter_evtcontext<In...>, Traits_> {
0130 using DataHandleMixin<std::tuple<Out...>, filter_evtcontext<In...>, Traits_>::DataHandleMixin;
0131
0132
0133 StatusCode execute( const EventContext& ctx ) const override final {
0134 try {
0135 GF_SUPPRESS_SPURIOUS_CLANG_WARNING_BEGIN
0136 std::apply(
0137 [this, &ctx]( auto&... ohandle ) {
0138 if constexpr ( sizeof...( In ) == 0 ) {
0139 std::apply( [&ohandle...](
0140 auto&&... data ) { ( put( ohandle, std::forward<decltype( data )>( data ) ), ... ); },
0141 ( *this )() );
0142 } else if constexpr ( std::tuple_size_v<filter_evtcontext<In...>> == 0 ) {
0143 std::apply( [&ohandle...](
0144 auto&&... data ) { ( put( ohandle, std::forward<decltype( data )>( data ) ), ... ); },
0145 ( *this )( ctx ) );
0146 } else {
0147 std::apply( [&ohandle...](
0148 auto&&... data ) { ( put( ohandle, std::forward<decltype( data )>( data ) ), ... ); },
0149 filter_evtcontext_t<In...>::apply( *this, ctx, this->m_inputs ) );
0150 }
0151 },
0152 this->m_outputs );
0153 GF_SUPPRESS_SPURIOUS_CLANG_WARNING_END
0154 return FilterDecision::PASSED;
0155 } catch ( GaudiException& e ) {
0156 if ( e.code().isFailure() ) this->error() << e.tag() << " : " << e.message() << endmsg;
0157 return e.code();
0158 }
0159 }
0160
0161
0162 virtual std::tuple<Out...> operator()( const In&... ) const = 0;
0163 };
0164
0165
0166
0167
0168 template <typename Signature, typename Traits_, bool isLegacy>
0169 struct MultiTransformerFilter;
0170
0171 template <typename... Out, typename... In, typename Traits_>
0172 struct MultiTransformerFilter<std::tuple<Out...>( const In&... ), Traits_, true>
0173 : DataHandleMixin<std::tuple<Out...>, filter_evtcontext<In...>, Traits_> {
0174 using DataHandleMixin<std::tuple<Out...>, filter_evtcontext<In...>, Traits_>::DataHandleMixin;
0175
0176
0177 StatusCode execute() override final {
0178 try {
0179 return std::apply(
0180 [&]( auto&... ohandle ) {
0181 GF_SUPPRESS_SPURIOUS_CLANG_WARNING_BEGIN
0182 return std::apply(
0183 [&ohandle...]( bool passed, auto&&... data ) {
0184 ( put( ohandle, std::forward<decltype( data )>( data ) ), ... );
0185 return passed;
0186 },
0187 filter_evtcontext_t<In...>::apply( *this, this->m_inputs ) );
0188 GF_SUPPRESS_SPURIOUS_CLANG_WARNING_END
0189 },
0190 this->m_outputs )
0191 ? FilterDecision::PASSED
0192 : FilterDecision::FAILED;
0193 } catch ( GaudiException& e ) {
0194 if ( e.code().isFailure() ) this->error() << e.tag() << " : " << e.message() << endmsg;
0195 return e.code();
0196 }
0197 }
0198
0199
0200 virtual std::tuple<bool, Out...> operator()( const In&... ) const = 0;
0201 };
0202
0203 template <typename... Out, typename... In, typename Traits_>
0204 struct MultiTransformerFilter<std::tuple<Out...>( const In&... ), Traits_, false>
0205 : DataHandleMixin<std::tuple<Out...>, filter_evtcontext<In...>, Traits_> {
0206 using DataHandleMixin<std::tuple<Out...>, filter_evtcontext<In...>, Traits_>::DataHandleMixin;
0207
0208
0209 StatusCode execute( const EventContext& ctx ) const override final {
0210 try {
0211 return std::apply(
0212 GF_SUPPRESS_SPURIOUS_CLANG_WARNING_BEGIN[&]( auto&... ohandle ) {
0213 return std::apply(
0214 [&ohandle...]( bool passed, auto&&... data ) {
0215 ( put( ohandle, std::forward<decltype( data )>( data ) ), ... );
0216 return passed;
0217 },
0218 filter_evtcontext_t<In...>::apply( *this, ctx, this->m_inputs ) );
0219 },
0220 GF_SUPPRESS_SPURIOUS_CLANG_WARNING_END
0221
0222 this->m_outputs )
0223 ? FilterDecision::PASSED
0224 : FilterDecision::FAILED;
0225 } catch ( GaudiException& e ) {
0226 if ( e.code().isFailure() ) this->error() << e.tag() << " : " << e.message() << endmsg;
0227 return e.code();
0228 }
0229 }
0230
0231
0232 virtual std::tuple<bool, Out...> operator()( const In&... ) const = 0;
0233 };
0234 }
0235
0236 template <typename Signature, typename Traits_ = Traits::useDefaults>
0237 using Transformer = details::Transformer<Signature, Traits_, details::isLegacy<Traits_>>;
0238
0239 template <typename Signature, typename Traits_ = Traits::useDefaults>
0240 using MultiTransformer = details::MultiTransformer<Signature, Traits_, details::isLegacy<Traits_>>;
0241
0242 template <typename Signature, typename Traits_ = Traits::useDefaults>
0243 using MultiTransformerFilter = details::MultiTransformerFilter<Signature, Traits_, details::isLegacy<Traits_>>;
0244
0245 }