Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:12:10

0001 #pragma once
0002 
0003 #include <string>
0004 #include <tuple>
0005 #include <vector>
0006 
0007 #include <algorithms/algorithm.h>
0008 #include <algorithms/type_traits.h>
0009 
0010 #include <GaudiAlg/GaudiAlgorithm.h>
0011 #include <k4FWCore/DataHandle.h>
0012 
0013 namespace Jug::Algo::detail {
0014 
0015 enum class DataMode : unsigned { kInput, kOutput };
0016 
0017 // Generate properties for each of the data arguments
0018 template <class T, DataMode kMode> class DataElement {
0019 
0020 public:
0021   using value_type = std::conditional_t<kMode == DataMode::kInput, algorithms::input_type_t<T>,
0022                                         algorithms::output_type_t<T>>;
0023   using data_type  = algorithms::data_type_t<T>;
0024   constexpr static const bool kIsOptional = algorithms::is_optional_v<T>;
0025 
0026   template <class Owner>
0027   DataElement(Owner* owner, std::string_view name)
0028       : m_data_name{std::make_unique<Gaudi::Property<std::string>>(owner, std::string(name), "")}
0029       , m_owner{owner} {}
0030   void init() {
0031     if (m_handle) {
0032       // treat error: already initialized
0033     }
0034     if (!m_data_name->empty()) {
0035       m_handle = std::make_unique<DataHandle<data_type>>(
0036           *m_data_name,
0037           ((kMode == DataMode::kInput) ? Gaudi::DataHandle::Reader : Gaudi::DataHandle::Writer),
0038           m_owner);
0039     } else if (!algorithms::is_optional_v<T>) {
0040       // treat error: member not optional but no collection name given
0041     }
0042   }
0043   value_type get() const {
0044     if constexpr (kIsOptional) {
0045       if (!m_handle) {
0046         return nullptr;
0047       }
0048     }
0049     if constexpr (kMode == DataMode::kInput) {
0050       return m_handle->get();
0051     } else {
0052       return m_handle->createAndPut();
0053     }
0054   }
0055 
0056 private:
0057   std::unique_ptr<Gaudi::Property<std::string>>
0058       m_data_name; // This needs to be a pointer, else things go wrong once we go through
0059                    // createElements - probably something about passing the Property through an
0060                    // rvalue (or copy) constructor
0061   std::unique_ptr<DataHandle<data_type>> m_handle;
0062   gsl::not_null<Gaudi::Algorithm*> m_owner;
0063 };
0064 
0065 // Specialization for vectors
0066 template <class T, class A, DataMode kMode> class DataElement<std::vector<T, A>, kMode> {
0067 public:
0068   using value_type = std::conditional_t<kMode == DataMode::kInput, algorithms::input_type_t<T>,
0069                                         algorithms::output_type_t<T>>;
0070   using data_type  = algorithms::data_type_t<T>;
0071 
0072   template <class Owner>
0073   DataElement(Owner* owner, std::string_view name)
0074       : m_data_names{std::make_unique<Gaudi::Property<std::vector<std::string>>>(
0075             owner, std::string(name), {})}
0076       , m_owner{owner} {}
0077   void init() {
0078     if (!m_handles.empty()) {
0079       // treat error: already initialized
0080     }
0081     if (!m_data_names->empty()) {
0082       for (const auto& name : *m_data_names) {
0083         if (!name.empty()) {
0084           m_handles.emplace_back(std::make_unique<DataHandle<data_type>>(
0085               name,
0086               (kMode == DataMode::kInput ? Gaudi::DataHandle::Reader : Gaudi::DataHandle::Writer),
0087               m_owner));
0088         } else {
0089           // treat error: empty name
0090         }
0091       }
0092     } else {
0093       // OK if nothing given here, no error
0094     }
0095   }
0096   std::vector<value_type> get() const {
0097     std::vector<value_type> ret;
0098     for (auto& handle : m_handles) {
0099       if constexpr (kMode == DataMode::kInput) {
0100         ret.emplace_back(handle->get());
0101       } else {
0102         ret.emplace_back(handle->createAndPut());
0103       }
0104     }
0105     return ret;
0106   }
0107 
0108 private:
0109   std::unique_ptr<Gaudi::Property<std::vector<std::string>>> m_data_names;
0110   std::vector<std::unique_ptr<DataHandle<T>>> m_handles;
0111   gsl::not_null<Gaudi::Algorithm*> m_owner;
0112 };
0113 
0114 template <DataMode kMode, class Owner, class NamesArray, class Tuple, size_t... I>
0115 auto createElements(Owner* owner, const NamesArray& names, const Tuple&, std::index_sequence<I...>)
0116     -> std::tuple<DataElement<std::tuple_element_t<I, Tuple>, kMode>...> {
0117   return {DataElement<std::tuple_element_t<I, Tuple>, kMode>(owner, std::get<I>(names))...};
0118 }
0119 
0120 // Call ::get() on each element of the HandleTuple, and return the result in the format of
0121 // ReturnTuple
0122 template <class ReturnTuple, class HandleTuple, size_t... I>
0123 ReturnTuple getElements(HandleTuple& handles, std::index_sequence<I...>) {
0124   return {std::get<I>(handles).get()...};
0125 }
0126 
0127 // Create data handle structure for all members
0128 
0129 template <class Data> class DataProxy {
0130 public:
0131   static constexpr DataMode kMode =
0132       (algorithms::is_input_v<Data> ? DataMode::kInput : DataMode::kOutput);
0133   using value_type              = typename Data::value_type;
0134   using data_type               = typename Data::data_type;
0135   constexpr static size_t kSize = Data::kSize;
0136   using names_type              = typename Data::key_type;
0137   using elements_type =
0138       decltype(createElements<kMode>(std::declval<GaudiAlgorithm*>(), names_type(), data_type(),
0139                                      std::make_index_sequence<kSize>()));
0140 
0141   template <class Owner>
0142   DataProxy(Owner* owner, const names_type& names)
0143       : m_elements{
0144             createElements<kMode>(owner, names, data_type(), std::make_index_sequence<kSize>())} {}
0145   void init() {
0146     std::apply([](auto&&... el) { (el.init(), ...); }, m_elements);
0147   }
0148   value_type get() const {
0149     return getElements<value_type>(m_elements, std::make_index_sequence<kSize>());
0150   }
0151 
0152 private:
0153   elements_type m_elements;
0154 };
0155 
0156 } // namespace Jug::Algo::detail