The Gaudi Framework  master (2e52acd2)
Loading...
Searching...
No Matches
ScalarTransformer.h
Go to the documentation of this file.
1/***********************************************************************************\
2* (c) Copyright 1998-2026 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#pragma once
12#include "Transformer.h"
13#include "zip.h"
14
15namespace Gaudi::Functional {
16 namespace details {
17 template <typename Fun, typename Container>
18 void applyPostProcessing( const Fun& fun, Container& c ) {
19 if constexpr ( requires { fun.postprocess( c ); } ) { fun.postprocess( c ); }
20 }
21 } // namespace details
22
23 // Scalar->Vector adapted N->1 algorithm
24 template <typename ScalarOp, typename TransformerSignature, typename Traits_ = Traits::useDefaults>
26 template <typename ScalarOp, typename Out, typename... In, typename Traits_>
27 class ScalarTransformer<ScalarOp, Out( const In&... ), Traits_> : public Transformer<Out( const In&... ), Traits_> {
28
30 const ScalarOp& scalarOp() const { return static_cast<const ScalarOp&>( *this ); }
31
32 public:
33 using Transformer<Out( const In&... ), Traits_>::Transformer;
34
36 Out operator()( const In&... in ) const override final {
37 const auto inrange = details::zip::range( in... );
38 Out out;
39 out.reserve( inrange.size() );
40 auto& scalar = scalarOp();
41 for ( const auto& tuple : inrange ) {
44 [&out]( auto&& arg ) { details::insert( out, std::forward<decltype( arg )>( arg ) ); },
45 std::apply( [&]( const auto&... i ) { return scalar( details::deref( i )... ); }, tuple ) );
46 }
47 details::applyPostProcessing( scalar, out );
48 return out;
49 }
50 };
51
52 // Scalar->Vector adapted N->M algorithm
53 template <typename ScalarOp, typename TransformerSignature, typename Traits_ = Traits::useDefaults>
55 template <typename ScalarOp, typename... Out, typename... In, typename Traits_>
56 class MultiScalarTransformer<ScalarOp, std::tuple<Out...>( const In&... ), Traits_>
57 : public MultiTransformer<std::tuple<Out...>( const In&... ), Traits_> {
58
60 const ScalarOp& scalarOp() const { return static_cast<const ScalarOp&>( *this ); }
61
62 public:
63 using MultiTransformer<std::tuple<Out...>( const In&... ), Traits_>::MultiTransformer;
64
66 std::tuple<Out...> operator()( const In&... in ) const override final {
67 const auto inrange = details::zip::range( in... );
68 std::tuple<Out...> out;
69 std::apply( [sz = inrange.size()]( auto&&... o ) { ( o.reserve( sz ), ... ); }, out );
70 auto& scalar = scalarOp();
71 for ( const auto& indata : inrange ) {
72 std::apply(
73 [&scalar, &indata]( auto&... out ) {
78 [&out...]( auto&& outdata ) {
79 std::apply(
80 [&out...]( auto&&... outdata1 ) {
81 ( details::insert( out, std::forward<decltype( outdata1 )>( outdata1 ) ), ... );
82 },
83 std::forward<decltype( outdata )>( outdata ) );
84 },
85 std::apply( [&scalar]( const auto&... args ) { return scalar( details::deref( args )... ); },
86 indata ) );
87 },
88 out );
89 }
90 details::applyPostProcessing( scalar, out );
91 return out;
92 }
93 };
94} // namespace Gaudi::Functional
std::tuple< Out... > operator()(const In &... in) const override final
The main operator.
Out operator()(const In &... in) const override final
The main operator.
decltype(auto) range(Args &&... args)
Zips multiple containers together to form a single range.
Definition zip.h:67
void applyPostProcessing(const Fun &fun, Container &c)
constexpr struct Gaudi::Functional::details::deref_t deref
constexpr struct Gaudi::Functional::details::insert_t insert
constexpr struct Gaudi::Functional::details::invoke_optionally_t invoke_optionally
STL namespace.