Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RFieldSTLMisc.hxx
Go to the documentation of this file.
1/// \file ROOT/RField/STLMisc.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_STLMisc
17#define ROOT7_RField_STLMisc
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 <atomic>
27#include <bitset>
28#include <cstddef>
29#include <memory>
30#include <optional>
31#include <string>
32#include <string_view>
33#include <variant>
34
35namespace ROOT {
36namespace Experimental {
37
38namespace Detail {
39class RFieldVisitor;
40} // namespace Detail
41
42////////////////////////////////////////////////////////////////////////////////
43/// Template specializations for C++ std::atomic
44////////////////////////////////////////////////////////////////////////////////
45
46class RAtomicField : public RFieldBase {
47protected:
48 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
49
50 void ConstructValue(void *where) const final { CallConstructValueOn(*fSubFields[0], where); }
51 std::unique_ptr<RDeleter> GetDeleter() const final { return GetDeleterOf(*fSubFields[0]); }
52
53 std::size_t AppendImpl(const void *from) final { return CallAppendOn(*fSubFields[0], from); }
54 void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final { CallReadOn(*fSubFields[0], globalIndex, to); }
55 void ReadInClusterImpl(RClusterIndex clusterIndex, void *to) final { CallReadOn(*fSubFields[0], clusterIndex, to); }
56
57public:
58 RAtomicField(std::string_view fieldName, std::string_view typeName, std::unique_ptr<RFieldBase> itemField);
59 RAtomicField(RAtomicField &&other) = default;
60 RAtomicField &operator=(RAtomicField &&other) = default;
61 ~RAtomicField() override = default;
62
63 std::vector<RValue> SplitValue(const RValue &value) const final;
64
65 size_t GetValueSize() const final { return fSubFields[0]->GetValueSize(); }
66 size_t GetAlignment() const final { return fSubFields[0]->GetAlignment(); }
67
68 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
69};
70
71template <typename ItemT>
72class RField<std::atomic<ItemT>> final : public RAtomicField {
73public:
74 static std::string TypeName() { return "std::atomic<" + RField<ItemT>::TypeName() + ">"; }
75 explicit RField(std::string_view name) : RAtomicField(name, TypeName(), std::make_unique<RField<ItemT>>("_0")) {}
76 RField(RField &&other) = default;
77 RField &operator=(RField &&other) = default;
78 ~RField() override = default;
79};
80
81////////////////////////////////////////////////////////////////////////////////
82/// Template specializations for C++ std::bitset
83////////////////////////////////////////////////////////////////////////////////
84
85/// The generic field an std::bitset<N>. All compilers we care about store the bits in an array of unsigned long.
86/// TODO(jblomer): reading and writing efficiency should be improved; currently it is one bit at a time
87/// with an array of bools on the page level.
88class RBitsetField : public RFieldBase {
89 using Word_t = unsigned long;
90 static constexpr std::size_t kWordSize = sizeof(Word_t);
91 static constexpr std::size_t kBitsPerWord = kWordSize * 8;
92
93protected:
94 std::size_t fN;
95
96protected:
97 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
98 {
99 return std::make_unique<RBitsetField>(newName, fN);
100 }
101 const RColumnRepresentations &GetColumnRepresentations() const final;
102 void GenerateColumns() final;
103 void GenerateColumns(const RNTupleDescriptor &desc) final;
104 void ConstructValue(void *where) const final { memset(where, 0, GetValueSize()); }
105 std::size_t AppendImpl(const void *from) final;
106 void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final;
107 void ReadInClusterImpl(RClusterIndex clusterIndex, void *to) final;
108
109public:
110 RBitsetField(std::string_view fieldName, std::size_t N);
111 RBitsetField(RBitsetField &&other) = default;
113 ~RBitsetField() override = default;
114
115 size_t GetValueSize() const final { return kWordSize * ((fN + kBitsPerWord - 1) / kBitsPerWord); }
116 size_t GetAlignment() const final { return alignof(Word_t); }
117 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
118
119 /// Get the number of bits in the bitset, i.e. the N in std::bitset<N>
120 std::size_t GetN() const { return fN; }
121};
122
123template <std::size_t N>
124class RField<std::bitset<N>> final : public RBitsetField {
125public:
126 static std::string TypeName() { return "std::bitset<" + std::to_string(N) + ">"; }
127 explicit RField(std::string_view name) : RBitsetField(name, N) {}
128 RField(RField &&other) = default;
129 RField &operator=(RField &&other) = default;
130 ~RField() override = default;
131};
132
133////////////////////////////////////////////////////////////////////////////////
134/// Template specializations for C++ std::byte
135////////////////////////////////////////////////////////////////////////////////
136
137extern template class RSimpleField<std::byte>;
138
139template <>
140class RField<std::byte> final : public RSimpleField<std::byte> {
141protected:
142 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
143 {
144 return std::make_unique<RField>(newName);
145 }
146
147 const RColumnRepresentations &GetColumnRepresentations() const final;
148
149public:
150 static std::string TypeName() { return "std::byte"; }
151 explicit RField(std::string_view name) : RSimpleField(name, TypeName()) {}
152 RField(RField &&other) = default;
153 RField &operator=(RField &&other) = default;
154 ~RField() override = default;
155
156 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
157};
158
159////////////////////////////////////////////////////////////////////////////////
160/// Template specializations for C++ std::optional and std::unique_ptr
161////////////////////////////////////////////////////////////////////////////////
162
163/// The field for values that may or may not be present in an entry. Parent class for unique pointer field and
164/// optional field. A nullable field cannot be instantiated itself but only its descendants.
165/// The RNullableField takes care of the on-disk representation. Child classes are responsible for the in-memory
166/// representation. Nullable fields use a (Split)Index[64|32] column to point to the available items.
168 /// The number of written non-null items in this cluster
169 ClusterSize_t fNWritten{0};
170
171protected:
172 const RFieldBase::RColumnRepresentations &GetColumnRepresentations() const final;
173 void GenerateColumns() final;
174 void GenerateColumns(const RNTupleDescriptor &) final;
175
176 std::size_t AppendNull();
177 std::size_t AppendValue(const void *from);
178 void CommitClusterImpl() final { fNWritten = 0; }
179
180 /// Given the index of the nullable field, returns the corresponding global index of the subfield or,
181 /// if it is null, returns kInvalidClusterIndex
182 RClusterIndex GetItemIndex(NTupleSize_t globalIndex);
183
184 RNullableField(std::string_view fieldName, std::string_view typeName, std::unique_ptr<RFieldBase> itemField);
185
186public:
187 RNullableField(RNullableField &&other) = default;
189 ~RNullableField() override = default;
190
191 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
192};
193
195 class ROptionalDeleter : public RDeleter {
196 private:
197 std::unique_ptr<RDeleter> fItemDeleter;
198
199 public:
200 explicit ROptionalDeleter(std::unique_ptr<RDeleter> itemDeleter) : fItemDeleter(std::move(itemDeleter)) {}
201 void operator()(void *objPtr, bool dtorOnly) final;
202 };
203
204 std::unique_ptr<RDeleter> fItemDeleter;
205
206 /// Given a pointer to an std::optional<T> in `optionalPtr`, extract a pointer to the value T* and a pointer
207 /// to the engagement boolean. Assumes that an std::optional<T> is stored as
208 /// `struct { T t; bool engagement; };`
209 std::pair<const void *, const bool *> GetValueAndEngagementPtrs(const void *optionalPtr) const;
210 std::pair<void *, bool *> GetValueAndEngagementPtrs(void *optionalPtr) const;
211
212protected:
213 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
214
215 void ConstructValue(void *where) const final;
216 std::unique_ptr<RDeleter> GetDeleter() const final;
217
218 std::size_t AppendImpl(const void *from) final;
219 void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final;
220
221public:
222 ROptionalField(std::string_view fieldName, std::string_view typeName, std::unique_ptr<RFieldBase> itemField);
223 ROptionalField(ROptionalField &&other) = default;
224 ROptionalField &operator=(ROptionalField &&other) = default;
225 ~ROptionalField() override = default;
226
227 std::vector<RValue> SplitValue(const RValue &value) const final;
228 size_t GetValueSize() const final;
229 size_t GetAlignment() const final;
230};
231
232template <typename ItemT>
233class RField<std::optional<ItemT>> final : public ROptionalField {
234public:
235 static std::string TypeName() { return "std::optional<" + RField<ItemT>::TypeName() + ">"; }
236 explicit RField(std::string_view name) : ROptionalField(name, TypeName(), std::make_unique<RField<ItemT>>("_0")) {}
237 RField(RField &&other) = default;
238 RField &operator=(RField &&other) = default;
239 ~RField() override = default;
240};
241
244 private:
245 std::unique_ptr<RDeleter> fItemDeleter;
246
247 public:
248 explicit RUniquePtrDeleter(std::unique_ptr<RDeleter> itemDeleter) : fItemDeleter(std::move(itemDeleter)) {}
249 void operator()(void *objPtr, bool dtorOnly) final;
250 };
251
252 std::unique_ptr<RDeleter> fItemDeleter;
253
254protected:
255 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
256
257 void ConstructValue(void *where) const final { new (where) std::unique_ptr<char>(); }
258 std::unique_ptr<RDeleter> GetDeleter() const final;
259
260 std::size_t AppendImpl(const void *from) final;
261 void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final;
262
263public:
264 RUniquePtrField(std::string_view fieldName, std::string_view typeName, std::unique_ptr<RFieldBase> itemField);
266 RUniquePtrField &operator=(RUniquePtrField &&other) = default;
267 ~RUniquePtrField() override = default;
268
269 std::vector<RValue> SplitValue(const RValue &value) const final;
270 size_t GetValueSize() const final { return sizeof(std::unique_ptr<char>); }
271 size_t GetAlignment() const final { return alignof(std::unique_ptr<char>); }
272};
273
274template <typename ItemT>
275class RField<std::unique_ptr<ItemT>> final : public RUniquePtrField {
276public:
277 static std::string TypeName() { return "std::unique_ptr<" + RField<ItemT>::TypeName() + ">"; }
278 explicit RField(std::string_view name) : RUniquePtrField(name, TypeName(), std::make_unique<RField<ItemT>>("_0")) {}
279 RField(RField &&other) = default;
280 RField &operator=(RField &&other) = default;
281 ~RField() override = default;
282};
283
284////////////////////////////////////////////////////////////////////////////////
285/// Template specializations for C++ std::string
286////////////////////////////////////////////////////////////////////////////////
287
288template <>
289class RField<std::string> final : public RFieldBase {
290private:
291 ClusterSize_t fIndex;
292
293 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
294 {
295 return std::make_unique<RField>(newName);
296 }
297
298 const RColumnRepresentations &GetColumnRepresentations() const final;
299 void GenerateColumns() final;
300 void GenerateColumns(const RNTupleDescriptor &desc) final;
301
302 void ConstructValue(void *where) const final { new (where) std::string(); }
303 std::unique_ptr<RDeleter> GetDeleter() const final { return std::make_unique<RTypedDeleter<std::string>>(); }
304
305 std::size_t AppendImpl(const void *from) final;
306 void ReadGlobalImpl(ROOT::Experimental::NTupleSize_t globalIndex, void *to) final;
307
308 void CommitClusterImpl() final { fIndex = 0; }
309
310public:
311 static std::string TypeName() { return "std::string"; }
312 explicit RField(std::string_view name)
313 : RFieldBase(name, TypeName(), ENTupleStructure::kLeaf, false /* isSimple */), fIndex(0)
314 {
315 }
316 RField(RField &&other) = default;
317 RField &operator=(RField &&other) = default;
318 ~RField() override = default;
319
320 size_t GetValueSize() const final { return sizeof(std::string); }
321 size_t GetAlignment() const final { return std::alignment_of<std::string>(); }
322 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
323};
324
325////////////////////////////////////////////////////////////////////////////////
326/// Template specializations for C++ std::variant
327////////////////////////////////////////////////////////////////////////////////
328
329/// The generic field for std::variant types
330class RVariantField : public RFieldBase {
331private:
332 // Most compilers support at least 255 variants (256 - 1 value for the empty variant).
333 // Some compilers switch to a two-byte tag field already with 254 variants.
334 // MSVC only supports 163 variants in older versions, 250 in newer ones. It switches to a 2 byte
335 // tag as of 128 variants (at least in debug mode), so for simplicity we set the limit to 125 variants.
336 static constexpr std::size_t kMaxVariants = 125;
337
338 class RVariantDeleter : public RDeleter {
339 private:
340 std::size_t fTagOffset;
341 std::size_t fVariantOffset;
342 std::vector<std::unique_ptr<RDeleter>> fItemDeleters;
343
344 public:
345 RVariantDeleter(std::size_t tagOffset, std::size_t variantOffset,
346 std::vector<std::unique_ptr<RDeleter>> &itemDeleters)
347 : fTagOffset(tagOffset), fVariantOffset(variantOffset), fItemDeleters(std::move(itemDeleters))
348 {
349 }
350 void operator()(void *objPtr, bool dtorOnly) final;
351 };
352
353 size_t fMaxItemSize = 0;
354 size_t fMaxAlignment = 1;
355 /// In the std::variant memory layout, at which byte number is the index stored
356 size_t fTagOffset = 0;
357 /// In the std::variant memory layout, the actual union of types may start at an offset > 0
358 size_t fVariantOffset = 0;
359 std::vector<ClusterSize_t::ValueType> fNWritten;
360
361 static std::string GetTypeList(const std::vector<RFieldBase *> &itemFields);
362 /// Extracts the index from an std::variant and transforms it into the 1-based index used for the switch column
363 /// The implementation supports two memory layouts that are in use: a trailing unsigned byte, zero-indexed,
364 /// having the exception caused empty state encoded by the max tag value,
365 /// or a trailing unsigned int instead of a char.
366 static std::uint8_t GetTag(const void *variantPtr, std::size_t tagOffset);
367 static void SetTag(void *variantPtr, std::size_t tagOffset, std::uint8_t tag);
368
369protected:
370 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
371
373 void GenerateColumns() final;
374 void GenerateColumns(const RNTupleDescriptor &desc) final;
375
376 void ConstructValue(void *where) const override;
377 std::unique_ptr<RDeleter> GetDeleter() const final;
378
379 std::size_t AppendImpl(const void *from) final;
380 void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final;
381
382 void CommitClusterImpl() final;
383
384public:
385 // TODO(jblomer): use std::span in signature
386 RVariantField(std::string_view fieldName, const std::vector<RFieldBase *> &itemFields);
387 RVariantField(RVariantField &&other) = default;
388 RVariantField &operator=(RVariantField &&other) = default;
389 ~RVariantField() override = default;
390
391 size_t GetValueSize() const final;
392 size_t GetAlignment() const final;
393};
394
395template <typename... ItemTs>
396class RField<std::variant<ItemTs...>> final : public RVariantField {
397 using ContainerT = typename std::variant<ItemTs...>;
398
399private:
400 template <typename HeadT, typename... TailTs>
401 static std::string BuildItemTypes()
402 {
403 std::string result = RField<HeadT>::TypeName();
404 if constexpr (sizeof...(TailTs) > 0)
405 result += "," + BuildItemTypes<TailTs...>();
406 return result;
407 }
408
409 template <typename HeadT, typename... TailTs>
410 static std::vector<RFieldBase *> BuildItemFields(unsigned int index = 0)
411 {
412 std::vector<RFieldBase *> result;
413 result.emplace_back(new RField<HeadT>("_" + std::to_string(index)));
414 if constexpr (sizeof...(TailTs) > 0) {
415 auto tailFields = BuildItemFields<TailTs...>(index + 1);
416 result.insert(result.end(), tailFields.begin(), tailFields.end());
417 }
418 return result;
419 }
420
421protected:
422 void ConstructValue(void *where) const final { new (where) ContainerT(); }
423
424public:
425 static std::string TypeName() { return "std::variant<" + BuildItemTypes<ItemTs...>() + ">"; }
426 explicit RField(std::string_view name) : RVariantField(name, BuildItemFields<ItemTs...>()) {}
427 RField(RField &&other) = default;
428 RField &operator=(RField &&other) = default;
429 ~RField() override = default;
430};
431
432} // namespace Experimental
433} // namespace ROOT
434
435#endif
#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 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
TRObject operator()(const T1 &t1) const
Binding & operator=(OUT(*fun)(void))
Abstract base class for classes implementing the visitor design pattern.
Template specializations for C++ std::atomic.
~RAtomicField() override=default
void ReadInClusterImpl(RClusterIndex clusterIndex, void *to) final
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
Definition RField.cxx:4055
std::unique_ptr< RDeleter > GetDeleter() const final
void ConstructValue(void *where) const final
Constructs value in a given location of size at least GetValueSize(). Called by the base class' Creat...
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
size_t GetAlignment() const final
As a rule of thumb, the alignment is equal to the size of the type.
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:4062
RAtomicField & operator=(RAtomicField &&other)=default
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
RAtomicField(RAtomicField &&other)=default
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
Definition RField.cxx:4069
Template specializations for C++ std::bitset.
std::size_t GetN() const
Get the number of bits in the bitset, i.e. the N in std::bitset<N>
RBitsetField(RBitsetField &&other)=default
size_t GetAlignment() const final
As a rule of thumb, the alignment is equal to the size of the type.
static constexpr std::size_t kWordSize
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
Definition RField.cxx:3383
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
Definition RField.cxx:3397
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
static constexpr std::size_t kBitsPerWord
void ConstructValue(void *where) const final
Constructs value in a given location of size at least GetValueSize(). Called by the base class' Creat...
void GenerateColumns() final
Implementations in derived classes should create the backing columns corresponsing to the field type ...
Definition RField.cxx:3373
const RColumnRepresentations & GetColumnRepresentations() const final
Implementations in derived classes should return a static RColumnRepresentations object.
Definition RField.cxx:3367
~RBitsetField() override=default
RBitsetField & operator=(RBitsetField &&other)=default
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
Definition RField.cxx:3422
void ReadInClusterImpl(RClusterIndex clusterIndex, void *to) final
Definition RField.cxx:3409
size_t GetValueSize() const override
The number of bytes taken by a value of the appropriate type.
Definition RField.cxx:1990
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
Definition RField.cxx:1916
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
Definition RField.cxx:1925
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
void AcceptVisitor(Detail::RFieldVisitor &visitor) const override
Definition RField.cxx:2005
size_t GetAlignment() const final
As a rule of thumb, the alignment is equal to the size of the type.
Definition RField.hxx:150
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...
Some fields have multiple possible column representations, e.g.
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.
virtual void GenerateColumns()
Implementations in derived classes should create the backing columns corresponsing to the field type ...
static std::size_t CallAppendOn(RFieldBase &other, const void *from)
Allow derived classes to call Append and Read on other (sub) fields.
static std::unique_ptr< RDeleter > GetDeleterOf(const RFieldBase &other)
static void CallReadOn(RFieldBase &other, RClusterIndex clusterIndex, void *to)
static void CallConstructValueOn(const RFieldBase &other, void *where)
Allow derived classes to call ConstructValue(void *) and GetDeleter on other (sub) fields.
std::vector< std::unique_ptr< RFieldBase > > fSubFields
Collections and classes own sub fields.
RFieldBase(std::string_view name, std::string_view type, ENTupleStructure structure, bool isSimple, std::size_t nRepetitions=0)
The constructor creates the underlying column objects and connects them to either a sink or a source.
Definition RField.cxx:572
virtual const RColumnRepresentations & GetColumnRepresentations() const
Implementations in derived classes should return a static RColumnRepresentations object.
Definition RField.cxx:921
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
The on-storage meta-data of an ntuple.
Template specializations for C++ std::optional and std::unique_ptr.
RNullableField & operator=(RNullableField &&other)=default
~RNullableField() override=default
RNullableField(RNullableField &&other)=default
ROptionalDeleter(std::unique_ptr< RDeleter > itemDeleter)
std::unique_ptr< RDeleter > fItemDeleter
RUniquePtrDeleter(std::unique_ptr< RDeleter > itemDeleter)
void ConstructValue(void *where) const final
Constructs value in a given location of size at least GetValueSize(). Called by the base class' Creat...
std::unique_ptr< RDeleter > fItemDeleter
size_t GetAlignment() const final
As a rule of thumb, the alignment is equal to the size of the type.
void operator()(void *objPtr, bool dtorOnly) final
Definition RField.cxx:3556
std::vector< std::unique_ptr< RDeleter > > fItemDeleters
RVariantDeleter(std::size_t tagOffset, std::size_t variantOffset, std::vector< std::unique_ptr< RDeleter > > &itemDeleters)
Template specializations for C++ std::variant.
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
Definition RField.cxx:3514
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
Definition RField.cxx:3580
RVariantField & operator=(RVariantField &&other)=default
const RColumnRepresentations & GetColumnRepresentations() const final
Implementations in derived classes should return a static RColumnRepresentations object.
Definition RField.cxx:3533
static void SetTag(void *variantPtr, std::size_t tagOffset, std::uint8_t tag)
Definition RField.cxx:3493
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:3549
static std::string GetTypeList(const std::vector< RFieldBase * > &itemFields)
Definition RField.cxx:3429
std::vector< ClusterSize_t::ValueType > fNWritten
size_t fTagOffset
In the std::variant memory layout, at which byte number is the index stored.
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
Definition RField.cxx:3474
static constexpr std::size_t kMaxVariants
static std::uint8_t GetTag(const void *variantPtr, std::size_t tagOffset)
Extracts the index from an std::variant and transforms it into the 1-based index used for the switch ...
Definition RField.cxx:3486
size_t fVariantOffset
In the std::variant memory layout, the actual union of types may start at an offset > 0.
std::unique_ptr< RDeleter > GetDeleter() const final
Definition RField.cxx:3565
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
Definition RField.cxx:3500
size_t GetAlignment() const final
As a rule of thumb, the alignment is equal to the size of the type.
Definition RField.cxx:3575
void GenerateColumns() final
Implementations in derived classes should create the backing columns corresponsing to the field type ...
Definition RField.cxx:3539
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
RClusterSize ClusterSize_t
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...
Wrap the integer in a struct in order to avoid template specialization clash with std::uint64_t.