Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:57:28

0001 /***********************************************************************************\
0002 * (c) Copyright 1998-2022 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 <Gaudi/Accumulators.h>
0014 #include <array>
0015 #include <string>
0016 #include <utility>
0017 
0018 namespace Gaudi::Accumulators {
0019 
0020   namespace details {
0021 
0022     /**
0023      * Default formating for counter names, only calling fmt::format
0024      * on the text given at construction and passing the histo index as argument
0025      */
0026     struct FormatCounterDefault {
0027       std::string_view text;
0028       FormatCounterDefault( std::string_view t ) : text{ t } {}
0029       std::string operator()( size_t n );
0030     };
0031 
0032     /**
0033      * internal class implementing an array of counters
0034      * @see CounterArray
0035      */
0036     template <typename Counter, std::size_t N>
0037     struct CounterArrayInternal : std::array<Counter, N> {
0038       /// constructor with callables for FormatName
0039       template <typename OWNER, typename FormatName, std::size_t... Ns,
0040                 typename = typename std::enable_if_t<std::is_invocable_v<FormatName, int>>>
0041       CounterArrayInternal( OWNER* owner, FormatName&& fname, std::integer_sequence<std::size_t, Ns...> )
0042           : std::array<Counter, N>{ Counter{ owner, fname( Ns ) }... } {
0043         static_assert( sizeof...( Ns ) < 1000, "Using CounterArray with 1000 arrays or more is prohibited. This "
0044                                                "would lead to very long compilation times" );
0045       }
0046       /// constructor for strings, FormatCounterDefault is used as the default callable
0047       template <typename OWNER, std::size_t... Ns>
0048       CounterArrayInternal( OWNER* owner, std::string_view name, std::integer_sequence<std::size_t, Ns...> )
0049           : std::array<Counter, N>{ Counter{ owner, FormatCounterDefault{ name }( Ns ) }... } {
0050         static_assert( sizeof...( Ns ) < 1000, "Using CounterArray with 1000 arrays or more is prohibited. This "
0051                                                "would lead to very long compilation times" );
0052       }
0053       /// Method to form an array of buffers
0054       template <std::size_t... Ns>
0055       auto buffer( std::integer_sequence<std::size_t, Ns...> ) {
0056         return std::array{ ( *this )[Ns].buffer()... };
0057       }
0058     };
0059   } // namespace details
0060 
0061   /**
0062    * generic class implementing an array of counters
0063    * The only addition to a raw array is the constructor that allows
0064    * to build names of the counters automatically from the index of the
0065    * counter in the array
0066    * There are 2 possibilities :
0067    *   - if a string_view is given, it is used in a call to std::format(name, n);
0068    *   - if a callable is given, it is called on the index
0069    *     it should take a size_t and return some type convertible to string_view
0070    * actual implementation is in CounterArrayInternal
0071    *
0072    * Typical usage :
0073    *    // Array of 5 simple counters with simple names. Names will be MyCounter-0, MyCounter-1, ...
0074    *    CounterArray<Counter<>, 5> counters{ &algo, "MyCounter-{}" };
0075    *    ++counters[1];
0076    *    // Array of 5 averaging counters with same simple names
0077    *    CounterArray<AveragingCounter<>, 5> avgCounters{ &algo, "MyCounter-{}" };
0078    *    avgCounters[2] += 3.14;
0079    *    // Array of 5 simple counters with custom names. Names will be "0^2=0", "1^2=1", "2^2=4", ...
0080    *    CounterArray<Counter<>, 5> customCounters{
0081    *      &algo,
0082    *      []( int n ) { return fmt::format( "{}^2={}", n, n*n ); }
0083    *    }
0084    *    ++customCounters[3];
0085    *    // increment via local buffer object
0086    *    auto cbuffer = counters.buffer();
0087    *    ++cbuffer[4];
0088    */
0089   template <typename Counter, std::size_t N>
0090   struct CounterArray : details::CounterArrayInternal<Counter, N> {
0091     template <typename OWNER, typename FormatName>
0092     CounterArray( OWNER* owner, FormatName&& fname )
0093         : details::CounterArrayInternal<Counter, N>( owner, fname, std::make_integer_sequence<std::size_t, N>{} ) {}
0094     auto buffer() {
0095       return details::CounterArrayInternal<Counter, N>::buffer( std::make_integer_sequence<std::size_t, N>{} );
0096     }
0097   };
0098 
0099 } // namespace Gaudi::Accumulators