33#include <unordered_set>
42 const std::string childName =
child->GetFieldName();
56 auto result = std::make_unique<RFieldZero>();
57 for (
auto &
f : fSubfields) {
58 result->Attach(
f->Clone(
f->GetFieldName()));
59 result->fSubfieldNames.insert(
f->GetFieldName());
66 std::vector<std::unique_ptr<ROOT::RFieldBase>>
result;
67 std::swap(fSubfields,
result);
87 return representations;
92 GenerateColumnsImpl<ROOT::Internal::RColumnIndex>(desc);
97 EnsureMatchingOnDiskField(desc, kDiffTypeVersion | kDiffStructure | kDiffTypeName).ThrowOnError();
101 if (fieldDesc.GetTypeName().rfind(
"ROOT::RNTupleCardinality<", 0) != 0) {
103 " expects an on-disk leaf field of the same type\n" +
107 if (!fieldDesc.IsSoACollection() && fieldDesc.GetTypeVersion() != 0) {
108 throw RException(
R__FAIL(
"invalid on-disk type version for RCardinalityField " + GetQualifiedFieldName() +
112 throw RException(
R__FAIL(
"invalid on-disk structural role for RCardinalityField " + GetQualifiedFieldName() +
137 EnsureMatchingOnDiskField(desc, kDiffTypeName);
141 SetOnDiskId(desc.
FindFieldId(
"_0", GetOnDiskId()));
145 static const std::string gIntegralTypeNames[] = {
"bool",
"char",
"std::int8_t",
"std::uint8_t",
146 "std::int16_t",
"std::uint16_t",
"std::int32_t",
"std::uint32_t",
147 "std::int64_t",
"std::uint64_t"};
148 if (std::find(std::begin(gIntegralTypeNames), std::end(gIntegralTypeNames), fieldDesc.
GetTypeName()) ==
149 std::end(gIntegralTypeNames)) {
158 EnsureMatchingOnDiskField(desc, kDiffTypeName);
188 return representations;
203 return representations;
232 return representations;
261 return representations;
290 return representations;
310 return representations;
332 return representations;
342 fTypeAlias =
"Double32_t";
366 return representations;
395 return representations;
424 return representations;
453 return representations;
482 return representations;
511 return representations;
528 return representations;
533 GenerateColumnsImpl<ROOT::Internal::RColumnIndex, char>();
538 GenerateColumnsImpl<ROOT::Internal::RColumnIndex, char>(desc);
543 auto typedValue =
static_cast<const std::string *
>(from);
544 auto length = typedValue->length();
545 fAuxiliaryColumn->AppendV(typedValue->data(),
length);
547 fPrincipalColumn->Append(&fIndex);
548 return length + fPrincipalColumn->GetElement()->GetPackedSize();
553 auto typedValue =
static_cast<std::string *
>(to);
554 RNTupleLocalIndex collectionStart;
556 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nChars);
560 typedValue->resize(nChars);
561 fAuxiliaryColumn->ReadV(collectionStart, nChars,
const_cast<char *
>(typedValue->data()));
574 fMaxAlignment(source.fMaxAlignment),
576 fOffsets(source.fOffsets)
579 Attach(
f->Clone(
f->GetFieldName()));
589std::unique_ptr<ROOT::RFieldBase>
591 std::vector<std::unique_ptr<RFieldBase>> itemFields,
595 return std::unique_ptr<RFieldBase>(
new RRecordField(fieldName, std::move(itemFields), &emulatedFrom));
599 std::unique_ptr<RFieldBase> itemField,
603 return std::unique_ptr<RFieldBase>(
new RVectorField(fieldName, std::move(itemField), &emulatedFrom));
628 fSize += GetItemPadding(
fSize, item->GetAlignment());
629 if (!IsPairOrTuple()) {
630 fOffsets.emplace_back(
fSize);
632 fSize += item->GetValueSize();
633 fMaxAlignment = std::max(fMaxAlignment, item->GetAlignment());
634 fTraits &= item->GetTraits() | (fTraits & kTraitExtensible);
636 if (IsPairOrTuple()) {
637 Attach(std::move(item),
"_" + std::to_string(fSubfields.size()));
639 const std::string itemName = item->GetFieldName();
640 if (fSubfieldNames.count(itemName) > 0)
642 Attach(std::move(item));
643 fSubfieldNames.insert(itemName);
651 record.
AddItem(std::move(newItem));
656 while (parent &&
typeid(*parent) !=
typeid(
RFieldZero)) {
661 std::vector<std::unique_ptr<ROOT::RFieldBase>> subfields;
662 std::swap(precord->fSubfields, subfields);
664 precord->fSubfieldNames.clear();
665 precord->fMaxAlignment = 1;
667 precord->fOffsets.clear();
668 precord->AttachItemFields(std::move(subfields));
670 parent = precord->fParent;
676 if (itemAlignment > 1) {
677 auto remainder = baseOffset % itemAlignment;
679 return itemAlignment - remainder;
686 return std::unique_ptr<RRecordField>(
new RRecordField(newName, *
this));
691 std::size_t nbytes = 0;
692 for (
unsigned i = 0; i < fSubfields.size(); ++i) {
693 nbytes += CallAppendOn(*fSubfields[i],
static_cast<const unsigned char *
>(from) + fOffsets[i]);
700 for (
unsigned i = 0; i < fSubfields.size(); ++i) {
701 CallReadOn(*fSubfields[i], globalIndex,
static_cast<unsigned char *
>(to) + fOffsets[i]);
707 for (
unsigned i = 0; i < fSubfields.size(); ++i) {
708 CallReadOn(*fSubfields[i], localIndex,
static_cast<unsigned char *
>(to) + fOffsets[i]);
714 if (fTraits & kTraitEmulatedField) {
721 EnsureMatchingOnDiskField(desc, kDiffTypeName | kDiffTypeVersion).ThrowOnError();
727 std::unordered_set<std::string_view> onDiskSubfields;
729 onDiskSubfields.insert(subField.GetFieldName());
731 for (
auto &
f : fSubfields) {
732 if (onDiskSubfields.count(
f->GetFieldName()) == 0)
733 CallSetArtificialOn(*
f);
739 for (
unsigned i = 0; i < fSubfields.size(); ++i) {
740 CallConstructValueOn(*fSubfields[i],
static_cast<unsigned char *
>(where) + fOffsets[i]);
746 for (
unsigned i = 0; i < fItemDeleters.size(); ++i) {
747 fItemDeleters[i]->operator()(
reinterpret_cast<unsigned char *
>(objPtr) + fOffsets[i],
true );
749 RDeleter::operator()(objPtr, dtorOnly);
754 std::vector<std::unique_ptr<RDeleter>> itemDeleters;
755 itemDeleters.reserve(fOffsets.size());
756 for (
const auto &
f : fSubfields) {
757 itemDeleters.emplace_back(GetDeleterOf(*
f));
759 return std::make_unique<RRecordDeleter>(std::move(itemDeleters), fOffsets, GetAlignment());
764 auto valuePtr =
value.GetPtr<
void>();
765 auto charPtr =
static_cast<unsigned char *
>(valuePtr.get());
766 std::vector<RValue>
result;
767 result.reserve(fSubfields.size());
768 for (
unsigned i = 0; i < fSubfields.size(); ++i) {
769 result.emplace_back(fSubfields[i]->BindValue(std::shared_ptr<void>(valuePtr, charPtr + fOffsets[i])));
792 return representations;
797 GenerateColumnsImpl<bool>();
802 GenerateColumnsImpl<bool>(desc);
805template <
typename FUlong,
typename FUlonglong,
typename... Args>
808 if (WordSize() ==
sizeof(
unsigned long)) {
809 fUlong(std::forward<Args>(args)..., fN, *fPrincipalColumn);
810 }
else if (WordSize() ==
sizeof(
unsigned long long)) {
812 fUlonglong(std::forward<Args>(args)..., fN, *fPrincipalColumn);
818template <
typename Word_t>
821 constexpr auto kBitsPerWord =
sizeof(Word_t) * 8;
823 constexpr std::size_t kChunkSize = 256;
824 bool buffer[kChunkSize];
826 const auto *asWordArray =
static_cast<const Word_t *
>(from);
827 std::size_t bitIdx = 0;
828 while (bitIdx < nBits) {
829 const std::size_t nBatch = std::min(kChunkSize, nBits - bitIdx);
830 for (std::size_t
b = 0;
b < nBatch; ++
b) {
831 const std::size_t currentBit = bitIdx +
b;
833 (asWordArray[currentBit / kBitsPerWord] & (
static_cast<Word_t
>(1) << (currentBit % kBitsPerWord))) != 0;
835 column.
AppendV(buffer, nBatch);
842 SelectWordSize(BitsetAppendImpl<unsigned long>, BitsetAppendImpl<unsigned long long>, from);
846template <
typename Word_t>
850 constexpr auto kBitsPerWord =
sizeof(Word_t) * 8;
852 constexpr std::size_t kChunkSize = 256;
853 bool buffer[kChunkSize];
855 auto *asWordArray =
static_cast<Word_t *
>(to);
856 std::size_t bitIdx = 0;
857 while (bitIdx < nBits) {
858 const std::size_t nBatch = std::min(kChunkSize, nBits - bitIdx);
859 column.
ReadV(globalIndex * nBits + bitIdx, nBatch, buffer);
860 for (std::size_t
b = 0;
b < nBatch; ++
b) {
861 const std::size_t currentBit = bitIdx +
b;
862 const Word_t
mask =
static_cast<Word_t
>(1) << (currentBit % kBitsPerWord);
863 const Word_t bit =
static_cast<Word_t
>(buffer[
b]) << (currentBit % kBitsPerWord);
864 asWordArray[currentBit / kBitsPerWord] = (asWordArray[currentBit / kBitsPerWord] & ~mask) | bit;
872 SelectWordSize(BitsetReadGlobalImpl<unsigned long>, BitsetReadGlobalImpl<unsigned long long>, globalIndex, to);
875template <
typename Word_t>
879 constexpr auto kBitsPerWord =
sizeof(Word_t) * 8;
880 constexpr std::size_t kChunkSize = 256;
881 bool buffer[kChunkSize];
883 auto *asWordArray =
static_cast<Word_t *
>(to);
884 std::size_t bitIdx = 0;
885 while (bitIdx < nBits) {
886 const std::size_t nBatch = std::min(kChunkSize, nBits - bitIdx);
889 for (std::size_t
b = 0;
b < nBatch; ++
b) {
890 const std::size_t currentBit = bitIdx +
b;
891 const Word_t
mask =
static_cast<Word_t
>(1) << (currentBit % kBitsPerWord);
892 const Word_t bit =
static_cast<Word_t
>(buffer[
b]) << (currentBit % kBitsPerWord);
893 asWordArray[currentBit / kBitsPerWord] = (asWordArray[currentBit / kBitsPerWord] & ~mask) | bit;
901 SelectWordSize(BitsetReadInClusterImpl<unsigned long>, BitsetReadInClusterImpl<unsigned long long>, localIndex, to);
912 std::unique_ptr<RFieldBase> itemField)
916 if (!itemField->GetTypeAlias().empty())
917 fTypeAlias = typePrefix +
"<" + itemField->GetTypeAlias() +
">";
919 Attach(std::move(itemField),
"_0");
929 return representations;
935 GenerateColumnsImpl<ROOT::Internal::RColumnIndex>();
940 if (!fIsEvolvedFromInnerType)
941 GenerateColumnsImpl<ROOT::Internal::RColumnIndex>(desc);
946 fPrincipalColumn->Append(&fNWritten);
952 auto nbytesItem = CallAppendOn(*fSubfields[0], from);
954 fPrincipalColumn->Append(&fNWritten);
960 static const std::vector<std::string> prefixes = {
"std::optional<",
"std::unique_ptr<"};
962 auto success = EnsureMatchingOnDiskField(desc, kDiffTypeName);
964 fIsEvolvedFromInnerType =
true;
966 success = EnsureMatchingTypePrefix(desc, prefixes);
967 fIsEvolvedFromInnerType = !success;
970 if (fIsEvolvedFromInnerType)
971 fSubfields[0]->SetOnDiskId(GetOnDiskId());
978 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &collectionSize);
986 fPrincipalColumn->GetCollectionInfo(localIndex, &collectionStart, &collectionSize);
999struct PolymorphicClass {
1000 virtual ~PolymorphicClass() =
default;
1005 :
RNullableField(fieldName,
"std::unique_ptr", std::move(itemField)), fItemDeleter(GetDeleterOf(*fSubfields[0]))
1014 auto newItemField = fSubfields[0]->Clone(fSubfields[0]->GetFieldName());
1015 return std::make_unique<RUniquePtrField>(newName, std::move(newItemField));
1020 auto typedValue =
static_cast<const std::unique_ptr<char> *
>(from);
1022 const void *obj = typedValue->get();
1023 if (fPolymorphicTypeInfo !=
nullptr) {
1026 const std::type_info &t =
typeid(*
static_cast<const PolymorphicClass *
>(obj));
1027 if (t != *fPolymorphicTypeInfo) {
1028 std::string msg =
"invalid dynamic type of object, expected " + fSubfields[0]->GetTypeName();
1032 msg = msg +
" but was passed " + demangled;
1035 msg +=
" and upcasting of polymorphic types is not supported in RNTuple";
1039 return AppendValue(obj);
1041 return AppendNull();
1047 auto ptr =
static_cast<std::unique_ptr<char> *
>(to);
1048 bool isValidValue =
static_cast<bool>(*ptr);
1050 void *valuePtr =
nullptr;
1052 valuePtr = ptr->get();
1054 if (isValidValue && !hasOnDiskValue) {
1056 fItemDeleter->operator()(valuePtr,
false );
1058 }
else if (!isValidValue && hasOnDiskValue) {
1059 valuePtr = CallCreateObjectRawPtrOn(*fSubfields[0]);
1060 ptr->reset(
reinterpret_cast<char *
>(valuePtr));
1069 if (!fIsEvolvedFromInnerType)
1070 itemIndex = GetItemIndex(globalIndex);
1072 auto valuePtr = PrepareRead(to, hasOnDiskValue);
1073 if (hasOnDiskValue) {
1074 if (fIsEvolvedFromInnerType) {
1075 CallReadOn(*fSubfields[0], globalIndex, valuePtr);
1077 CallReadOn(*fSubfields[0], itemIndex, valuePtr);
1085 if (!fIsEvolvedFromInnerType) {
1086 itemIndex = GetItemIndex(localIndex);
1088 itemIndex = localIndex;
1091 auto valuePtr = PrepareRead(to, hasOnDiskValue);
1093 CallReadOn(*fSubfields[0], itemIndex, valuePtr);
1098 auto typedPtr =
static_cast<std::unique_ptr<char> *
>(objPtr);
1100 fItemDeleter->operator()(typedPtr->get(),
false );
1101 typedPtr->release();
1103 RDeleter::operator()(objPtr, dtorOnly);
1108 return std::make_unique<RUniquePtrDeleter>(GetDeleterOf(*fSubfields[0]));
1113 std::vector<RValue>
result;
1114 auto valuePtr =
value.GetPtr<
void>();
1115 const auto &uniquePtr = *
static_cast<std::unique_ptr<char> *
>(valuePtr.get());
1117 result.emplace_back(fSubfields[0]->BindValue(std::shared_ptr<void>(valuePtr, uniquePtr.get())));
1125 :
RNullableField(fieldName,
"std::optional", std::move(itemField)), fItemDeleter(GetDeleterOf(*fSubfields[0]))
1133 return reinterpret_cast<bool *
>(
reinterpret_cast<unsigned char *
>(optionalPtr) + fSubfields[0]->GetValueSize());
1138 return GetEngagementPtr(
const_cast<void *
>(optionalPtr));
1143 auto newItemField = fSubfields[0]->Clone(fSubfields[0]->GetFieldName());
1144 return std::make_unique<ROptionalField>(newName, std::move(newItemField));
1149 if (*GetEngagementPtr(from)) {
1150 return AppendValue(from);
1152 return AppendNull();
1158 auto engagementPtr = GetEngagementPtr(to);
1159 if (hasOnDiskValue) {
1160 if (!(*engagementPtr) && !(fSubfields[0]->GetTraits() & kTraitTriviallyConstructible))
1161 CallConstructValueOn(*fSubfields[0], to);
1162 *engagementPtr =
true;
1164 if (*engagementPtr && !(fSubfields[0]->GetTraits() & kTraitTriviallyDestructible))
1165 fItemDeleter->operator()(to,
true );
1166 *engagementPtr =
false;
1173 if (!fIsEvolvedFromInnerType)
1174 itemIndex = GetItemIndex(globalIndex);
1176 PrepareRead(to, hasOnDiskValue);
1177 if (hasOnDiskValue) {
1178 if (fIsEvolvedFromInnerType) {
1179 CallReadOn(*fSubfields[0], globalIndex, to);
1181 CallReadOn(*fSubfields[0], itemIndex, to);
1189 if (!fIsEvolvedFromInnerType) {
1190 itemIndex = GetItemIndex(localIndex);
1192 itemIndex = localIndex;
1195 PrepareRead(to, hasOnDiskValue);
1197 CallReadOn(*fSubfields[0], itemIndex, to);
1202 *GetEngagementPtr(where) =
false;
1208 auto engagementPtr =
reinterpret_cast<bool *
>(
reinterpret_cast<unsigned char *
>(objPtr) + fEngagementPtrOffset);
1210 fItemDeleter->operator()(objPtr,
true );
1212 RDeleter::operator()(objPtr, dtorOnly);
1217 return std::make_unique<ROptionalDeleter>(
1218 (fSubfields[0]->GetTraits() & kTraitTriviallyDestructible) ?
nullptr : GetDeleterOf(*fSubfields[0]),
1219 fSubfields[0]->GetValueSize(), GetAlignment());
1224 std::vector<RValue>
result;
1225 const auto valuePtr =
value.GetPtr<
void>().get();
1226 if (*GetEngagementPtr(valuePtr)) {
1227 result.emplace_back(fSubfields[0]->BindValue(std::shared_ptr<void>(
value.GetPtr<
void>(), valuePtr)));
1236 const auto actualSize = fSubfields[0]->GetValueSize() +
sizeof(
bool);
1239 auto remainder = actualSize %
alignment;
1243 return actualSize + padding;
1248 return fSubfields[0]->GetAlignment();
1262 if (!itemField->GetTypeAlias().empty())
1263 fTypeAlias =
"std::atomic<" + itemField->GetTypeAlias() +
">";
1265 Attach(std::move(itemField),
"_0");
1270 auto newItemField = fSubfields[0]->Clone(fSubfields[0]->GetFieldName());
1271 return std::make_unique<RAtomicField>(newName, std::move(newItemField));
1277 if (fieldDesc.GetTypeName().rfind(
"std::atomic<", 0) == 0) {
1278 EnsureMatchingOnDiskField(desc, kDiffTypeName).ThrowOnError();
1280 fSubfields[0]->SetOnDiskId(GetOnDiskId());
1286 std::vector<RValue>
result;
1287 result.emplace_back(fSubfields[0]->BindValue(
value.GetPtr<
void>()));
#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)
#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 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 child
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.
virtual void VisitBitsetField(const ROOT::RBitsetField &field)
virtual void VisitByteField(const ROOT::RField< std::byte > &field)
virtual void VisitInt64Field(const ROOT::RIntegralField< std::int64_t > &field)
virtual void VisitInt8Field(const ROOT::RIntegralField< std::int8_t > &field)
virtual void VisitCharField(const ROOT::RField< char > &field)
virtual void VisitDoubleField(const ROOT::RField< double > &field)
virtual void VisitUInt32Field(const ROOT::RIntegralField< std::uint32_t > &field)
virtual void VisitCardinalityField(const ROOT::RCardinalityField &field)
virtual void VisitInt32Field(const ROOT::RIntegralField< std::int32_t > &field)
virtual void VisitUInt8Field(const ROOT::RIntegralField< std::uint8_t > &field)
virtual void VisitFieldZero(const ROOT::RFieldZero &field)
virtual void VisitStringField(const ROOT::RField< std::string > &field)
virtual void VisitUInt16Field(const ROOT::RIntegralField< std::uint16_t > &field)
virtual void VisitNullableField(const ROOT::RNullableField &field)
virtual void VisitInt16Field(const ROOT::RIntegralField< std::int16_t > &field)
virtual void VisitUInt64Field(const ROOT::RIntegralField< std::uint64_t > &field)
virtual void VisitBoolField(const ROOT::RField< bool > &field)
virtual void VisitRecordField(const ROOT::RRecordField &field)
virtual void VisitAtomicField(const ROOT::RAtomicField &field)
virtual void VisitFloatField(const ROOT::RField< float > &field)
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 AppendV(const void *from, std::size_t count)
void ReadV(ROOT::NTupleSize_t globalIndex, ROOT::NTupleSize_t count, void *to)
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, std::string_view expectedChildName="")
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.
std::vector< const RFieldBase * > GetConstSubfields() const
virtual void GenerateColumns()
Implementations in derived classes should create the backing columns corresponding to the field type ...
@ kTraitEmulatedField
This field is a user defined type that was missing dictionaries and was reconstructed from the on-dis...
@ kTraitTriviallyDestructible
The type is cleaned up just by freeing its memory. I.e. the destructor performs a no-op.
@ kTraitExtensible
Can attach new item fields even when already connected.
@ kTraitTriviallyConstructible
No constructor needs to be called, i.e.
@ kTraitTypeChecksum
The TClass checksum is set and valid.
std::uint32_t fTraits
Properties of the type that allow for optimizations of collections of that type.
RFieldBase * fParent
Subfields point to their mother field.
std::string fTypeAlias
A typedef or using name that was used when creating the field.
std::uint32_t GetTraits() const
const std::string & GetTypeName() const
Metadata stored for every field of an RNTuple.
std::optional< std::uint32_t > GetTypeChecksum() const
std::uint32_t GetTypeVersion() const
const std::string & GetTypeName() const
The container field for an ntuple model, which itself has no physical representation.
std::unordered_set< std::string > fSubfieldNames
Efficient detection of duplicate field names.
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.
bool fAllowFieldSubstitutions
If field substitutions are allowed, upon connecting to a page source the field hierarchy will replace...
void Attach(std::unique_ptr< RFieldBase > child)
A public version of the Attach method that allows piece-wise construction of the zero field.
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...
ROOT::NTupleSize_t GetIndexInCluster() const
ROOT::DescriptorId_t GetClusterId() const
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...
std::size_t GetAlignment() const final
What alignof(T) for this type returns.
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.
std::size_t GetValueSize() const final
What sizeof(T) for this type returns.
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::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
std::unordered_set< std::string > fSubfieldNames
Efficient detection of duplicate field names.
RRecordField(std::string_view name, const RRecordField &source)
void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final
void AttachItemFields(ContainerT &&itemFields)
std::uint32_t fEmulatedTypeVersion
std::unique_ptr< RDeleter > GetDeleter() const final
std::size_t GetItemPadding(std::size_t baseOffset, std::size_t itemAlignment) const
void AddItem(std::unique_ptr< RFieldBase > item)
Adds an additional item field.
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::uint32_t fEmulatedTypeChecksum
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, const RFieldDescriptor &emulatedFrom)
std::unique_ptr< RFieldBase > CreateEmulatedRecordField(std::string_view fieldName, std::vector< std::unique_ptr< RFieldBase > > itemFields, const RFieldDescriptor &emulatedFrom)
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 ...
void AddItemToRecord(RRecordField &record, std::unique_ptr< RFieldBase > newItem)
bool IsCustomEnumFieldDesc(const RNTupleDescriptor &desc, const RFieldDescriptor &fieldDesc)
Tells if the field describes a user-defined enum type.
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.