From 05ebe37db1ccb723725d5d3bbf7721ada5b660e9 Mon Sep 17 00:00:00 2001 From: Chris Jones <jonesc@hep.phy.cam.ac.uk> Date: Thu, 7 Nov 2024 15:32:21 +0000 Subject: [PATCH] RichHistoBase: Remove workarounds for Gaudi < v39r1 --- .../include/RichFutureKernel/RichHistoBase.h | 140 ++++-------------- 1 file changed, 28 insertions(+), 112 deletions(-) diff --git a/Rich/RichFutureKernel/include/RichFutureKernel/RichHistoBase.h b/Rich/RichFutureKernel/include/RichFutureKernel/RichHistoBase.h index 1f41e6bf5ae..2b168f3e90e 100644 --- a/Rich/RichFutureKernel/include/RichFutureKernel/RichHistoBase.h +++ b/Rich/RichFutureKernel/include/RichFutureKernel/RichHistoBase.h @@ -36,13 +36,8 @@ #include "RichUtils/RichMap.h" // Gaudi -#include "GAUDI_VERSION.h" +#include "Gaudi/Accumulators/StaticHistogram.h" #include "Gaudi/Property.h" -#if GAUDI_MAJOR_VERSION < 39 -# include "Gaudi/Accumulators/Histogram.h" -#else -# include "Gaudi/Accumulators/StaticHistogram.h" -#endif // STL #include <array> @@ -63,7 +58,7 @@ namespace Rich::Future { namespace details { /// Check if a given type is one of a given list. template <typename T, typename... Types> - using is_one_of = std::disjunction<std::is_base_of<std::remove_pointer_t<T>, std::remove_pointer_t<Types>>...>; + using is_one_of = std::disjunction<std::is_base_of<std::remove_cvref_t<T>, std::remove_cvref_t<Types>>...>; template <typename T, typename... Types> constexpr bool is_one_of_v = is_one_of<T, Types...>::value; /// Check if it is 'OK' to cast a parameter From -> To @@ -83,157 +78,78 @@ namespace Rich::Future { constexpr bool is_dim_v = std::is_same_v<typename T::value_type::NumberDimensions, std::integral_constant<I, ND>>; /// Check histogram types for various arthemtic emplate types template <typename T, template <typename, Gaudi::Accumulators::atomicity> typename H, - Gaudi::Accumulators::atomicity ATOMICITY = Gaudi::Accumulators::atomicity::full> - constexpr bool is_hist_type_v = - is_one_of_v<T, H<float, ATOMICITY>, H<double, ATOMICITY>, // - H<std::int64_t, ATOMICITY>, H<std::int32_t, ATOMICITY>, H<std::int16_t, ATOMICITY>, // - H<std::uint64_t, ATOMICITY>, H<std::uint32_t, ATOMICITY>, H<std::uint16_t, ATOMICITY>>; + Gaudi::Accumulators::atomicity ATOMICITY> + constexpr bool is_hist_type_v = is_one_of_v<T, H<float, ATOMICITY>, H<double, ATOMICITY>, // + H<std::int64_t, ATOMICITY>, H<std::uint64_t, ATOMICITY>, // + H<std::int32_t, ATOMICITY>, H<std::uint32_t, ATOMICITY>, // + H<std::int16_t, ATOMICITY>, H<std::uint16_t, ATOMICITY>, // + H<std::int8_t, ATOMICITY>, H<std::uint8_t, ATOMICITY>>; template <typename T, template <typename, Gaudi::Accumulators::atomicity> typename... Hs> - constexpr bool is_one_of_hist_types_v = ( ... || is_hist_type_v<T, Hs> ); + constexpr bool is_one_of_hist_types_v = ( (... || is_hist_type_v<T, Hs, Gaudi::Accumulators::atomicity::full>) || + (... || is_hist_type_v<T, Hs, Gaudi::Accumulators::atomicity::none>)); /// Base class wrapper for all histograms, making them optional. template <typename H> struct BaseH : std::optional<H> { using std::optional<H>::value; using std::optional<H>::has_value; using std::optional<H>::emplace; -#if GAUDI_MAJOR_VERSION < 39 - using ArithmeticType = typename H::AxisArithmeticType; - [[nodiscard]] auto operator[]( const ArithmeticType arg ) { return this->value()[arg]; } - [[nodiscard]] auto operator[]( const std::pair<ArithmeticType, ArithmeticType> arg ) { - return this->value()[{arg.first, arg.second}]; - } -#else - [[nodiscard]] auto operator[]( typename H::AxisTupleArithmeticType&& arg ) { - return this->value()[std::forward<typename H::AxisTupleArithmeticType>( arg )]; - } -#endif + using std::optional<H>::operator->; + using ArgType = typename H::AxisTupleArithmeticType; + + /// Forward operator call to underlying histogram + [[nodiscard]] auto operator[]( ArgType&& arg ) { return this->value()[std::forward<ArgType>( arg )]; } + /// Axis access template <unsigned int N> [[nodiscard]] auto& axis() const { -#if GAUDI_MAJOR_VERSION < 39 - return this->value().axis()[N]; -#else return this->value().template axis<N>(); -#endif } - // Histogram buffers have broken move semantics in old Gaudi releases. - // std::optional needs this so only use in known working versions. - // Otherwise for older v38 Gaudi releases uses a (tempoary) workaround - // that mimics a buffer but just caches a pointer to the original histogram. - - /// Wrapper class for histogram buffers that are movable + /// Wrapper class for histogram buffers template <typename B> - struct MovableBuffer : std::optional<B> { - [[nodiscard]] auto operator[]( typename H::AxisTupleArithmeticType&& arg ) { - return this->value()[std::forward<typename H::AxisTupleArithmeticType>( arg )]; - } - }; - - /// Wrapper class for histogram 'buffers' that are not movable - /// FixMe: Remove when we no longer need to build against the older Gaudi versions. - struct NonMovableBuffer { - public: - NonMovableBuffer() = default; - NonMovableBuffer( H& h ) : m_h{&h} {} -#if GAUDI_MAJOR_VERSION < 39 - [[nodiscard]] auto operator[]( const ArithmeticType arg ) { - assert( m_h ); - return ( *m_h )[arg]; - } - [[nodiscard]] auto operator[]( const std::pair<ArithmeticType, ArithmeticType> arg ) { - assert( m_h ); - return ( *m_h )[{arg.first, arg.second}]; - } -#else - [[nodiscard]] auto operator[]( typename H::AxisTupleArithmeticType&& arg ) { - assert( m_h ); - return ( *m_h )[std::forward<typename H::AxisTupleArithmeticType>( arg )]; - } -#endif - - private: - H* m_h = nullptr; + struct Buffer : std::optional<B> { + [[nodiscard]] auto operator[]( ArgType&& arg ) { return this->value()[std::forward<ArgType>( arg )]; } }; /// Create a buffer object for this histogram [[nodiscard]] auto buffer() { -#if GAUDI_VERSION >= CALC_GAUDI_VERSION( 39, 1 ) using BuffT = decltype( this->value().buffer() ); static_assert( std::is_move_constructible_v<BuffT> ); - return ( this->has_value() ? MovableBuffer<BuffT>{this->value().buffer()} : MovableBuffer<BuffT>{} ); -#else - return ( this->has_value() ? NonMovableBuffer( this->value() ) : NonMovableBuffer{} ); -#endif + return ( this->has_value() ? Buffer<BuffT>{( *this )->buffer()} : Buffer<BuffT>{} ); } }; } // namespace details using DefaultArithmeticType = double; -// Use different gaudi histogram implementation in different Gaudi versions -#if GAUDI_MAJOR_VERSION < 39 - // 1D histogram types template <typename TYPE = DefaultArithmeticType, Gaudi::Accumulators::atomicity ATOMICITY = Gaudi::Accumulators::atomicity::full> - using H1D = details::BaseH<Gaudi::Accumulators::Histogram<1, ATOMICITY, TYPE>>; - template <typename TYPE = DefaultArithmeticType, - Gaudi::Accumulators::atomicity ATOMICITY = Gaudi::Accumulators::atomicity::full> - using WH1D = details::BaseH<Gaudi::Accumulators::WeightedHistogram<1, ATOMICITY, TYPE>>; - template <typename TYPE = DefaultArithmeticType, - Gaudi::Accumulators::atomicity ATOMICITY = Gaudi::Accumulators::atomicity::full> - using P1D = details::BaseH<Gaudi::Accumulators::ProfileHistogram<1, ATOMICITY, TYPE>>; - template <typename TYPE = DefaultArithmeticType, - Gaudi::Accumulators::atomicity ATOMICITY = Gaudi::Accumulators::atomicity::full> - using WP1D = details::BaseH<Gaudi::Accumulators::WeightedProfileHistogram<1, ATOMICITY, TYPE>>; - - // 2D histogram types - template <typename TYPE = DefaultArithmeticType, - Gaudi::Accumulators::atomicity ATOMICITY = Gaudi::Accumulators::atomicity::full> - using H2D = details::BaseH<Gaudi::Accumulators::Histogram<2, ATOMICITY, TYPE>>; - template <typename TYPE = DefaultArithmeticType, - Gaudi::Accumulators::atomicity ATOMICITY = Gaudi::Accumulators::atomicity::full> - using WH2D = details::BaseH<Gaudi::Accumulators::WeightedHistogram<2, ATOMICITY, TYPE>>; - template <typename TYPE = DefaultArithmeticType, - Gaudi::Accumulators::atomicity ATOMICITY = Gaudi::Accumulators::atomicity::full> - using P2D = details::BaseH<Gaudi::Accumulators::ProfileHistogram<2, ATOMICITY, TYPE>>; - template <typename TYPE = DefaultArithmeticType, - Gaudi::Accumulators::atomicity ATOMICITY = Gaudi::Accumulators::atomicity::full> - using WP2D = details::BaseH<Gaudi::Accumulators::WeightedProfileHistogram<2, ATOMICITY, TYPE>>; - -#else - - // 1D histogram types - template <typename TYPE = DefaultArithmeticType, - Gaudi::Accumulators::atomicity ATOMICITY = Gaudi::Accumulators::atomicity::full> using H1D = details::BaseH<Gaudi::Accumulators::StaticHistogram<1, ATOMICITY, TYPE>>; - template <typename TYPE = DefaultArithmeticType, + template <typename TYPE = DefaultArithmeticType, Gaudi::Accumulators::atomicity ATOMICITY = Gaudi::Accumulators::atomicity::full> using WH1D = details::BaseH<Gaudi::Accumulators::StaticWeightedHistogram<1, ATOMICITY, TYPE>>; - template <typename TYPE = DefaultArithmeticType, + template <typename TYPE = DefaultArithmeticType, Gaudi::Accumulators::atomicity ATOMICITY = Gaudi::Accumulators::atomicity::full> using P1D = details::BaseH<Gaudi::Accumulators::StaticProfileHistogram<1, ATOMICITY, TYPE>>; - template <typename TYPE = DefaultArithmeticType, + template <typename TYPE = DefaultArithmeticType, Gaudi::Accumulators::atomicity ATOMICITY = Gaudi::Accumulators::atomicity::full> using WP1D = details::BaseH<Gaudi::Accumulators::StaticWeightedProfileHistogram<1, ATOMICITY, TYPE>>; // 2D histogram types - template <typename TYPE = DefaultArithmeticType, + template <typename TYPE = DefaultArithmeticType, Gaudi::Accumulators::atomicity ATOMICITY = Gaudi::Accumulators::atomicity::full> using H2D = details::BaseH<Gaudi::Accumulators::StaticHistogram<2, ATOMICITY, TYPE>>; - template <typename TYPE = DefaultArithmeticType, + template <typename TYPE = DefaultArithmeticType, Gaudi::Accumulators::atomicity ATOMICITY = Gaudi::Accumulators::atomicity::full> using WH2D = details::BaseH<Gaudi::Accumulators::StaticWeightedHistogram<2, ATOMICITY, TYPE>>; - template <typename TYPE = DefaultArithmeticType, + template <typename TYPE = DefaultArithmeticType, Gaudi::Accumulators::atomicity ATOMICITY = Gaudi::Accumulators::atomicity::full> using P2D = details::BaseH<Gaudi::Accumulators::StaticProfileHistogram<2, ATOMICITY, TYPE>>; - template <typename TYPE = DefaultArithmeticType, + template <typename TYPE = DefaultArithmeticType, Gaudi::Accumulators::atomicity ATOMICITY = Gaudi::Accumulators::atomicity::full> using WP2D = details::BaseH<Gaudi::Accumulators::StaticWeightedProfileHistogram<2, ATOMICITY, TYPE>>; -#endif - // some type traits // Histogram Dimensionality @@ -265,7 +181,7 @@ namespace Rich::Future { template <typename T, std::size_t N, typename INDEX = std::size_t> struct Array : public Rich::TypedIndexArray<T, N, INDEX> { // create buffer object for contained histograms - auto buffer() { + inline auto buffer() { auto buff_array = std::apply( []( auto&... i ) { return std::array{i.buffer()...}; }, static_cast<std::array<T, N>&>( *this ) ); using BUFFER = typename decltype( buff_array )::value_type; -- GitLab