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 {
34
35////////////////////////////////////////////////////////////////////////////////
36/// Template specializations for C++ std::atomic
37////////////////////////////////////////////////////////////////////////////////
38
39class RAtomicField : public RFieldBase {
40protected:
41 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
42
43 void ConstructValue(void *where) const final { CallConstructValueOn(*fSubfields[0], where); }
44 std::unique_ptr<RDeleter> GetDeleter() const final { return GetDeleterOf(*fSubfields[0]); }
45
46 std::size_t AppendImpl(const void *from) final { return CallAppendOn(*fSubfields[0], from); }
47 void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final { CallReadOn(*fSubfields[0], globalIndex, to); }
48 void ReadInClusterImpl(RNTupleLocalIndex localIndex, void *to) final { CallReadOn(*fSubfields[0], localIndex, to); }
49
50 void ReconcileOnDiskField(const RNTupleDescriptor &desc) final;
51
52public:
53 RAtomicField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField);
54 RAtomicField(RAtomicField &&other) = default;
55 RAtomicField &operator=(RAtomicField &&other) = default;
56 ~RAtomicField() override = default;
57
58 std::vector<RValue> SplitValue(const RValue &value) const final;
59
60 size_t GetValueSize() const final { return fSubfields[0]->GetValueSize(); }
61 size_t GetAlignment() const final { return fSubfields[0]->GetAlignment(); }
62
63 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
64};
65
66template <typename ItemT>
67class RField<std::atomic<ItemT>> final : public RAtomicField {
68public:
69 static std::string TypeName() { return "std::atomic<" + RField<ItemT>::TypeName() + ">"; }
70 explicit RField(std::string_view name) : RAtomicField(name, std::make_unique<RField<ItemT>>("_0")) {}
71 RField(RField &&other) = default;
72 RField &operator=(RField &&other) = default;
73 ~RField() final = default;
74};
75
76////////////////////////////////////////////////////////////////////////////////
77/// Template specializations for C++ std::bitset
78////////////////////////////////////////////////////////////////////////////////
79
80/// The generic field for a `std::bitset<N>`.
81/// GCC and Clang store the bits in an array of unsigned long, whereas MSVC uses either a single uint32_t for `N <= 32`
82/// or an array of uint64_t for `N > 32` (reference: https://github.com/microsoft/STL/blob/main/stl/inc/bitset).
83class RBitsetField : public RFieldBase {
84protected:
85 std::size_t fN;
86
87protected:
88 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
89 {
90 return std::make_unique<RBitsetField>(newName, fN);
91 }
92 const RColumnRepresentations &GetColumnRepresentations() const final;
93 void GenerateColumns() final;
94 void GenerateColumns(const ROOT::RNTupleDescriptor &desc) final;
95 void ConstructValue(void *where) const final { memset(where, 0, GetValueSize()); }
96 std::size_t AppendImpl(const void *from) final;
97 void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
98 void ReadInClusterImpl(RNTupleLocalIndex localIndex, void *to) final;
99
100 size_t WordSize() const
101 {
102#if defined(_MSC_VER)
103 const size_t wordSize = (fN <= sizeof(unsigned long) * 8) ? sizeof(unsigned long) : sizeof(unsigned long long);
104#else
105 const size_t wordSize = sizeof(unsigned long);
106#endif
107 return wordSize;
108 }
109
110 template <typename FUlong, typename FUlonglong, typename... Args>
111 void SelectWordSize(FUlong &&fUlong, FUlonglong &&fUlonglong, Args &&...args);
112
113public:
114 RBitsetField(std::string_view fieldName, std::size_t N);
115 RBitsetField(RBitsetField &&other) = default;
117 ~RBitsetField() override = default;
118
119 size_t GetValueSize() const final
120 {
121 const size_t bitsPerWord = WordSize() * 8;
122 return WordSize() * ((fN + bitsPerWord - 1) / bitsPerWord);
123 }
124
125 size_t GetAlignment() const final
126 {
127#if defined(_MSC_VER)
128 return WordSize() == sizeof(unsigned long) ? alignof(unsigned long) : alignof(unsigned long long);
129#else
130 return alignof(unsigned long);
131#endif
132 }
133
134 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
135
136 /// Get the number of bits in the bitset, i.e. the `N` in `std::bitset<N>`
137 std::size_t GetN() const { return fN; }
138};
139
140template <std::size_t N>
141class RField<std::bitset<N>> final : public RBitsetField {
142public:
143 static std::string TypeName() { return "std::bitset<" + std::to_string(N) + ">"; }
144 explicit RField(std::string_view name) : RBitsetField(name, N) {}
145 RField(RField &&other) = default;
146 RField &operator=(RField &&other) = default;
147 ~RField() final = default;
148};
149
150////////////////////////////////////////////////////////////////////////////////
151/// Template specializations for C++ std::byte
152////////////////////////////////////////////////////////////////////////////////
153
154extern template class RSimpleField<std::byte>;
155
156template <>
157class RField<std::byte> final : public RSimpleField<std::byte> {
158protected:
159 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
160 {
161 return std::make_unique<RField>(newName);
162 }
163
164 const RColumnRepresentations &GetColumnRepresentations() const final;
165
166public:
167 static std::string TypeName() { return "std::byte"; }
168 explicit RField(std::string_view name) : RSimpleField(name, TypeName()) {}
169 RField(RField &&other) = default;
170 RField &operator=(RField &&other) = default;
171 ~RField() final = default;
172
173 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
174};
175
176////////////////////////////////////////////////////////////////////////////////
177/// Template specializations for C++ std::optional and std::unique_ptr
178////////////////////////////////////////////////////////////////////////////////
179
180/// The field for values that may or may not be present in an entry. Parent class for unique pointer field and
181/// optional field. A nullable field cannot be instantiated itself but only its descendants.
182/// The RNullableField takes care of the on-disk representation. Child classes are responsible for the in-memory
183/// representation. Nullable fields use a `(Split)Index[64|32]` column to point to the available items.
185 /// The number of written non-null items in this cluster
187
188protected:
189 // For reading, indicates that we read type T as a nullable field of type T, i.e. the value is always present
190 bool fIsEvolvedFromInnerType = false;
191
193 void GenerateColumns() final;
194 void GenerateColumns(const ROOT::RNTupleDescriptor &) final;
195
196 std::size_t AppendNull();
197 std::size_t AppendValue(const void *from);
198 void CommitClusterImpl() final { fNWritten = 0; }
199
200 void ReconcileOnDiskField(const RNTupleDescriptor &desc) final;
201
202 /// Given the global index of the nullable field, returns the corresponding cluster-local index of the subfield or,
203 /// if it is null, returns a default constructed RNTupleLocalIndex
204 RNTupleLocalIndex GetItemIndex(NTupleSize_t globalIndex);
205 /// Given the cluster-local index of the nullable field, returns the corresponding cluster-local index of
206 /// the subfield or, if it is null, returns a default constructed RNTupleLocalIndex
207 RNTupleLocalIndex GetItemIndex(RNTupleLocalIndex localIndex);
208
209 RNullableField(std::string_view fieldName, const std::string &typePrefix, std::unique_ptr<RFieldBase> itemField);
210
211public:
212 RNullableField(RNullableField &&other) = default;
214 ~RNullableField() override = default;
215
216 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
217};
218
220 class ROptionalDeleter : public RDeleter {
221 private:
222 std::unique_ptr<RDeleter> fItemDeleter; // nullptr for trivially destructible items
223 std::size_t fEngagementPtrOffset = 0;
224
225 public:
226 ROptionalDeleter(std::unique_ptr<RDeleter> itemDeleter, std::size_t engagementPtrOffset, std::size_t alignment)
227 : RDeleter(alignment), fItemDeleter(std::move(itemDeleter)), fEngagementPtrOffset(engagementPtrOffset)
228 {
229 }
230 void operator()(void *objPtr, bool dtorOnly) final;
231 };
232
233 std::unique_ptr<RDeleter> fItemDeleter;
234
235 /// Given a pointer to an `std::optional<T>` in `optionalPtr`, extract a pointer to the engagement boolean.
236 /// Assumes that an `std::optional<T>` is stored as `struct { T t; bool engagement; };`
237 const bool *GetEngagementPtr(const void *optionalPtr) const;
238 bool *GetEngagementPtr(void *optionalPtr) const;
239 std::size_t GetEngagementPtrOffset() const;
240 void PrepareRead(void *to, bool hasOnDiskValue);
241
242protected:
243 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
244
245 void ConstructValue(void *where) const final;
246 std::unique_ptr<RDeleter> GetDeleter() const final;
247
248 std::size_t AppendImpl(const void *from) final;
249 void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
250 void ReadInClusterImpl(ROOT::RNTupleLocalIndex localIndex, void *to) final;
251
252public:
253 ROptionalField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField);
254 ROptionalField(ROptionalField &&other) = default;
255 ROptionalField &operator=(ROptionalField &&other) = default;
256 ~ROptionalField() override = default;
257
258 std::vector<RValue> SplitValue(const RValue &value) const final;
259 std::size_t GetValueSize() const final;
260 std::size_t GetAlignment() const final;
261};
262
263template <typename ItemT>
264class RField<std::optional<ItemT>> final : public ROptionalField {
265public:
266 static std::string TypeName() { return "std::optional<" + RField<ItemT>::TypeName() + ">"; }
267 explicit RField(std::string_view name) : ROptionalField(name, std::make_unique<RField<ItemT>>("_0")) {}
268 RField(RField &&other) = default;
269 RField &operator=(RField &&other) = default;
270 ~RField() final = default;
271};
272
275 private:
276 std::unique_ptr<RDeleter> fItemDeleter;
277
278 public:
279 explicit RUniquePtrDeleter(std::unique_ptr<RDeleter> itemDeleter)
280 : RDeleter(alignof(std::unique_ptr<char>)), fItemDeleter(std::move(itemDeleter))
281 {
282 }
283 void operator()(void *objPtr, bool dtorOnly) final;
284 };
285
286 std::unique_ptr<RDeleter> fItemDeleter;
287 /// If the item type is a polymorphic class (that declares or inherits at least one virtual method), points to the
288 /// expected dynamic type of any user object; otherwise nullptr.
289 const std::type_info *fPolymorphicTypeInfo = nullptr;
290
291 // Returns the value pointer, i.e. where to read the subfield into
292 void *PrepareRead(void *to, bool hasOnDiskValue);
293
294protected:
295 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
296
297 void ConstructValue(void *where) const final { new (where) std::unique_ptr<char>(); }
298 std::unique_ptr<RDeleter> GetDeleter() const final;
299
300 std::size_t AppendImpl(const void *from) final;
301 void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
302 void ReadInClusterImpl(ROOT::RNTupleLocalIndex localIndex, void *to) final;
303
304public:
305 RUniquePtrField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField);
307 RUniquePtrField &operator=(RUniquePtrField &&other) = default;
308 ~RUniquePtrField() override = default;
309
310 std::vector<RValue> SplitValue(const RValue &value) const final;
311 std::size_t GetValueSize() const final { return sizeof(std::unique_ptr<char>); }
312 std::size_t GetAlignment() const final { return alignof(std::unique_ptr<char>); }
313};
314
315template <typename ItemT>
316class RField<std::unique_ptr<ItemT>> final : public RUniquePtrField {
317public:
318 static std::string TypeName() { return "std::unique_ptr<" + RField<ItemT>::TypeName() + ">"; }
319 explicit RField(std::string_view name) : RUniquePtrField(name, std::make_unique<RField<ItemT>>("_0")) {}
320 RField(RField &&other) = default;
321 RField &operator=(RField &&other) = default;
322 ~RField() final = default;
323};
324
325////////////////////////////////////////////////////////////////////////////////
326/// Template specializations for C++ std::string
327////////////////////////////////////////////////////////////////////////////////
328
329template <>
330class RField<std::string> final : public RFieldBase {
331private:
333
334 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
335 {
336 return std::make_unique<RField>(newName);
337 }
338
339 const RColumnRepresentations &GetColumnRepresentations() const final;
340 void GenerateColumns() final;
341 void GenerateColumns(const ROOT::RNTupleDescriptor &desc) final;
342
343 void ConstructValue(void *where) const final { new (where) std::string(); }
344 std::unique_ptr<RDeleter> GetDeleter() const final { return std::make_unique<RTypedDeleter<std::string>>(); }
345
346 std::size_t AppendImpl(const void *from) final;
347 void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
348
349 void CommitClusterImpl() final { fIndex = 0; }
350
351public:
352 static std::string TypeName() { return "std::string"; }
353 explicit RField(std::string_view name)
354 : RFieldBase(name, TypeName(), ROOT::ENTupleStructure::kPlain, false /* isSimple */), fIndex(0)
355 {
356 }
357 RField(RField &&other) = default;
358 RField &operator=(RField &&other) = default;
359 ~RField() final = default;
360
361 std::size_t GetValueSize() const final { return sizeof(std::string); }
362 std::size_t GetAlignment() const final { return alignof(std::string); }
363 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
364};
365
366////////////////////////////////////////////////////////////////////////////////
367/// Template specializations for C++ std::variant
368////////////////////////////////////////////////////////////////////////////////
369
370/// The generic field for std::variant types
371class RVariantField : public RFieldBase {
372private:
373 // Most compilers support at least 255 variants (256 - 1 value for the empty variant).
374 // Some compilers switch to a two-byte tag field already with 254 variants.
375 // MSVC only supports 163 variants in older versions, 250 in newer ones. It switches to a 2 byte
376 // tag as of 128 variants (at least in debug mode), so for simplicity we set the limit to 125 variants.
377 static constexpr std::size_t kMaxVariants = 125;
378
379 class RVariantDeleter : public RDeleter {
380 private:
381 std::size_t fTagOffset;
382 std::size_t fVariantOffset;
383 std::vector<std::unique_ptr<RDeleter>> fItemDeleters;
384
385 public:
386 RVariantDeleter(std::size_t tagOffset, std::size_t variantOffset, std::size_t alignment,
387 std::vector<std::unique_ptr<RDeleter>> itemDeleters)
389 fTagOffset(tagOffset),
390 fVariantOffset(variantOffset),
391 fItemDeleters(std::move(itemDeleters))
392 {
393 }
394 void operator()(void *objPtr, bool dtorOnly) final;
395 };
396
397 size_t fMaxItemSize = 0;
398 size_t fMaxAlignment = 1;
399 /// In the `std::variant` memory layout, at which byte number is the index stored
400 size_t fTagOffset = 0;
401 /// In the `std::variant` memory layout, the actual union of types may start at an offset > 0
402 size_t fVariantOffset = 0;
403 std::vector<ROOT::Internal::RColumnIndex::ValueType> fNWritten;
404
405 /// Extracts the index from an `std::variant` and transforms it into the 1-based index used for the switch column
406 /// The implementation supports two memory layouts that are in use: a trailing unsigned byte, zero-indexed,
407 /// having the exception caused empty state encoded by the max tag value,
408 /// or a trailing unsigned int instead of a char.
409 static std::uint8_t GetTag(const void *variantPtr, std::size_t tagOffset);
410 static void SetTag(void *variantPtr, std::size_t tagOffset, std::uint8_t tag);
411
412 RVariantField(std::string_view name, const RVariantField &source); // Used by CloneImpl()
413
414protected:
415 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
416
417 const RColumnRepresentations &GetColumnRepresentations() const final;
418 void GenerateColumns() final;
419 void GenerateColumns(const ROOT::RNTupleDescriptor &desc) final;
420
421 void ConstructValue(void *where) const final;
422 std::unique_ptr<RDeleter> GetDeleter() const final;
423
424 std::size_t AppendImpl(const void *from) final;
425 void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
426
427 void CommitClusterImpl() final;
428
429 void ReconcileOnDiskField(const RNTupleDescriptor &desc) final;
430
431public:
432 RVariantField(std::string_view fieldName, std::vector<std::unique_ptr<RFieldBase>> itemFields);
433 RVariantField(RVariantField &&other) = default;
434 RVariantField &operator=(RVariantField &&other) = default;
435 ~RVariantField() override = default;
436
437 std::size_t GetValueSize() const final;
438 std::size_t GetAlignment() const final;
439};
440
441template <typename... ItemTs>
442class RField<std::variant<ItemTs...>> final : public RVariantField {
443private:
444 template <typename HeadT, typename... TailTs>
445 static std::string BuildItemTypes()
446 {
447 std::string result = RField<HeadT>::TypeName();
448 if constexpr (sizeof...(TailTs) > 0)
449 result += "," + BuildItemTypes<TailTs...>();
450 return result;
451 }
452
453 template <typename HeadT, typename... TailTs>
454 static void _BuildItemFields(std::vector<std::unique_ptr<RFieldBase>> &itemFields, unsigned int index = 0)
455 {
456 itemFields.emplace_back(new RField<HeadT>("_" + std::to_string(index)));
457 if constexpr (sizeof...(TailTs) > 0)
458 _BuildItemFields<TailTs...>(itemFields, index + 1);
459 }
460 static std::vector<std::unique_ptr<RFieldBase>> BuildItemFields()
461 {
462 std::vector<std::unique_ptr<RFieldBase>> result;
463 _BuildItemFields<ItemTs...>(result);
464 return result;
465 }
466
467public:
468 static std::string TypeName() { return "std::variant<" + BuildItemTypes<ItemTs...>() + ">"; }
469 explicit RField(std::string_view name) : RVariantField(name, BuildItemFields()) {}
470 RField(RField &&other) = default;
471 RField &operator=(RField &&other) = default;
472 ~RField() final = default;
473};
474
475} // namespace ROOT
476
477#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:142
TCanvas * alignment()
Definition alignment.C:1
Abstract base class for classes implementing the visitor design pattern.
The in-memory representation of a 32bit or 64bit on-disk index column.
Template specializations for C++ std::atomic.
RAtomicField(RAtomicField &&other)=default
size_t GetValueSize() const final
What sizeof(T) for this type returns.
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
What alignof(T) for this type returns.
void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final
Definition RField.cxx:1285
void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final
RAtomicField(std::string_view fieldName, std::unique_ptr< RFieldBase > itemField)
Definition RField.cxx:1247
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
Definition RField.cxx:1262
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:1268
~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:1278
RAtomicField & operator=(RAtomicField &&other)=default
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>
size_t GetAlignment() const final
What alignof(T) for this type returns.
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
What sizeof(T) for this type returns.
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.
std::size_t GetValueSize() const final
What sizeof(T) for this type returns.
void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) 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 AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final
void ReadInClusterImpl(RNTupleLocalIndex localIndex, void *to) final
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.
virtual void CommitClusterImpl()
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:342
~RField() final=default
RField & operator=(RField &&other)=default
static std::string TypeName()
Definition RField.hxx:344
RField(std::string_view name)
Definition RField.hxx:345
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.
~RNullableField() override=default
RNullableField & operator=(RNullableField &&other)=default
RNullableField(RNullableField &&other)=default
ROptionalDeleter(std::unique_ptr< RDeleter > itemDeleter, std::size_t engagementPtrOffset, std::size_t alignment)
std::unique_ptr< RDeleter > fItemDeleter
std::size_t GetEngagementPtrOffset() const
std::unique_ptr< RDeleter > fItemDeleter
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::size_t GetAlignment() const final
What alignof(T) for this type returns.
std::vector< std::unique_ptr< RDeleter > > fItemDeleters
RVariantDeleter(std::size_t tagOffset, std::size_t variantOffset, std::size_t alignment, std::vector< std::unique_ptr< RDeleter > > itemDeleters)
Template specializations for C++ std::variant.
std::vector< ROOT::Internal::RColumnIndex::ValueType > fNWritten
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.