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