Logo ROOT  
Reference Guide
Loading...
Searching...
No Matches
RFieldSTLMisc.hxx
Go to the documentation of this file.
1/// \file ROOT/RField/STLMisc.hxx
2/// \author Jakob Blomer <jblomer@cern.ch>
3/// \date 2018-10-09
4
5/*************************************************************************
6 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
7 * All rights reserved. *
8 * *
9 * For the licensing terms see $ROOTSYS/LICENSE. *
10 * For the list of contributors see $ROOTSYS/README/CREDITS. *
11 *************************************************************************/
12
13#ifndef ROOT_RField_STLMisc
14#define ROOT_RField_STLMisc
15
16#ifndef ROOT_RField
17#error "Please include RField.hxx!"
18#endif
19
20#include <ROOT/RFieldBase.hxx>
21#include <ROOT/RNTupleTypes.hxx>
22
23#include <atomic>
24#include <bitset>
25#include <cstddef>
26#include <memory>
27#include <optional>
28#include <string>
29#include <string_view>
30#include <typeinfo>
31#include <variant>
32
33namespace ROOT {
34namespace Experimental {
35
36namespace Detail {
37class RFieldVisitor;
38} // namespace Detail
39
40} // namespace Experimental
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(ROOT::NTupleSize_t globalIndex, void *to) final { CallReadOn(*fSubfields[0], globalIndex, to); }
55 void ReadInClusterImpl(RNTupleLocalIndex localIndex, void *to) final { CallReadOn(*fSubfields[0], localIndex, to); }
56
57 void ReconcileOnDiskField(const RNTupleDescriptor &desc) final;
58
59public:
60 RAtomicField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField);
61 RAtomicField(RAtomicField &&other) = default;
62 RAtomicField &operator=(RAtomicField &&other) = default;
63 ~RAtomicField() override = default;
64
65 std::vector<RValue> SplitValue(const RValue &value) const final;
66
67 size_t GetValueSize() const final { return fSubfields[0]->GetValueSize(); }
68 size_t GetAlignment() const final { return fSubfields[0]->GetAlignment(); }
69
70 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
71};
72
73template <typename ItemT>
74class RField<std::atomic<ItemT>> final : public RAtomicField {
75public:
76 static std::string TypeName() { return "std::atomic<" + RField<ItemT>::TypeName() + ">"; }
77 explicit RField(std::string_view name) : RAtomicField(name, std::make_unique<RField<ItemT>>("_0")) {}
78 RField(RField &&other) = default;
79 RField &operator=(RField &&other) = default;
80 ~RField() final = default;
81};
82
83////////////////////////////////////////////////////////////////////////////////
84/// Template specializations for C++ std::bitset
85////////////////////////////////////////////////////////////////////////////////
86
87/// The generic field for a `std::bitset<N>`.
88/// GCC and Clang store the bits in an array of unsigned long, whereas MSVC uses either a single uint32_t for `N <= 32`
89/// or an array of uint64_t for `N > 32` (reference: https://github.com/microsoft/STL/blob/main/stl/inc/bitset).
90/// TODO(jblomer): reading and writing efficiency should be improved; currently it is one bit at a time
91/// with an array of bools on the page level.
92class RBitsetField : public RFieldBase {
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 ROOT::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(ROOT::NTupleSize_t globalIndex, void *to) final;
107 void ReadInClusterImpl(RNTupleLocalIndex localIndex, void *to) final;
108
109 size_t WordSize() const
110 {
111#if defined(_MSC_VER)
112 const size_t wordSize = (fN <= sizeof(unsigned long) * 8) ? sizeof(unsigned long) : sizeof(unsigned long long);
113#else
114 const size_t wordSize = sizeof(unsigned long);
115#endif
116 return wordSize;
117 }
118
119 template <typename FUlong, typename FUlonglong, typename... Args>
120 void SelectWordSize(FUlong &&fUlong, FUlonglong &&fUlonglong, Args &&...args);
121
122public:
123 RBitsetField(std::string_view fieldName, std::size_t N);
124 RBitsetField(RBitsetField &&other) = default;
126 ~RBitsetField() override = default;
127
128 size_t GetValueSize() const final
129 {
130 const size_t bitsPerWord = WordSize() * 8;
131 return WordSize() * ((fN + bitsPerWord - 1) / bitsPerWord);
132 }
133
134 size_t GetAlignment() const final
135 {
136#if defined(_MSC_VER)
137 return WordSize() == sizeof(unsigned long) ? alignof(unsigned long) : alignof(unsigned long long);
138#else
139 return alignof(unsigned long);
140#endif
141 }
142
143 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
144
145 /// Get the number of bits in the bitset, i.e. the `N` in `std::bitset<N>`
146 std::size_t GetN() const { return fN; }
147};
148
149template <std::size_t N>
150class RField<std::bitset<N>> final : public RBitsetField {
151public:
152 static std::string TypeName() { return "std::bitset<" + std::to_string(N) + ">"; }
153 explicit RField(std::string_view name) : RBitsetField(name, N) {}
154 RField(RField &&other) = default;
155 RField &operator=(RField &&other) = default;
156 ~RField() final = default;
157};
158
159////////////////////////////////////////////////////////////////////////////////
160/// Template specializations for C++ std::byte
161////////////////////////////////////////////////////////////////////////////////
162
163extern template class RSimpleField<std::byte>;
164
165template <>
166class RField<std::byte> final : public RSimpleField<std::byte> {
167protected:
168 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
169 {
170 return std::make_unique<RField>(newName);
171 }
172
173 const RColumnRepresentations &GetColumnRepresentations() const final;
174
175public:
176 static std::string TypeName() { return "std::byte"; }
177 explicit RField(std::string_view name) : RSimpleField(name, TypeName()) {}
178 RField(RField &&other) = default;
179 RField &operator=(RField &&other) = default;
180 ~RField() final = default;
181
182 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
183};
184
185////////////////////////////////////////////////////////////////////////////////
186/// Template specializations for C++ std::optional and std::unique_ptr
187////////////////////////////////////////////////////////////////////////////////
188
189/// The field for values that may or may not be present in an entry. Parent class for unique pointer field and
190/// optional field. A nullable field cannot be instantiated itself but only its descendants.
191/// The RNullableField takes care of the on-disk representation. Child classes are responsible for the in-memory
192/// representation. Nullable fields use a `(Split)Index[64|32]` column to point to the available items.
194 /// The number of written non-null items in this cluster
196
197protected:
198 // For reading, indicates that we read type T as a nullable field of type T, i.e. the value is always present
200
202 void GenerateColumns() final;
203 void GenerateColumns(const ROOT::RNTupleDescriptor &) final;
204
205 std::size_t AppendNull();
206 std::size_t AppendValue(const void *from);
207 void CommitClusterImpl() final { fNWritten = 0; }
208
209 void ReconcileOnDiskField(const RNTupleDescriptor &desc) final;
210
211 /// Given the global index of the nullable field, returns the corresponding cluster-local index of the subfield or,
212 /// if it is null, returns a default constructed RNTupleLocalIndex
213 RNTupleLocalIndex GetItemIndex(NTupleSize_t globalIndex);
214 /// Given the cluster-local index of the nullable field, returns the corresponding cluster-local index of
215 /// the subfield or, if it is null, returns a default constructed RNTupleLocalIndex
216 RNTupleLocalIndex GetItemIndex(RNTupleLocalIndex localIndex);
217
218 RNullableField(std::string_view fieldName, const std::string &typePrefix, std::unique_ptr<RFieldBase> itemField);
219
220public:
221 RNullableField(RNullableField &&other) = default;
223 ~RNullableField() override = default;
224
225 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
226};
227
229 class ROptionalDeleter : public RDeleter {
230 private:
231 std::unique_ptr<RDeleter> fItemDeleter; // nullptr for trivially destructible items
232 std::size_t fEngagementPtrOffset = 0;
233
234 public:
235 ROptionalDeleter(std::unique_ptr<RDeleter> itemDeleter, std::size_t engagementPtrOffset)
236 : fItemDeleter(std::move(itemDeleter)), fEngagementPtrOffset(engagementPtrOffset) {}
237 void operator()(void *objPtr, bool dtorOnly) final;
238 };
239
240 std::unique_ptr<RDeleter> fItemDeleter;
241
242 /// Given a pointer to an `std::optional<T>` in `optionalPtr`, extract a pointer to the engagement boolean.
243 /// Assumes that an `std::optional<T>` is stored as `struct { T t; bool engagement; };`
244 const bool *GetEngagementPtr(const void *optionalPtr) const;
245 bool *GetEngagementPtr(void *optionalPtr) const;
246 std::size_t GetEngagementPtrOffset() const;
247 void PrepareRead(void *to, bool hasOnDiskValue);
248
249protected:
250 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
251
252 void ConstructValue(void *where) const final;
253 std::unique_ptr<RDeleter> GetDeleter() const final;
254
255 std::size_t AppendImpl(const void *from) final;
256 void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
257 void ReadInClusterImpl(ROOT::RNTupleLocalIndex localIndex, void *to) final;
258
259public:
260 ROptionalField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField);
261 ROptionalField(ROptionalField &&other) = default;
262 ROptionalField &operator=(ROptionalField &&other) = default;
263 ~ROptionalField() override = default;
264
265 std::vector<RValue> SplitValue(const RValue &value) const final;
266 size_t GetValueSize() const final;
267 size_t GetAlignment() const final;
268};
269
270template <typename ItemT>
271class RField<std::optional<ItemT>> final : public ROptionalField {
272public:
273 static std::string TypeName() { return "std::optional<" + RField<ItemT>::TypeName() + ">"; }
274 explicit RField(std::string_view name) : ROptionalField(name, std::make_unique<RField<ItemT>>("_0")) {}
275 RField(RField &&other) = default;
276 RField &operator=(RField &&other) = default;
277 ~RField() final = default;
278};
279
282 private:
283 std::unique_ptr<RDeleter> fItemDeleter;
284
285 public:
286 explicit RUniquePtrDeleter(std::unique_ptr<RDeleter> itemDeleter) : fItemDeleter(std::move(itemDeleter)) {}
287 void operator()(void *objPtr, bool dtorOnly) final;
288 };
289
290 std::unique_ptr<RDeleter> fItemDeleter;
291 /// If the item type is a polymorphic class (that declares or inherits at least one virtual method), points to the
292 /// expected dynamic type of any user object; otherwise nullptr.
293 const std::type_info *fPolymorphicTypeInfo = nullptr;
294
295 // Returns the value pointer, i.e. where to read the subfield into
296 void *PrepareRead(void *to, bool hasOnDiskValue);
297
298protected:
299 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
300
301 void ConstructValue(void *where) const final { new (where) std::unique_ptr<char>(); }
302 std::unique_ptr<RDeleter> GetDeleter() const final;
303
304 std::size_t AppendImpl(const void *from) final;
305 void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
306 void ReadInClusterImpl(ROOT::RNTupleLocalIndex localIndex, void *to) final;
307
308public:
309 RUniquePtrField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField);
311 RUniquePtrField &operator=(RUniquePtrField &&other) = default;
312 ~RUniquePtrField() override = default;
313
314 std::vector<RValue> SplitValue(const RValue &value) const final;
315 size_t GetValueSize() const final { return sizeof(std::unique_ptr<char>); }
316 size_t GetAlignment() const final { return alignof(std::unique_ptr<char>); }
317};
318
319template <typename ItemT>
320class RField<std::unique_ptr<ItemT>> final : public RUniquePtrField {
321public:
322 static std::string TypeName() { return "std::unique_ptr<" + RField<ItemT>::TypeName() + ">"; }
323 explicit RField(std::string_view name) : RUniquePtrField(name, std::make_unique<RField<ItemT>>("_0")) {}
324 RField(RField &&other) = default;
325 RField &operator=(RField &&other) = default;
326 ~RField() final = default;
327};
328
329////////////////////////////////////////////////////////////////////////////////
330/// Template specializations for C++ std::string
331////////////////////////////////////////////////////////////////////////////////
332
333template <>
334class RField<std::string> final : public RFieldBase {
335private:
336 ROOT::Internal::RColumnIndex fIndex;
337
338 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
339 {
340 return std::make_unique<RField>(newName);
341 }
342
343 const RColumnRepresentations &GetColumnRepresentations() const final;
344 void GenerateColumns() final;
345 void GenerateColumns(const ROOT::RNTupleDescriptor &desc) final;
346
347 void ConstructValue(void *where) const final { new (where) std::string(); }
348 std::unique_ptr<RDeleter> GetDeleter() const final { return std::make_unique<RTypedDeleter<std::string>>(); }
349
350 std::size_t AppendImpl(const void *from) final;
351 void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
352
353 void CommitClusterImpl() final { fIndex = 0; }
354
355public:
356 static std::string TypeName() { return "std::string"; }
357 explicit RField(std::string_view name)
358 : RFieldBase(name, TypeName(), ROOT::ENTupleStructure::kPlain, false /* isSimple */), fIndex(0)
359 {
360 }
361 RField(RField &&other) = default;
362 RField &operator=(RField &&other) = default;
363 ~RField() final = default;
364
365 size_t GetValueSize() const final { return sizeof(std::string); }
366 size_t GetAlignment() const final { return std::alignment_of<std::string>(); }
367 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
368};
369
370////////////////////////////////////////////////////////////////////////////////
371/// Template specializations for C++ std::variant
372////////////////////////////////////////////////////////////////////////////////
373
374/// The generic field for std::variant types
375class RVariantField : public RFieldBase {
376private:
377 // Most compilers support at least 255 variants (256 - 1 value for the empty variant).
378 // Some compilers switch to a two-byte tag field already with 254 variants.
379 // MSVC only supports 163 variants in older versions, 250 in newer ones. It switches to a 2 byte
380 // tag as of 128 variants (at least in debug mode), so for simplicity we set the limit to 125 variants.
381 static constexpr std::size_t kMaxVariants = 125;
382
383 class RVariantDeleter : public RDeleter {
384 private:
385 std::size_t fTagOffset;
386 std::size_t fVariantOffset;
387 std::vector<std::unique_ptr<RDeleter>> fItemDeleters;
388
389 public:
390 RVariantDeleter(std::size_t tagOffset, std::size_t variantOffset,
391 std::vector<std::unique_ptr<RDeleter>> itemDeleters)
392 : fTagOffset(tagOffset), fVariantOffset(variantOffset), fItemDeleters(std::move(itemDeleters))
393 {
394 }
395 void operator()(void *objPtr, bool dtorOnly) final;
396 };
397
398 size_t fMaxItemSize = 0;
399 size_t fMaxAlignment = 1;
400 /// In the `std::variant` memory layout, at which byte number is the index stored
401 size_t fTagOffset = 0;
402 /// In the `std::variant` memory layout, the actual union of types may start at an offset > 0
403 size_t fVariantOffset = 0;
404 std::vector<ROOT::Internal::RColumnIndex::ValueType> fNWritten;
405
406 /// Extracts the index from an `std::variant` and transforms it into the 1-based index used for the switch column
407 /// The implementation supports two memory layouts that are in use: a trailing unsigned byte, zero-indexed,
408 /// having the exception caused empty state encoded by the max tag value,
409 /// or a trailing unsigned int instead of a char.
410 static std::uint8_t GetTag(const void *variantPtr, std::size_t tagOffset);
411 static void SetTag(void *variantPtr, std::size_t tagOffset, std::uint8_t tag);
412
413 RVariantField(std::string_view name, const RVariantField &source); // Used by CloneImpl()
414
415protected:
416 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
417
419 void GenerateColumns() final;
420 void GenerateColumns(const ROOT::RNTupleDescriptor &desc) final;
421
422 void ConstructValue(void *where) const final;
423 std::unique_ptr<RDeleter> GetDeleter() const final;
424
425 std::size_t AppendImpl(const void *from) final;
426 void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
427
428 void CommitClusterImpl() final;
429
430 void ReconcileOnDiskField(const RNTupleDescriptor &desc) final;
431
432public:
433 RVariantField(std::string_view fieldName, std::vector<std::unique_ptr<RFieldBase>> itemFields);
434 RVariantField(RVariantField &&other) = default;
435 RVariantField &operator=(RVariantField &&other) = default;
436 ~RVariantField() override = default;
437
438 size_t GetValueSize() const final;
439 size_t GetAlignment() const final;
440};
441
442template <typename... ItemTs>
443class RField<std::variant<ItemTs...>> final : public RVariantField {
444private:
445 template <typename HeadT, typename... TailTs>
446 static std::string BuildItemTypes()
447 {
448 std::string result = RField<HeadT>::TypeName();
449 if constexpr (sizeof...(TailTs) > 0)
450 result += "," + BuildItemTypes<TailTs...>();
451 return result;
452 }
453
454 template <typename HeadT, typename... TailTs>
455 static void _BuildItemFields(std::vector<std::unique_ptr<RFieldBase>> &itemFields, unsigned int index = 0)
456 {
457 itemFields.emplace_back(new RField<HeadT>("_" + std::to_string(index)));
458 if constexpr (sizeof...(TailTs) > 0)
459 _BuildItemFields<TailTs...>(itemFields, index + 1);
460 }
461 static std::vector<std::unique_ptr<RFieldBase>> BuildItemFields()
462 {
463 std::vector<std::unique_ptr<RFieldBase>> result;
464 _BuildItemFields<ItemTs...>(result);
465 return result;
466 }
467
468public:
469 static std::string TypeName() { return "std::variant<" + BuildItemTypes<ItemTs...>() + ">"; }
470 explicit RField(std::string_view name) : RVariantField(name, BuildItemFields()) {}
471 RField(RField &&other) = default;
472 RField &operator=(RField &&other) = default;
473 ~RField() final = default;
474};
475
476} // namespace ROOT
477
478#endif
#define N
char name[80]
Definition TGX11.cxx:148
TRObject operator()(const T1 &t1) const
Binding & operator=(OUT(*fun)(void))
Abstract base class for classes implementing the visitor design pattern.
The in-memory representation of a 32bit or 64bit on-disk index column.
RAtomicField(RAtomicField &&other)=default
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
void ConstructValue(void *where) const final
Constructs value in a given location of size at least GetValueSize(). Called by the base class' Creat...
size_t GetAlignment() const final
As a rule of thumb, the alignment is equal to the size of the type.
void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final
Definition RField.cxx:1243
void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final
RAtomicField(std::string_view fieldName, std::unique_ptr< RFieldBase > itemField)
Definition RField.cxx:1205
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
Definition RField.cxx:1220
void ReadInClusterImpl(RNTupleLocalIndex localIndex, void *to) final
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
std::unique_ptr< RDeleter > GetDeleter() const final
void ReconcileOnDiskField(const RNTupleDescriptor &desc) final
For non-artificial fields, check compatibility of the in-memory field and the on-disk field.
Definition RField.cxx:1226
~RAtomicField() override=default
std::vector< RValue > SplitValue(const RValue &value) const final
Creates the list of direct child values given an existing value for this field.
Definition RField.cxx:1236
RAtomicField & operator=(RAtomicField &&other)=default
Template specializations for C++ std::bitset.
RBitsetField(std::string_view fieldName, std::size_t N)
Definition RField.cxx:755
std::size_t GetN() const
Get the number of bits in the bitset, i.e. the N in std::bitset<N>.
void ConstructValue(void *where) const final
Constructs value in a given location of size at least GetValueSize(). Called by the base class' Creat...
size_t GetAlignment() const final
As a rule of thumb, the alignment is equal to the size of the type.
size_t WordSize() const
~RBitsetField() override=default
RBitsetField & operator=(RBitsetField &&other)=default
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
RBitsetField(RBitsetField &&other)=default
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
void ReconcileOnDiskField(const RNTupleDescriptor &desc) final
For non-artificial fields, check compatibility of the in-memory field and the on-disk field.
void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final
void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final
void ReadInClusterImpl(RNTupleLocalIndex localIndex, void *to) final
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
The list of column representations a field can have.
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.
std::vector< std::unique_ptr< RFieldBase > > fSubfields
Collections and classes own subfields.
virtual const RColumnRepresentations & GetColumnRepresentations() const
Implementations in derived classes should return a static RColumnRepresentations object.
virtual void GenerateColumns()
Implementations in derived classes should create the backing columns corresponding to the field type ...
static std::unique_ptr< RDeleter > GetDeleterOf(const RFieldBase &other)
static std::size_t CallAppendOn(RFieldBase &other, const void *from)
Allow derived classes to call Append() and Read() on other (sub)fields.
RFieldBase(std::string_view name, std::string_view type, ROOT::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.
static void CallReadOn(RFieldBase &other, RNTupleLocalIndex localIndex, void *to)
static void CallConstructValueOn(const RFieldBase &other, void *where)
Allow derived classes to call ConstructValue(void *) and GetDeleter() on other (sub)fields.
Classes with dictionaries that can be inspected by TClass.
Definition RField.hxx:320
~RField() final=default
RField & operator=(RField &&other)=default
static std::string TypeName()
Definition RField.hxx:322
RField(std::string_view name)
Definition RField.hxx:323
The on-storage metadata of an RNTuple.
Addresses a column element or field item relative to a particular cluster, instead of a global NTuple...
Template specializations for C++ std::optional and std::unique_ptr.
void CommitClusterImpl() final
ROOT::Internal::RColumnIndex fNWritten
The number of written non-null items in this cluster.
RNullableField(std::string_view fieldName, const std::string &typePrefix, std::unique_ptr< RFieldBase > itemField)
Definition RField.cxx:864
std::size_t AppendNull()
Definition RField.cxx:897
std::size_t AppendValue(const void *from)
Definition RField.cxx:903
void GenerateColumns() final
Implementations in derived classes should create the backing columns corresponding to the field type ...
Definition RField.cxx:885
~RNullableField() override=default
RNullableField & operator=(RNullableField &&other)=default
RNullableField(RNullableField &&other)=default
ROptionalDeleter(std::unique_ptr< RDeleter > itemDeleter, std::size_t engagementPtrOffset)
std::unique_ptr< RDeleter > fItemDeleter
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.cxx:1152
size_t GetAlignment() const final
As a rule of thumb, the alignment is equal to the size of the type.
Definition RField.cxx:1198
std::unique_ptr< RDeleter > GetDeleter() const final
Definition RField.cxx:1167
std::size_t GetEngagementPtrOffset() const
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
Definition RField.cxx:1093
std::unique_ptr< RDeleter > fItemDeleter
const bool * GetEngagementPtr(const void *optionalPtr) const
Given a pointer to an std::optional<T> in optionalPtr, extract a pointer to the engagement boolean.
Definition RField.cxx:1088
void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final
Definition RField.cxx:1122
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
Definition RField.cxx:1099
void ReadInClusterImpl(ROOT::RNTupleLocalIndex localIndex, void *to) final
Definition RField.cxx:1138
std::vector< RValue > SplitValue(const RValue &value) const final
Creates the list of direct child values given an existing value for this field.
Definition RField.cxx:1174
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
Definition RField.cxx:1184
void PrepareRead(void *to, bool hasOnDiskValue)
Definition RField.cxx:1108
ROptionalField(std::string_view fieldName, std::unique_ptr< RFieldBase > itemField)
Definition RField.cxx:1076
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
std::vector< RValue > SplitValue(const RValue &value) const final
Creates the list of direct child values given an existing value for this field.
Definition RField.cxx:1063
const std::type_info * fPolymorphicTypeInfo
If the item type is a polymorphic class (that declares or inherits at least one virtual method),...
void * PrepareRead(void *to, bool hasOnDiskValue)
Definition RField.cxx:998
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
Definition RField.cxx:965
RUniquePtrField(std::string_view fieldName, std::unique_ptr< RFieldBase > itemField)
Definition RField.cxx:957
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::unique_ptr< RDeleter > > fItemDeleters
RVariantDeleter(std::size_t tagOffset, std::size_t variantOffset, std::vector< std::unique_ptr< RDeleter > > itemDeleters)
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.
static constexpr std::size_t kMaxVariants
std::vector< ROOT::Internal::RColumnIndex::ValueType > fNWritten
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 ...
void GenerateColumns() final
Implementations in derived classes should create the backing columns corresponding to the field type ...
size_t fVariantOffset
In the std::variant memory layout, the actual union of types may start at an offset > 0.
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
std::unique_ptr< RDeleter > GetDeleter() const final
void ReconcileOnDiskField(const RNTupleDescriptor &desc) final
For non-artificial fields, check compatibility of the in-memory field and the on-disk field.
const RColumnRepresentations & GetColumnRepresentations() const final
Implementations in derived classes should return a static RColumnRepresentations object.
void ConstructValue(void *where) const final
Constructs value in a given location of size at least GetValueSize(). Called by the base class' Creat...
size_t fTagOffset
In the std::variant memory layout, at which byte number is the index stored.
RVariantField(std::string_view name, const RVariantField &source)
void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final
static void SetTag(void *variantPtr, std::size_t tagOffset, std::uint8_t tag)
void CommitClusterImpl() final
STL class.
STL class.
STL class.
Namespace for ROOT features in testing.
Definition TROOT.h:100
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
ENTupleStructure
The fields in the RNTuple data model tree can carry different structural information about the type s...