32#include <unordered_set>
41 auto result = std::make_unique<RFieldZero>();
43 result->Attach(
f->Clone(
f->GetFieldName()));
49 std::vector<std::unique_ptr<ROOT::RFieldBase>>
result;
50 std::swap(fSubfields,
result);
81 EnsureMatchingOnDiskField(
fieldDesc, kDiffTypeVersion | kDiffStructure | kDiffTypeName).ThrowOnError();
83 if (
fieldDesc.GetTypeName().rfind(
"ROOT::RNTupleCardinality<", 0) != 0) {
85 " expects an on-disk leaf field of the same type"));
88 throw RException(
R__FAIL(
"invalid on-disk structural role for RCardinalityField " + GetQualifiedFieldName()));
94 visitor.VisitCardinalityField(*
this);
113 EnsureMatchingOnDiskField(
fieldDesc, kDiffTypeName);
116 SetOnDiskId(desc.
FindFieldId(
"_0", GetOnDiskId()));
120 static const std::string
gIntegralTypeNames[] = {
"bool",
"char",
"std::int8_t",
"std::uint8_t",
121 "std::int16_t",
"std::uint16_t",
"std::int32_t",
"std::uint32_t",
122 "std::int64_t",
"std::uint64_t"};
126 GetTypeName() +
"'"));
134 EnsureMatchingOnDiskField(
fieldDesc, kDiffTypeName);
138 GetTypeName() +
"'"));
241 visitor.VisitUInt8Field(*
this);
290 visitor.VisitFloatField(*
this);
312 visitor.VisitDoubleField(*
this);
317 fTypeAlias =
"Double32_t";
346 visitor.VisitInt16Field(*
this);
375 visitor.VisitUInt16Field(*
this);
404 visitor.VisitInt32Field(*
this);
433 visitor.VisitUInt32Field(*
this);
462 visitor.VisitUInt64Field(*
this);
491 visitor.VisitInt64Field(*
this);
518 auto typedValue =
static_cast<const std::string *
>(from);
522 fPrincipalColumn->Append(&fIndex);
523 return length + fPrincipalColumn->GetElement()->GetPackedSize();
528 auto typedValue =
static_cast<std::string *
>(to);
542 visitor.VisitStringField(*
this);
549 fMaxAlignment(
source.fMaxAlignment),
553 for (
const auto &
f :
source.GetConstSubfields())
554 Attach(
f->Clone(
f->GetFieldName()));
565 fTraits |= kTraitTrivialType;
567 fMaxAlignment = std::max(fMaxAlignment,
item->GetAlignment());
569 fTraits &=
item->GetTraits();
570 Attach(std::move(
item));
574 fSize += GetItemPadding(
fSize, fMaxAlignment);
577std::unique_ptr<ROOT::RFieldBase>
579 std::vector<std::unique_ptr<RFieldBase>>
itemFields,
637 for (
unsigned i = 0; i < fSubfields.size(); ++i) {
638 nbytes += CallAppendOn(*fSubfields[i],
static_cast<const unsigned char *
>(from) + fOffsets[i]);
645 for (
unsigned i = 0; i < fSubfields.size(); ++i) {
646 CallReadOn(*fSubfields[i],
globalIndex,
static_cast<unsigned char *
>(to) + fOffsets[i]);
652 for (
unsigned i = 0; i < fSubfields.size(); ++i) {
653 CallReadOn(*fSubfields[i],
localIndex,
static_cast<unsigned char *
>(to) + fOffsets[i]);
659 if (fTraits & kTraitEmulatedField) {
667 EnsureMatchingOnDiskField(
fieldDesc, kDiffTypeName | kDiffTypeVersion).ThrowOnError();
676 for (
auto &
f : fSubfields) {
678 CallSetArtificialOn(*
f);
684 for (
unsigned i = 0; i < fSubfields.size(); ++i) {
685 CallConstructValueOn(*fSubfields[i],
static_cast<unsigned char *
>(
where) + fOffsets[i]);
691 for (
unsigned i = 0; i < fItemDeleters.size(); ++i) {
692 fItemDeleters[i]->operator()(
reinterpret_cast<unsigned char *
>(
objPtr) + fOffsets[i],
true );
701 for (
const auto &
f : fSubfields) {
704 return std::make_unique<RRecordDeleter>(std::move(
itemDeleters), fOffsets);
711 std::vector<RValue>
result;
712 result.reserve(fSubfields.size());
713 for (
unsigned i = 0; i < fSubfields.size(); ++i) {
714 result.emplace_back(fSubfields[i]->BindValue(std::shared_ptr<void>(
valuePtr,
charPtr + fOffsets[i])));
721 visitor.VisitRecordField(*
this);
753 if (WordSize() ==
sizeof(
unsigned long)) {
754 fUlong(std::forward<Args>(args)..., fN, *fPrincipalColumn);
755 }
else if (WordSize() ==
sizeof(
unsigned long long)) {
757 fUlonglong(std::forward<Args>(args)..., fN, *fPrincipalColumn);
763template <
typename Word_t>
766 constexpr auto kBitsPerWord =
sizeof(Word_t) * 8;
768 const auto *
asWordArray =
static_cast<const Word_t *
>(from);
771 for (std::size_t
word = 0;
word < (
nBits + kBitsPerWord - 1) / kBitsPerWord; ++
word) {
785template <
typename Word_t>
789 constexpr auto kBitsPerWord =
sizeof(Word_t) * 8;
793 for (std::size_t i = 0; i <
nBits; ++i) {
795 Word_t
mask =
static_cast<Word_t
>(1) << (i % kBitsPerWord);
806template <
typename Word_t>
810 constexpr auto kBitsPerWord =
sizeof(Word_t) * 8;
814 for (std::size_t i = 0; i <
nBits; ++i) {
817 Word_t
mask =
static_cast<Word_t
>(1) << (i % kBitsPerWord);
830 visitor.VisitBitsetField(*
this);
865 fPrincipalColumn->Append(&fNWritten);
871 auto nbytesItem = CallAppendOn(*fSubfields[0], from);
873 fPrincipalColumn->Append(&fNWritten);
879 static const std::vector<std::string>
prefixes = {
"std::optional<",
"std::unique_ptr<"};
882 EnsureMatchingOnDiskField(
fieldDesc, kDiffTypeName).ThrowOnError();
896 visitor.VisitNullableField(*
this);
908 auto newItemField = fSubfields[0]->Clone(fSubfields[0]->GetFieldName());
914 auto typedValue =
static_cast<const std::unique_ptr<char> *
>(from);
924 auto ptr =
static_cast<std::unique_ptr<char> *
>(to);
936 fItemDeleter->operator()(
valuePtr,
false );
944 valuePtr = CallCreateObjectRawPtrOn(*fSubfields[0]);
945 ptr->reset(
reinterpret_cast<char *
>(
valuePtr));
955 fItemDeleter->operator()(
typedPtr->get(),
false );
963 return std::make_unique<RUniquePtrDeleter>(GetDeleterOf(*fSubfields[0]));
968 std::vector<RValue>
result;
988 return reinterpret_cast<bool *
>(
reinterpret_cast<unsigned char *
>(
optionalPtr) + fSubfields[0]->GetValueSize());
993 return GetEngagementPtr(
const_cast<void *
>(
optionalPtr));
998 auto newItemField = fSubfields[0]->Clone(fSubfields[0]->GetFieldName());
1004 if (*GetEngagementPtr(from)) {
1005 return AppendValue(from);
1007 return AppendNull();
1016 if (*
engagementPtr && !(fSubfields[0]->GetTraits() & kTraitTriviallyDestructible))
1017 fItemDeleter->operator()(to,
true );
1020 if (!(*
engagementPtr) && !(fSubfields[0]->GetTraits() & kTraitTriviallyConstructible))
1021 CallConstructValueOn(*fSubfields[0], to);
1022 CallReadOn(*fSubfields[0],
itemIndex, to);
1029 *GetEngagementPtr(
where) =
false;
1035 auto engagementPtr =
reinterpret_cast<bool *
>(
reinterpret_cast<unsigned char *
>(
objPtr) + fEngagementPtrOffset);
1037 fItemDeleter->operator()(
objPtr,
true );
1044 return std::make_unique<ROptionalDeleter>(
1045 (fSubfields[0]->GetTraits() & kTraitTriviallyDestructible) ?
nullptr : GetDeleterOf(*fSubfields[0]),
1046 fSubfields[0]->GetValueSize());
1051 std::vector<RValue>
result;
1054 result.emplace_back(fSubfields[0]->BindValue(std::shared_ptr<void>(
value.GetPtr<
void>(),
valuePtr)));
1063 const auto actualSize = fSubfields[0]->GetValueSize() +
sizeof(
bool);
1075 return fSubfields[0]->GetAlignment();
1093 auto newItemField = fSubfields[0]->Clone(fSubfields[0]->GetFieldName());
1099 static const std::vector<std::string>
prefixes = {
"std::atomic<"};
1102 EnsureMatchingOnDiskField(
fieldDesc, kDiffTypeName).ThrowOnError();
1108 std::vector<RValue>
result;
1109 result.emplace_back(fSubfields[0]->BindValue(
value.GetPtr<
void>()));
1115 visitor.VisitAtomicField(*
this);
#define R__FAIL(msg)
Short-hand to return an RResult<T> in an error state; the RError is implicitly converted into RResult...
static void BitsetReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to, size_t nBits, ROOT::Internal::RColumn &column)
static void BitsetReadInClusterImpl(ROOT::RNTupleLocalIndex localIndex, void *to, size_t nBits, ROOT::Internal::RColumn &column)
static void BitsetAppendImpl(const void *from, size_t nBits, ROOT::Internal::RColumn &column)
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
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 mask
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 Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h length
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Abstract base class for classes implementing the visitor design pattern.
The in-memory representation of a 32bit or 64bit on-disk index column.
A column is a storage-backed array of a simple, fixed-size type, from which pages can be mapped into ...
void Read(const ROOT::NTupleSize_t globalIndex, void *to)
void Append(const void *from)
void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const 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 ReconcileOnDiskField(const RNTupleDescriptor &desc) final
For non-artificial fields, check compatibility of the in-memory field and the on-disk field.
std::vector< RValue > SplitValue(const RValue &value) const final
Creates the list of direct child values given an existing value for this field.
RBitsetField(std::string_view fieldName, std::size_t N)
void ReadInClusterImpl(RNTupleLocalIndex localIndex, void *to) final
void GenerateColumns() final
Implementations in derived classes should create the backing columns corresponding to the field type ...
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.
const RColumnRepresentations & GetColumnRepresentations() const final
Implementations in derived classes should return a static RColumnRepresentations object.
void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final
void SelectWordSize(FUlong &&fUlong, FUlonglong &&fUlonglong, Args &&...args)
void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final
const RColumnRepresentations & GetColumnRepresentations() const final
Implementations in derived classes should return a static RColumnRepresentations object.
const RField< RNTupleCardinality< std::uint32_t > > * As32Bit() const
void ReconcileOnDiskField(const RNTupleDescriptor &desc) final
For non-artificial fields, check compatibility of the in-memory field and the on-disk field.
const RField< RNTupleCardinality< std::uint64_t > > * As64Bit() const
void GenerateColumns() final
Implementations in derived classes should create the backing columns corresponding to the field type ...
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final
void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final
Base class for all ROOT issued exceptions.
The list of column representations a field can have.
Points to an object with RNTuple I/O support and keeps a pointer to the corresponding field.
A field translates read and write calls from/to underlying columns to/from tree values.
void Attach(std::unique_ptr< RFieldBase > child)
Add a new subfield to the list of nested fields.
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 ...
std::uint32_t fTraits
Properties of the type that allow for optimizations of collections of that type.
std::uint32_t GetTraits() const
@ kTraitEmulatedField
This field is a user defined type that was missing dictionaries and was reconstructed from the on-dis...
@ kTraitTrivialType
Shorthand for types that are both trivially constructible and destructible.
@ kTraitTriviallyDestructible
The type is cleaned up just by freeing its memory. I.e. the destructor performs a no-op.
@ kTraitTriviallyConstructible
No constructor needs to be called, i.e.
Metadata stored for every field of an RNTuple.
The container field for an ntuple model, which itself has no physical representation.
void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
std::vector< std::unique_ptr< RFieldBase > > ReleaseSubfields()
Moves all subfields into the returned vector.
Classes with dictionaries that can be inspected by TClass.
The on-storage metadata of an RNTuple.
RFieldDescriptorIterable GetFieldIterable(const RFieldDescriptor &fieldDesc) const
const RFieldDescriptor & GetFieldDescriptor(ROOT::DescriptorId_t fieldId) const
ROOT::DescriptorId_t FindFieldId(std::string_view fieldName, ROOT::DescriptorId_t parentId) const
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 ReconcileOnDiskField(const RNTupleDescriptor &desc) final
For non-artificial fields, check compatibility of the in-memory field and the on-disk field.
RNullableField(std::string_view fieldName, const std::string &typePrefix, std::unique_ptr< RFieldBase > itemField)
RNTupleLocalIndex GetItemIndex(ROOT::NTupleSize_t globalIndex)
Given the index of the nullable field, returns the corresponding global index of the subfield or,...
std::size_t AppendValue(const void *from)
void GenerateColumns() final
Implementations in derived classes should create the backing columns corresponding to the field type ...
void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final
const RFieldBase::RColumnRepresentations & GetColumnRepresentations() const final
Implementations in derived classes should return a static RColumnRepresentations object.
void operator()(void *objPtr, bool dtorOnly) final
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::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
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.
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.
ROptionalField(std::string_view fieldName, std::unique_ptr< RFieldBase > itemField)
void operator()(void *objPtr, bool dtorOnly) final
The field for an untyped record.
std::vector< RValue > SplitValue(const RValue &value) const final
Creates the list of direct child values given an existing value for this field.
std::size_t fMaxAlignment
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const override
Called by Clone(), which additionally copies the on-disk ID.
void ReadInClusterImpl(RNTupleLocalIndex localIndex, void *to) final
RRecordField(std::string_view name, const RRecordField &source)
void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final
std::unique_ptr< RDeleter > GetDeleter() const final
void AttachItemFields(std::vector< std::unique_ptr< RFieldBase > > itemFields)
std::size_t GetItemPadding(std::size_t baseOffset, std::size_t itemAlignment) const
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...
std::vector< std::size_t > fOffsets
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
void ReconcileOnDiskField(const RNTupleDescriptor &desc) override
For non-artificial fields, check compatibility of the in-memory field and the on-disk field.
void ReconcileIntegralField(const RNTupleDescriptor &desc)
void ReconcileFloatingPointField(const RNTupleDescriptor &desc)
void operator()(void *objPtr, bool dtorOnly) final
std::vector< RValue > SplitValue(const RValue &value) const final
Creates the list of direct child values given an existing value for this field.
std::unique_ptr< RDeleter > GetDeleter() const final
void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final
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)
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
Template specializations for C++ std::vector.
void SetAllowFieldSubstitutions(RFieldZero &fieldZero, bool val)
std::unique_ptr< RFieldBase > CreateEmulatedVectorField(std::string_view fieldName, std::unique_ptr< RFieldBase > itemField, std::string_view emulatedFromType)
std::unique_ptr< RFieldBase > CreateEmulatedRecordField(std::string_view fieldName, std::vector< std::unique_ptr< RFieldBase > > itemFields, std::string_view emulatedFromType)
constexpr NTupleSize_t kInvalidNTupleIndex
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...