ATLAS Offline Software
Loading...
Searching...
No Matches
ColumnAccessorArray.icc
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5/// @author Nils Krumnack
6
7
8#include <ColumnarCore/ColumnAccessorDataArray.h>
9#include <ColumnarCore/VectorConvertView.h>
10
11namespace columnar
12{
13 namespace detail
14 {
15 struct ColumnAccessorOptionsArray final
16 {
17 std::string_view offsetName;
18 std::string baseName;
19 std::string dataSuffix = "";
20 bool isOffset = false;
21 unsigned numOffsets = 0u;
22 };
23
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
28 {
29 /// Common Public Members
30 /// =====================
31 public:
32
33 static_assert (CAM == ColumnAccessMode::input || MemoryAccessor<CT,CM>::viewIsReference || MemoryAccessor<CT,CM>::hasSetter, "output access not supported for this type");
34
35 using ColumnType = typename MemoryAccessor<CT,CM>::MemoryType;
36
37 static constexpr bool isDefined = true;
38 static constexpr bool viewIsReference = MemoryAccessor<CT,CM>::viewIsReference;
39 static constexpr unsigned internalOffsetColumns = 0;
40
41 ContainerFreeAccessor () noexcept = default;
42
43 ContainerFreeAccessor (ColumnarTool<CM>& columnarTool, ColumnAccessorOptions&& options, ColumnAccessorOptionsArray&& optionsArray)
44 {
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));
51 }
52
53 ContainerFreeAccessor (ContainerFreeAccessor&& that)
54 {
55 moveAccessor (m_dataIndex, m_accessorData, that.m_dataIndex, that.m_accessorData);
56 }
57
58 ContainerFreeAccessor& operator = (ContainerFreeAccessor&& that)
59 {
60 if (this != &that)
61 moveAccessor (m_dataIndex, m_accessorData, that.m_dataIndex, that.m_accessorData);
62 return *this;
63 }
64
65 ContainerFreeAccessor (const ContainerFreeAccessor&) = delete;
66 ContainerFreeAccessor& operator = (const ContainerFreeAccessor&) = delete;
67
68 [[nodiscard]] ColumnType& operator () (void** dataArea, std::size_t index) const noexcept
69 requires (viewIsReference)
70 {
71 auto *data = static_cast<ColumnType*>(dataArea[m_dataIndex]);
72 return data[index];
73 }
74
75 [[nodiscard]] decltype(auto) operator () (void** dataArea, std::size_t index) const noexcept
76 requires (!viewIsReference && CAM == ColumnAccessMode::input)
77 {
78 auto *data = static_cast<ColumnType*>(dataArea[m_dataIndex]);
79 return MemoryAccessor<CT,CM>::makeViewer (dataArea)(data[index]);
80 }
81
82 [[nodiscard]] std::span<ColumnType> operator () (void** dataArea, std::size_t beginIndex, std::size_t endIndex) const noexcept
83 requires (viewIsReference)
84 {
85 auto *data = static_cast<ColumnType*>(dataArea[m_dataIndex]);
86 return std::span<ColumnType> (data+beginIndex, endIndex-beginIndex);
87 }
88
89 [[nodiscard]] auto operator () (void** dataArea, std::size_t beginIndex, std::size_t endIndex) const noexcept
90 requires (!viewIsReference && CAM == ColumnAccessMode::input)
91 {
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));
95 }
96
97 [[nodiscard]] bool isAvailable (void** dataArea) const noexcept
98 {
99 auto *data = static_cast<ColumnType*>(dataArea[m_dataIndex]);
100 return data != nullptr;
101 }
102
103 /// Private Members
104 /// ===============
105 private:
106
107 unsigned m_dataIndex = 0u;
108 std::unique_ptr<ColumnAccessorDataArray> m_accessorData;
109 };
110 }
111
112
113
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
118 {
119 /// Common Public Members
120 /// =====================
121 public:
122
123 static_assert (!std::is_const_v<CT>, "CT must not be const");
124
125 AccessorTemplate () noexcept = default;
126
127 AccessorTemplate (ColumnarTool<CM>& columnarTool, const std::string& name, ColumnAccessorOptions&& options = {})
128 : m_accessor (columnarTool, std::move (options), detail::ColumnAccessorOptionsArray{.offsetName = CI::perEventRange ? CI::idName : eventContextCIName, .baseName = std::string (CI::idName) + "." + name})
129 {
130 static_assert (CI::perEventRange + CI::perEventId == 1, "ContainerId must be either per-event-range or per-event-id");
131 }
132
133 AccessorTemplate (AccessorTemplate&& that) = default;
134 AccessorTemplate& operator = (AccessorTemplate&& that) = default;
135 AccessorTemplate (const AccessorTemplate&) = delete;
136 AccessorTemplate& operator = (const AccessorTemplate&) = delete;
137
138 void reset (ColumnarTool<CM>& columnarTool, const std::string& name, ColumnAccessorOptions&& options = {})
139 {
140 *this = AccessorTemplate (columnarTool, name, std::move (options));
141 }
142
143 [[nodiscard]] decltype(auto) operator () (ObjectId<CI,CM> id) const noexcept
144 {
145 return m_accessor(id.getDataArea(), id.getIndex());
146 }
147
148 [[nodiscard]] decltype(auto) operator () (ObjectRange<CI,CM> range) const noexcept
149 {
150 return m_accessor(range.getDataArea(), range.beginIndex(), range.endIndex());
151 }
152
153 template<typename T>
154 requires requires(T value) {std::declval<detail::ContainerFreeAccessor<CT,CAM,CM>>().set (nullptr,0,value);}
155 void set (ObjectId<CI,CM> id, T&& value) const noexcept
156 {
157 m_accessor.set (id.getDataArea(), id.getIndex(), std::forward<T>(value));
158 }
159
160 [[nodiscard]] bool isAvailable (ObjectId<CI,CM> id) const noexcept
161 {
162 return m_accessor.isAvailable (id.getDataArea());
163 }
164
165 [[nodiscard]] bool isAvailable (const ObjectRange<CI,CM>& range) const noexcept
166 {
167 return m_accessor.isAvailable (range.getDataArea());
168 }
169
170 [[nodiscard]] auto getOptional (ObjectId<CI,CM> id) const
171 {
172 std::optional<std::decay_t<decltype(std::declval<detail::ContainerFreeAccessor<CT,CAM,CM>>()(nullptr,0))>> result;
173 if (m_accessor.isAvailable (id.getDataArea()))
174 result = m_accessor (id.getDataArea(), id.getIndex());
175 return result;
176 }
177
178 /// Private Members
179 /// ===============
180 private:
181
182 detail::ContainerFreeAccessor<CT,CAM,CM> m_accessor;
183 };
184}