2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
5/// @author Nils Krumnack
8#include <ColumnarCore/ColumnAccessorDataArray.h>
9#include <ColumnarCore/VectorConvertView.h>
15 struct ColumnAccessorOptionsArray final
17 std::string_view offsetName;
19 std::string dataSuffix = "";
20 bool isOffset = false;
21 unsigned numOffsets = 0u;
24 // the Array mode specialization for native types
25 template<typename CT,ColumnAccessMode CAM,ColumnarArrayMode CM>
26 requires (MemoryAccessor<CT,CM>::isDefined)
27 class ContainerFreeAccessor<CT,CAM,CM> final
29 /// Common Public Members
30 /// =====================
33 static_assert (CAM == ColumnAccessMode::input || MemoryAccessor<CT,CM>::viewIsReference || MemoryAccessor<CT,CM>::hasSetter, "output access not supported for this type");
35 using ColumnType = typename MemoryAccessor<CT,CM>::MemoryType;
37 static constexpr bool isDefined = true;
38 static constexpr bool viewIsReference = MemoryAccessor<CT,CM>::viewIsReference;
39 static constexpr unsigned internalOffsetColumns = 0;
41 ContainerFreeAccessor () noexcept = default;
43 ContainerFreeAccessor (ColumnarTool<CM>& columnarTool, ColumnAccessorOptions&& options, ColumnAccessorOptionsArray&& optionsArray)
45 auto info = options.makeColumnInfo();
46 info.offsetName = optionsArray.offsetName;
47 info.isOffset = optionsArray.isOffset;
48 MemoryAccessor<CT,CM>::updateColumnInfo (info);
49 m_accessorData = std::make_unique<ColumnAccessorDataArray> (&m_dataIndex, &m_accessorData, &typeid (typename MemoryAccessor<CT,CM>::MemoryType), CAM);
50 columnarTool.addColumn (optionsArray.baseName + optionsArray.dataSuffix, m_accessorData.get(), std::move (info));
53 ContainerFreeAccessor (ContainerFreeAccessor&& that)
55 moveAccessor (m_dataIndex, m_accessorData, that.m_dataIndex, that.m_accessorData);
58 ContainerFreeAccessor& operator = (ContainerFreeAccessor&& that)
61 moveAccessor (m_dataIndex, m_accessorData, that.m_dataIndex, that.m_accessorData);
65 ContainerFreeAccessor (const ContainerFreeAccessor&) = delete;
66 ContainerFreeAccessor& operator = (const ContainerFreeAccessor&) = delete;
68 [[nodiscard]] ColumnType& operator () (void** dataArea, std::size_t index) const noexcept
69 requires (viewIsReference)
71 auto *data = static_cast<ColumnType*>(dataArea[m_dataIndex]);
75 [[nodiscard]] decltype(auto) operator () (void** dataArea, std::size_t index) const noexcept
76 requires (!viewIsReference && CAM == ColumnAccessMode::input)
78 auto *data = static_cast<ColumnType*>(dataArea[m_dataIndex]);
79 return MemoryAccessor<CT,CM>::makeViewer (dataArea)(data[index]);
82 [[nodiscard]] std::span<ColumnType> operator () (void** dataArea, std::size_t beginIndex, std::size_t endIndex) const noexcept
83 requires (viewIsReference)
85 auto *data = static_cast<ColumnType*>(dataArea[m_dataIndex]);
86 return std::span<ColumnType> (data+beginIndex, endIndex-beginIndex);
89 [[nodiscard]] auto operator () (void** dataArea, std::size_t beginIndex, std::size_t endIndex) const noexcept
90 requires (!viewIsReference && CAM == ColumnAccessMode::input)
92 auto *data = static_cast<ColumnType*>(dataArea[m_dataIndex]);
93 std::span<ColumnType> mySpan (data+beginIndex, endIndex-beginIndex);
94 return VectorConvertView (MemoryAccessor<CT,CM>::makeViewer (dataArea), std::span (mySpan));
97 [[nodiscard]] bool isAvailable (void** dataArea) const noexcept
99 auto *data = static_cast<ColumnType*>(dataArea[m_dataIndex]);
100 return data != nullptr;
107 unsigned m_dataIndex = 0u;
108 std::unique_ptr<ColumnAccessorDataArray> m_accessorData;
114 // the Array mode specialization for native types
115 template<ContainerIdConcept CI,typename CT,ColumnAccessMode CAM,ColumnarArrayMode CM>
116 requires (CI::regularColumnAccessorArray && detail::ContainerFreeAccessor<CT,CAM,CM>::isDefined)
117 class AccessorTemplate<CI,CT,CAM,CM> final
119 /// Common Public Members
120 /// =====================
123 static_assert (!std::is_const_v<CT>, "CT must not be const");
125 AccessorTemplate () noexcept = default;
127 AccessorTemplate (ColumnarTool<CM>& columnarTool, const std::string& name, ColumnAccessorOptions&& options = {})
128 : m_accessor (columnarTool, std::move (options), detail::ColumnAccessorOptionsArray{.offsetName = CI::idName, .baseName = std::string (CI::idName) + "." + name})
131 AccessorTemplate (AccessorTemplate&& that) = default;
132 AccessorTemplate& operator = (AccessorTemplate&& that) = default;
133 AccessorTemplate (const AccessorTemplate&) = delete;
134 AccessorTemplate& operator = (const AccessorTemplate&) = delete;
136 void reset (ColumnarTool<CM>& columnarTool, const std::string& name, ColumnAccessorOptions&& options = {})
138 *this = AccessorTemplate (columnarTool, name, std::move (options));
141 [[nodiscard]] decltype(auto) operator () (ObjectId<CI,CM> id) const noexcept
143 return m_accessor(id.getDataArea(), id.getIndex());
146 [[nodiscard]] decltype(auto) operator () (ObjectRange<CI,CM> range) const noexcept
148 return m_accessor(range.getDataArea(), range.beginIndex(), range.endIndex());
152 requires requires(T value) {std::declval<detail::ContainerFreeAccessor<CT,CAM,CM>>().set (nullptr,0,value);}
153 void set (ObjectId<CI,CM> id, T&& value) const noexcept
155 m_accessor.set (id.getDataArea(), id.getIndex(), std::forward<T>(value));
158 [[nodiscard]] bool isAvailable (ObjectId<CI,CM> id) const noexcept
160 return m_accessor.isAvailable (id.getDataArea());
163 [[nodiscard]] bool isAvailable (const ObjectRange<CI,CM>& range) const noexcept
165 return m_accessor.isAvailable (range.getDataArea());
168 [[nodiscard]] auto getOptional (ObjectId<CI,CM> id) const
170 std::optional<std::decay_t<decltype(std::declval<detail::ContainerFreeAccessor<CT,CAM,CM>>()(nullptr,0))>> result;
171 if (m_accessor.isAvailable (id.getDataArea()))
172 result = m_accessor (id.getDataArea(), id.getIndex());
180 detail::ContainerFreeAccessor<CT,CAM,CM> m_accessor;