Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-03-13 09:09:48

0001 /***********************************************************************************\
0002 * (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations *
0003 *                                                                                   *
0004 * This software is distributed under the terms of the Apache version 2 licence,     *
0005 * copied verbatim in the file "LICENSE".                                            *
0006 *                                                                                   *
0007 * In applying this licence, CERN does not waive the privileges and immunities       *
0008 * granted to it by virtue of its status as an Intergovernmental Organization        *
0009 * or submit itself to any jurisdiction.                                             *
0010 \***********************************************************************************/
0011 #pragma once
0012 
0013 #include "Transformer.h"
0014 
0015 namespace Gaudi::Functional {
0016 
0017   // Scalar->Vector adapted N->1 algorithm
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     /// Access the scalar operator
0024     const ScalarOp& scalarOp() const { return static_cast<const ScalarOp&>( *this ); }
0025 
0026   public:
0027     using Transformer<Out( const In&... ), Traits_>::Transformer;
0028 
0029     /// The main operator
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         /// Call the scalar operator with the objects obtained from the given tuple as arguments
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   // Scalar->Vector adapted N->M algorithm
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     /// Access the scalar operator
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     /// The main operator
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               /// Call the scalar operator with the objects obtained from the given indata,
0069               /// and invoke insert with it (unless the resulting type is an  optional,
0070               /// and the optional is not engaged)
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 } // namespace Gaudi::Functional