34#include <unordered_set>
43 auto result = std::make_unique<RFieldZero>();
45 result->Attach(
f->Clone(
f->GetFieldName()));
51 std::vector<std::unique_ptr<ROOT::RFieldBase>>
result;
52 std::swap(fSubfields,
result);
82 EnsureMatchingOnDiskField(desc, kDiffTypeVersion | kDiffStructure | kDiffTypeName).ThrowOnError();
86 if (
fieldDesc.GetTypeName().rfind(
"ROOT::RNTupleCardinality<", 0) != 0) {
88 " expects an on-disk leaf field of the same type\n" +
92 throw RException(
R__FAIL(
"invalid on-disk structural role for RCardinalityField " + GetQualifiedFieldName() +
99 visitor.VisitCardinalityField(*
this);
117 EnsureMatchingOnDiskField(desc, kDiffTypeName);
121 SetOnDiskId(desc.
FindFieldId(
"_0", GetOnDiskId()));
125 static const std::string
gIntegralTypeNames[] = {
"bool",
"char",
"std::int8_t",
"std::uint8_t",
126 "std::int16_t",
"std::uint16_t",
"std::int32_t",
"std::uint32_t",
127 "std::int64_t",
"std::uint64_t"};
138 EnsureMatchingOnDiskField(desc, kDiffTypeName);
246 visitor.VisitUInt8Field(*
this);
295 visitor.VisitFloatField(*
this);
317 visitor.VisitDoubleField(*
this);
322 fTypeAlias =
"Double32_t";
351 visitor.VisitInt16Field(*
this);
380 visitor.VisitUInt16Field(*
this);
409 visitor.VisitInt32Field(*
this);
438 visitor.VisitUInt32Field(*
this);
467 visitor.VisitUInt64Field(*
this);
496 visitor.VisitInt64Field(*
this);
523 auto typedValue =
static_cast<const std::string *
>(from);
527 fPrincipalColumn->Append(&fIndex);
528 return length + fPrincipalColumn->GetElement()->GetPackedSize();
533 auto typedValue =
static_cast<std::string *
>(to);
547 visitor.VisitStringField(*
this);
554 fMaxAlignment(
source.fMaxAlignment),
558 for (
const auto &
f :
source.GetConstSubfields())
559 Attach(
f->Clone(
f->GetFieldName()));
570 fTraits |= kTraitTrivialType;
572 fMaxAlignment = std::max(fMaxAlignment,
item->GetAlignment());
574 fTraits &=
item->GetTraits();
575 Attach(std::move(
item));
579 fSize += GetItemPadding(
fSize, fMaxAlignment);
582std::unique_ptr<ROOT::RFieldBase>
584 std::vector<std::unique_ptr<RFieldBase>>
itemFields,
642 for (
unsigned i = 0; i < fSubfields.size(); ++i) {
643 nbytes += CallAppendOn(*fSubfields[i],
static_cast<const unsigned char *
>(from) + fOffsets[i]);
650 for (
unsigned i = 0; i < fSubfields.size(); ++i) {
651 CallReadOn(*fSubfields[i],
globalIndex,
static_cast<unsigned char *
>(to) + fOffsets[i]);
657 for (
unsigned i = 0; i < fSubfields.size(); ++i) {
658 CallReadOn(*fSubfields[i],
localIndex,
static_cast<unsigned char *
>(to) + fOffsets[i]);
664 if (fTraits & kTraitEmulatedField) {
671 EnsureMatchingOnDiskField(desc, kDiffTypeName | kDiffTypeVersion).ThrowOnError();
681 for (
auto &
f : fSubfields) {
683 CallSetArtificialOn(*
f);
689 for (
unsigned i = 0; i < fSubfields.size(); ++i) {
690 CallConstructValueOn(*fSubfields[i],
static_cast<unsigned char *
>(
where) + fOffsets[i]);
696 for (
unsigned i = 0; i < fItemDeleters.size(); ++i) {
697 fItemDeleters[i]->operator()(
reinterpret_cast<unsigned char *
>(
objPtr) + fOffsets[i],
true );
706 for (
const auto &
f : fSubfields) {
709 return std::make_unique<RRecordDeleter>(std::move(
itemDeleters), fOffsets);
716 std::vector<RValue>
result;
717 result.reserve(fSubfields.size());
718 for (
unsigned i = 0; i < fSubfields.size(); ++i) {
719 result.emplace_back(fSubfields[i]->BindValue(std::shared_ptr<void>(
valuePtr,
charPtr + fOffsets[i])));
726 visitor.VisitRecordField(*
this);
758 if (WordSize() ==
sizeof(
unsigned long)) {
759 fUlong(std::forward<Args>(args)..., fN, *fPrincipalColumn);
760 }
else if (WordSize() ==
sizeof(
unsigned long long)) {
762 fUlonglong(std::forward<Args>(args)..., fN, *fPrincipalColumn);
768template <
typename Word_t>
771 constexpr auto kBitsPerWord =
sizeof(Word_t) * 8;
773 const auto *
asWordArray =
static_cast<const Word_t *
>(from);
776 for (std::size_t
word = 0;
word < (
nBits + kBitsPerWord - 1) / kBitsPerWord; ++
word) {
790template <
typename Word_t>
794 constexpr auto kBitsPerWord =
sizeof(Word_t) * 8;
798 for (std::size_t i = 0; i <
nBits; ++i) {
800 Word_t
mask =
static_cast<Word_t
>(1) << (i % kBitsPerWord);
811template <
typename Word_t>
815 constexpr auto kBitsPerWord =
sizeof(Word_t) * 8;
819 for (std::size_t i = 0; i <
nBits; ++i) {
822 Word_t
mask =
static_cast<Word_t
>(1) << (i % kBitsPerWord);
835 visitor.VisitBitsetField(*
this);
866 if (!fIsEvolvedFromInnerType)
872 fPrincipalColumn->Append(&fNWritten);
878 auto nbytesItem = CallAppendOn(*fSubfields[0], from);
880 fPrincipalColumn->Append(&fNWritten);
886 static const std::vector<std::string>
prefixes = {
"std::optional<",
"std::unique_ptr<"};
888 auto success = EnsureMatchingOnDiskField(desc, kDiffTypeName);
890 fIsEvolvedFromInnerType =
true;
893 fIsEvolvedFromInnerType = !
success;
896 if (fIsEvolvedFromInnerType)
897 fSubfields[0]->SetOnDiskId(GetOnDiskId());
918 visitor.VisitNullableField(*
this);
925struct PolymorphicClass {
940 auto newItemField = fSubfields[0]->Clone(fSubfields[0]->GetFieldName());
946 auto typedValue =
static_cast<const std::unique_ptr<char> *
>(from);
949 if (fPolymorphicTypeInfo !=
nullptr) {
952 const std::type_info &t =
typeid(*
static_cast<const PolymorphicClass *
>(obj));
953 if (t != *fPolymorphicTypeInfo) {
954 std::string
msg =
"invalid dynamic type of object, expected " + fSubfields[0]->GetTypeName();
961 msg +=
" and upcasting of polymorphic types is not supported in RNTuple";
965 return AppendValue(obj);
973 auto ptr =
static_cast<std::unique_ptr<char> *
>(to);
982 fItemDeleter->operator()(
valuePtr,
false );
984 valuePtr = CallCreateObjectRawPtrOn(*fSubfields[0]);
985 ptr->reset(
reinterpret_cast<char *
>(
valuePtr));
994 if (!fIsEvolvedFromInnerType)
999 if (fIsEvolvedFromInnerType) {
1010 if (!fIsEvolvedFromInnerType) {
1025 fItemDeleter->operator()(
typedPtr->get(),
false );
1033 return std::make_unique<RUniquePtrDeleter>(GetDeleterOf(*fSubfields[0]));
1038 std::vector<RValue>
result;
1058 return reinterpret_cast<bool *
>(
reinterpret_cast<unsigned char *
>(
optionalPtr) + fSubfields[0]->GetValueSize());
1063 return GetEngagementPtr(
const_cast<void *
>(
optionalPtr));
1068 auto newItemField = fSubfields[0]->Clone(fSubfields[0]->GetFieldName());
1074 if (*GetEngagementPtr(from)) {
1075 return AppendValue(from);
1077 return AppendNull();
1085 if (!(*
engagementPtr) && !(fSubfields[0]->GetTraits() & kTraitTriviallyConstructible))
1086 CallConstructValueOn(*fSubfields[0], to);
1089 if (*
engagementPtr && !(fSubfields[0]->GetTraits() & kTraitTriviallyDestructible))
1090 fItemDeleter->operator()(to,
true );
1098 if (!fIsEvolvedFromInnerType)
1103 if (fIsEvolvedFromInnerType) {
1106 CallReadOn(*fSubfields[0],
itemIndex, to);
1114 if (!fIsEvolvedFromInnerType) {
1122 CallReadOn(*fSubfields[0],
itemIndex, to);
1127 *GetEngagementPtr(
where) =
false;
1133 auto engagementPtr =
reinterpret_cast<bool *
>(
reinterpret_cast<unsigned char *
>(
objPtr) + fEngagementPtrOffset);
1135 fItemDeleter->operator()(
objPtr,
true );
1142 return std::make_unique<ROptionalDeleter>(
1143 (fSubfields[0]->GetTraits() & kTraitTriviallyDestructible) ?
nullptr : GetDeleterOf(*fSubfields[0]),
1144 fSubfields[0]->GetValueSize());
1149 std::vector<RValue>
result;
1152 result.emplace_back(fSubfields[0]->BindValue(std::shared_ptr<void>(
value.GetPtr<
void>(),
valuePtr)));
1161 const auto actualSize = fSubfields[0]->GetValueSize() +
sizeof(
bool);
1173 return fSubfields[0]->GetAlignment();
1191 auto newItemField = fSubfields[0]->Clone(fSubfields[0]->GetFieldName());
1198 if (
fieldDesc.GetTypeName().rfind(
"std::atomic<", 0) == 0) {
1199 EnsureMatchingOnDiskField(desc, kDiffTypeName).ThrowOnError();
1201 fSubfields[0]->SetOnDiskId(GetOnDiskId());
1207 std::vector<RValue>
result;
1208 result.emplace_back(fSubfields[0]->BindValue(
value.GetPtr<
void>()));
1214 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 ...
The field for a class with dictionary.
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.
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< 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...
char * DemangleTypeIdName(const std::type_info &ti, int &errorCode)
Demangle in a portable way the type id name.