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
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
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
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;
0059
0060
0061 std::unique_ptr<DataHandle<data_type>> m_handle;
0062 gsl::not_null<Gaudi::Algorithm*> m_owner;
0063 };
0064
0065
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
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
0090 }
0091 }
0092 } else {
0093
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
0121
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
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 }