File indexing completed on 2025-03-13 09:09:48
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #pragma once
0012
0013 #include "Transformer.h"
0014
0015 namespace Gaudi::Functional {
0016
0017
0018 template <typename ScalarOp, typename TransformerSignature, typename Traits_ = Traits::useDefaults>
0019 class ScalarTransformer;
0020 template <typename ScalarOp, typename Out, typename... In, typename Traits_>
0021 class ScalarTransformer<ScalarOp, Out( const In&... ), Traits_> : public Transformer<Out( const In&... ), Traits_> {
0022
0023
0024 const ScalarOp& scalarOp() const { return static_cast<const ScalarOp&>( *this ); }
0025
0026 public:
0027 using Transformer<Out( const In&... ), Traits_>::Transformer;
0028
0029
0030 Out operator()( const In&... in ) const override final {
0031 const auto inrange = details::zip::range( in... );
0032 Out out;
0033 out.reserve( inrange.size() );
0034 auto& scalar = scalarOp();
0035 for ( const auto&& tuple : inrange ) {
0036
0037 details::invoke_optionally(
0038 [&out]( auto&& arg ) { details::insert( out, std::forward<decltype( arg )>( arg ) ); },
0039 std::apply( [&]( const auto&... i ) { return scalar( details::deref( i )... ); }, tuple ) );
0040 }
0041 details::applyPostProcessing( scalar, out );
0042 return out;
0043 }
0044 };
0045
0046
0047 template <typename ScalarOp, typename TransformerSignature, typename Traits_ = Traits::useDefaults>
0048 class MultiScalarTransformer;
0049 template <typename ScalarOp, typename... Out, typename... In, typename Traits_>
0050 class MultiScalarTransformer<ScalarOp, std::tuple<Out...>( const In&... ), Traits_>
0051 : public MultiTransformer<std::tuple<Out...>( const In&... ), Traits_> {
0052
0053
0054 const ScalarOp& scalarOp() const { return static_cast<const ScalarOp&>( *this ); }
0055
0056 public:
0057 using MultiTransformer<std::tuple<Out...>( const In&... ), Traits_>::MultiTransformer;
0058
0059
0060 std::tuple<Out...> operator()( const In&... in ) const override final {
0061 const auto inrange = details::zip::range( in... );
0062 std::tuple<Out...> out;
0063 std::apply( [sz = inrange.size()]( auto&&... o ) { ( o.reserve( sz ), ... ); }, out );
0064 auto& scalar = scalarOp();
0065 for ( const auto&& indata : inrange ) {
0066 std::apply(
0067 [&scalar, &indata]( auto&... out ) {
0068
0069
0070
0071 details::invoke_optionally(
0072 [&out...]( auto&& outdata ) {
0073 GF_SUPPRESS_SPURIOUS_CLANG_WARNING_BEGIN
0074 std::apply(
0075 [&out...]( auto&&... outdata1 ) {
0076 ( details::insert( out, std::forward<decltype( outdata1 )>( outdata1 ) ), ... );
0077 },
0078 std::forward<decltype( outdata )>( outdata ) );
0079 GF_SUPPRESS_SPURIOUS_CLANG_WARNING_END
0080 },
0081 std::apply( [&scalar]( const auto&... args ) { return scalar( details::deref( args )... ); },
0082 indata ) );
0083 },
0084 out );
0085 }
0086 details::applyPostProcessing( scalar, out );
0087 return out;
0088 }
0089 };
0090 }