13#ifndef ROOT_RField_STLMisc
14#define ROOT_RField_STLMisc
17#error "Please include RField.hxx!"
48 std::unique_ptr<RFieldBase>
CloneImpl(std::string_view newName)
const final;
60 RAtomicField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField);
73template <
typename ItemT>
74class RField<std::atomic<ItemT>> final :
public RAtomicField {
77 explicit RField(std::string_view
name) : RAtomicField(
name, std::make_unique<
RField<ItemT>>(
"_0")) {}
97 std::unique_ptr<RFieldBase>
CloneImpl(std::string_view newName)
const final
99 return std::make_unique<RBitsetField>(newName,
fN);
105 std::size_t
AppendImpl(
const void *from)
final;
112 const size_t wordSize = (
fN <=
sizeof(
unsigned long) * 8) ?
sizeof(
unsigned long) :
sizeof(
unsigned long long);
114 const size_t wordSize =
sizeof(
unsigned long);
119 template <
typename FUlong,
typename FUlonglong,
typename... Args>
120 void SelectWordSize(FUlong &&fUlong, FUlonglong &&fUlonglong, Args &&...args);
130 const size_t bitsPerWord =
WordSize() * 8;
131 return WordSize() * ((
fN + bitsPerWord - 1) / bitsPerWord);
137 return WordSize() ==
sizeof(
unsigned long) ?
alignof(
unsigned long) :
alignof(
unsigned long long);
139 return alignof(
unsigned long);
149template <std::
size_t N>
150class RField<std::bitset<N>> final :
public RBitsetField {
152 static std::string
TypeName() {
return "std::bitset<" + std::to_string(
N) +
">"; }
163extern template class RSimpleField<std::
byte>;
166class
RField<std::
byte> final : public RSimpleField<std::
byte> {
168 std::unique_ptr<RFieldBase>
CloneImpl(std::string_view newName)
const final
170 return std::make_unique<RField>(newName);
176 static std::
string TypeName() {
return "std::byte"; }
182 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
218 RNullableField(std::string_view fieldName,
const std::string &typePrefix, std::unique_ptr<RFieldBase> itemField);
237 void operator()(
void *objPtr,
bool dtorOnly)
final;
250 std::unique_ptr<RFieldBase>
CloneImpl(std::string_view newName)
const final;
253 std::unique_ptr<RDeleter>
GetDeleter() const final;
255 std::
size_t AppendImpl(const
void *from) final;
270template <typename ItemT>
287 void operator()(
void *objPtr,
bool dtorOnly)
final;
299 std::unique_ptr<RFieldBase>
CloneImpl(std::string_view newName)
const final;
301 void ConstructValue(
void *where)
const final {
new (where) std::unique_ptr<char>(); }
302 std::unique_ptr<RDeleter> GetDeleter() const final;
304 std::
size_t AppendImpl(const
void *from) 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>); }
319template <
typename ItemT>
320class RField<std::
unique_ptr<ItemT>> final :
public RUniquePtrField {
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;
334class RField<std::
string> final : public RFieldBase {
336 ROOT::Internal::RColumnIndex fIndex;
338 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName)
const final
340 return std::make_unique<RField>(newName);
343 const RColumnRepresentations &GetColumnRepresentations() const final;
344 void GenerateColumns() final;
345 void GenerateColumns(const ROOT::RNTupleDescriptor &desc) final;
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>>(); }
350 std::size_t AppendImpl(
const void *from)
final;
353 void CommitClusterImpl() final { fIndex = 0; }
356 static std::string TypeName() {
return "std::string"; }
357 explicit RField(std::string_view
name)
361 RField(RField &&other) =
default;
362 RField &
operator=(RField &&other) =
default;
363 ~RField() final = default;
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;
391 std::vector<std::unique_ptr<RDeleter>> itemDeleters)
395 void operator()(
void *objPtr,
bool dtorOnly)
final;
404 std::vector<ROOT::Internal::RColumnIndex::ValueType>
fNWritten;
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);
416 std::unique_ptr<RFieldBase>
CloneImpl(std::string_view newName)
const final;
425 std::
size_t AppendImpl(const
void *from) final;
442template <typename... ItemTs>
445 template <
typename HeadT,
typename... TailTs>
446 static std::string BuildItemTypes()
449 if constexpr (
sizeof...(TailTs) > 0)
450 result +=
"," + BuildItemTypes<TailTs...>();
454 template <
typename HeadT,
typename... TailTs>
455 static void _BuildItemFields(std::vector<std::unique_ptr<RFieldBase>> &itemFields,
unsigned int index = 0)
457 itemFields.emplace_back(
new RField<HeadT>(
"_" + std::to_string(index)));
458 if constexpr (
sizeof...(TailTs) > 0)
459 _BuildItemFields<TailTs...>(itemFields, index + 1);
461 static std::vector<std::unique_ptr<RFieldBase>> BuildItemFields()
463 std::vector<std::unique_ptr<RFieldBase>> result;
464 _BuildItemFields<ItemTs...>(result);
469 static std::string TypeName() {
return "std::variant<" + BuildItemTypes<ItemTs...>() +
">"; }
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
void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final
RAtomicField(std::string_view fieldName, std::unique_ptr< RFieldBase > itemField)
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
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.
~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.
RAtomicField & operator=(RAtomicField &&other)=default
Template specializations for C++ std::bitset.
RBitsetField(std::string_view fieldName, std::size_t N)
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.
~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.
RField & operator=(RField &&other)=default
static std::string TypeName()
RField(std::string_view name)
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)
std::size_t AppendValue(const void *from)
void GenerateColumns() final
Implementations in derived classes should create the backing columns corresponding to the field type ...
~RNullableField() override=default
RNullableField & operator=(RNullableField &&other)=default
RNullableField(RNullableField &&other)=default
bool fIsEvolvedFromInnerType
ROptionalDeleter(std::unique_ptr< RDeleter > itemDeleter, std::size_t engagementPtrOffset)
std::size_t fEngagementPtrOffset
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...
size_t GetAlignment() const final
As a rule of thumb, the alignment is equal to the size of the type.
std::unique_ptr< RDeleter > GetDeleter() const final
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.
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.
void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
void ReadInClusterImpl(ROOT::RNTupleLocalIndex localIndex, void *to) final
std::vector< RValue > SplitValue(const RValue &value) const final
Creates the list of direct child values given an existing value for this field.
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
void PrepareRead(void *to, bool hasOnDiskValue)
ROptionalField(std::string_view fieldName, std::unique_ptr< RFieldBase > itemField)
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.
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)
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
RUniquePtrField(std::string_view fieldName, std::unique_ptr< RFieldBase > itemField)
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
std::size_t fVariantOffset
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
Namespace for ROOT features in testing.
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...