Logo ROOT  
Reference Guide
RField.cxx
Go to the documentation of this file.
1 /// \file RField.cxx
2 /// \ingroup NTuple ROOT7
3 /// \author Jakob Blomer <jblomer@cern.ch>
4 /// \date 2018-10-15
5 /// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
6 /// is welcome!
7 
8 /*************************************************************************
9  * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
10  * All rights reserved. *
11  * *
12  * For the licensing terms see $ROOTSYS/LICENSE. *
13  * For the list of contributors see $ROOTSYS/README/CREDITS. *
14  *************************************************************************/
15 
16 #include <ROOT/RColumn.hxx>
17 #include <ROOT/RColumnModel.hxx>
18 #include <ROOT/REntry.hxx>
19 #include <ROOT/RError.hxx>
20 #include <ROOT/RField.hxx>
21 #include <ROOT/RFieldValue.hxx>
22 #include <ROOT/RFieldVisitor.hxx>
23 #include <ROOT/RLogger.hxx>
24 #include <ROOT/RNTuple.hxx>
25 #include <ROOT/RNTupleModel.hxx>
26 
27 #include <TClass.h>
28 #include <TCollection.h>
29 #include <TDataMember.h>
30 #include <TError.h>
31 #include <TList.h>
32 
33 #include <algorithm>
34 #include <cctype> // for isspace
35 #include <cstdlib> // for malloc, free
36 #include <cstring> // for memset
37 #include <exception>
38 #include <iostream>
39 #include <type_traits>
40 
41 namespace {
42 
43 /// Used in CreateField() in order to get the comma-separated list of template types
44 /// E.g., gets {"int", "std::variant<double,int>"} from "int,std::variant<double,int>"
45 std::vector<std::string> TokenizeTypeList(std::string templateType) {
46  std::vector<std::string> result;
47  if (templateType.empty())
48  return result;
49 
50  const char *eol = templateType.data() + templateType.length();
51  const char *typeBegin = templateType.data();
52  const char *typeCursor = templateType.data();
53  unsigned int nestingLevel = 0;
54  while (typeCursor != eol) {
55  switch (*typeCursor) {
56  case '<':
57  ++nestingLevel;
58  break;
59  case '>':
60  --nestingLevel;
61  break;
62  case ',':
63  if (nestingLevel == 0) {
64  result.push_back(std::string(typeBegin, typeCursor - typeBegin));
65  typeBegin = typeCursor + 1;
66  }
67  break;
68  }
69  typeCursor++;
70  }
71  result.push_back(std::string(typeBegin, typeCursor - typeBegin));
72  return result;
73 }
74 
75 /// Remove leading and trailing white spaces
76 std::string Trim(const std::string &raw) {
77  if (raw.empty()) return "";
78 
79  unsigned start_pos = 0;
80  for (; (start_pos < raw.length()) && (raw[start_pos] == ' ' || raw[start_pos] == '\t'); ++start_pos) { }
81 
82  unsigned end_pos = raw.length() - 1; // at least one character in raw
83  for (; (end_pos >= start_pos) && (raw[end_pos] == ' ' || raw[end_pos] == '\t'); --end_pos) { }
84 
85  return raw.substr(start_pos, end_pos - start_pos + 1);
86 }
87 
88 std::string GetNormalizedType(const std::string &typeName) {
89  std::string normalizedType(Trim(typeName));
90  // TODO(jblomer): use a type translation map
91  if (normalizedType == "Bool_t") normalizedType = "bool";
92  if (normalizedType == "Float_t") normalizedType = "float";
93  if (normalizedType == "Double_t") normalizedType = "double";
94  if (normalizedType == "UChar_t") normalizedType = "std::uint8_t";
95  if (normalizedType == "unsigned char") normalizedType = "std::uint8_t";
96  if (normalizedType == "uint8_t") normalizedType = "std::uint8_t";
97  if (normalizedType == "Int_t") normalizedType = "std::int32_t";
98  if (normalizedType == "int") normalizedType = "std::int32_t";
99  if (normalizedType == "int32_t") normalizedType = "std::int32_t";
100  if (normalizedType == "unsigned") normalizedType = "std::uint32_t";
101  if (normalizedType == "unsigned int") normalizedType = "std::uint32_t";
102  if (normalizedType == "UInt_t") normalizedType = "std::uint32_t";
103  if (normalizedType == "uint32_t") normalizedType = "std::uint32_t";
104  if (normalizedType == "ULong64_t") normalizedType = "std::uint64_t";
105  if (normalizedType == "uint64_t") normalizedType = "std::uint64_t";
106  if (normalizedType == "string") normalizedType = "std::string";
107  if (normalizedType.substr(0, 7) == "vector<") normalizedType = "std::" + normalizedType;
108  if (normalizedType.substr(0, 6) == "array<") normalizedType = "std::" + normalizedType;
109  if (normalizedType.substr(0, 8) == "variant<") normalizedType = "std::" + normalizedType;
110 
111  return normalizedType;
112 }
113 
114 } // anonymous namespace
115 
117 {
118  if (field.fColumns.empty())
119  field.GenerateColumnsImpl();
120  for (auto& column : field.fColumns)
121  column->Connect(fieldId, &pageStorage);
122 }
123 
124 
125 //------------------------------------------------------------------------------
126 
127 
129  std::string_view name, std::string_view type, ENTupleStructure structure, bool isSimple, std::size_t nRepetitions)
130  : fName(name), fType(type), fStructure(structure), fNRepetitions(nRepetitions), fIsSimple(isSimple),
131  fParent(nullptr), fPrincipalColumn(nullptr)
132 {
133 }
134 
136 {
137 }
138 
140 ROOT::Experimental::Detail::RFieldBase::Create(const std::string &fieldName, const std::string &typeName)
141 {
142  std::string normalizedType(GetNormalizedType(typeName));
143 
144  if (normalizedType == "ROOT::Experimental::ClusterSize_t") return new RField<ClusterSize_t>(fieldName);
145  if (normalizedType == "bool") return new RField<bool>(fieldName);
146  if (normalizedType == "std::uint8_t") return new RField<std::uint8_t>(fieldName);
147  if (normalizedType == "std::int32_t") return new RField<std::int32_t>(fieldName);
148  if (normalizedType == "std::uint32_t") return new RField<std::uint32_t>(fieldName);
149  if (normalizedType == "std::uint64_t") return new RField<std::uint64_t>(fieldName);
150  if (normalizedType == "float") return new RField<float>(fieldName);
151  if (normalizedType == "double") return new RField<double>(fieldName);
152  if (normalizedType == "std::string") return new RField<std::string>(fieldName);
153  if (normalizedType == "std::vector<bool>") return new RField<std::vector<bool>>(fieldName);
154  if (normalizedType.substr(0, 12) == "std::vector<") {
155  std::string itemTypeName = normalizedType.substr(12, normalizedType.length() - 13);
156  auto itemField = Create(GetNormalizedType(itemTypeName), itemTypeName);
157  return new RVectorField(fieldName, std::unique_ptr<Detail::RFieldBase>(itemField));
158  }
159  // For the time being, we silently read RVec fields as std::vector
160  if (normalizedType == "ROOT::VecOps::RVec<bool>") return new RField<ROOT::VecOps::RVec<bool>>(fieldName);
161  if (normalizedType.substr(0, 19) == "ROOT::VecOps::RVec<") {
162  std::string itemTypeName = normalizedType.substr(19, normalizedType.length() - 20);
163  auto itemField = Create(GetNormalizedType(itemTypeName), itemTypeName);
164  return new RVectorField(fieldName, std::unique_ptr<Detail::RFieldBase>(itemField));
165  }
166  if (normalizedType.substr(0, 11) == "std::array<") {
167  auto arrayDef = TokenizeTypeList(normalizedType.substr(11, normalizedType.length() - 12));
168  R__ASSERT(arrayDef.size() == 2);
169  auto arrayLength = std::stoi(arrayDef[1]);
170  auto itemField = Create(GetNormalizedType(arrayDef[0]), arrayDef[0]);
171  return new RArrayField(fieldName, std::unique_ptr<Detail::RFieldBase>(itemField), arrayLength);
172  }
173 #if __cplusplus >= 201703L
174  if (normalizedType.substr(0, 13) == "std::variant<") {
175  auto innerTypes = TokenizeTypeList(normalizedType.substr(13, normalizedType.length() - 14));
176  std::vector<RFieldBase *> items;
177  for (unsigned int i = 0; i < innerTypes.size(); ++i) {
178  items.emplace_back(Create("variant" + std::to_string(i), innerTypes[i]));
179  }
180  return new RVariantField(fieldName, items);
181  }
182 #endif
183  // TODO: create an RCollectionField?
184  if (normalizedType == ":Collection:") return new RField<ClusterSize_t>(fieldName);
185  auto cl = TClass::GetClass(normalizedType.c_str());
186  if (cl != nullptr) {
187  return new RClassField(fieldName, normalizedType);
188  }
189  R__ERROR_HERE("NTuple") << "Field " << fieldName << " has unknown type " << normalizedType;
190  R__ASSERT(false);
191  return nullptr;
192 }
193 
196 {
197  if (fieldName == "") {
198  return R__FAIL("field name cannot be empty string \"\"");
199  } else if (fieldName.find(".") != std::string::npos) {
200  return R__FAIL("field name '" + std::string(fieldName) + "' cannot contain dot characters '.'");
201  }
202  return RResult<void>::Success();
203 }
204 
206  R__ASSERT(false);
207 }
208 
211  RFieldValue* /*value*/)
212 {
213  R__ASSERT(false);
214 }
215 
217 {
218  void *where = malloc(GetValueSize());
219  R__ASSERT(where != nullptr);
220  return GenerateValue(where);
221 }
222 
224 {
225  if (!dtorOnly)
226  free(value.GetRawPtr());
227 }
228 
229 std::vector<ROOT::Experimental::Detail::RFieldValue>
231 {
232  return std::vector<RFieldValue>();
233 }
234 
236  std::unique_ptr<ROOT::Experimental::Detail::RFieldBase> child)
237 {
238  child->fParent = this;
239  fSubFields.emplace_back(std::move(child));
240 }
241 
242 
243 std::vector<const ROOT::Experimental::Detail::RFieldBase *>
245 {
246  std::vector<const RFieldBase *> result;
247  for (const auto &f : fSubFields) {
248  result.emplace_back(f.get());
249  }
250  return result;
251 }
252 
253 
255 {
256  for (auto& column : fColumns) {
257  column->Flush();
258  }
259 }
260 
261 
263 {
264  visitor.VisitField(*this);
265 }
266 
267 
269 {
270  if (fSubFields.empty()) return RSchemaIterator(this, -1);
271  return RSchemaIterator(this->fSubFields[0].get(), 0);
272 }
273 
274 
276 {
277  return RSchemaIterator(this, -1);
278 }
279 
280 
281 //-----------------------------------------------------------------------------
282 
283 
285 {
286  auto itr = fStack.rbegin();
287  if (!itr->fFieldPtr->fSubFields.empty()) {
288  fStack.emplace_back(Position(itr->fFieldPtr->fSubFields[0].get(), 0));
289  return;
290  }
291 
292  unsigned int nextIdxInParent = ++(itr->fIdxInParent);
293  while (nextIdxInParent >= itr->fFieldPtr->fParent->fSubFields.size()) {
294  if (fStack.size() == 1) {
295  itr->fFieldPtr = itr->fFieldPtr->fParent;
296  itr->fIdxInParent = -1;
297  return;
298  }
299  fStack.pop_back();
300  itr = fStack.rbegin();
301  nextIdxInParent = ++(itr->fIdxInParent);
302  }
303  itr->fFieldPtr = itr->fFieldPtr->fParent->fSubFields[nextIdxInParent].get();
304 }
305 
306 
307 //------------------------------------------------------------------------------
308 
309 
311 {
312  Detail::RFieldBase* result = new RFieldZero();
313  for (auto &f : fSubFields) {
314  auto clone = f->Clone(f->GetName());
315  result->Attach(std::unique_ptr<RFieldBase>(clone));
316  }
317  return result;
318 }
319 
320 
322 {
323  auto entry = new REntry();
324  for (auto& f : fSubFields) {
325  entry->AddValue(f->GenerateValue());
326  }
327  return entry;
328 }
329 
331 {
332  visitor.VisitFieldZero(*this);
333 }
334 
335 
336 //------------------------------------------------------------------------------
337 
338 
340 {
341  RColumnModel model(EColumnType::kIndex, true /* isSorted*/);
342  fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
343  Detail::RColumn::Create<ClusterSize_t, EColumnType::kIndex>(model, 0)));
344  fPrincipalColumn = fColumns[0].get();
345 }
346 
348 {
349  visitor.VisitClusterSizeField(*this);
350 }
351 
352 //------------------------------------------------------------------------------
353 
355 {
356  RColumnModel model(EColumnType::kByte, false /* isSorted*/);
357  fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(Detail::RColumn::Create<
359  fPrincipalColumn = fColumns[0].get();
360 }
361 
362 void ROOT::Experimental::RField<std::uint8_t>::AcceptVisitor(Detail::RFieldVisitor &visitor) const
363 {
364  visitor.VisitUInt8Field(*this);
365 }
366 
367 //------------------------------------------------------------------------------
368 
369 
371 {
372  RColumnModel model(EColumnType::kBit, false /* isSorted*/);
373  fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
374  Detail::RColumn::Create<bool, EColumnType::kBit>(model, 0)));
375  fPrincipalColumn = fColumns[0].get();
376 }
377 
379 {
380  visitor.VisitBoolField(*this);
381 }
382 
383 //------------------------------------------------------------------------------
384 
385 
387 {
388  RColumnModel model(EColumnType::kReal32, false /* isSorted*/);
389  fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
390  Detail::RColumn::Create<float, EColumnType::kReal32>(model, 0)));
391  fPrincipalColumn = fColumns[0].get();
392 }
393 
395 {
396  visitor.VisitFloatField(*this);
397 }
398 
399 
400 //------------------------------------------------------------------------------
401 
403 {
404  RColumnModel model(EColumnType::kReal64, false /* isSorted*/);
405  fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
406  Detail::RColumn::Create<double, EColumnType::kReal64>(model, 0)));
407  fPrincipalColumn = fColumns[0].get();
408 }
409 
411 {
412  visitor.VisitDoubleField(*this);
413 }
414 
415 //------------------------------------------------------------------------------
416 
418 {
419  RColumnModel model(EColumnType::kInt32, false /* isSorted*/);
420  fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(Detail::RColumn::Create<
421  std::int32_t, EColumnType::kInt32>(model, 0)));
422  fPrincipalColumn = fColumns[0].get();
423 }
424 
425 void ROOT::Experimental::RField<std::int32_t>::AcceptVisitor(Detail::RFieldVisitor &visitor) const
426 {
427  visitor.VisitIntField(*this);
428 }
429 
430 //------------------------------------------------------------------------------
431 
433 {
434  RColumnModel model(EColumnType::kInt32, false /* isSorted*/);
435  fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
436  Detail::RColumn::Create<std::uint32_t, EColumnType::kInt32>(model, 0)));
437  fPrincipalColumn = fColumns[0].get();
438 }
439 
440 void ROOT::Experimental::RField<std::uint32_t>::AcceptVisitor(Detail::RFieldVisitor &visitor) const
441 {
442  visitor.VisitUInt32Field(*this);
443 }
444 
445 //------------------------------------------------------------------------------
446 
448 {
449  RColumnModel model(EColumnType::kInt64, false /* isSorted*/);
450  fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
451  Detail::RColumn::Create<std::uint64_t, EColumnType::kInt64>(model, 0)));
452  fPrincipalColumn = fColumns[0].get();
453 }
454 
455 void ROOT::Experimental::RField<std::uint64_t>::AcceptVisitor(Detail::RFieldVisitor &visitor) const
456 {
457  visitor.VisitUInt64Field(*this);
458 }
459 
460 //------------------------------------------------------------------------------
461 
462 
464 {
465  RColumnModel modelIndex(EColumnType::kIndex, true /* isSorted*/);
466  fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
467  Detail::RColumn::Create<ClusterSize_t, EColumnType::kIndex>(modelIndex, 0)));
468 
469  RColumnModel modelChars(EColumnType::kByte, false /* isSorted*/);
470  fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
471  Detail::RColumn::Create<char, EColumnType::kByte>(modelChars, 1)));
472  fPrincipalColumn = fColumns[0].get();
473 }
474 
476 {
477  auto typedValue = value.Get<std::string>();
478  auto length = typedValue->length();
479  Detail::RColumnElement<char, EColumnType::kByte> elemChars(const_cast<char*>(typedValue->data()));
480  fColumns[1]->AppendV(elemChars, length);
481  fIndex += length;
482  fColumns[0]->Append(fElemIndex);
483 }
484 
487 {
488  auto typedValue = value->Get<std::string>();
489  RClusterIndex collectionStart;
490  ClusterSize_t nChars;
491  fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nChars);
492  if (nChars == 0) {
493  typedValue->clear();
494  } else {
495  typedValue->resize(nChars);
496  Detail::RColumnElement<char, EColumnType::kByte> elemChars(const_cast<char*>(typedValue->data()));
497  fColumns[1]->ReadV(collectionStart, nChars, &elemChars);
498  }
499 }
500 
502 {
503  fIndex = 0;
504 }
505 
506 void ROOT::Experimental::RField<std::string>::AcceptVisitor(Detail::RFieldVisitor &visitor) const
507 {
508  visitor.VisitStringField(*this);
509 }
510 
511 //------------------------------------------------------------------------------
512 
513 
515  : ROOT::Experimental::Detail::RFieldBase(fieldName, className, ENTupleStructure::kRecord, false /* isSimple */)
516  , fClass(TClass::GetClass(std::string(className).c_str()))
517 {
518  if (fClass == nullptr) {
519  throw std::runtime_error("RField: no I/O support for type " + std::string(className));
520  }
522  while (auto dataMember = static_cast<TDataMember *>(next())) {
523  //printf("Now looking at %s %s\n", dataMember->GetName(), dataMember->GetFullTypeName());
524  auto subField = Detail::RFieldBase::Create(dataMember->GetName(), dataMember->GetFullTypeName());
525  fMaxAlignment = std::max(fMaxAlignment, subField->GetAlignment());
526  Attach(std::unique_ptr<Detail::RFieldBase>(subField));
527  }
528 }
529 
531 {
532  return new RClassField(newName, GetType());
533 }
534 
536  TIter next(fClass->GetListOfDataMembers());
537  unsigned i = 0;
538  while (auto dataMember = static_cast<TDataMember *>(next())) {
539  auto memberValue = fSubFields[i]->CaptureValue(value.Get<unsigned char>() + dataMember->GetOffset());
540  fSubFields[i]->Append(memberValue);
541  i++;
542  }
543 }
544 
546 {
547  TIter next(fClass->GetListOfDataMembers());
548  unsigned i = 0;
549  while (auto dataMember = static_cast<TDataMember *>(next())) {
550  auto memberValue = fSubFields[i]->GenerateValue(value->Get<unsigned char>() + dataMember->GetOffset());
551  fSubFields[i]->Read(globalIndex, &memberValue);
552  i++;
553  }
554 }
555 
557 {
558  TIter next(fClass->GetListOfDataMembers());
559  unsigned i = 0;
560  while (auto dataMember = static_cast<TDataMember *>(next())) {
561  auto memberValue = fSubFields[i]->GenerateValue(value->Get<unsigned char>() + dataMember->GetOffset());
562  fSubFields[i]->Read(clusterIndex, &memberValue);
563  i++;
564  }
565 }
566 
568 {
569 }
570 
572 {
573  return Detail::RFieldValue(true /* captureFlag */, this, fClass->New(where));
574 }
575 
577 {
578  fClass->Destructor(value.GetRawPtr(), true /* dtorOnly */);
579  if (!dtorOnly)
580  free(value.GetRawPtr());
581 }
582 
584 {
585  return Detail::RFieldValue(true /* captureFlat */, this, where);
586 }
587 
588 
589 std::vector<ROOT::Experimental::Detail::RFieldValue>
591 {
592  TIter next(fClass->GetListOfDataMembers());
593  unsigned i = 0;
594  std::vector<Detail::RFieldValue> result;
595  while (auto dataMember = static_cast<TDataMember *>(next())) {
596  auto memberValue = fSubFields[i]->CaptureValue(value.Get<unsigned char>() + dataMember->GetOffset());
597  result.emplace_back(memberValue);
598  i++;
599  }
600  return result;
601 }
602 
603 
605 {
606  return fClass->GetClassSize();
607 }
608 
610 {
611  visitor.VisitClassField(*this);
612 }
613 
614 //------------------------------------------------------------------------------
615 
616 
618  std::string_view fieldName, std::unique_ptr<Detail::RFieldBase> itemField)
619  : ROOT::Experimental::Detail::RFieldBase(
620  fieldName, "std::vector<" + itemField->GetType() + ">", ENTupleStructure::kCollection, false /* isSimple */)
621  , fItemSize(itemField->GetValueSize()), fNWritten(0)
622 {
623  Attach(std::move(itemField));
624 }
625 
627 {
628  auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetName());
629  return new RVectorField(newName, std::unique_ptr<Detail::RFieldBase>(newItemField));
630 }
631 
633  auto typedValue = value.Get<std::vector<char>>();
634  R__ASSERT((typedValue->size() % fItemSize) == 0);
635  auto count = typedValue->size() / fItemSize;
636  for (unsigned i = 0; i < count; ++i) {
637  auto itemValue = fSubFields[0]->CaptureValue(typedValue->data() + (i * fItemSize));
638  fSubFields[0]->Append(itemValue);
639  }
641  fNWritten += count;
642  fColumns[0]->Append(elemIndex);
643 }
644 
646 {
647  auto typedValue = value->Get<std::vector<char>>();
648 
649  ClusterSize_t nItems;
650  RClusterIndex collectionStart;
651  fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
652 
653  typedValue->resize(nItems * fItemSize);
654  for (unsigned i = 0; i < nItems; ++i) {
655  auto itemValue = fSubFields[0]->GenerateValue(typedValue->data() + (i * fItemSize));
656  fSubFields[0]->Read(collectionStart + i, &itemValue);
657  }
658 }
659 
661 {
662  RColumnModel modelIndex(EColumnType::kIndex, true /* isSorted*/);
663  fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
664  Detail::RColumn::Create<ClusterSize_t, EColumnType::kIndex>(modelIndex, 0)));
665  fPrincipalColumn = fColumns[0].get();
666 }
667 
669 {
670  return Detail::RFieldValue(this, reinterpret_cast<std::vector<char>*>(where));
671 }
672 
674 {
675  auto vec = static_cast<std::vector<char>*>(value.GetRawPtr());
676  R__ASSERT((vec->size() % fItemSize) == 0);
677  auto nItems = vec->size() / fItemSize;
678  for (unsigned i = 0; i < nItems; ++i) {
679  auto itemValue = fSubFields[0]->CaptureValue(vec->data() + (i * fItemSize));
680  fSubFields[0]->DestroyValue(itemValue, true /* dtorOnly */);
681  }
682  vec->~vector();
683  if (!dtorOnly)
684  free(vec);
685 }
686 
688 {
689  return Detail::RFieldValue(true /* captureFlag */, this, where);
690 }
691 
692 std::vector<ROOT::Experimental::Detail::RFieldValue>
694 {
695  auto vec = static_cast<std::vector<char>*>(value.GetRawPtr());
696  R__ASSERT((vec->size() % fItemSize) == 0);
697  auto nItems = vec->size() / fItemSize;
698  std::vector<Detail::RFieldValue> result;
699  for (unsigned i = 0; i < nItems; ++i) {
700  result.emplace_back(fSubFields[0]->CaptureValue(vec->data() + (i * fItemSize)));
701  }
702  return result;
703 }
704 
706 {
707  fNWritten = 0;
708 }
709 
711 {
712  visitor.VisitVectorField(*this);
713 }
714 
715 
716 //------------------------------------------------------------------------------
717 
718 
720  : ROOT::Experimental::Detail::RFieldBase(name, "std::vector<bool>", ENTupleStructure::kCollection,
721  false /* isSimple */)
722 {
723  Attach(std::make_unique<RField<bool>>("bool"));
724 }
725 
726 void ROOT::Experimental::RField<std::vector<bool>>::AppendImpl(const Detail::RFieldValue& value) {
727  auto typedValue = value.Get<std::vector<bool>>();
728  auto count = typedValue->size();
729  for (unsigned i = 0; i < count; ++i) {
730  bool bval = (*typedValue)[i];
731  auto itemValue = fSubFields[0]->CaptureValue(&bval);
732  fSubFields[0]->Append(itemValue);
733  }
734  Detail::RColumnElement<ClusterSize_t, EColumnType::kIndex> elemIndex(&fNWritten);
735  fNWritten += count;
736  fColumns[0]->Append(elemIndex);
737 }
738 
739 void ROOT::Experimental::RField<std::vector<bool>>::ReadGlobalImpl(NTupleSize_t globalIndex, Detail::RFieldValue* value)
740 {
741  auto typedValue = value->Get<std::vector<bool>>();
742 
743  ClusterSize_t nItems;
744  RClusterIndex collectionStart;
745  fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
746 
747  typedValue->resize(nItems);
748  for (unsigned i = 0; i < nItems; ++i) {
749  bool bval;
750  auto itemValue = fSubFields[0]->GenerateValue(&bval);
751  fSubFields[0]->Read(collectionStart + i, &itemValue);
752  (*typedValue)[i] = bval;
753  }
754 }
755 
756 void ROOT::Experimental::RField<std::vector<bool>>::GenerateColumnsImpl()
757 {
758  RColumnModel modelIndex(EColumnType::kIndex, true /* isSorted*/);
759  fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
760  Detail::RColumn::Create<ClusterSize_t, EColumnType::kIndex>(modelIndex, 0)));
761  fPrincipalColumn = fColumns[0].get();
762 }
763 
764 std::vector<ROOT::Experimental::Detail::RFieldValue>
765 ROOT::Experimental::RField<std::vector<bool>>::SplitValue(const Detail::RFieldValue& value) const
766 {
767  const static bool trueValue = true;
768  const static bool falseValue = false;
769 
770  auto typedValue = value.Get<std::vector<bool>>();
771  auto count = typedValue->size();
772  std::vector<Detail::RFieldValue> result;
773  for (unsigned i = 0; i < count; ++i) {
774  if ((*typedValue)[i])
775  result.emplace_back(fSubFields[0]->CaptureValue(const_cast<bool *>(&trueValue)));
776  else
777  result.emplace_back(fSubFields[0]->CaptureValue(const_cast<bool *>(&falseValue)));
778  }
779  return result;
780 }
781 
782 
783 void ROOT::Experimental::RField<std::vector<bool>>::DestroyValue(const Detail::RFieldValue& value, bool dtorOnly)
784 {
785  auto vec = static_cast<std::vector<bool>*>(value.GetRawPtr());
786  vec->~vector();
787  if (!dtorOnly)
788  free(vec);
789 }
790 
791 void ROOT::Experimental::RField<std::vector<bool>>::AcceptVisitor(Detail::RFieldVisitor &visitor) const
792 {
793  visitor.VisitVectorBoolField(*this);
794 }
795 
796 
797 //------------------------------------------------------------------------------
798 
799 
801  std::string_view fieldName, std::unique_ptr<Detail::RFieldBase> itemField, std::size_t arrayLength)
802  : ROOT::Experimental::Detail::RFieldBase(
803  fieldName, "std::array<" + itemField->GetType() + "," + std::to_string(arrayLength) + ">",
804  ENTupleStructure::kLeaf, false /* isSimple */, arrayLength)
805  , fItemSize(itemField->GetValueSize()), fArrayLength(arrayLength)
806 {
807  Attach(std::move(itemField));
808 }
809 
811 {
812  auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetName());
813  return new RArrayField(newName, std::unique_ptr<Detail::RFieldBase>(newItemField), fArrayLength);
814 }
815 
817  auto arrayPtr = value.Get<unsigned char>();
818  for (unsigned i = 0; i < fArrayLength; ++i) {
819  auto itemValue = fSubFields[0]->CaptureValue(arrayPtr + (i * fItemSize));
820  fSubFields[0]->Append(itemValue);
821  }
822 }
823 
825 {
826  auto arrayPtr = value->Get<unsigned char>();
827  for (unsigned i = 0; i < fArrayLength; ++i) {
828  auto itemValue = fSubFields[0]->GenerateValue(arrayPtr + (i * fItemSize));
829  fSubFields[0]->Read(globalIndex * fArrayLength + i, &itemValue);
830  }
831 }
832 
834 {
835  auto arrayPtr = value->Get<unsigned char>();
836  for (unsigned i = 0; i < fArrayLength; ++i) {
837  auto itemValue = fSubFields[0]->GenerateValue(arrayPtr + (i * fItemSize));
838  fSubFields[0]->Read(RClusterIndex(clusterIndex.GetClusterId(), clusterIndex.GetIndex() * fArrayLength + i),
839  &itemValue);
840  }
841 }
842 
844 {
845 }
846 
848 {
849  auto arrayPtr = reinterpret_cast<unsigned char *>(where);
850  for (unsigned i = 0; i < fArrayLength; ++i) {
851  fSubFields[0]->GenerateValue(arrayPtr + (i * fItemSize));
852  }
853  return Detail::RFieldValue(true /* captureFlag */, this, where);
854 }
855 
857 {
858  auto arrayPtr = value.Get<unsigned char>();
859  for (unsigned i = 0; i < fArrayLength; ++i) {
860  auto itemValue = fSubFields[0]->CaptureValue(arrayPtr + (i * fItemSize));
861  fSubFields[0]->DestroyValue(itemValue, true /* dtorOnly */);
862  }
863  if (!dtorOnly)
864  free(arrayPtr);
865 }
866 
868 {
869  return Detail::RFieldValue(true /* captureFlag */, this, where);
870 }
871 
872 std::vector<ROOT::Experimental::Detail::RFieldValue>
874 {
875  auto arrayPtr = value.Get<unsigned char>();
876  std::vector<Detail::RFieldValue> result;
877  for (unsigned i = 0; i < fArrayLength; ++i) {
878  auto itemValue = fSubFields[0]->CaptureValue(arrayPtr + (i * fItemSize));
879  result.emplace_back(itemValue);
880  }
881  return result;
882 }
883 
885 {
886  visitor.VisitArrayField(*this);
887 }
888 
889 //------------------------------------------------------------------------------
890 
891 #if __cplusplus >= 201703L
892 std::string ROOT::Experimental::RVariantField::GetTypeList(const std::vector<Detail::RFieldBase *> &itemFields)
893 {
894  std::string result;
895  for (size_t i = 0; i < itemFields.size(); ++i) {
896  result += itemFields[i]->GetType() + ",";
897  }
898  R__ASSERT(!result.empty()); // there is always at least one variant
899  result.pop_back(); // remove trailing comma
900  return result;
901 }
902 
903 ROOT::Experimental::RVariantField::RVariantField(
904  std::string_view fieldName, const std::vector<Detail::RFieldBase *> &itemFields)
905  : ROOT::Experimental::Detail::RFieldBase(fieldName,
906  "std::variant<" + GetTypeList(itemFields) + ">", ENTupleStructure::kVariant, false /* isSimple */)
907 {
908  auto nFields = itemFields.size();
909  R__ASSERT(nFields > 0);
910  fNWritten.resize(nFields, 0);
911  for (unsigned int i = 0; i < nFields; ++i) {
912  fMaxItemSize = std::max(fMaxItemSize, itemFields[i]->GetValueSize());
913  fMaxAlignment = std::max(fMaxAlignment, itemFields[i]->GetAlignment());
914  Attach(std::unique_ptr<Detail::RFieldBase>(itemFields[i]));
915  }
916  fTagOffset = (fMaxItemSize < fMaxAlignment) ? fMaxAlignment : fMaxItemSize;
917 }
918 
919 ROOT::Experimental::Detail::RFieldBase *ROOT::Experimental::RVariantField::Clone(std::string_view newName)
920 {
921  auto nFields = fSubFields.size();
922  std::vector<Detail::RFieldBase *> itemFields;
923  for (unsigned i = 0; i < nFields; ++i) {
924  itemFields.emplace_back(fSubFields[i]->Clone(fSubFields[i]->GetName()));
925  }
926  return new RVariantField(newName, itemFields);
927 }
928 
929 std::uint32_t ROOT::Experimental::RVariantField::GetTag(void *variantPtr) const
930 {
931  auto index = *(reinterpret_cast<char *>(variantPtr) + fTagOffset);
932  return (index < 0) ? 0 : index + 1;
933 }
934 
935 void ROOT::Experimental::RVariantField::SetTag(void *variantPtr, std::uint32_t tag) const
936 {
937  auto index = reinterpret_cast<char *>(variantPtr) + fTagOffset;
938  *index = static_cast<char>(tag - 1);
939 }
940 
941 void ROOT::Experimental::RVariantField::AppendImpl(const Detail::RFieldValue& value)
942 {
943  auto tag = GetTag(value.GetRawPtr());
944  auto index = 0;
945  if (tag > 0) {
946  auto itemValue = fSubFields[tag - 1]->CaptureValue(value.GetRawPtr());
947  fSubFields[tag - 1]->Append(itemValue);
948  index = fNWritten[tag - 1]++;
949  }
950  RColumnSwitch varSwitch(ClusterSize_t(index), tag);
951  Detail::RColumnElement<RColumnSwitch, EColumnType::kSwitch> elemSwitch(&varSwitch);
952  fColumns[0]->Append(elemSwitch);
953 }
954 
955 void ROOT::Experimental::RVariantField::ReadGlobalImpl(NTupleSize_t globalIndex, Detail::RFieldValue *value)
956 {
957  RClusterIndex variantIndex;
958  std::uint32_t tag;
959  fPrincipalColumn->GetSwitchInfo(globalIndex, &variantIndex, &tag);
960  R__ASSERT(tag > 0); // TODO(jblomer): deal with invalid variants
961 
962  auto itemValue = fSubFields[tag - 1]->GenerateValue(value->GetRawPtr());
963  fSubFields[tag - 1]->Read(variantIndex, &itemValue);
964  SetTag(value->GetRawPtr(), tag);
965 }
966 
967 void ROOT::Experimental::RVariantField::GenerateColumnsImpl()
968 {
969  RColumnModel modelSwitch(EColumnType::kSwitch, false);
970  fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
971  Detail::RColumn::Create<RColumnSwitch, EColumnType::kSwitch>(modelSwitch, 0)));
972  fPrincipalColumn = fColumns[0].get();
973 }
974 
975 ROOT::Experimental::Detail::RFieldValue ROOT::Experimental::RVariantField::GenerateValue(void *where)
976 {
977  memset(where, 0, GetValueSize());
978  fSubFields[0]->GenerateValue(where);
979  SetTag(where, 1);
980  return Detail::RFieldValue(this, reinterpret_cast<unsigned char *>(where));
981 }
982 
983 void ROOT::Experimental::RVariantField::DestroyValue(const Detail::RFieldValue& value, bool dtorOnly)
984 {
985  auto variantPtr = value.GetRawPtr();
986  auto tag = GetTag(variantPtr);
987  if (tag > 0) {
988  auto itemValue = fSubFields[tag - 1]->CaptureValue(variantPtr);
989  fSubFields[tag - 1]->DestroyValue(itemValue, true /* dtorOnly */);
990  }
991  if (!dtorOnly)
992  free(variantPtr);
993 }
994 
995 ROOT::Experimental::Detail::RFieldValue ROOT::Experimental::RVariantField::CaptureValue(void *where)
996 {
997  return Detail::RFieldValue(true /* captureFlag */, this, where);
998 }
999 
1000 size_t ROOT::Experimental::RVariantField::GetValueSize() const
1001 {
1002  return fMaxItemSize + fMaxAlignment; // TODO: fix for more than 255 items
1003 }
1004 
1005 void ROOT::Experimental::RVariantField::CommitCluster()
1006 {
1007  std::fill(fNWritten.begin(), fNWritten.end(), 0);
1008 }
1009 #endif
1010 
1011 
1012 //------------------------------------------------------------------------------
1013 
1014 
1017  std::shared_ptr<RCollectionNTuple> collectionNTuple,
1018  std::unique_ptr<RNTupleModel> collectionModel)
1019  : RFieldBase(name, ":Collection:", ENTupleStructure::kCollection, true /* isSimple */)
1020  , fCollectionNTuple(collectionNTuple)
1021 {
1022  for (unsigned i = 0; i < collectionModel->GetFieldZero()->fSubFields.size(); ++i) {
1023  auto& subField = collectionModel->GetFieldZero()->fSubFields[i];
1024  Attach(std::move(subField));
1025  }
1026 }
1027 
1028 
1030 {
1031  RColumnModel modelIndex(EColumnType::kIndex, true /* isSorted*/);
1032  fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
1033  Detail::RColumn::Create<ClusterSize_t, EColumnType::kIndex>(modelIndex, 0)));
1034  fPrincipalColumn = fColumns[0].get();
1035 }
1036 
1037 
1039 {
1040  // TODO(jblomer)
1041  return nullptr;
1042  //auto result = new RCollectionField(newName, fCollectionNTuple, RNTupleModel::Create());
1043  //for (auto& f : fSubFields) {
1044  // // switch the name prefix for the new parent name
1045  // std::string cloneName = std::string(newName) + f->GetName().substr(GetName().length());
1046  // auto clone = f->Clone(cloneName);
1047  // result->Attach(std::unique_ptr<RFieldBase>(clone));
1048  //}
1049  //return result;
1050 }
1051 
1053  *fCollectionNTuple->GetOffsetPtr() = 0;
1054 }
1055 
ROOT::Experimental::RArrayField::Clone
RFieldBase * Clone(std::string_view newName) final
Definition: RField.cxx:810
ROOT::Experimental::RArrayField
The generic field for fixed size arrays, which do not need an offset column.
Definition: RField.hxx:341
ROOT::Experimental::RField< float >
Definition: RField.hxx:549
ROOT::Experimental::Detail::RColumn::Create
static RColumn * Create(const RColumnModel &model, std::uint32_t index)
Definition: RColumn.hxx:88
ROOT::Experimental::RVectorField::ReadGlobalImpl
void ReadGlobalImpl(NTupleSize_t globalIndex, Detail::RFieldValue *value) final
Definition: RField.cxx:645
ROOT::Experimental::Detail::RFieldVisitor
Abstract base class for classes implementing the visitor design pattern.
Definition: RFieldVisitor.hxx:62
ROOT::Experimental::RClassField::Clone
RFieldBase * Clone(std::string_view newName) final
Definition: RField.cxx:530
ROOT::Experimental::Detail::RFieldBase::AppendImpl
virtual void AppendImpl(const RFieldValue &value)
Operations on values of complex types, e.g.
Definition: RField.cxx:205
ROOT::Experimental::Detail::RFieldBase
Definition: RField.hxx:74
fit1_py.fill
fill
Definition: fit1_py.py:6
RNTupleModel.hxx
ROOT::Experimental::EColumnType::kReal64
@ kReal64
ROOT::Experimental::Detail::RFieldValue::Get
T * Get() const
Definition: RFieldValue.hxx:97
ROOT::Experimental::Detail::RFieldBase::Attach
void Attach(std::unique_ptr< Detail::RFieldBase > child)
Add a new subfield to the list of nested fields.
Definition: RField.cxx:235
ROOT::Experimental::Detail::RFieldBase::end
RSchemaIterator end()
Definition: RField.cxx:275
ROOT::Experimental::EColumnType::kIndex
@ kIndex
ROOT::Experimental::RArrayField::CaptureValue
Detail::RFieldValue CaptureValue(void *where) final
Creates a value from a memory location with an already constructed object.
Definition: RField.cxx:867
ROOT::Experimental::kLeaf
@ kLeaf
Definition: RNTupleUtil.hxx:51
ROOT::Experimental::RCollectionField::RCollectionField
RCollectionField(std::string_view name, std::shared_ptr< RCollectionNTuple > collectionNTuple, std::unique_ptr< RNTupleModel > collectionModel)
Definition: RField.cxx:1015
f
#define f(i)
Definition: RSha256.hxx:122
ROOT::Experimental::RClassField::CaptureValue
Detail::RFieldValue CaptureValue(void *where) final
Creates a value from a memory location with an already constructed object.
Definition: RField.cxx:583
ROOT::Experimental::RFieldZero::Clone
RFieldBase * Clone(std::string_view newName)
Definition: RField.cxx:310
ROOT::Experimental::Detail::RFieldBase::RSchemaIterator::Advance
void Advance()
Given that the iterator points to a valid field which is not the end iterator, go to the next field i...
Definition: RField.cxx:284
ROOT::Experimental::RVectorField::GenerateColumnsImpl
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type and name.
Definition: RField.cxx:660
ROOT::Experimental::RVectorField::AcceptVisitor
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
Definition: RField.cxx:710
ROOT::Experimental::Detail::RFieldBase::AcceptVisitor
virtual void AcceptVisitor(RFieldVisitor &visitor) const
Definition: RField.cxx:262
ROOT::Experimental::RFieldZero::AcceptVisitor
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
Definition: RField.cxx:330
ROOT::Experimental::Detail::RFieldBase::Create
static RFieldBase * Create(const std::string &fieldName, const std::string &typeName)
Factory method to resurrect a field from the stored on-disk type information.
Definition: RField.cxx:140
ROOT::TMetaUtils::GetNormalizedType
clang::QualType GetNormalizedType(const clang::QualType &type, const cling::Interpreter &interpreter, const TNormalizedCtxt &normCtxt)
Return the type normalized for ROOT, keeping only the ROOT opaque typedef (Double32_t,...
Definition: TClingUtils.cxx:4010
ROOT::Experimental::Detail::RFieldValue::GetRawPtr
void * GetRawPtr() const
Definition: RFieldValue.hxx:99
ROOT::Experimental::RArrayField::GetAlignment
size_t GetAlignment() const final
For many types, the alignment requirement is equal to the size; otherwise override.
Definition: RField.hxx:366
ROOT::Experimental::EColumnType::kSwitch
@ kSwitch
ROOT::Experimental::Detail::RFieldVisitor::VisitArrayField
virtual void VisitArrayField(const RArrayField &field)
Definition: RFieldVisitor.hxx:66
TCollection.h
ROOT::Experimental::DescriptorId_t
std::uint64_t DescriptorId_t
Distriniguishes elements of the same type within a descriptor, e.g. different fields.
Definition: RNTupleUtil.hxx:90
ROOT::Experimental::Detail::RFieldBase::GenerateColumnsImpl
virtual void GenerateColumnsImpl()=0
Creates the backing columns corresponsing to the field type and name.
ROOT::Experimental::Detail::RFieldVisitor::VisitClassField
virtual void VisitClassField(const RClassField &field)
Definition: RFieldVisitor.hxx:68
ROOT::Experimental::Detail::RPageStorage
Common functionality of an ntuple storage for both reading and writing.
Definition: RPageStorage.hxx:72
RField.hxx
ROOT::Experimental::Detail::RFieldVisitor::VisitBoolField
virtual void VisitBoolField(const RField< bool > &field)
Definition: RFieldVisitor.hxx:67
ROOT::Experimental::RVectorField::CaptureValue
Detail::RFieldValue CaptureValue(void *where) override
Creates a value from a memory location with an already constructed object.
Definition: RField.cxx:687
string_view
basic_string_view< char > string_view
Definition: libcpp_string_view.h:785
ROOT::Experimental::RCollectionField::CommitCluster
void CommitCluster() final
Perform housekeeping tasks for global to cluster-local index translation.
Definition: RField.cxx:1052
TDataMember.h
ROOT::Experimental::Detail::RFieldVisitor::VisitFloatField
virtual void VisitFloatField(const RField< float > &field)
Definition: RFieldVisitor.hxx:71
TDataMember
Definition: TDataMember.h:31
ROOT::Experimental::RClassField::fClass
TClass * fClass
Definition: RField.hxx:278
uint8_t
uint8_t
Definition: Converters.cxx:858
ROOT::Experimental::RArrayField::AcceptVisitor
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
Definition: RField.cxx:884
ROOT::Experimental::RClassField::AcceptVisitor
void AcceptVisitor(Detail::RFieldVisitor &visitor) const override
Definition: RField.cxx:609
ROOT::Experimental::RArrayField::ReadGlobalImpl
void ReadGlobalImpl(NTupleSize_t globalIndex, Detail::RFieldValue *value) final
Definition: RField.cxx:824
ROOT::Experimental::NTupleSize_t
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
Definition: RNTupleUtil.hxx:54
TClass.h
ROOT::Experimental::Detail::RFieldBase::GetSubFields
std::vector< const RFieldBase * > GetSubFields() const
Definition: RField.cxx:244
TList.h
ROOT::GetClass
TClass * GetClass(T *)
Definition: TClass.h:589
ROOT::Experimental::ENTupleStructure
ENTupleStructure
The fields in the ntuple model tree can carry different structural information about the type system.
Definition: RNTupleUtil.hxx:44
ROOT::Experimental::RClassField::GetValueSize
size_t GetValueSize() const override
The number of bytes taken by a value of the appropriate type.
Definition: RField.cxx:604
ROOT::Experimental::RClassField::DestroyValue
void DestroyValue(const Detail::RFieldValue &value, bool dtorOnly=false) final
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
Definition: RField.cxx:576
ROOT::Experimental::RVectorField::SplitValue
std::vector< Detail::RFieldValue > SplitValue(const Detail::RFieldValue &value) const final
Creates the list of direct child values given a value for this field.
Definition: RField.cxx:693
ROOT::Experimental::RClassField::GenerateColumnsImpl
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type and name.
Definition: RField.cxx:567
ROOT::Experimental::Detail::RFieldValue
Definition: RFieldValue.hxx:59
ROOT::Experimental::RArrayField::GenerateColumnsImpl
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type and name.
Definition: RField.cxx:843
ROOT::Experimental::REntry
The REntry is a collection of values in an ntuple corresponding to a complete row in the data set.
Definition: REntry.hxx:54
ROOT::Experimental::Detail::RFieldBase::GenerateValue
RFieldValue GenerateValue()
Generates an object of the field type and allocates new initialized memory according to the type.
Definition: RField.cxx:216
ROOT::Experimental::Detail::RFieldBase::RFieldBase
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.
Definition: RField.cxx:128
ROOT::Experimental::EColumnType::kInt64
@ kInt64
ROOT::Experimental::Detail::RFieldBase::fColumns
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.
Definition: RField.hxx:100
ROOT::Experimental::Detail::RFieldBase::begin
RSchemaIterator begin()
Definition: RField.cxx:268
ROOT::Experimental::EColumnType::kInt32
@ kInt32
ROOT::Experimental::RClusterIndex::GetIndex
ClusterSize_t::ValueType GetIndex() const
Definition: RNTupleUtil.hxx:115
ROOT::Experimental::RClassField::SplitValue
std::vector< Detail::RFieldValue > SplitValue(const Detail::RFieldValue &value) const final
Creates the list of direct child values given a value for this field.
Definition: RField.cxx:590
ROOT::Experimental::EColumnType::kBit
@ kBit
ROOT::Experimental::RVectorField::AppendImpl
void AppendImpl(const Detail::RFieldValue &value) final
Operations on values of complex types, e.g.
Definition: RField.cxx:632
ROOT::Experimental::Detail::RFieldBase::EnsureValidFieldName
static RResult< void > EnsureValidFieldName(std::string_view fieldName)
Check whether a given string is a valid field name.
Definition: RField.cxx:195
RFieldBase
A field translates read and write calls from/to underlying columns to/from tree values.
Definition: RField.hxx:60
ROOT::Experimental::Detail::RFieldBase::RSchemaIterator
Iterates over the sub tree of fields in depth-first search order.
Definition: RField.hxx:115
ROOT::Experimental::Detail::RFieldBase::RSchemaIterator::Position
Definition: RField.hxx:117
ROOT::Experimental::kCollection
@ kCollection
Definition: RNTupleUtil.hxx:52
ROOT::Experimental::Detail::RFieldBase::Flush
void Flush() const
Ensure that all received items are written from page buffers to the storage.
Definition: RField.cxx:254
ROOT::Experimental::Detail::RFieldBase::fSubFields
std::vector< std::unique_ptr< RFieldBase > > fSubFields
Collections and classes own sub fields.
Definition: RField.hxx:92
RLogger.hxx
ROOT::Experimental::RResult
The class is used as a return type for operations that can fail; wraps a value of type T or an RError...
Definition: RError.hxx:197
ROOT::Experimental::RField< double >
Definition: RField.hxx:587
ROOT::Experimental::EColumnType::kReal32
@ kReal32
ROOT::Experimental::RResult< void >
RResult<void> has no data member and no Inspect() method but instead a Success() factory method.
Definition: RError.hxx:259
malloc
#define malloc
Definition: civetweb.c:1536
ROOT::Experimental::RClassField::fMaxAlignment
std::size_t fMaxAlignment
Definition: RField.hxx:279
R__ERROR_HERE
#define R__ERROR_HERE(GROUP)
Definition: RLogger.hxx:183
ROOT::Experimental::Detail::RFieldVisitor::VisitFieldZero
virtual void VisitFieldZero(const RFieldZero &field)
Definition: RFieldVisitor.hxx:65
RColumnModel.hxx
ROOT::Experimental::RClassField::ReadGlobalImpl
void ReadGlobalImpl(NTupleSize_t globalIndex, Detail::RFieldValue *value) final
Definition: RField.cxx:545
ROOT::Experimental::RClusterIndex::GetClusterId
DescriptorId_t GetClusterId() const
Definition: RNTupleUtil.hxx:114
RColumn.hxx
ROOT::Experimental::Detail::RFieldBase::~RFieldBase
virtual ~RFieldBase()
Definition: RField.cxx:135
ROOT::Experimental::Detail::RFieldBase::ReadGlobalImpl
virtual void ReadGlobalImpl(NTupleSize_t globalIndex, RFieldValue *value)
Definition: RField.cxx:209
ROOT::Experimental::EColumnType::kByte
@ kByte
ROOT::Experimental::Detail::RFieldBase::CommitCluster
virtual void CommitCluster()
Perform housekeeping tasks for global to cluster-local index translation.
Definition: RField.hxx:214
ROOT::Experimental::RArrayField::RArrayField
RArrayField(std::string_view fieldName, std::unique_ptr< Detail::RFieldBase > itemField, std::size_t arrayLength)
Definition: RField.cxx:800
ROOT::Experimental::Detail::RFieldFuse::Connect
static void Connect(DescriptorId_t fieldId, RPageStorage &pageStorage, RFieldBase &field)
Definition: RField.cxx:116
ROOT::Experimental::kRecord
@ kRecord
Definition: RNTupleUtil.hxx:53
TClass::GetClass
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.
Definition: TClass.cxx:2925
ROOT::Experimental::RColumnModel
Holds the static meta-data of a column in a tree.
Definition: RColumnModel.hxx:72
ROOT::Experimental::Detail::RFieldVisitor::VisitDoubleField
virtual void VisitDoubleField(const RField< double > &field)
Definition: RFieldVisitor.hxx:70
ROOT::Experimental::RVectorField::RVectorField
RVectorField(std::string_view fieldName, std::unique_ptr< Detail::RFieldBase > itemField)
Definition: RField.cxx:617
ROOT::Experimental::RCollectionField::GenerateColumnsImpl
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type and name.
Definition: RField.cxx:1029
ROOT::Experimental::RVectorField::Clone
RFieldBase * Clone(std::string_view newName) final
Definition: RField.cxx:626
fClass
Cppyy::TCppType_t fClass
Definition: DeclareConverters.h:259
ROOT::Experimental::RArrayField::SplitValue
std::vector< Detail::RFieldValue > SplitValue(const Detail::RFieldValue &value) const final
Creates the list of direct child values given a value for this field.
Definition: RField.cxx:873
ROOT::Experimental::RClusterIndex
Addresses a column element or field item relative to a particular cluster, instead of a global NTuple...
Definition: RNTupleUtil.hxx:94
ROOT::Experimental::RClusterSize
Wrap the 32bit integer in a struct in order to avoid template specialization clash with std::uint32_t...
Definition: RNTupleUtil.hxx:57
ROOT::Experimental::RArrayField::DestroyValue
void DestroyValue(const Detail::RFieldValue &value, bool dtorOnly=false) final
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
Definition: RField.cxx:856
RNTuple.hxx
ROOT::Experimental::RFieldZero::GenerateEntry
REntry * GenerateEntry()
Generates managed values for the top-level sub fields.
Definition: RField.cxx:321
R__FAIL
#define R__FAIL(msg)
Short-hand to return an RResult<T> in an error state; the RError is implicitly converted into RResult...
Definition: RError.hxx:293
ROOT::Experimental::RField< ClusterSize_t >
Template specializations for concrete C++ types.
Definition: RField.hxx:466
ROOT::Experimental::kVariant
@ kVariant
Definition: RNTupleUtil.hxx:54
ROOT::Experimental::RVectorField::CommitCluster
void CommitCluster() final
Perform housekeeping tasks for global to cluster-local index translation.
Definition: RField.cxx:705
R__ASSERT
#define R__ASSERT(e)
Definition: TError.h:120
ROOT::Experimental::RArrayField::ReadInClusterImpl
void ReadInClusterImpl(const RClusterIndex &clusterIndex, Detail::RFieldValue *value) final
Definition: RField.cxx:833
ROOT::Experimental::RFieldZero
The container field for an ntuple model, which itself has no physical representation.
Definition: RField.hxx:259
ROOT::Experimental::RVectorField::DestroyValue
void DestroyValue(const Detail::RFieldValue &value, bool dtorOnly=false) final
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
Definition: RField.cxx:673
TClass::GetListOfDataMembers
TList * GetListOfDataMembers(Bool_t load=kTRUE)
Return list containing the TDataMembers of a class.
Definition: TClass.cxx:3665
TClass
Definition: TClass.h:80
ROOT::Experimental::RVectorField
The generic field for a (nested) std::vector<Type> except for std::vector<bool>
Definition: RField.hxx:305
ROOT::Experimental::ClusterSize_t
RClusterSize ClusterSize_t
Definition: RNTupleUtil.hxx:69
ROOT::Experimental::RField< bool >
Definition: RField.hxx:512
ROOT::Experimental::RClassField::AppendImpl
void AppendImpl(const Detail::RFieldValue &value) final
Operations on values of complex types, e.g.
Definition: RField.cxx:535
name
char name[80]
Definition: TGX11.cxx:110
ROOT::Experimental::RClassField::RClassField
RClassField(std::string_view fieldName, std::string_view className)
Definition: RField.cxx:514
RFieldVisitor.hxx
ROOT::Experimental::RArrayField::GetValueSize
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
Definition: RField.hxx:365
ROOT::Experimental::RArrayField::AppendImpl
void AppendImpl(const Detail::RFieldValue &value) final
Operations on values of complex types, e.g.
Definition: RField.cxx:816
TIter
Definition: TCollection.h:233
RError.hxx
make_cnn_model.model
model
Definition: make_cnn_model.py:6
ROOT::Experimental::Detail::RFieldBase::SplitValue
virtual std::vector< RFieldValue > SplitValue(const RFieldValue &value) const
Creates the list of direct child values given a value for this field.
Definition: RField.cxx:230
ROOT::Experimental::RCollectionField::Clone
RFieldBase * Clone(std::string_view newName) final
Definition: RField.cxx:1038
ROOT::Experimental::Detail::RFieldVisitor::VisitField
virtual void VisitField(const Detail::RFieldBase &field)=0
ROOT::Experimental::Detail::RFieldVisitor::VisitVectorField
virtual void VisitVectorField(const RVectorField &field)
Definition: RFieldVisitor.hxx:77
REntry.hxx
type
int type
Definition: TGX11.cxx:121
ROOT::Experimental::Detail::RFieldBase::DestroyValue
virtual void DestroyValue(const RFieldValue &value, bool dtorOnly=false)
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
Definition: RField.cxx:223
free
#define free
Definition: civetweb.c:1539
RooStats::HistFactory::Constraint::GetType
Type GetType(const std::string &Name)
Definition: Systematics.cxx:34
ROOT::Experimental::RClassField
The field for a class with dictionary.
Definition: RField.hxx:276
ROOT
VSD Structures.
Definition: StringConv.hxx:21
RFieldValue.hxx
ROOT::Experimental::RClassField::ReadInClusterImpl
void ReadInClusterImpl(const RClusterIndex &clusterIndex, Detail::RFieldValue *value) final
Definition: RField.cxx:556
ROOT::Experimental::Detail::RColumnElement< ClusterSize_t, EColumnType::kIndex >
Definition: RColumnElement.hxx:214
ROOT::Experimental::RField
Classes with dictionaries that can be inspected by TClass.
Definition: RField.hxx:411
TError.h