Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RFieldRecord.hxx
Go to the documentation of this file.
1/// \file ROOT/RField/Fundamental.hxx
2/// \ingroup NTuple ROOT7
3/// \author Jakob Blomer <jblomer@cern.ch>
4/// \date 2018-10-09
5/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
6/// is welcome!
7
8/*************************************************************************
9 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
10 * All rights reserved. *
11 * *
12 * For the licensing terms see $ROOTSYS/LICENSE. *
13 * For the list of contributors see $ROOTSYS/README/CREDITS. *
14 *************************************************************************/
15
16#ifndef ROOT7_RField_Record
17#define ROOT7_RField_Record
18
19#ifndef ROOT7_RField
20#error "Please include RField.hxx!"
21#endif
22
23#include <ROOT/RFieldBase.hxx>
24#include <ROOT/RNTupleUtil.hxx>
25
26#include <string>
27#include <string_view>
28#include <tuple>
29#include <utility>
30#include <vector>
31
32namespace ROOT {
33namespace Experimental {
34
35namespace Detail {
36class RFieldVisitor;
37} // namespace Detail
38
39/// The field for an untyped record. The subfields are stored consequitively in a memory block, i.e.
40/// the memory layout is identical to one that a C++ struct would have
41class RRecordField : public RFieldBase {
42private:
43 class RRecordDeleter : public RDeleter {
44 private:
45 std::vector<std::unique_ptr<RDeleter>> fItemDeleters;
46 std::vector<std::size_t> fOffsets;
47
48 public:
49 RRecordDeleter(std::vector<std::unique_ptr<RDeleter>> &itemDeleters, const std::vector<std::size_t> &offsets)
50 : fItemDeleters(std::move(itemDeleters)), fOffsets(offsets)
51 {
52 }
53 void operator()(void *objPtr, bool dtorOnly) final;
54 };
55
56protected:
57 std::size_t fMaxAlignment = 1;
58 std::size_t fSize = 0;
59 std::vector<std::size_t> fOffsets;
60
61 std::size_t GetItemPadding(std::size_t baseOffset, std::size_t itemAlignment) const;
62
63 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const override;
64
65 void ConstructValue(void *where) const override;
66 std::unique_ptr<RDeleter> GetDeleter() const override;
67
68 std::size_t AppendImpl(const void *from) final;
69 void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final;
70 void ReadInClusterImpl(RClusterIndex clusterIndex, void *to) final;
71
72 RRecordField(std::string_view fieldName, std::vector<std::unique_ptr<RFieldBase>> &&itemFields,
73 const std::vector<std::size_t> &offsets, std::string_view typeName = "");
74
75 template <std::size_t N>
76 RRecordField(std::string_view fieldName, std::array<std::unique_ptr<RFieldBase>, N> &&itemFields,
77 const std::array<std::size_t, N> &offsets, std::string_view typeName = "")
78 : ROOT::Experimental::RFieldBase(fieldName, typeName, ENTupleStructure::kRecord, false /* isSimple */)
79 {
81 for (unsigned i = 0; i < N; ++i) {
82 fOffsets.push_back(offsets[i]);
83 fMaxAlignment = std::max(fMaxAlignment, itemFields[i]->GetAlignment());
84 fSize += GetItemPadding(fSize, itemFields[i]->GetAlignment()) + itemFields[i]->GetValueSize();
85 fTraits &= itemFields[i]->GetTraits();
86 Attach(std::move(itemFields[i]));
87 }
88 }
89
90public:
91 /// Construct a RRecordField based on a vector of child fields. The ownership of the child fields is transferred
92 /// to the RRecordField instance.
93 RRecordField(std::string_view fieldName, std::vector<std::unique_ptr<RFieldBase>> &&itemFields);
94 RRecordField(std::string_view fieldName, std::vector<std::unique_ptr<RFieldBase>> &itemFields);
95 RRecordField(RRecordField &&other) = default;
96 RRecordField &operator=(RRecordField &&other) = default;
97 ~RRecordField() override = default;
98
99 std::vector<RValue> SplitValue(const RValue &value) const final;
100 size_t GetValueSize() const final { return fSize; }
101 size_t GetAlignment() const final { return fMaxAlignment; }
102 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
103
104 const std::vector<std::size_t> &GetOffsets() const { return fOffsets; }
105};
106
107////////////////////////////////////////////////////////////////////////////////
108/// Template specializations for C++ std::pair
109////////////////////////////////////////////////////////////////////////////////
110
111/// The generic field for `std::pair<T1, T2>` types
112class RPairField : public RRecordField {
113private:
114 class RPairDeleter : public RDeleter {
115 private:
117
118 public:
119 explicit RPairDeleter(TClass *cl) : fClass(cl) {}
120 void operator()(void *objPtr, bool dtorOnly) final;
121 };
122
123 TClass *fClass = nullptr;
124 static std::string GetTypeList(const std::array<std::unique_ptr<RFieldBase>, 2> &itemFields);
125
126protected:
127 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const override;
128
129 void ConstructValue(void *where) const override;
130 std::unique_ptr<RDeleter> GetDeleter() const override { return std::make_unique<RPairDeleter>(fClass); }
131
132 RPairField(std::string_view fieldName, std::array<std::unique_ptr<RFieldBase>, 2> &&itemFields,
133 const std::array<std::size_t, 2> &offsets);
134
135public:
136 RPairField(std::string_view fieldName, std::array<std::unique_ptr<RFieldBase>, 2> &itemFields);
137 RPairField(RPairField &&other) = default;
138 RPairField &operator=(RPairField &&other) = default;
139 ~RPairField() override = default;
140};
141
142template <typename T1, typename T2>
143class RField<std::pair<T1, T2>> final : public RPairField {
144 using ContainerT = typename std::pair<T1, T2>;
145
146private:
147 template <typename Ty1, typename Ty2>
148 static std::array<std::unique_ptr<RFieldBase>, 2> BuildItemFields()
149 {
150 return {std::make_unique<RField<Ty1>>("_0"), std::make_unique<RField<Ty2>>("_1")};
151 }
152
153 static std::array<std::size_t, 2> BuildItemOffsets()
154 {
155 auto pair = ContainerT();
156 auto offsetFirst = reinterpret_cast<std::uintptr_t>(&(pair.first)) - reinterpret_cast<std::uintptr_t>(&pair);
157 auto offsetSecond = reinterpret_cast<std::uintptr_t>(&(pair.second)) - reinterpret_cast<std::uintptr_t>(&pair);
158 return {offsetFirst, offsetSecond};
159 }
160
161protected:
162 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
163 {
164 std::array<std::unique_ptr<RFieldBase>, 2> items{fSubFields[0]->Clone(fSubFields[0]->GetFieldName()),
165 fSubFields[1]->Clone(fSubFields[1]->GetFieldName())};
166 return std::make_unique<RField<std::pair<T1, T2>>>(newName, std::move(items));
167 }
168
169 void ConstructValue(void *where) const final { new (where) ContainerT(); }
170 std::unique_ptr<RDeleter> GetDeleter() const final { return std::make_unique<RTypedDeleter<ContainerT>>(); }
171
172public:
173 static std::string TypeName() { return "std::pair<" + RField<T1>::TypeName() + "," + RField<T2>::TypeName() + ">"; }
174 explicit RField(std::string_view name, std::array<std::unique_ptr<RFieldBase>, 2> &&itemFields)
175 : RPairField(name, std::move(itemFields), BuildItemOffsets())
176 {
177 fMaxAlignment = std::max(alignof(T1), alignof(T2));
178 fSize = sizeof(ContainerT);
179 }
180 explicit RField(std::string_view name) : RField(name, BuildItemFields<T1, T2>()) {}
181 RField(RField &&other) = default;
182 RField &operator=(RField &&other) = default;
183 ~RField() override = default;
184};
185
186////////////////////////////////////////////////////////////////////////////////
187/// Template specializations for C++ std::tuple
188////////////////////////////////////////////////////////////////////////////////
189
190/// The generic field for `std::tuple<Ts...>` types
191class RTupleField : public RRecordField {
192private:
193 class RTupleDeleter : public RDeleter {
194 private:
196
197 public:
198 explicit RTupleDeleter(TClass *cl) : fClass(cl) {}
199 void operator()(void *objPtr, bool dtorOnly) final;
200 };
201
202 TClass *fClass = nullptr;
203 static std::string GetTypeList(const std::vector<std::unique_ptr<RFieldBase>> &itemFields);
204
205protected:
206 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const override;
207
208 void ConstructValue(void *where) const override;
209 std::unique_ptr<RDeleter> GetDeleter() const override { return std::make_unique<RTupleDeleter>(fClass); }
210
211 RTupleField(std::string_view fieldName, std::vector<std::unique_ptr<RFieldBase>> &&itemFields,
212 const std::vector<std::size_t> &offsets);
213
214public:
215 RTupleField(std::string_view fieldName, std::vector<std::unique_ptr<RFieldBase>> &itemFields);
216 RTupleField(RTupleField &&other) = default;
217 RTupleField &operator=(RTupleField &&other) = default;
218 ~RTupleField() override = default;
219};
220
221template <typename... ItemTs>
222class RField<std::tuple<ItemTs...>> final : public RTupleField {
223 using ContainerT = typename std::tuple<ItemTs...>;
224
225private:
226 template <typename HeadT, typename... TailTs>
227 static std::string BuildItemTypes()
228 {
229 std::string result = RField<HeadT>::TypeName();
230 if constexpr (sizeof...(TailTs) > 0)
231 result += "," + BuildItemTypes<TailTs...>();
232 return result;
233 }
234
235 template <typename HeadT, typename... TailTs>
236 static void _BuildItemFields(std::vector<std::unique_ptr<RFieldBase>> &itemFields, unsigned int index = 0)
237 {
238 itemFields.emplace_back(new RField<HeadT>("_" + std::to_string(index)));
239 if constexpr (sizeof...(TailTs) > 0)
240 _BuildItemFields<TailTs...>(itemFields, index + 1);
241 }
242 template <typename... Ts>
243 static std::vector<std::unique_ptr<RFieldBase>> BuildItemFields()
244 {
245 std::vector<std::unique_ptr<RFieldBase>> result;
246 _BuildItemFields<Ts...>(result);
247 return result;
248 }
249
250 template <unsigned Index, typename HeadT, typename... TailTs>
251 static void _BuildItemOffsets(std::vector<std::size_t> &offsets, const ContainerT &tuple)
252 {
253 auto offset =
254 reinterpret_cast<std::uintptr_t>(&std::get<Index>(tuple)) - reinterpret_cast<std::uintptr_t>(&tuple);
255 offsets.emplace_back(offset);
256 if constexpr (sizeof...(TailTs) > 0)
257 _BuildItemOffsets<Index + 1, TailTs...>(offsets, tuple);
258 }
259 template <typename... Ts>
260 static std::vector<std::size_t> BuildItemOffsets()
261 {
262 std::vector<std::size_t> result;
263 _BuildItemOffsets<0, Ts...>(result, ContainerT());
264 return result;
265 }
266
267protected:
268 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
269 {
270 std::vector<std::unique_ptr<RFieldBase>> items;
271 for (auto &item : fSubFields)
272 items.push_back(item->Clone(item->GetFieldName()));
273 return std::make_unique<RField<std::tuple<ItemTs...>>>(newName, std::move(items));
274 }
275
276 void ConstructValue(void *where) const final { new (where) ContainerT(); }
277 std::unique_ptr<RDeleter> GetDeleter() const final { return std::make_unique<RTypedDeleter<ContainerT>>(); }
278
279public:
280 static std::string TypeName() { return "std::tuple<" + BuildItemTypes<ItemTs...>() + ">"; }
281 explicit RField(std::string_view name, std::vector<std::unique_ptr<RFieldBase>> &&itemFields)
282 : RTupleField(name, std::move(itemFields), BuildItemOffsets<ItemTs...>())
283 {
284 fMaxAlignment = std::max({alignof(ItemTs)...});
285 fSize = sizeof(ContainerT);
286 }
287 explicit RField(std::string_view name) : RField(name, BuildItemFields<ItemTs...>()) {}
288 RField(RField &&other) = default;
289 RField &operator=(RField &&other) = default;
290 ~RField() override = default;
291};
292
293} // namespace Experimental
294} // namespace ROOT
295
296#endif
dim_t fSize
#define N
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
char name[80]
Definition TGX11.cxx:110
Abstract base class for classes implementing the visitor design pattern.
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
Definition RField.cxx:1909
std::unique_ptr< RDeleter > GetDeleter() const final
Definition RField.hxx:135
Addresses a column element or field item relative to a particular cluster, instead of a global NTuple...
A functor to release the memory acquired by CreateValue (memory and constructor).
Points to an object with RNTuple I/O support and keeps a pointer to the corresponding field.
A field translates read and write calls from/to underlying columns to/from tree values.
void Attach(std::unique_ptr< RFieldBase > child)
Add a new subfield to the list of nested fields.
Definition RField.cxx:994
const std::string & GetFieldName() const
int fTraits
Properties of the type that allow for optimizations of collections of that type.
std::unique_ptr< RFieldBase > Clone(std::string_view newName) const
Copies the field and its sub fields using a possibly new name and a new, unconnected set of columns.
Definition RField.cxx:927
std::vector< std::unique_ptr< RFieldBase > > fSubFields
Collections and classes own sub fields.
static constexpr int kTraitTrivialType
Shorthand for types that are both trivially constructible and destructible.
Classes with dictionaries that can be inspected by TClass.
Definition RField.hxx:238
void ConstructValue(void *where) const final
Constructs value in a given location of size at least GetValueSize(). Called by the base class' Creat...
Definition RField.hxx:240
RField & operator=(RField &&other)=default
static std::string TypeName()
Definition RField.hxx:251
~RField() override=default
void operator()(void *objPtr, bool dtorOnly) final
Definition RField.cxx:3964
Template specializations for C++ std::pair.
~RPairField() override=default
void ConstructValue(void *where) const override
Constructs value in a given location of size at least GetValueSize(). Called by the base class' Creat...
Definition RField.cxx:3959
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const override
Called by Clone(), which additionally copies the on-disk ID.
Definition RField.cxx:3949
static std::string GetTypeList(const std::array< std::unique_ptr< RFieldBase >, 2 > &itemFields)
RPairField(RPairField &&other)=default
std::unique_ptr< RDeleter > GetDeleter() const override
RPairField & operator=(RPairField &&other)=default
void operator()(void *objPtr, bool dtorOnly) final
Definition RField.cxx:2592
std::vector< std::unique_ptr< RDeleter > > fItemDeleters
RRecordDeleter(std::vector< std::unique_ptr< RDeleter > > &itemDeleters, const std::vector< std::size_t > &offsets)
The field for an untyped record.
RRecordField(std::string_view fieldName, std::array< std::unique_ptr< RFieldBase >, N > &&itemFields, const std::array< std::size_t, N > &offsets, std::string_view typeName="")
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
size_t GetAlignment() const final
As a rule of thumb, the alignment is equal to the size of the type.
std::vector< std::size_t > fOffsets
void ReadInClusterImpl(RClusterIndex clusterIndex, void *to) final
Definition RField.cxx:2578
RRecordField(RRecordField &&other)=default
std::unique_ptr< RDeleter > GetDeleter() const override
Definition RField.cxx:2600
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
Definition RField.cxx:2571
std::vector< RValue > SplitValue(const RValue &value) const final
Creates the list of direct child values given a value for this field.
Definition RField.cxx:2611
std::size_t GetItemPadding(std::size_t baseOffset, std::size_t itemAlignment) const
Definition RField.cxx:2542
~RRecordField() override=default
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
Definition RField.cxx:2562
const std::vector< std::size_t > & GetOffsets() const
RRecordField & operator=(RRecordField &&other)=default
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
Definition RField.cxx:2622
void ConstructValue(void *where) const override
Constructs value in a given location of size at least GetValueSize(). Called by the base class' Creat...
Definition RField.cxx:2585
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const override
Called by Clone(), which additionally copies the on-disk ID.
Definition RField.cxx:2553
void operator()(void *objPtr, bool dtorOnly) final
Definition RField.cxx:4035
Template specializations for C++ std::tuple.
std::unique_ptr< RDeleter > GetDeleter() const override
RTupleField & operator=(RTupleField &&other)=default
static std::string GetTypeList(const std::vector< std::unique_ptr< RFieldBase > > &itemFields)
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const override
Called by Clone(), which additionally copies the on-disk ID.
Definition RField.cxx:4018
void ConstructValue(void *where) const override
Constructs value in a given location of size at least GetValueSize(). Called by the base class' Creat...
Definition RField.cxx:4030
~RTupleField() override=default
RTupleField(RTupleField &&other)=default
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:81
RooCmdArg Index(RooCategory &icat)
#define T2
Definition md5.inl:147
#define T1
Definition md5.inl:146
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
ENTupleStructure
The fields in the ntuple model tree can carry different structural information about the type system.
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...