38 #include <type_traits>
44 std::vector<std::string> TokenizeTypeList(std::string templateType) {
45 std::vector<std::string> result;
46 if (templateType.empty())
49 const char *eol = templateType.data() + templateType.length();
50 const char *typeBegin = templateType.data();
51 const char *typeCursor = templateType.data();
52 unsigned int nestingLevel = 0;
53 while (typeCursor != eol) {
54 switch (*typeCursor) {
62 if (nestingLevel == 0) {
63 result.push_back(std::string(typeBegin, typeCursor - typeBegin));
64 typeBegin = typeCursor + 1;
70 result.push_back(std::string(typeBegin, typeCursor - typeBegin));
76 void ROOT::Experimental::Detail::RFieldFuse::Connect(DescriptorId_t fieldId, RPageStorage &pageStorage, RFieldBase &field)
78 if (field.fColumns.empty())
79 field.DoGenerateColumns();
80 for (
auto& column : field.fColumns)
81 column->Connect(fieldId, &pageStorage);
88 ROOT::Experimental::Detail::RFieldBase::RFieldBase(
89 std::string_view name, std::string_view type, ENTupleStructure structure,
bool isSimple, std::size_t nRepetitions)
90 : fName(name), fType(type), fStructure(structure), fNRepetitions(nRepetitions), fIsSimple(isSimple),
91 fParent(nullptr), fPrincipalColumn(nullptr)
95 ROOT::Experimental::Detail::RFieldBase::~RFieldBase()
99 ROOT::Experimental::Detail::RFieldBase*
100 ROOT::Experimental::Detail::RFieldBase::Create(
const std::string &fieldName,
const std::string &typeName)
102 std::string normalizedType(typeName);
103 normalizedType.erase(remove_if(normalizedType.begin(), normalizedType.end(), isspace), normalizedType.end());
105 if (normalizedType ==
"Bool_t") normalizedType =
"bool";
106 if (normalizedType ==
"Float_t") normalizedType =
"float";
107 if (normalizedType ==
"Double_t") normalizedType =
"double";
108 if (normalizedType ==
"UChar_t") normalizedType =
"std::uint8_t";
109 if (normalizedType ==
"unsigned char") normalizedType =
"std::uint8_t";
110 if (normalizedType ==
"uint8_t") normalizedType =
"std::uint8_t";
111 if (normalizedType ==
"Int_t") normalizedType =
"std::int32_t";
112 if (normalizedType ==
"int") normalizedType =
"std::int32_t";
113 if (normalizedType ==
"int32_t") normalizedType =
"std::int32_t";
114 if (normalizedType ==
"unsigned") normalizedType =
"std::uint32_t";
115 if (normalizedType ==
"unsigned int") normalizedType =
"std::uint32_t";
116 if (normalizedType ==
"UInt_t") normalizedType =
"std::uint32_t";
117 if (normalizedType ==
"uint32_t") normalizedType =
"std::uint32_t";
118 if (normalizedType ==
"ULong64_t") normalizedType =
"std::uint64_t";
119 if (normalizedType ==
"uint64_t") normalizedType =
"std::uint64_t";
120 if (normalizedType ==
"string") normalizedType =
"std::string";
121 if (normalizedType.substr(0, 7) ==
"vector<") normalizedType =
"std::" + normalizedType;
122 if (normalizedType.substr(0, 6) ==
"array<") normalizedType =
"std::" + normalizedType;
123 if (normalizedType.substr(0, 8) ==
"variant<") normalizedType =
"std::" + normalizedType;
125 if (normalizedType ==
"ROOT::Experimental::ClusterSize_t")
return new RField<ClusterSize_t>(fieldName);
126 if (normalizedType ==
"bool")
return new RField<bool>(fieldName);
127 if (normalizedType ==
"std::uint8_t")
return new RField<std::uint8_t>(fieldName);
128 if (normalizedType ==
"std::int32_t")
return new RField<std::int32_t>(fieldName);
129 if (normalizedType ==
"std::uint32_t")
return new RField<std::uint32_t>(fieldName);
130 if (normalizedType ==
"std::uint64_t")
return new RField<std::uint64_t>(fieldName);
131 if (normalizedType ==
"float")
return new RField<float>(fieldName);
132 if (normalizedType ==
"double")
return new RField<double>(fieldName);
133 if (normalizedType ==
"std::string")
return new RField<std::string>(fieldName);
134 if (normalizedType ==
"std::vector<bool>")
return new RField<std::vector<bool>>(fieldName);
135 if (normalizedType.substr(0, 12) ==
"std::vector<") {
136 std::string itemTypeName = normalizedType.substr(12, normalizedType.length() - 13);
137 auto itemField = Create(itemTypeName, itemTypeName);
138 return new RFieldVector(fieldName, std::unique_ptr<Detail::RFieldBase>(itemField));
141 if (normalizedType ==
"ROOT::VecOps::RVec<bool>")
return new RField<ROOT::VecOps::RVec<bool>>(fieldName);
142 if (normalizedType.substr(0, 19) ==
"ROOT::VecOps::RVec<") {
143 std::string itemTypeName = normalizedType.substr(19, normalizedType.length() - 20);
144 auto itemField = Create(itemTypeName, itemTypeName);
145 return new RFieldVector(fieldName, std::unique_ptr<Detail::RFieldBase>(itemField));
147 if (normalizedType.substr(0, 11) ==
"std::array<") {
148 auto arrayDef = TokenizeTypeList(normalizedType.substr(11, normalizedType.length() - 12));
149 R__ASSERT(arrayDef.size() == 2);
150 auto arrayLength = std::stoi(arrayDef[1]);
151 auto itemField = Create(arrayDef[0], arrayDef[0]);
152 return new RFieldArray(fieldName, std::unique_ptr<Detail::RFieldBase>(itemField), arrayLength);
154 #if __cplusplus >= 201703L
155 if (normalizedType.substr(0, 13) ==
"std::variant<") {
156 auto innerTypes = TokenizeTypeList(normalizedType.substr(13, normalizedType.length() - 14));
157 std::vector<RFieldBase *> items;
158 for (
unsigned int i = 0; i < innerTypes.size(); ++i) {
159 items.emplace_back(Create(
"variant" + std::to_string(i), innerTypes[i]));
161 return new RFieldVariant(fieldName, items);
165 if (normalizedType ==
":Collection:")
return new RField<ClusterSize_t>(fieldName);
166 auto cl = TClass::GetClass(normalizedType.c_str());
168 return new RFieldClass(fieldName, normalizedType);
170 R__ERROR_HERE(
"NTuple") <<
"Field " << fieldName <<
" has unknown type " << normalizedType;
175 void ROOT::Experimental::Detail::RFieldBase::DoAppend(
const ROOT::Experimental::Detail::RFieldValue& ) {
179 void ROOT::Experimental::Detail::RFieldBase::DoReadGlobal(
180 ROOT::Experimental::NTupleSize_t ,
186 ROOT::Experimental::Detail::RFieldValue ROOT::Experimental::Detail::RFieldBase::GenerateValue()
188 void *where = malloc(GetValueSize());
189 R__ASSERT(where !=
nullptr);
190 return GenerateValue(where);
193 void ROOT::Experimental::Detail::RFieldBase::DestroyValue(
const RFieldValue &value,
bool dtorOnly)
196 free(value.GetRawPtr());
199 void ROOT::Experimental::Detail::RFieldBase::Attach(
200 std::unique_ptr<ROOT::Experimental::Detail::RFieldBase> child)
202 child->fParent =
this;
203 child->SetOrder(fSubFields.size()+1);
204 fSubFields.emplace_back(std::move(child));
207 void ROOT::Experimental::Detail::RFieldBase::Flush()
const
209 for (
auto& column : fColumns) {
214 void ROOT::Experimental::Detail::RFieldBase::TraverseVisitor(RNTupleVisitor &visitor,
int level)
const
217 this->AcceptVisitor(visitor, level);
219 for (
const auto &fieldPtr: fSubFields) {
220 fieldPtr->TraverseVisitor(visitor, level);
224 void ROOT::Experimental::Detail::RFieldBase::AcceptVisitor(Detail::RNTupleVisitor &visitor,
int level)
const
226 visitor.VisitField(*
this, level);
229 ROOT::Experimental::Detail::RFieldBase::RIterator ROOT::Experimental::Detail::RFieldBase::begin()
231 if (fSubFields.empty())
return RIterator(
this, -1);
232 return RIterator(this->fSubFields[0].
get(), 0);
235 ROOT::Experimental::Detail::RFieldBase::RIterator ROOT::Experimental::Detail::RFieldBase::end()
237 return RIterator(
this, -1);
244 void ROOT::Experimental::Detail::RFieldBase::RIterator::Advance()
246 auto itr = fStack.rbegin();
247 if (!itr->fFieldPtr->fSubFields.empty()) {
248 fStack.emplace_back(Position(itr->fFieldPtr->fSubFields[0].get(), 0));
252 unsigned int nextIdxInParent = ++(itr->fIdxInParent);
253 while (nextIdxInParent >= itr->fFieldPtr->fParent->fSubFields.size()) {
254 if (fStack.size() == 1) {
255 itr->fFieldPtr = itr->fFieldPtr->fParent;
256 itr->fIdxInParent = -1;
260 itr = fStack.rbegin();
261 nextIdxInParent = ++(itr->fIdxInParent);
263 itr->fFieldPtr = itr->fFieldPtr->fParent->fSubFields[nextIdxInParent].get();
270 ROOT::Experimental::Detail::RFieldBase *ROOT::Experimental::RFieldRoot::Clone(std::string_view )
272 Detail::RFieldBase* result =
new RFieldRoot();
273 for (
auto &f : fSubFields) {
274 auto clone = f->Clone(f->GetName());
275 result->Attach(std::unique_ptr<RFieldBase>(clone));
281 ROOT::Experimental::REntry* ROOT::Experimental::RFieldRoot::GenerateEntry()
283 auto entry =
new REntry();
284 for (
auto& f : fSubFields) {
285 entry->AddValue(f->GenerateValue());
290 void ROOT::Experimental::RFieldRoot::AcceptVisitor(Detail::RNTupleVisitor &visitor,
int level)
const
292 visitor.VisitRootField(*
this, level);
299 void ROOT::Experimental::RField<ROOT::Experimental::ClusterSize_t>::DoGenerateColumns()
301 RColumnModel model(EColumnType::kIndex,
true );
302 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
303 Detail::RColumn::Create<ClusterSize_t, EColumnType::kIndex>(model, 0)));
304 fPrincipalColumn = fColumns[0].get();
309 void ROOT::Experimental::RField<std::uint8_t>::DoGenerateColumns()
311 RColumnModel model(EColumnType::kByte,
false );
312 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(Detail::RColumn::Create<
313 std::uint8_t, EColumnType::kByte>(model, 0)));
314 fPrincipalColumn = fColumns[0].get();
321 void ROOT::Experimental::RField<bool>::DoGenerateColumns()
323 RColumnModel model(EColumnType::kBit,
false );
324 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
325 Detail::RColumn::Create<bool, EColumnType::kBit>(model, 0)));
326 fPrincipalColumn = fColumns[0].get();
333 void ROOT::Experimental::RField<float>::DoGenerateColumns()
335 RColumnModel model(EColumnType::kReal32,
false );
336 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
337 Detail::RColumn::Create<float, EColumnType::kReal32>(model, 0)));
338 fPrincipalColumn = fColumns[0].get();
343 void ROOT::Experimental::RField<double>::DoGenerateColumns()
345 RColumnModel model(EColumnType::kReal64,
false );
346 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
347 Detail::RColumn::Create<double, EColumnType::kReal64>(model, 0)));
348 fPrincipalColumn = fColumns[0].get();
354 void ROOT::Experimental::RField<std::int32_t>::DoGenerateColumns()
356 RColumnModel model(EColumnType::kInt32,
false );
357 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(Detail::RColumn::Create<
358 std::int32_t, EColumnType::kInt32>(model, 0)));
359 fPrincipalColumn = fColumns[0].get();
364 void ROOT::Experimental::RField<std::uint32_t>::DoGenerateColumns()
366 RColumnModel model(EColumnType::kInt32,
false );
367 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
368 Detail::RColumn::Create<std::uint32_t, EColumnType::kInt32>(model, 0)));
369 fPrincipalColumn = fColumns[0].get();
374 void ROOT::Experimental::RField<std::uint64_t>::DoGenerateColumns()
376 RColumnModel model(EColumnType::kInt64,
false );
377 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
378 Detail::RColumn::Create<std::uint64_t, EColumnType::kInt64>(model, 0)));
379 fPrincipalColumn = fColumns[0].get();
385 void ROOT::Experimental::RField<std::string>::DoGenerateColumns()
387 RColumnModel modelIndex(EColumnType::kIndex,
true );
388 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
389 Detail::RColumn::Create<ClusterSize_t, EColumnType::kIndex>(modelIndex, 0)));
391 RColumnModel modelChars(EColumnType::kByte,
false );
392 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
393 Detail::RColumn::Create<char, EColumnType::kByte>(modelChars, 1)));
394 fPrincipalColumn = fColumns[0].get();
397 void ROOT::Experimental::RField<std::string>::DoAppend(
const ROOT::Experimental::Detail::RFieldValue& value)
399 auto typedValue = value.Get<std::string>();
400 auto length = typedValue->length();
401 Detail::RColumnElement<char, EColumnType::kByte> elemChars(const_cast<char*>(typedValue->data()));
402 fColumns[1]->AppendV(elemChars, length);
404 fColumns[0]->Append(fElemIndex);
407 void ROOT::Experimental::RField<std::string>::DoReadGlobal(
408 ROOT::Experimental::NTupleSize_t globalIndex, ROOT::Experimental::Detail::RFieldValue *value)
410 auto typedValue = value->Get<std::string>();
411 RClusterIndex collectionStart;
412 ClusterSize_t nChars;
413 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nChars);
414 typedValue->resize(nChars);
415 Detail::RColumnElement<char, EColumnType::kByte> elemChars(const_cast<char*>(typedValue->data()));
416 fColumns[1]->ReadV(collectionStart, nChars, &elemChars);
419 void ROOT::Experimental::RField<std::string>::CommitCluster()
428 ROOT::Experimental::RFieldClass::RFieldClass(std::string_view fieldName, std::string_view className)
429 : ROOT::Experimental::Detail::RFieldBase(fieldName, className, ENTupleStructure::kRecord, false )
430 , fClass(TClass::GetClass(std::string(className).c_str()))
432 if (fClass ==
nullptr) {
433 throw std::runtime_error(
"RField: no I/O support for type " + std::string(className));
435 TIter next(fClass->GetListOfDataMembers());
436 while (
auto dataMember = static_cast<TDataMember *>(next())) {
438 auto subField = Detail::RFieldBase::Create(dataMember->GetName(), dataMember->GetFullTypeName());
439 fMaxAlignment = std::max(fMaxAlignment, subField->GetAlignment());
440 Attach(std::unique_ptr<Detail::RFieldBase>(subField));
444 ROOT::Experimental::Detail::RFieldBase* ROOT::Experimental::RFieldClass::Clone(std::string_view newName)
446 return new RFieldClass(newName, GetType());
449 void ROOT::Experimental::RFieldClass::DoAppend(
const Detail::RFieldValue& value) {
450 TIter next(fClass->GetListOfDataMembers());
452 while (
auto dataMember = static_cast<TDataMember *>(next())) {
453 auto memberValue = fSubFields[i]->CaptureValue(value.Get<
unsigned char>() + dataMember->GetOffset());
454 fSubFields[i]->Append(memberValue);
459 void ROOT::Experimental::RFieldClass::DoReadGlobal(NTupleSize_t globalIndex, Detail::RFieldValue *value)
461 TIter next(fClass->GetListOfDataMembers());
463 while (
auto dataMember = static_cast<TDataMember *>(next())) {
464 auto memberValue = fSubFields[i]->GenerateValue(value->Get<
unsigned char>() + dataMember->GetOffset());
465 fSubFields[i]->Read(globalIndex, &memberValue);
470 void ROOT::Experimental::RFieldClass::DoReadInCluster(
const RClusterIndex &clusterIndex, Detail::RFieldValue *value)
472 TIter next(fClass->GetListOfDataMembers());
474 while (
auto dataMember = static_cast<TDataMember *>(next())) {
475 auto memberValue = fSubFields[i]->GenerateValue(value->Get<
unsigned char>() + dataMember->GetOffset());
476 fSubFields[i]->Read(clusterIndex, &memberValue);
481 void ROOT::Experimental::RFieldClass::DoGenerateColumns()
485 ROOT::Experimental::Detail::RFieldValue ROOT::Experimental::RFieldClass::GenerateValue(
void* where)
487 return Detail::RFieldValue(
true ,
this, fClass->New(where));
490 void ROOT::Experimental::RFieldClass::DestroyValue(
const Detail::RFieldValue& value,
bool dtorOnly)
492 fClass->Destructor(value.GetRawPtr(),
true );
494 free(value.GetRawPtr());
497 ROOT::Experimental::Detail::RFieldValue ROOT::Experimental::RFieldClass::CaptureValue(
void* where)
499 return Detail::RFieldValue(
true ,
this, where);
502 size_t ROOT::Experimental::RFieldClass::GetValueSize()
const
504 return fClass->GetClassSize();
511 ROOT::Experimental::RFieldVector::RFieldVector(
512 std::string_view fieldName, std::unique_ptr<Detail::RFieldBase> itemField)
513 : ROOT::Experimental::Detail::RFieldBase(
514 fieldName,
"std::vector<" + itemField->GetType() +
">", ENTupleStructure::kCollection, false )
515 , fItemSize(itemField->GetValueSize()), fNWritten(0)
517 Attach(std::move(itemField));
520 ROOT::Experimental::Detail::RFieldBase* ROOT::Experimental::RFieldVector::Clone(std::string_view newName)
522 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetName());
523 return new RFieldVector(newName, std::unique_ptr<Detail::RFieldBase>(newItemField));
526 void ROOT::Experimental::RFieldVector::DoAppend(
const Detail::RFieldValue& value) {
527 auto typedValue = value.Get<std::vector<char>>();
528 R__ASSERT((typedValue->size() % fItemSize) == 0);
529 auto count = typedValue->size() / fItemSize;
530 for (
unsigned i = 0; i < count; ++i) {
531 auto itemValue = fSubFields[0]->CaptureValue(typedValue->data() + (i * fItemSize));
532 fSubFields[0]->Append(itemValue);
534 Detail::RColumnElement<ClusterSize_t, EColumnType::kIndex> elemIndex(&fNWritten);
536 fColumns[0]->Append(elemIndex);
539 void ROOT::Experimental::RFieldVector::DoReadGlobal(NTupleSize_t globalIndex, Detail::RFieldValue *value)
541 auto typedValue = value->Get<std::vector<char>>();
543 ClusterSize_t nItems;
544 RClusterIndex collectionStart;
545 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
547 typedValue->resize(nItems * fItemSize);
548 for (
unsigned i = 0; i < nItems; ++i) {
549 auto itemValue = fSubFields[0]->GenerateValue(typedValue->data() + (i * fItemSize));
550 fSubFields[0]->Read(collectionStart + i, &itemValue);
554 void ROOT::Experimental::RFieldVector::DoGenerateColumns()
556 RColumnModel modelIndex(EColumnType::kIndex,
true );
557 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
558 Detail::RColumn::Create<ClusterSize_t, EColumnType::kIndex>(modelIndex, 0)));
559 fPrincipalColumn = fColumns[0].get();
562 ROOT::Experimental::Detail::RFieldValue ROOT::Experimental::RFieldVector::GenerateValue(
void* where)
564 return Detail::RFieldValue(
this,
reinterpret_cast<std::vector<char>*
>(where));
567 void ROOT::Experimental::RFieldVector::DestroyValue(
const Detail::RFieldValue& value,
bool dtorOnly)
569 auto vec =
static_cast<std::vector<char>*
>(value.GetRawPtr());
570 R__ASSERT((vec->size() % fItemSize) == 0);
571 auto nItems = vec->size() / fItemSize;
572 for (
unsigned i = 0; i < nItems; ++i) {
573 auto itemValue = fSubFields[0]->CaptureValue(vec->data() + (i * fItemSize));
574 fSubFields[0]->DestroyValue(itemValue,
true );
581 ROOT::Experimental::Detail::RFieldValue ROOT::Experimental::RFieldVector::CaptureValue(
void* where)
583 return Detail::RFieldValue(
true ,
this, where);
586 void ROOT::Experimental::RFieldVector::CommitCluster()
595 ROOT::Experimental::RField<std::vector<bool>>::RField(std::string_view name)
596 : ROOT::Experimental::Detail::RFieldBase(name,
"std::vector<bool>", ENTupleStructure::kCollection,
599 Attach(std::make_unique<RField<bool>>(
"bool"));
602 void ROOT::Experimental::RField<std::vector<bool>>::DoAppend(
const Detail::RFieldValue& value) {
603 auto typedValue = value.Get<std::vector<bool>>();
604 auto count = typedValue->size();
605 for (
unsigned i = 0; i < count; ++i) {
606 bool bval = (*typedValue)[i];
607 auto itemValue = fSubFields[0]->CaptureValue(&bval);
608 fSubFields[0]->Append(itemValue);
610 Detail::RColumnElement<ClusterSize_t, EColumnType::kIndex> elemIndex(&fNWritten);
612 fColumns[0]->Append(elemIndex);
615 void ROOT::Experimental::RField<std::vector<bool>>::DoReadGlobal(NTupleSize_t globalIndex, Detail::RFieldValue* value)
617 auto typedValue = value->Get<std::vector<bool>>();
619 ClusterSize_t nItems;
620 RClusterIndex collectionStart;
621 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
623 typedValue->resize(nItems);
624 for (
unsigned i = 0; i < nItems; ++i) {
626 auto itemValue = fSubFields[0]->GenerateValue(&bval);
627 fSubFields[0]->Read(collectionStart + i, &itemValue);
628 (*typedValue)[i] = bval;
632 void ROOT::Experimental::RField<std::vector<bool>>::DoGenerateColumns()
634 RColumnModel modelIndex(EColumnType::kIndex,
true );
635 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
636 Detail::RColumn::Create<ClusterSize_t, EColumnType::kIndex>(modelIndex, 0)));
637 fPrincipalColumn = fColumns[0].get();
640 void ROOT::Experimental::RField<std::vector<bool>>::DestroyValue(
const Detail::RFieldValue& value,
bool dtorOnly)
642 auto vec =
static_cast<std::vector<bool>*
>(value.GetRawPtr());
652 ROOT::Experimental::RFieldArray::RFieldArray(
653 std::string_view fieldName, std::unique_ptr<Detail::RFieldBase> itemField, std::size_t arrayLength)
654 : ROOT::Experimental::Detail::RFieldBase(
655 fieldName,
"std::array<" + itemField->GetType() +
"," + std::to_string(arrayLength) +
">",
656 ENTupleStructure::kLeaf, false , arrayLength)
657 , fItemSize(itemField->GetValueSize()), fArrayLength(arrayLength)
659 Attach(std::move(itemField));
662 ROOT::Experimental::Detail::RFieldBase *ROOT::Experimental::RFieldArray::Clone(std::string_view newName)
664 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetName());
665 return new RFieldArray(newName, std::unique_ptr<Detail::RFieldBase>(newItemField), fArrayLength);
668 void ROOT::Experimental::RFieldArray::DoAppend(
const Detail::RFieldValue& value) {
669 auto arrayPtr = value.Get<
unsigned char>();
670 for (
unsigned i = 0; i < fArrayLength; ++i) {
671 auto itemValue = fSubFields[0]->CaptureValue(arrayPtr + (i * fItemSize));
672 fSubFields[0]->Append(itemValue);
676 void ROOT::Experimental::RFieldArray::DoReadGlobal(NTupleSize_t globalIndex, Detail::RFieldValue *value)
678 auto arrayPtr = value->Get<
unsigned char>();
679 for (
unsigned i = 0; i < fArrayLength; ++i) {
680 auto itemValue = fSubFields[0]->GenerateValue(arrayPtr + (i * fItemSize));
681 fSubFields[0]->Read(globalIndex * fArrayLength + i, &itemValue);
685 void ROOT::Experimental::RFieldArray::DoReadInCluster(
const RClusterIndex &clusterIndex, Detail::RFieldValue *value)
687 auto arrayPtr = value->Get<
unsigned char>();
688 for (
unsigned i = 0; i < fArrayLength; ++i) {
689 auto itemValue = fSubFields[0]->GenerateValue(arrayPtr + (i * fItemSize));
690 fSubFields[0]->Read(RClusterIndex(clusterIndex.GetClusterId(), clusterIndex.GetIndex() * fArrayLength + i),
695 void ROOT::Experimental::RFieldArray::DoGenerateColumns()
699 ROOT::Experimental::Detail::RFieldValue ROOT::Experimental::RFieldArray::GenerateValue(
void *where)
701 auto arrayPtr =
reinterpret_cast<unsigned char *
>(where);
702 for (
unsigned i = 0; i < fArrayLength; ++i) {
703 fSubFields[0]->GenerateValue(arrayPtr + (i * fItemSize));
705 return Detail::RFieldValue(
true ,
this, where);
708 void ROOT::Experimental::RFieldArray::DestroyValue(
const Detail::RFieldValue& value,
bool dtorOnly)
710 auto arrayPtr = value.Get<
unsigned char>();
711 for (
unsigned i = 0; i < fArrayLength; ++i) {
712 auto itemValue = fSubFields[0]->CaptureValue(arrayPtr + (i * fItemSize));
713 fSubFields[0]->DestroyValue(itemValue,
true );
719 ROOT::Experimental::Detail::RFieldValue ROOT::Experimental::RFieldArray::CaptureValue(
void *where)
721 return Detail::RFieldValue(
true ,
this, where);
727 #if __cplusplus >= 201703L
728 std::string ROOT::Experimental::RFieldVariant::GetTypeList(
const std::vector<Detail::RFieldBase *> &itemFields)
731 for (
size_t i = 0; i < itemFields.size(); ++i) {
732 result += itemFields[i]->GetType() +
",";
734 R__ASSERT(!result.empty());
739 ROOT::Experimental::RFieldVariant::RFieldVariant(
740 std::string_view fieldName,
const std::vector<Detail::RFieldBase *> &itemFields)
741 : ROOT::Experimental::Detail::RFieldBase(fieldName,
742 "std::variant<" + GetTypeList(itemFields) +
">", ENTupleStructure::kVariant, false )
744 auto nFields = itemFields.size();
745 R__ASSERT(nFields > 0);
746 fNWritten.resize(nFields, 0);
747 for (
unsigned int i = 0; i < nFields; ++i) {
748 fMaxItemSize = std::max(fMaxItemSize, itemFields[i]->GetValueSize());
749 fMaxAlignment = std::max(fMaxAlignment, itemFields[i]->GetAlignment());
750 Attach(std::unique_ptr<Detail::RFieldBase>(itemFields[i]));
752 fTagOffset = (fMaxItemSize < fMaxAlignment) ? fMaxAlignment : fMaxItemSize;
755 ROOT::Experimental::Detail::RFieldBase *ROOT::Experimental::RFieldVariant::Clone(std::string_view newName)
757 auto nFields = fSubFields.size();
758 std::vector<Detail::RFieldBase *> itemFields;
759 for (
unsigned i = 0; i < nFields; ++i) {
760 itemFields.emplace_back(fSubFields[i]->Clone(fSubFields[i]->GetName()));
762 return new RFieldVariant(newName, itemFields);
765 std::uint32_t ROOT::Experimental::RFieldVariant::GetTag(
void *variantPtr)
const
767 auto index = *(
reinterpret_cast<char *
>(variantPtr) + fTagOffset);
768 return (index < 0) ? 0 : index + 1;
771 void ROOT::Experimental::RFieldVariant::SetTag(
void *variantPtr, std::uint32_t tag)
const
773 auto index =
reinterpret_cast<char *
>(variantPtr) + fTagOffset;
774 *index =
static_cast<char>(tag - 1);
777 void ROOT::Experimental::RFieldVariant::DoAppend(
const Detail::RFieldValue& value)
779 auto tag = GetTag(value.GetRawPtr());
782 auto itemValue = fSubFields[tag - 1]->CaptureValue(value.GetRawPtr());
783 fSubFields[tag - 1]->Append(itemValue);
784 index = fNWritten[tag - 1]++;
786 RColumnSwitch varSwitch(ClusterSize_t(index), tag);
787 Detail::RColumnElement<RColumnSwitch, EColumnType::kSwitch> elemSwitch(&varSwitch);
788 fColumns[0]->Append(elemSwitch);
791 void ROOT::Experimental::RFieldVariant::DoReadGlobal(NTupleSize_t globalIndex, Detail::RFieldValue *value)
793 RClusterIndex variantIndex;
795 fPrincipalColumn->GetSwitchInfo(globalIndex, &variantIndex, &tag);
798 auto itemValue = fSubFields[tag - 1]->GenerateValue(value->GetRawPtr());
799 fSubFields[tag - 1]->Read(variantIndex, &itemValue);
800 SetTag(value->GetRawPtr(), tag);
803 void ROOT::Experimental::RFieldVariant::DoGenerateColumns()
805 RColumnModel modelSwitch(EColumnType::kSwitch,
false);
806 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
807 Detail::RColumn::Create<RColumnSwitch, EColumnType::kSwitch>(modelSwitch, 0)));
808 fPrincipalColumn = fColumns[0].get();
811 ROOT::Experimental::Detail::RFieldValue ROOT::Experimental::RFieldVariant::GenerateValue(
void *where)
813 memset(where, 0, GetValueSize());
814 fSubFields[0]->GenerateValue(where);
816 return Detail::RFieldValue(
this, reinterpret_cast<unsigned char *>(where));
819 void ROOT::Experimental::RFieldVariant::DestroyValue(
const Detail::RFieldValue& value,
bool dtorOnly)
821 auto variantPtr = value.GetRawPtr();
822 auto tag = GetTag(variantPtr);
824 auto itemValue = fSubFields[tag - 1]->CaptureValue(variantPtr);
825 fSubFields[tag - 1]->DestroyValue(itemValue,
true );
831 ROOT::Experimental::Detail::RFieldValue ROOT::Experimental::RFieldVariant::CaptureValue(
void *where)
833 return Detail::RFieldValue(
true ,
this, where);
836 size_t ROOT::Experimental::RFieldVariant::GetValueSize()
const
838 return fMaxItemSize + fMaxAlignment;
841 void ROOT::Experimental::RFieldVariant::CommitCluster()
843 std::fill(fNWritten.begin(), fNWritten.end(), 0);
851 ROOT::Experimental::RFieldCollection::RFieldCollection(
852 std::string_view name,
853 std::shared_ptr<RCollectionNTuple> collectionNTuple,
854 std::unique_ptr<RNTupleModel> collectionModel)
855 : RFieldBase(name,
":Collection:", ENTupleStructure::kCollection, true )
856 , fCollectionNTuple(collectionNTuple)
858 for (
unsigned i = 0; i < collectionModel->GetRootField()->fSubFields.size(); ++i) {
859 auto& subField = collectionModel->GetRootField()->fSubFields[i];
860 Attach(std::move(subField));
865 void ROOT::Experimental::RFieldCollection::DoGenerateColumns()
867 RColumnModel modelIndex(EColumnType::kIndex,
true );
868 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
869 Detail::RColumn::Create<ClusterSize_t, EColumnType::kIndex>(modelIndex, 0)));
870 fPrincipalColumn = fColumns[0].get();
874 ROOT::Experimental::Detail::RFieldBase* ROOT::Experimental::RFieldCollection::Clone(std::string_view )
888 void ROOT::Experimental::RFieldCollection::CommitCluster() {
889 *fCollectionNTuple->GetOffsetPtr() = 0;