40#include <unordered_map>
46std::vector<std::string> TokenizeTypeList(std::string templateType) {
47 std::vector<std::string> result;
48 if (templateType.empty())
51 const char *eol = templateType.data() + templateType.length();
52 const char *typeBegin = templateType.data();
53 const char *typeCursor = templateType.data();
54 unsigned int nestingLevel = 0;
55 while (typeCursor != eol) {
56 switch (*typeCursor) {
64 if (nestingLevel == 0) {
65 result.push_back(std::string(typeBegin, typeCursor - typeBegin));
66 typeBegin = typeCursor + 1;
72 result.push_back(std::string(typeBegin, typeCursor - typeBegin));
77std::string Trim(
const std::string &raw) {
78 if (raw.empty())
return "";
80 unsigned start_pos = 0;
81 for (; (start_pos < raw.length()) && (raw[start_pos] ==
' ' || raw[start_pos] ==
'\t'); ++start_pos) { }
83 unsigned end_pos = raw.length() - 1;
84 for (; (end_pos >= start_pos) && (raw[end_pos] ==
' ' || raw[end_pos] ==
'\t'); --end_pos) { }
86 return raw.substr(start_pos, end_pos - start_pos + 1);
90 std::string normalizedType(Trim(typeName));
93 if (normalizedType ==
"Bool_t") normalizedType =
"bool";
94 if (normalizedType ==
"Float_t") normalizedType =
"float";
95 if (normalizedType ==
"Double_t") normalizedType =
"double";
96 if (normalizedType ==
"UChar_t") normalizedType =
"std::uint8_t";
97 if (normalizedType ==
"unsigned char") normalizedType =
"std::uint8_t";
98 if (normalizedType ==
"uint8_t") normalizedType =
"std::uint8_t";
99 if (normalizedType ==
"Int_t") normalizedType =
"std::int32_t";
100 if (normalizedType ==
"int") normalizedType =
"std::int32_t";
101 if (normalizedType ==
"int32_t") normalizedType =
"std::int32_t";
102 if (normalizedType ==
"unsigned") normalizedType =
"std::uint32_t";
103 if (normalizedType ==
"unsigned int") normalizedType =
"std::uint32_t";
104 if (normalizedType ==
"UInt_t") normalizedType =
"std::uint32_t";
105 if (normalizedType ==
"uint32_t") normalizedType =
"std::uint32_t";
106 if (normalizedType ==
"ULong64_t") normalizedType =
"std::uint64_t";
107 if (normalizedType ==
"uint64_t") normalizedType =
"std::uint64_t";
108 if (normalizedType ==
"string") normalizedType =
"std::string";
109 if (normalizedType.substr(0, 7) ==
"vector<") normalizedType =
"std::" + normalizedType;
110 if (normalizedType.substr(0, 6) ==
"array<") normalizedType =
"std::" + normalizedType;
111 if (normalizedType.substr(0, 8) ==
"variant<") normalizedType =
"std::" + normalizedType;
113 return normalizedType;
123 column->Connect(fieldId, &pageStorage);
130 Connect(fieldId, pageSource, field);
131 std::unordered_map<const RFieldBase *, DescriptorId_t> field2Id;
132 field2Id[&field] = fieldId;
133 for (
auto &
f : field) {
136 field2Id[&
f] = subFieldId;
146 : fName(
name), fType(
type), fStructure(structure), fNRepetitions(nRepetitions), fIsSimple(isSimple),
147 fParent(nullptr), fPrincipalColumn(nullptr)
158 std::string normalizedType(GetNormalizedType(typeName));
159 if (normalizedType.empty())
160 return R__FAIL(
"no type name specified for Field " + fieldName);
162 std::unique_ptr<ROOT::Experimental::Detail::RFieldBase> result;
164 if (normalizedType ==
"ROOT::Experimental::ClusterSize_t") {
165 result = std::make_unique<RField<ClusterSize_t>>(fieldName);
166 }
else if (normalizedType ==
"bool") {
167 result = std::make_unique<RField<bool>>(fieldName);
168 }
else if (normalizedType ==
"std::uint8_t") {
169 result = std::make_unique<RField<std::uint8_t>>(fieldName);
170 }
else if (normalizedType ==
"std::int32_t") {
171 result = std::make_unique<RField<std::int32_t>>(fieldName);
172 }
else if (normalizedType ==
"std::uint32_t") {
173 result = std::make_unique<RField<std::uint32_t>>(fieldName);
174 }
else if (normalizedType ==
"std::uint64_t") {
175 result = std::make_unique<RField<std::uint64_t>>(fieldName);
176 }
else if (normalizedType ==
"float") {
177 result = std::make_unique<RField<float>>(fieldName);
178 }
else if (normalizedType ==
"double") {
179 result = std::make_unique<RField<double>>(fieldName);
180 }
else if (normalizedType ==
"std::string") {
181 result = std::make_unique<RField<std::string>>(fieldName);
182 }
else if (normalizedType ==
"std::vector<bool>") {
183 result = std::make_unique<RField<std::vector<bool>>>(fieldName);
184 }
else if (normalizedType.substr(0, 12) ==
"std::vector<") {
185 std::string itemTypeName = normalizedType.substr(12, normalizedType.length() - 13);
186 auto itemField = Create(GetNormalizedType(itemTypeName), itemTypeName);
187 result = std::make_unique<RVectorField>(fieldName, itemField.Unwrap());
188 }
else if (normalizedType ==
"ROOT::VecOps::RVec<bool>") {
189 result = std::make_unique<RField<ROOT::VecOps::RVec<bool>>>(fieldName);
190 }
else if (normalizedType.substr(0, 19) ==
"ROOT::VecOps::RVec<") {
192 std::string itemTypeName = normalizedType.substr(19, normalizedType.length() - 20);
193 auto itemField = Create(GetNormalizedType(itemTypeName), itemTypeName);
194 result = std::make_unique<RVectorField>(fieldName, itemField.Unwrap());
195 }
else if (normalizedType.substr(0, 11) ==
"std::array<") {
196 auto arrayDef = TokenizeTypeList(normalizedType.substr(11, normalizedType.length() - 12));
198 auto arrayLength = std::stoi(arrayDef[1]);
199 auto itemField = Create(GetNormalizedType(arrayDef[0]), arrayDef[0]);
200 result = std::make_unique<RArrayField>(fieldName, itemField.Unwrap(), arrayLength);
202#if __cplusplus >= 201703L
203 if (normalizedType.substr(0, 13) ==
"std::variant<") {
204 auto innerTypes = TokenizeTypeList(normalizedType.substr(13, normalizedType.length() - 14));
205 std::vector<RFieldBase *> items;
206 for (
unsigned int i = 0; i < innerTypes.size(); ++i) {
207 items.emplace_back(Create(
"variant" + std::to_string(i), innerTypes[i]).Unwrap().release());
209 result = std::make_unique<RVariantField>(fieldName, items);
213 if (normalizedType ==
":Collection:")
214 result = std::make_unique<RField<ClusterSize_t>>(fieldName);
219 result = std::make_unique<RClassField>(fieldName, normalizedType);
225 return R__FAIL(std::string(
"Field ") + fieldName +
" has unknown type " + normalizedType);
231 if (fieldName ==
"") {
232 return R__FAIL(
"name cannot be empty string \"\"");
233 }
else if (fieldName.find(
".") != std::string::npos) {
234 return R__FAIL(
"name '" + std::string(fieldName) +
"' cannot contain dot characters '.'");
252 void *where =
malloc(GetValueSize());
254 return GenerateValue(where);
263std::vector<ROOT::Experimental::Detail::RFieldValue>
266 return std::vector<RFieldValue>();
270 std::unique_ptr<ROOT::Experimental::Detail::RFieldBase> child)
272 child->fParent =
this;
273 fSubFields.emplace_back(std::move(child));
277std::vector<const ROOT::Experimental::Detail::RFieldBase *>
280 std::vector<const RFieldBase *> result;
281 for (
const auto &
f : fSubFields) {
282 result.emplace_back(
f.get());
290 for (
auto& column : fColumns) {
320 auto itr = fStack.rbegin();
321 if (!itr->fFieldPtr->fSubFields.empty()) {
322 fStack.emplace_back(
Position(itr->fFieldPtr->fSubFields[0].get(), 0));
326 unsigned int nextIdxInParent = ++(itr->fIdxInParent);
327 while (nextIdxInParent >= itr->fFieldPtr->fParent->fSubFields.size()) {
328 if (fStack.size() == 1) {
329 itr->fFieldPtr = itr->fFieldPtr->fParent;
330 itr->fIdxInParent = -1;
334 itr = fStack.rbegin();
335 nextIdxInParent = ++(itr->fIdxInParent);
337 itr->fFieldPtr = itr->fFieldPtr->fParent->fSubFields[nextIdxInParent].get();
344std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
347 auto result = std::make_unique<RFieldZero>();
348 for (
auto &
f : fSubFields)
349 result->Attach(
f->Clone(
f->GetName()));
356 auto entry = std::make_unique<REntry>();
357 for (
auto&
f : fSubFields) {
358 entry->AddValue(
f->GenerateValue());
375 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
376 Detail::RColumn::Create<ClusterSize_t, EColumnType::kIndex>(model, 0)));
377 fPrincipalColumn = fColumns[0].get();
382 visitor.VisitClusterSizeField(*
this);
392 fPrincipalColumn = fColumns[0].get();
397 visitor.VisitUInt8Field(*
this);
406 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
407 Detail::RColumn::Create<bool, EColumnType::kBit>(model, 0)));
408 fPrincipalColumn = fColumns[0].get();
422 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
423 Detail::RColumn::Create<float, EColumnType::kReal32>(model, 0)));
424 fPrincipalColumn = fColumns[0].get();
438 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
439 Detail::RColumn::Create<double, EColumnType::kReal64>(model, 0)));
440 fPrincipalColumn = fColumns[0].get();
455 fPrincipalColumn = fColumns[0].get();
460 visitor.VisitIntField(*
this);
468 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
469 Detail::RColumn::Create<std::uint32_t, EColumnType::kInt32>(model, 0)));
470 fPrincipalColumn = fColumns[0].get();
475 visitor.VisitUInt32Field(*
this);
483 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
484 Detail::RColumn::Create<std::uint64_t, EColumnType::kInt64>(model, 0)));
485 fPrincipalColumn = fColumns[0].get();
490 visitor.VisitUInt64Field(*
this);
499 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
500 Detail::RColumn::Create<ClusterSize_t, EColumnType::kIndex>(modelIndex, 0)));
503 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
504 Detail::RColumn::Create<char, EColumnType::kByte>(modelChars, 1)));
505 fPrincipalColumn = fColumns[0].get();
510 auto typedValue = value.
Get<std::string>();
511 auto length = typedValue->length();
512 Detail::RColumnElement<char, EColumnType::kByte> elemChars(
const_cast<char*
>(typedValue->data()));
513 fColumns[1]->AppendV(elemChars, length);
515 fColumns[0]->Append(fElemIndex);
521 auto typedValue = value->
Get<std::string>();
522 RClusterIndex collectionStart;
524 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nChars);
528 typedValue->resize(nChars);
529 Detail::RColumnElement<char, EColumnType::kByte> elemChars(
const_cast<char*
>(typedValue->data()));
530 fColumns[1]->ReadV(collectionStart, nChars, &elemChars);
541 visitor.VisitStringField(*
this);
552 throw std::runtime_error(
"RField: no I/O support for type " + std::string(className));
555 while (
auto dataMember =
static_cast<TDataMember *
>(next())) {
559 Attach(std::move(subField));
563std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
566 return std::make_unique<RClassField>(newName, GetType());
572 while (
auto dataMember =
static_cast<TDataMember *
>(next())) {
573 auto memberValue = fSubFields[i]->CaptureValue(value.
Get<
unsigned char>() + dataMember->GetOffset());
574 fSubFields[i]->Append(memberValue);
583 while (
auto dataMember =
static_cast<TDataMember *
>(next())) {
584 auto memberValue = fSubFields[i]->GenerateValue(value->
Get<
unsigned char>() + dataMember->GetOffset());
585 fSubFields[i]->Read(globalIndex, &memberValue);
594 while (
auto dataMember =
static_cast<TDataMember *
>(next())) {
595 auto memberValue = fSubFields[i]->GenerateValue(value->
Get<
unsigned char>() + dataMember->GetOffset());
596 fSubFields[i]->Read(clusterIndex, &memberValue);
623std::vector<ROOT::Experimental::Detail::RFieldValue>
628 std::vector<Detail::RFieldValue> result;
629 while (
auto dataMember =
static_cast<TDataMember *
>(next())) {
630 auto memberValue = fSubFields[i]->CaptureValue(value.
Get<
unsigned char>() + dataMember->GetOffset());
631 result.emplace_back(memberValue);
640 return fClass->GetClassSize();
652 std::string_view fieldName, std::unique_ptr<Detail::RFieldBase> itemField)
655 , fItemSize(itemField->GetValueSize()), fNWritten(0)
657 Attach(std::move(itemField));
660std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
663 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetName());
664 return std::make_unique<RVectorField>(newName, std::move(newItemField));
668 auto typedValue = value.
Get<std::vector<char>>();
669 R__ASSERT((typedValue->size() % fItemSize) == 0);
670 auto count = typedValue->size() / fItemSize;
671 for (
unsigned i = 0; i < count; ++i) {
672 auto itemValue = fSubFields[0]->CaptureValue(typedValue->data() + (i * fItemSize));
673 fSubFields[0]->Append(itemValue);
677 fColumns[0]->Append(elemIndex);
682 auto typedValue = value->
Get<std::vector<char>>();
686 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
688 typedValue->resize(nItems * fItemSize);
689 for (
unsigned i = 0; i < nItems; ++i) {
690 auto itemValue = fSubFields[0]->GenerateValue(typedValue->data() + (i * fItemSize));
691 fSubFields[0]->Read(collectionStart + i, &itemValue);
698 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
699 Detail::RColumn::Create<ClusterSize_t, EColumnType::kIndex>(modelIndex, 0)));
700 fPrincipalColumn = fColumns[0].get();
710 auto vec =
static_cast<std::vector<char>*
>(value.
GetRawPtr());
711 R__ASSERT((vec->size() % fItemSize) == 0);
712 auto nItems = vec->size() / fItemSize;
713 for (
unsigned i = 0; i < nItems; ++i) {
714 auto itemValue = fSubFields[0]->CaptureValue(vec->data() + (i * fItemSize));
715 fSubFields[0]->DestroyValue(itemValue,
true );
727std::vector<ROOT::Experimental::Detail::RFieldValue>
730 auto vec =
static_cast<std::vector<char>*
>(value.
GetRawPtr());
731 R__ASSERT((vec->size() % fItemSize) == 0);
732 auto nItems = vec->size() / fItemSize;
733 std::vector<Detail::RFieldValue> result;
734 for (
unsigned i = 0; i < nItems; ++i) {
735 result.emplace_back(fSubFields[0]->CaptureValue(vec->data() + (i * fItemSize)));
762 auto typedValue = value.Get<std::vector<bool>>();
763 auto count = typedValue->size();
764 for (
unsigned i = 0; i < count; ++i) {
765 bool bval = (*typedValue)[i];
767 fSubFields[0]->Append(itemValue);
769 Detail::RColumnElement<ClusterSize_t, EColumnType::kIndex> elemIndex(&fNWritten);
771 fColumns[0]->Append(elemIndex);
776 auto typedValue = value->Get<std::vector<bool>>();
779 RClusterIndex collectionStart;
780 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
782 typedValue->resize(nItems);
783 for (
unsigned i = 0; i < nItems; ++i) {
785 auto itemValue = fSubFields[0]->GenerateValue(&bval);
786 fSubFields[0]->Read(collectionStart + i, &itemValue);
787 (*typedValue)[i] = bval;
794 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
795 Detail::RColumn::Create<ClusterSize_t, EColumnType::kIndex>(modelIndex, 0)));
796 fPrincipalColumn = fColumns[0].get();
799std::vector<ROOT::Experimental::Detail::RFieldValue>
802 const static bool trueValue =
true;
803 const static bool falseValue =
false;
805 auto typedValue = value.Get<std::vector<bool>>();
806 auto count = typedValue->size();
807 std::vector<Detail::RFieldValue> result;
808 for (
unsigned i = 0; i < count; ++i) {
809 if ((*typedValue)[i])
810 result.emplace_back(fSubFields[0]->CaptureValue(
const_cast<bool *
>(&trueValue)));
812 result.emplace_back(fSubFields[0]->CaptureValue(
const_cast<bool *
>(&falseValue)));
820 auto vec =
static_cast<std::vector<bool>*
>(value.GetRawPtr());
828 visitor.VisitVectorBoolField(*
this);
836 std::string_view fieldName, std::unique_ptr<Detail::RFieldBase> itemField, std::size_t arrayLength)
838 fieldName,
"std::array<" + itemField->GetType() +
"," + std::to_string(arrayLength) +
">",
840 , fItemSize(itemField->GetValueSize()), fArrayLength(arrayLength)
842 Attach(std::move(itemField));
845std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
848 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetName());
849 return std::make_unique<RArrayField>(newName, std::move(newItemField), fArrayLength);
853 auto arrayPtr = value.
Get<
unsigned char>();
854 for (
unsigned i = 0; i < fArrayLength; ++i) {
855 auto itemValue = fSubFields[0]->CaptureValue(arrayPtr + (i * fItemSize));
856 fSubFields[0]->Append(itemValue);
862 auto arrayPtr = value->
Get<
unsigned char>();
863 for (
unsigned i = 0; i < fArrayLength; ++i) {
864 auto itemValue = fSubFields[0]->GenerateValue(arrayPtr + (i * fItemSize));
865 fSubFields[0]->Read(globalIndex * fArrayLength + i, &itemValue);
871 auto arrayPtr = value->
Get<
unsigned char>();
872 for (
unsigned i = 0; i < fArrayLength; ++i) {
873 auto itemValue = fSubFields[0]->GenerateValue(arrayPtr + (i * fItemSize));
885 auto arrayPtr =
reinterpret_cast<unsigned char *
>(where);
886 for (
unsigned i = 0; i < fArrayLength; ++i) {
887 fSubFields[0]->GenerateValue(arrayPtr + (i * fItemSize));
894 auto arrayPtr = value.
Get<
unsigned char>();
895 for (
unsigned i = 0; i < fArrayLength; ++i) {
896 auto itemValue = fSubFields[0]->CaptureValue(arrayPtr + (i * fItemSize));
897 fSubFields[0]->DestroyValue(itemValue,
true );
908std::vector<ROOT::Experimental::Detail::RFieldValue>
911 auto arrayPtr = value.
Get<
unsigned char>();
912 std::vector<Detail::RFieldValue> result;
913 for (
unsigned i = 0; i < fArrayLength; ++i) {
914 auto itemValue = fSubFields[0]->CaptureValue(arrayPtr + (i * fItemSize));
915 result.emplace_back(itemValue);
927#if __cplusplus >= 201703L
928std::string ROOT::Experimental::RVariantField::GetTypeList(
const std::vector<Detail::RFieldBase *> &itemFields)
931 for (
size_t i = 0; i < itemFields.size(); ++i) {
932 result += itemFields[i]->GetType() +
",";
939ROOT::Experimental::RVariantField::RVariantField(
940 std::string_view fieldName,
const std::vector<Detail::RFieldBase *> &itemFields)
944 auto nFields = itemFields.size();
946 fNWritten.resize(nFields, 0);
947 for (
unsigned int i = 0; i < nFields; ++i) {
948 fMaxItemSize = std::max(fMaxItemSize, itemFields[i]->
GetValueSize());
949 fMaxAlignment = std::max(fMaxAlignment, itemFields[i]->
GetAlignment());
950 Attach(std::unique_ptr<Detail::RFieldBase>(itemFields[i]));
952 fTagOffset = (fMaxItemSize < fMaxAlignment) ? fMaxAlignment : fMaxItemSize;
955std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
956ROOT::Experimental::RVariantField::Clone(std::string_view newName)
const
958 auto nFields = fSubFields.size();
959 std::vector<Detail::RFieldBase *> itemFields;
960 for (
unsigned i = 0; i < nFields; ++i) {
962 itemFields.emplace_back(fSubFields[i]->Clone(fSubFields[i]->GetName()).release());
964 return std::make_unique<RVariantField>(newName, itemFields);
967std::uint32_t ROOT::Experimental::RVariantField::GetTag(
void *variantPtr)
const
969 auto index = *(
reinterpret_cast<char *
>(variantPtr) + fTagOffset);
970 return (index < 0) ? 0 : index + 1;
973void ROOT::Experimental::RVariantField::SetTag(
void *variantPtr, std::uint32_t tag)
const
975 auto index =
reinterpret_cast<char *
>(variantPtr) + fTagOffset;
976 *index =
static_cast<char>(tag - 1);
979void ROOT::Experimental::RVariantField::AppendImpl(
const Detail::RFieldValue& value)
981 auto tag = GetTag(value.GetRawPtr());
984 auto itemValue = fSubFields[tag - 1]->CaptureValue(value.GetRawPtr());
985 fSubFields[tag - 1]->Append(itemValue);
986 index = fNWritten[tag - 1]++;
989 Detail::RColumnElement<RColumnSwitch, EColumnType::kSwitch> elemSwitch(&varSwitch);
990 fColumns[0]->Append(elemSwitch);
993void ROOT::Experimental::RVariantField::ReadGlobalImpl(
NTupleSize_t globalIndex, Detail::RFieldValue *value)
995 RClusterIndex variantIndex;
997 fPrincipalColumn->GetSwitchInfo(globalIndex, &variantIndex, &tag);
1000 auto itemValue = fSubFields[tag - 1]->GenerateValue(value->GetRawPtr());
1001 fSubFields[tag - 1]->Read(variantIndex, &itemValue);
1002 SetTag(value->GetRawPtr(), tag);
1005void ROOT::Experimental::RVariantField::GenerateColumnsImpl()
1008 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
1009 Detail::RColumn::Create<RColumnSwitch, EColumnType::kSwitch>(modelSwitch, 0)));
1010 fPrincipalColumn = fColumns[0].get();
1015 memset(where, 0, GetValueSize());
1016 fSubFields[0]->GenerateValue(where);
1018 return Detail::RFieldValue(
this,
reinterpret_cast<unsigned char *
>(where));
1021void ROOT::Experimental::RVariantField::DestroyValue(
const Detail::RFieldValue& value,
bool dtorOnly)
1023 auto variantPtr = value.GetRawPtr();
1024 auto tag = GetTag(variantPtr);
1026 auto itemValue = fSubFields[tag - 1]->CaptureValue(variantPtr);
1027 fSubFields[tag - 1]->DestroyValue(itemValue,
true );
1035 return Detail::RFieldValue(
true ,
this, where);
1038size_t ROOT::Experimental::RVariantField::GetValueSize()
const
1040 return fMaxItemSize + fMaxAlignment;
1043void ROOT::Experimental::RVariantField::CommitCluster()
1045 std::fill(fNWritten.begin(), fNWritten.end(), 0);
1054 std::string_view
name,
1055 std::shared_ptr<RCollectionNTuple> collectionNTuple,
1056 std::unique_ptr<RNTupleModel> collectionModel)
1058 , fCollectionNTuple(collectionNTuple)
1060 for (
unsigned i = 0; i < collectionModel->GetFieldZero()->
fSubFields.size(); ++i) {
1061 auto& subField = collectionModel->GetFieldZero()->fSubFields[i];
1062 Attach(std::move(subField));
1070 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
1071 Detail::RColumn::Create<ClusterSize_t, EColumnType::kIndex>(modelIndex, 0)));
1072 fPrincipalColumn = fColumns[0].get();
1076std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
1092 *fCollectionNTuple->GetOffsetPtr() = 0;
#define R__FAIL(msg)
Short-hand to return an RResult<T> in an error state; the RError is implicitly converted into RResult...
Pairs of C++ type and column type, like float and EColumnType::kReal32.
static RColumn * Create(const RColumnModel &model, std::uint32_t index)
Iterates over the sub tree of fields in depth-first search order.
void Advance()
Given that the iterator points to a valid field which is not the end iterator, go to the next field i...
virtual void GenerateColumnsImpl()=0
Creates the backing columns corresponsing to the field type and name.
std::vector< std::unique_ptr< RFieldBase > > fSubFields
Collections and classes own sub fields.
RFieldBase(std::string_view name, std::string_view type, 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.
virtual void DestroyValue(const RFieldValue &value, bool dtorOnly=false)
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
friend class ROOT::Experimental::RCollectionField
void Flush() const
Ensure that all received items are written from page buffers to the storage.
virtual void CommitCluster()
Perform housekeeping tasks for global to cluster-local index translation.
virtual std::vector< RFieldValue > SplitValue(const RFieldValue &value) const
Creates the list of direct child values given a value for this field.
static RResult< void > EnsureValidFieldName(std::string_view fieldName)
Check whether a given string is a valid field name.
virtual void AppendImpl(const RFieldValue &value)
Operations on values of complex types, e.g.
static RResult< std::unique_ptr< RFieldBase > > Create(const std::string &fieldName, const std::string &typeName)
Factory method to resurrect a field from the stored on-disk type information.
virtual void AcceptVisitor(RFieldVisitor &visitor) const
std::vector< const RFieldBase * > GetSubFields() const
virtual void ReadGlobalImpl(NTupleSize_t globalIndex, RFieldValue *value)
std::vector< std::unique_ptr< RColumn > > fColumns
The columns are connected either to a sink or to a source (not to both); they are owned by the field.
void Attach(std::unique_ptr< Detail::RFieldBase > child)
Add a new subfield to the list of nested fields.
RFieldValue GenerateValue()
Generates an object of the field type and allocates new initialized memory according to the type.
static void ConnectRecursively(DescriptorId_t fieldId, RPageSource &pageSource, RFieldBase &field)
Connect the field columns and all sub field columns.
static void Connect(DescriptorId_t fieldId, RPageStorage &pageStorage, RFieldBase &field)
Abstract base class for classes implementing the visitor design pattern.
virtual void VisitBoolField(const RField< bool > &field)
virtual void VisitFieldZero(const RFieldZero &field)
virtual void VisitField(const Detail::RFieldBase &field)=0
virtual void VisitDoubleField(const RField< double > &field)
virtual void VisitArrayField(const RArrayField &field)
virtual void VisitClassField(const RClassField &field)
virtual void VisitVectorField(const RVectorField &field)
virtual void VisitFloatField(const RField< float > &field)
Abstract interface to read data from an ntuple.
const RNTupleDescriptor & GetDescriptor() const
Common functionality of an ntuple storage for both reading and writing.
std::vector< Detail::RFieldValue > SplitValue(const Detail::RFieldValue &value) const final
Creates the list of direct child values given a value for this field.
Detail::RFieldValue CaptureValue(void *where) final
Creates a value from a memory location with an already constructed object.
void ReadInClusterImpl(const RClusterIndex &clusterIndex, Detail::RFieldValue *value) final
void ReadGlobalImpl(NTupleSize_t globalIndex, Detail::RFieldValue *value) final
RArrayField(std::string_view fieldName, std::unique_ptr< Detail::RFieldBase > itemField, std::size_t arrayLength)
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type and name.
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
void DestroyValue(const Detail::RFieldValue &value, bool dtorOnly=false) final
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
void AppendImpl(const Detail::RFieldValue &value) final
Operations on values of complex types, e.g.
std::unique_ptr< Detail::RFieldBase > Clone(std::string_view newName) const final
size_t GetAlignment() const final
For many types, the alignment requirement is equal to the size; otherwise override.
Detail::RFieldValue CaptureValue(void *where) final
Creates a value from a memory location with an already constructed object.
size_t GetValueSize() const override
The number of bytes taken by a value of the appropriate type.
std::vector< Detail::RFieldValue > SplitValue(const Detail::RFieldValue &value) const final
Creates the list of direct child values given a value for this field.
std::unique_ptr< Detail::RFieldBase > Clone(std::string_view newName) const final
void AcceptVisitor(Detail::RFieldVisitor &visitor) const override
void AppendImpl(const Detail::RFieldValue &value) final
Operations on values of complex types, e.g.
void ReadInClusterImpl(const RClusterIndex &clusterIndex, Detail::RFieldValue *value) final
RClassField(std::string_view fieldName, std::string_view className)
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type and name.
std::size_t fMaxAlignment
void ReadGlobalImpl(NTupleSize_t globalIndex, Detail::RFieldValue *value) final
void DestroyValue(const Detail::RFieldValue &value, bool dtorOnly=false) final
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
Addresses a column element or field item relative to a particular cluster, instead of a global NTuple...
DescriptorId_t GetClusterId() const
ClusterSize_t::ValueType GetIndex() const
std::unique_ptr< Detail::RFieldBase > Clone(std::string_view newName) const final
void CommitCluster() final
Perform housekeeping tasks for global to cluster-local index translation.
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type and name.
Holds the static meta-data of a column in a tree.
A field translates read and write calls from/to underlying columns to/from tree values.
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
std::unique_ptr< REntry > GenerateEntry() const
Generates managed values for the top-level sub fields.
std::unique_ptr< Detail::RFieldBase > Clone(std::string_view newName) const
Classes with dictionaries that can be inspected by TClass.
DescriptorId_t FindFieldId(std::string_view fieldName, DescriptorId_t parentId) const
The class is used as a return type for operations that can fail; wraps a value of type T or an RError...
Detail::RFieldValue CaptureValue(void *where) override
Creates a value from a memory location with an already constructed object.
void CommitCluster() final
Perform housekeeping tasks for global to cluster-local index translation.
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
std::vector< Detail::RFieldValue > SplitValue(const Detail::RFieldValue &value) const final
Creates the list of direct child values given a value for this field.
void ReadGlobalImpl(NTupleSize_t globalIndex, Detail::RFieldValue *value) final
std::unique_ptr< Detail::RFieldBase > Clone(std::string_view newName) const final
void AppendImpl(const Detail::RFieldValue &value) final
Operations on values of complex types, e.g.
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type and name.
RVectorField(std::string_view fieldName, std::unique_ptr< Detail::RFieldBase > itemField)
void DestroyValue(const Detail::RFieldValue &value, bool dtorOnly=false) final
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
TClass instances represent classes, structs and namespaces in the ROOT type system.
TList * GetListOfDataMembers(Bool_t load=kTRUE)
Return list containing the TDataMembers of a class.
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
All ROOT classes may have RTTI (run time type identification) support added.
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
RClusterSize ClusterSize_t
ENTupleStructure
The fields in the ntuple model tree can carry different structural information about the type system.
std::uint64_t DescriptorId_t
Distriniguishes elements of the same type within a descriptor, e.g. different fields.
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
Wrap the 32bit integer in a struct in order to avoid template specialization clash with std::uint32_t...