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);
80 EnsureMatchingOnDiskField(desc, kDiffTypeVersion | kDiffStructure | kDiffTypeName).ThrowOnError();
84 if (
fieldDesc.GetTypeName().rfind(
"ROOT::RNTupleCardinality<", 0) != 0) {
86 " expects an on-disk leaf field of the same type\n" +
90 throw RException(
R__FAIL(
"invalid on-disk structural role for RCardinalityField " + GetQualifiedFieldName() +
97 visitor.VisitCardinalityField(*
this);
115 EnsureMatchingOnDiskField(desc, kDiffTypeName);
119 SetOnDiskId(desc.
FindFieldId(
"_0", GetOnDiskId()));
123 static const std::string
gIntegralTypeNames[] = {
"bool",
"char",
"std::int8_t",
"std::uint8_t",
124 "std::int16_t",
"std::uint16_t",
"std::int32_t",
"std::uint32_t",
125 "std::int64_t",
"std::uint64_t"};
136 EnsureMatchingOnDiskField(desc, kDiffTypeName);
244 visitor.VisitUInt8Field(*
this);
293 visitor.VisitFloatField(*
this);
315 visitor.VisitDoubleField(*
this);
320 fTypeAlias =
"Double32_t";
349 visitor.VisitInt16Field(*
this);
378 visitor.VisitUInt16Field(*
this);
407 visitor.VisitInt32Field(*
this);
436 visitor.VisitUInt32Field(*
this);
465 visitor.VisitUInt64Field(*
this);
494 visitor.VisitInt64Field(*
this);
521 auto typedValue =
static_cast<const std::string *
>(from);
525 fPrincipalColumn->Append(&fIndex);
526 return length + fPrincipalColumn->GetElement()->GetPackedSize();
531 auto typedValue =
static_cast<std::string *
>(to);
545 visitor.VisitStringField(*
this);
552 fMaxAlignment(
source.fMaxAlignment),
556 for (
const auto &
f :
source.GetConstSubfields())
557 Attach(
f->Clone(
f->GetFieldName()));
568 fTraits |= kTraitTrivialType;
570 fMaxAlignment = std::max(fMaxAlignment,
item->GetAlignment());
572 fTraits &=
item->GetTraits();
573 Attach(std::move(
item));
577 fSize += GetItemPadding(
fSize, fMaxAlignment);
580std::unique_ptr<ROOT::RFieldBase>
582 std::vector<std::unique_ptr<RFieldBase>>
itemFields,
640 for (
unsigned i = 0; i < fSubfields.size(); ++i) {
641 nbytes += CallAppendOn(*fSubfields[i],
static_cast<const unsigned char *
>(from) + fOffsets[i]);
648 for (
unsigned i = 0; i < fSubfields.size(); ++i) {
649 CallReadOn(*fSubfields[i],
globalIndex,
static_cast<unsigned char *
>(to) + fOffsets[i]);
655 for (
unsigned i = 0; i < fSubfields.size(); ++i) {
656 CallReadOn(*fSubfields[i],
localIndex,
static_cast<unsigned char *
>(to) + fOffsets[i]);
662 if (fTraits & kTraitEmulatedField) {
669 EnsureMatchingOnDiskField(desc, kDiffTypeName | kDiffTypeVersion).ThrowOnError();
679 for (
auto &
f : fSubfields) {
681 CallSetArtificialOn(*
f);
687 for (
unsigned i = 0; i < fSubfields.size(); ++i) {
688 CallConstructValueOn(*fSubfields[i],
static_cast<unsigned char *
>(
where) + fOffsets[i]);
694 for (
unsigned i = 0; i < fItemDeleters.size(); ++i) {
695 fItemDeleters[i]->operator()(
reinterpret_cast<unsigned char *
>(
objPtr) + fOffsets[i],
true );
704 for (
const auto &
f : fSubfields) {
707 return std::make_unique<RRecordDeleter>(std::move(
itemDeleters), fOffsets);
714 std::vector<RValue>
result;
715 result.reserve(fSubfields.size());
716 for (
unsigned i = 0; i < fSubfields.size(); ++i) {
717 result.emplace_back(fSubfields[i]->BindValue(std::shared_ptr<void>(
valuePtr,
charPtr + fOffsets[i])));
724 visitor.VisitRecordField(*
this);
756 if (WordSize() ==
sizeof(
unsigned long)) {
757 fUlong(std::forward<Args>(args)..., fN, *fPrincipalColumn);
758 }
else if (WordSize() ==
sizeof(
unsigned long long)) {
760 fUlonglong(std::forward<Args>(args)..., fN, *fPrincipalColumn);
766template <
typename Word_t>
769 constexpr auto kBitsPerWord =
sizeof(Word_t) * 8;
771 const auto *
asWordArray =
static_cast<const Word_t *
>(from);
774 for (std::size_t
word = 0;
word < (
nBits + kBitsPerWord - 1) / kBitsPerWord; ++
word) {
788template <
typename Word_t>
792 constexpr auto kBitsPerWord =
sizeof(Word_t) * 8;
796 for (std::size_t i = 0; i <
nBits; ++i) {
798 Word_t
mask =
static_cast<Word_t
>(1) << (i % kBitsPerWord);
809template <
typename Word_t>
813 constexpr auto kBitsPerWord =
sizeof(Word_t) * 8;
817 for (std::size_t i = 0; i <
nBits; ++i) {
820 Word_t
mask =
static_cast<Word_t
>(1) << (i % kBitsPerWord);
833 visitor.VisitBitsetField(*
this);
864 if (!fIsEvolvedFromInnerType)
870 fPrincipalColumn->Append(&fNWritten);
876 auto nbytesItem = CallAppendOn(*fSubfields[0], from);
878 fPrincipalColumn->Append(&fNWritten);
884 static const std::vector<std::string>
prefixes = {
"std::optional<",
"std::unique_ptr<"};
886 auto success = EnsureMatchingOnDiskField(desc, kDiffTypeName);
888 fIsEvolvedFromInnerType =
true;
891 fIsEvolvedFromInnerType = !
success;
894 if (fIsEvolvedFromInnerType)
895 fSubfields[0]->SetOnDiskId(GetOnDiskId());
916 visitor.VisitNullableField(*
this);
928 auto newItemField = fSubfields[0]->Clone(fSubfields[0]->GetFieldName());
934 auto typedValue =
static_cast<const std::unique_ptr<char> *
>(from);
944 auto ptr =
static_cast<std::unique_ptr<char> *
>(to);
953 fItemDeleter->operator()(
valuePtr,
false );
955 valuePtr = CallCreateObjectRawPtrOn(*fSubfields[0]);
956 ptr->reset(
reinterpret_cast<char *
>(
valuePtr));
965 if (!fIsEvolvedFromInnerType)
970 if (fIsEvolvedFromInnerType) {
981 if (!fIsEvolvedFromInnerType) {
996 fItemDeleter->operator()(
typedPtr->get(),
false );
1004 return std::make_unique<RUniquePtrDeleter>(GetDeleterOf(*fSubfields[0]));
1009 std::vector<RValue>
result;
1029 return reinterpret_cast<bool *
>(
reinterpret_cast<unsigned char *
>(
optionalPtr) + fSubfields[0]->GetValueSize());
1034 return GetEngagementPtr(
const_cast<void *
>(
optionalPtr));
1039 auto newItemField = fSubfields[0]->Clone(fSubfields[0]->GetFieldName());
1045 if (*GetEngagementPtr(from)) {
1046 return AppendValue(from);
1048 return AppendNull();
1056 if (!(*
engagementPtr) && !(fSubfields[0]->GetTraits() & kTraitTriviallyConstructible))
1057 CallConstructValueOn(*fSubfields[0], to);
1060 if (*
engagementPtr && !(fSubfields[0]->GetTraits() & kTraitTriviallyDestructible))
1061 fItemDeleter->operator()(to,
true );
1069 if (!fIsEvolvedFromInnerType)
1074 if (fIsEvolvedFromInnerType) {
1077 CallReadOn(*fSubfields[0],
itemIndex, to);
1085 if (!fIsEvolvedFromInnerType) {
1093 CallReadOn(*fSubfields[0],
itemIndex, to);
1098 *GetEngagementPtr(
where) =
false;
1104 auto engagementPtr =
reinterpret_cast<bool *
>(
reinterpret_cast<unsigned char *
>(
objPtr) + fEngagementPtrOffset);
1106 fItemDeleter->operator()(
objPtr,
true );
1113 return std::make_unique<ROptionalDeleter>(
1114 (fSubfields[0]->GetTraits() & kTraitTriviallyDestructible) ?
nullptr : GetDeleterOf(*fSubfields[0]),
1115 fSubfields[0]->GetValueSize());
1120 std::vector<RValue>
result;
1123 result.emplace_back(fSubfields[0]->BindValue(std::shared_ptr<void>(
value.GetPtr<
void>(),
valuePtr)));
1132 const auto actualSize = fSubfields[0]->GetValueSize() +
sizeof(
bool);
1144 return fSubfields[0]->GetAlignment();
1162 auto newItemField = fSubfields[0]->Clone(fSubfields[0]->GetFieldName());
1169 if (
fieldDesc.GetTypeName().rfind(
"std::atomic<", 0) == 0) {
1170 EnsureMatchingOnDiskField(desc, kDiffTypeName).ThrowOnError();
1172 fSubfields[0]->SetOnDiskId(GetOnDiskId());
1178 std::vector<RValue>
result;
1179 result.emplace_back(fSubfields[0]->BindValue(
value.GetPtr<
void>()));
1185 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.
RNTupleLocalIndex GetItemIndex(NTupleSize_t globalIndex)
Given the global index of the nullable field, returns the corresponding cluster-local index of the su...
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 ...
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.
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)
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.
void * PrepareRead(void *to, bool hasOnDiskValue)
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.
void ReadInClusterImpl(ROOT::RNTupleLocalIndex localIndex, void *to) final
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)
std::string GetTypeTraceReport(const RFieldBase &field, const RNTupleDescriptor &desc)
Prints the hierarchy of types with their field names and field IDs for the given in-memory field and ...
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...