52#include <unordered_map>
56const std::unordered_map<std::string_view, std::string_view> typeTranslationMap{
59 {
"Double_t",
"double"},
60 {
"string",
"std::string"},
63 {
"int8_t",
"std::int8_t"},
64 {
"signed char",
"char"},
65 {
"UChar_t",
"std::uint8_t"},
66 {
"unsigned char",
"std::uint8_t"},
67 {
"uint8_t",
"std::uint8_t"},
69 {
"Short_t",
"std::int16_t"},
70 {
"int16_t",
"std::int16_t"},
71 {
"short",
"std::int16_t"},
72 {
"UShort_t",
"std::uint16_t"},
73 {
"unsigned short",
"std::uint16_t"},
74 {
"uint16_t",
"std::uint16_t"},
76 {
"Int_t",
"std::int32_t"},
77 {
"int32_t",
"std::int32_t"},
78 {
"int",
"std::int32_t"},
79 {
"UInt_t",
"std::uint32_t"},
80 {
"unsigned",
"std::uint32_t"},
81 {
"unsigned int",
"std::uint32_t"},
82 {
"uint32_t",
"std::uint32_t"},
84 {
"Long_t",
"std::int64_t"},
85 {
"Long64_t",
"std::int64_t"},
86 {
"int64_t",
"std::int64_t"},
87 {
"long",
"std::int64_t"},
88 {
"ULong64_t",
"std::uint64_t"},
89 {
"unsigned long",
"std::uint64_t"},
90 {
"uint64_t",
"std::uint64_t"}
95std::vector<std::string> TokenizeTypeList(std::string templateType) {
96 std::vector<std::string>
result;
97 if (templateType.empty())
100 const char *eol = templateType.data() + templateType.length();
101 const char *typeBegin = templateType.data();
102 const char *typeCursor = templateType.data();
103 unsigned int nestingLevel = 0;
104 while (typeCursor != eol) {
105 switch (*typeCursor) {
113 if (nestingLevel == 0) {
114 result.push_back(std::string(typeBegin, typeCursor - typeBegin));
115 typeBegin = typeCursor + 1;
121 result.push_back(std::string(typeBegin, typeCursor - typeBegin));
130std::tuple<std::string, std::vector<size_t>> ParseArrayType(std::string_view typeName)
132 std::vector<size_t> sizeVec;
135 while (typeName.back() ==
']') {
136 auto posRBrace = typeName.size() - 1;
137 auto posLBrace = typeName.find_last_of(
'[', posRBrace);
138 if (posLBrace == std::string_view::npos)
142 if (std::from_chars(typeName.data() + posLBrace + 1, typeName.data() + posRBrace,
size).ec != std::errc{})
144 sizeVec.insert(sizeVec.begin(),
size);
145 typeName.remove_suffix(typeName.size() - posLBrace);
147 return std::make_tuple(std::string{typeName}, sizeVec);
152std::string GetCanonicalTypeName(
const std::string &typeName)
155 if (typeName ==
"ROOT::Experimental::ClusterSize_t" || typeName.substr(0, 5) ==
"std::" ||
156 typeName.substr(0, 39) ==
"ROOT::Experimental::RNTupleCardinality<")
166std::string GetNormalizedTypeName(
const std::string &typeName)
170 if (
auto it = typeTranslationMap.find(normalizedType); it != typeTranslationMap.end())
171 normalizedType = it->second;
173 if (normalizedType.substr(0, 7) ==
"vector<")
174 normalizedType =
"std::" + normalizedType;
175 if (normalizedType.substr(0, 6) ==
"array<")
176 normalizedType =
"std::" + normalizedType;
177 if (normalizedType.substr(0, 8) ==
"variant<")
178 normalizedType =
"std::" + normalizedType;
179 if (normalizedType.substr(0, 5) ==
"pair<")
180 normalizedType =
"std::" + normalizedType;
181 if (normalizedType.substr(0, 6) ==
"tuple<")
182 normalizedType =
"std::" + normalizedType;
183 if (normalizedType.substr(0, 7) ==
"bitset<")
184 normalizedType =
"std::" + normalizedType;
185 if (normalizedType.substr(0, 11) ==
"unique_ptr<")
186 normalizedType =
"std::" + normalizedType;
187 if (normalizedType.substr(0, 4) ==
"set<")
188 normalizedType =
"std::" + normalizedType;
189 if (normalizedType.substr(0, 14) ==
"unordered_set<")
190 normalizedType =
"std::" + normalizedType;
191 if (normalizedType.substr(0, 4) ==
"map<")
192 normalizedType =
"std::" + normalizedType;
193 if (normalizedType.substr(0, 14) ==
"unordered_map<")
194 normalizedType =
"std::" + normalizedType;
195 if (normalizedType.substr(0, 7) ==
"atomic<")
196 normalizedType =
"std::" + normalizedType;
197 if (normalizedType ==
"byte")
198 normalizedType =
"std::byte";
200 return normalizedType;
205std::tuple<void **, std::int32_t *, std::int32_t *> GetRVecDataMembers(
void *rvecPtr)
207 void **begin =
reinterpret_cast<void **
>(rvecPtr);
209 std::int32_t *
size =
reinterpret_cast<std::int32_t *
>(begin + 1);
212 std::int32_t *capacity =
size + 1;
214 return {begin,
size, capacity};
217std::tuple<const void *const *, const std::int32_t *, const std::int32_t *> GetRVecDataMembers(
const void *rvecPtr)
219 return {GetRVecDataMembers(
const_cast<void *
>(rvecPtr))};
227 auto iFrom = from.
cbegin();
228 auto iTo = to.
begin();
229 for (; iFrom != from.
cend(); ++iFrom, ++iTo) {
230 iTo->SetOnDiskId(iFrom->GetOnDiskId());
247 : fSerializationTypes(serializationTypes), fDeserializationTypes(serializationTypes)
250 deserializationExtraTypes.begin(), deserializationExtraTypes.end());
256 : fField(other.fField),
258 fCapacity(other.fCapacity),
260 fNValidValues(other.fNValidValues),
261 fFirstIndex(other.fFirstIndex)
263 std::swap(
fValues, other.fValues);
269 std::swap(fField, other.fField);
270 std::swap(fValues, other.fValues);
272 std::swap(fCapacity, other.fCapacity);
273 std::swap(
fSize, other.fSize);
274 std::swap(fMaskAvail, other.fMaskAvail);
275 std::swap(fNValidValues, other.fNValidValues);
276 std::swap(fFirstIndex, other.fFirstIndex);
293 for (std::size_t i = 0; i < fCapacity; ++i) {
294 fField->DestroyValue(GetValuePtrAt(i),
true );
301 if (fCapacity <
size) {
306 for (std::size_t i = 0; i <
size; ++i) {
307 fField->GenerateValue(GetValuePtrAt(i));
311 fMaskAvail = std::make_unique<bool[]>(
size);
315 std::fill(fMaskAvail.get(), fMaskAvail.get() +
size,
false);
318 fFirstIndex = firstIndex;
325 for (std::size_t i = 0; i <
fSize; ++i)
326 fNValidValues +=
static_cast<std::size_t
>(fMaskAvail[i]);
344 std::string
result = GetName();
346 while (parent && !parent->
GetName().empty()) {
356 auto typeAlias = GetNormalizedTypeName(typeName);
357 auto canonicalType = GetNormalizedTypeName(GetCanonicalTypeName(typeAlias));
363 const std::string &typeAlias)
365 if (canonicalType.empty())
366 return R__FAIL(
"no type name specified for Field " + fieldName);
368 if (
auto [arrayBaseType, arraySize] = ParseArrayType(canonicalType); !arraySize.empty()) {
370 if (arraySize.size() > 1)
371 return R__FAIL(
"multi-dimensional array type not supported " + canonicalType);
372 auto itemField = Create(
"_0", arrayBaseType).Unwrap();
373 return {std::make_unique<RArrayField>(fieldName, std::move(itemField), arraySize[0])};
376 std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
result;
378 if (canonicalType ==
"ROOT::Experimental::ClusterSize_t") {
379 result = std::make_unique<RField<ClusterSize_t>>(fieldName);
380 }
else if (canonicalType ==
"bool") {
381 result = std::make_unique<RField<bool>>(fieldName);
382 }
else if (canonicalType ==
"char") {
383 result = std::make_unique<RField<char>>(fieldName);
384 }
else if (canonicalType ==
"std::byte") {
385 result = std::make_unique<RField<std::byte>>(fieldName);
386 }
else if (canonicalType ==
"std::int8_t") {
387 result = std::make_unique<RField<std::int8_t>>(fieldName);
388 }
else if (canonicalType ==
"std::uint8_t") {
389 result = std::make_unique<RField<std::uint8_t>>(fieldName);
390 }
else if (canonicalType ==
"std::int16_t") {
391 result = std::make_unique<RField<std::int16_t>>(fieldName);
392 }
else if (canonicalType ==
"std::uint16_t") {
393 result = std::make_unique<RField<std::uint16_t>>(fieldName);
394 }
else if (canonicalType ==
"std::int32_t") {
395 result = std::make_unique<RField<std::int32_t>>(fieldName);
396 }
else if (canonicalType ==
"std::uint32_t") {
397 result = std::make_unique<RField<std::uint32_t>>(fieldName);
398 }
else if (canonicalType ==
"std::int64_t") {
399 result = std::make_unique<RField<std::int64_t>>(fieldName);
400 }
else if (canonicalType ==
"std::uint64_t") {
401 result = std::make_unique<RField<std::uint64_t>>(fieldName);
402 }
else if (canonicalType ==
"float") {
403 result = std::make_unique<RField<float>>(fieldName);
404 }
else if (canonicalType ==
"double") {
405 result = std::make_unique<RField<double>>(fieldName);
406 }
else if (canonicalType ==
"Double32_t") {
407 result = std::make_unique<RField<double>>(fieldName);
411 }
else if (canonicalType ==
"std::string") {
412 result = std::make_unique<RField<std::string>>(fieldName);
413 }
else if (canonicalType ==
"std::vector<bool>") {
414 result = std::make_unique<RField<std::vector<bool>>>(fieldName);
415 }
else if (canonicalType.substr(0, 12) ==
"std::vector<") {
416 std::string itemTypeName = canonicalType.substr(12, canonicalType.length() - 13);
417 auto itemField = Create(
"_0", itemTypeName);
418 result = std::make_unique<RVectorField>(fieldName, itemField.Unwrap());
419 }
else if (canonicalType.substr(0, 19) ==
"ROOT::VecOps::RVec<") {
420 std::string itemTypeName = canonicalType.substr(19, canonicalType.length() - 20);
421 auto itemField = Create(
"_0", itemTypeName);
422 result = std::make_unique<RRVecField>(fieldName, itemField.Unwrap());
423 }
else if (canonicalType.substr(0, 11) ==
"std::array<") {
424 auto arrayDef = TokenizeTypeList(canonicalType.substr(11, canonicalType.length() - 12));
426 auto arrayLength = std::stoi(arrayDef[1]);
427 auto itemField = Create(
"_0", arrayDef[0]);
428 result = std::make_unique<RArrayField>(fieldName, itemField.Unwrap(), arrayLength);
429 }
else if (canonicalType.substr(0, 13) ==
"std::variant<") {
430 auto innerTypes = TokenizeTypeList(canonicalType.substr(13, canonicalType.length() - 14));
431 std::vector<RFieldBase *> items;
432 for (
unsigned int i = 0; i < innerTypes.size(); ++i) {
433 items.emplace_back(Create(
"_" + std::to_string(i), innerTypes[i]).Unwrap().release());
435 result = std::make_unique<RVariantField>(fieldName, items);
436 }
else if (canonicalType.substr(0, 10) ==
"std::pair<") {
437 auto innerTypes = TokenizeTypeList(canonicalType.substr(10, canonicalType.length() - 11));
438 if (innerTypes.size() != 2)
439 return R__FAIL(
"the type list for std::pair must have exactly two elements");
440 std::array<std::unique_ptr<RFieldBase>, 2> items{Create(
"_0", innerTypes[0]).Unwrap(),
441 Create(
"_1", innerTypes[1]).Unwrap()};
442 result = std::make_unique<RPairField>(fieldName, items);
443 }
else if (canonicalType.substr(0, 11) ==
"std::tuple<") {
444 auto innerTypes = TokenizeTypeList(canonicalType.substr(11, canonicalType.length() - 12));
445 std::vector<std::unique_ptr<RFieldBase>> items;
446 for (
unsigned int i = 0; i < innerTypes.size(); ++i) {
447 items.emplace_back(Create(
"_" + std::to_string(i), innerTypes[i]).Unwrap());
449 result = std::make_unique<RTupleField>(fieldName, items);
450 }
else if (canonicalType.substr(0, 12) ==
"std::bitset<") {
451 auto size = std::stoull(canonicalType.substr(12, canonicalType.length() - 13));
452 result = std::make_unique<RBitsetField>(fieldName,
size);
453 }
else if (canonicalType.substr(0, 16) ==
"std::unique_ptr<") {
454 std::string itemTypeName = canonicalType.substr(16, canonicalType.length() - 17);
455 auto itemField = Create(
"_0", itemTypeName).Unwrap();
456 auto normalizedInnerTypeName = itemField->GetType();
457 result = std::make_unique<RUniquePtrField>(fieldName,
"std::unique_ptr<" + normalizedInnerTypeName +
">",
458 std::move(itemField));
459 }
else if (canonicalType.substr(0, 9) ==
"std::set<") {
460 std::string itemTypeName = canonicalType.substr(9, canonicalType.length() - 10);
461 auto itemField = Create(
"_0", itemTypeName).Unwrap();
462 auto normalizedInnerTypeName = itemField->GetType();
464 std::make_unique<RSetField>(fieldName,
"std::set<" + normalizedInnerTypeName +
">", std::move(itemField));
465 }
else if (canonicalType.substr(0, 19) ==
"std::unordered_set<") {
466 std::string itemTypeName = canonicalType.substr(19, canonicalType.length() - 20);
467 auto itemField = Create(
"_0", itemTypeName).Unwrap();
468 auto normalizedInnerTypeName = itemField->GetType();
469 result = std::make_unique<RSetField>(fieldName,
"std::unordered_set<" + normalizedInnerTypeName +
">",
470 std::move(itemField));
471 }
else if (canonicalType.substr(0, 9) ==
"std::map<") {
472 auto innerTypes = TokenizeTypeList(canonicalType.substr(9, canonicalType.length() - 10));
473 if (innerTypes.size() != 2)
474 return R__FAIL(
"the type list for std::map must have exactly two elements");
476 auto normalizedKeyTypeName = GetNormalizedTypeName(innerTypes[0]);
477 auto normalizedValueTypeName = GetNormalizedTypeName(innerTypes[1]);
480 Create(
"_0",
"std::pair<" + normalizedKeyTypeName +
"," + normalizedValueTypeName +
">").Unwrap();
481 result = std::make_unique<RMapField>(
482 fieldName,
"std::map<" + normalizedKeyTypeName +
"," + normalizedValueTypeName +
">", std::move(itemField));
483 }
else if (canonicalType.substr(0, 19) ==
"std::unordered_map<") {
484 auto innerTypes = TokenizeTypeList(canonicalType.substr(19, canonicalType.length() - 20));
485 if (innerTypes.size() != 2)
486 return R__FAIL(
"the type list for std::unordered_map must have exactly two elements");
488 auto normalizedKeyTypeName = GetNormalizedTypeName(innerTypes[0]);
489 auto normalizedValueTypeName = GetNormalizedTypeName(innerTypes[1]);
492 Create(
"_0",
"std::pair<" + normalizedKeyTypeName +
"," + normalizedValueTypeName +
">").Unwrap();
493 result = std::make_unique<RMapField>(
494 fieldName,
"std::unordered_map<" + normalizedKeyTypeName +
"," + normalizedValueTypeName +
">",
495 std::move(itemField));
496 }
else if (canonicalType.substr(0, 12) ==
"std::atomic<") {
497 std::string itemTypeName = canonicalType.substr(12, canonicalType.length() - 13);
498 auto itemField = Create(
"_0", itemTypeName).Unwrap();
499 auto normalizedInnerTypeName = itemField->GetType();
500 result = std::make_unique<RAtomicField>(fieldName,
"std::atomic<" + normalizedInnerTypeName +
">",
501 std::move(itemField));
502 }
else if (canonicalType ==
":Collection:") {
504 result = std::make_unique<RField<ClusterSize_t>>(fieldName);
505 }
else if (canonicalType.substr(0, 39) ==
"ROOT::Experimental::RNTupleCardinality<") {
506 auto innerTypes = TokenizeTypeList(canonicalType.substr(39, canonicalType.length() - 40));
507 if (innerTypes.size() != 1)
508 return R__FAIL(std::string(
"Field ") + fieldName +
" has invalid cardinality template: " + canonicalType);
509 if (innerTypes[0] ==
"std::uint32_t") {
510 result = std::make_unique<RField<RNTupleCardinality<std::uint32_t>>>(fieldName);
511 }
else if (innerTypes[0] ==
"std::uint64_t") {
512 result = std::make_unique<RField<RNTupleCardinality<std::uint64_t>>>(fieldName);
514 return R__FAIL(std::string(
"Field ") + fieldName +
" has invalid cardinality template: " + canonicalType);
521 result = std::make_unique<REnumField>(fieldName, canonicalType);
528 if (cl->GetCollectionProxy())
529 result = std::make_unique<RProxiedCollectionField>(fieldName, canonicalType);
531 result = std::make_unique<RClassField>(fieldName, canonicalType);
536 if (typeAlias != canonicalType)
537 result->fTypeAlias = typeAlias;
540 return R__FAIL(std::string(
"Field ") + fieldName +
" has unknown type " + canonicalType);
546 if (fieldName.empty()) {
547 return R__FAIL(
"name cannot be empty string \"\"");
548 }
else if (fieldName.find(
'.') != std::string::npos) {
549 return R__FAIL(
"name '" + std::string(fieldName) +
"' cannot contain dot characters '.'");
558 return representations;
561std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
564 auto clone = CloneImpl(newName);
565 clone->fTypeAlias = fTypeAlias;
566 clone->fOnDiskId = fOnDiskId;
567 clone->fDescription = fDescription;
569 clone->fColumnRepresentative = fColumnRepresentative;
575 R__ASSERT(
false &&
"A non-simple RField must implement its own AppendImpl");
586 const auto valueSize = GetValueSize();
587 std::size_t nRead = 0;
588 for (std::size_t i = 0; i < bulkSpec.
fCount; ++i) {
597 Read(bulkSpec.
fFirstIndex + i,
reinterpret_cast<unsigned char *
>(bulkSpec.
fValues) + i * valueSize);
606 void *where =
malloc(GetValueSize());
608 GenerateValue(where);
609 return RValue(
this, where,
true );
618std::vector<ROOT::Experimental::Detail::RFieldBase::RValue>
621 return std::vector<RValue>();
625 std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
child)
629 if (fState != EState::kUnconnected)
630 throw RException(
R__FAIL(
"invalid attempt to attach subfield to already connected field"));
631 child->fParent =
this;
632 fSubFields.emplace_back(std::move(
child));
638 std::size_t
result = globalIndex;
639 for (
auto f =
this;
f !=
nullptr;
f =
f->GetParent()) {
640 auto parent =
f->GetParent();
641 if (parent && (parent->GetStructure() ==
kCollection || parent->GetStructure() ==
kVariant))
643 result *= std::max(
f->GetNRepetitions(), std::size_t{1U});
650 std::vector<RFieldBase *>
result;
651 result.reserve(fSubFields.size());
652 for (
const auto &
f : fSubFields) {
660 for (
auto& column : fColumns) {
668 if (fState != EState::kUnconnected)
669 throw RException(
R__FAIL(
"cannot set field description once field is connected"));
670 fDescription = std::string(description);
675 if (fState != EState::kUnconnected)
683 if (fColumnRepresentative)
684 return *fColumnRepresentative;
685 return GetColumnRepresentations().GetSerializationDefault();
690 if (fState != EState::kUnconnected)
691 throw RException(
R__FAIL(
"cannot set column representative once field is connected"));
692 const auto &validTypes = GetColumnRepresentations().GetSerializationTypes();
693 auto itRepresentative = std::find(validTypes.begin(), validTypes.end(), representative);
694 if (itRepresentative == std::end(validTypes))
696 fColumnRepresentative = &(*itRepresentative);
703 throw RException(
R__FAIL(
"No on-disk column information for field `" + GetQualifiedFieldName() +
"`"));
707 onDiskTypes.emplace_back(
c.GetModel().GetType());
709 for (
const auto &t : GetColumnRepresentations().GetDeserializationTypes()) {
710 if (t == onDiskTypes)
714 std::string columnTypeNames;
715 for (
const auto &t : onDiskTypes) {
716 if (!columnTypeNames.empty())
717 columnTypeNames +=
", ";
720 throw RException(
R__FAIL(
"On-disk column types `" + columnTypeNames +
"` for field `" + GetQualifiedFieldName() +
721 "` cannot be matched."));
726 fReadCallbacks.push_back(func);
728 return fReadCallbacks.size() - 1;
733 fReadCallbacks.erase(fReadCallbacks.begin() + idx);
734 fIsSimple = (fTraits & kTraitMappable) && fReadCallbacks.empty();
739 if ((options.
GetCompression() == 0) && HasDefaultColumnRepresentative()) {
741 for (
auto &colType : rep) {
753 SetColumnRepresentative(rep);
758 for (
auto &colType : rep) {
765 SetColumnRepresentative(rep);
768 if (fTypeAlias ==
"Double32_t")
776 if (fState != EState::kUnconnected)
777 throw RException(
R__FAIL(
"invalid attempt to connect an already connected field to a page sink"));
781 GenerateColumnsImpl();
782 if (!fColumns.empty())
783 fPrincipalColumn = fColumns[0].get();
784 for (
auto &column : fColumns) {
785 auto firstElementIndex = (column.get() == fPrincipalColumn) ? EntryToColumnElementIndex(firstEntry) : 0;
786 column->Connect(fOnDiskId, &pageSink, firstElementIndex);
789 fState = EState::kConnectedToSink;
796 throw RException(
R__FAIL(
"invalid attempt to connect zero field to page source"));
797 if (fState != EState::kUnconnected)
798 throw RException(
R__FAIL(
"invalid attempt to connect an already connected field to a page source"));
800 if (fColumnRepresentative)
801 throw RException(
R__FAIL(
"fixed column representative only valid when connecting to a page sink"));
802 if (!fDescription.empty())
803 throw RException(
R__FAIL(
"setting description only valid when connecting to a page sink"));
808 GenerateColumnsImpl(desc);
810 for (
const auto &
c : fColumns) {
811 onDiskColumnTypes.emplace_back(
c->GetModel().GetType());
813 for (
const auto &t : GetColumnRepresentations().GetDeserializationTypes()) {
814 if (t == onDiskColumnTypes)
815 fColumnRepresentative = &t;
821 if (!fColumns.empty())
822 fPrincipalColumn = fColumns[0].get();
823 for (
auto& column : fColumns)
824 column->Connect(fOnDiskId, &pageSource);
825 OnConnectPageSource();
827 fState = EState::kConnectedToSource;
838std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
841 auto result = std::make_unique<RFieldZero>();
842 for (
auto &
f : fSubFields)
843 result->Attach(
f->Clone(
f->GetName()));
859 static RColumnRepresentations representations(
862 return representations;
867 fColumns.emplace_back(Detail::RColumn::Create<ClusterSize_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
872 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
873 fColumns.emplace_back(Detail::RColumn::Create<ClusterSize_t>(RColumnModel(onDiskTypes[0]), 0));
878 visitor.VisitClusterSizeField(*
this);
889 return representations;
894 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
895 fColumns.emplace_back(Detail::RColumn::Create<ClusterSize_t>(
RColumnModel(onDiskTypes[0]), 0));
921 return representations;
926 fColumns.emplace_back(Detail::RColumn::Create<char>(
RColumnModel(GetColumnRepresentative()[0]), 0));
931 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
932 fColumns.emplace_back(Detail::RColumn::Create<char>(
RColumnModel(onDiskTypes[0]), 0));
946 return representations;
951 fColumns.emplace_back(Detail::RColumn::Create<char>(RColumnModel(GetColumnRepresentative()[0]), 0));
956 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
957 fColumns.emplace_back(Detail::RColumn::Create<char>(RColumnModel(onDiskTypes[0]), 0));
962 visitor.VisitByteField(*
this);
971 return representations;
976 fColumns.emplace_back(Detail::RColumn::Create<std::int8_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
981 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
982 fColumns.emplace_back(Detail::RColumn::Create<std::int8_t>(RColumnModel(onDiskTypes[0]), 0));
987 visitor.VisitInt8Field(*
this);
996 return representations;
1001 fColumns.emplace_back(Detail::RColumn::Create<std::uint8_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
1006 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1007 fColumns.emplace_back(Detail::RColumn::Create<std::uint8_t>(RColumnModel(onDiskTypes[0]), 0));
1012 visitor.VisitUInt8Field(*
this);
1021 return representations;
1026 fColumns.emplace_back(Detail::RColumn::Create<bool>(
RColumnModel(GetColumnRepresentative()[0]), 0));
1031 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1032 fColumns.emplace_back(Detail::RColumn::Create<bool>(
RColumnModel(onDiskTypes[0]), 0));
1047 return representations;
1052 fColumns.emplace_back(Detail::RColumn::Create<float>(
RColumnModel(GetColumnRepresentative()[0]), 0));
1057 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1058 fColumns.emplace_back(Detail::RColumn::Create<float>(
RColumnModel(onDiskTypes[0]), 0));
1078 return representations;
1083 fColumns.emplace_back(Detail::RColumn::Create<double>(
RColumnModel(GetColumnRepresentative()[0]), 0));
1088 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1089 fColumns.emplace_back(Detail::RColumn::Create<double>(
RColumnModel(onDiskTypes[0]), 0));
1099 fTypeAlias =
"Double32_t";
1109 return representations;
1114 fColumns.emplace_back(Detail::RColumn::Create<std::int16_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
1119 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1120 fColumns.emplace_back(Detail::RColumn::Create<std::int16_t>(RColumnModel(onDiskTypes[0]), 0));
1125 visitor.VisitInt16Field(*
this);
1135 return representations;
1140 fColumns.emplace_back(Detail::RColumn::Create<std::uint16_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
1145 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1146 fColumns.emplace_back(Detail::RColumn::Create<std::uint16_t>(RColumnModel(onDiskTypes[0]), 0));
1151 visitor.VisitUInt16Field(*
this);
1161 return representations;
1166 fColumns.emplace_back(Detail::RColumn::Create<std::int32_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
1171 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1172 fColumns.emplace_back(Detail::RColumn::Create<std::int32_t>(RColumnModel(onDiskTypes[0]), 0));
1177 visitor.VisitIntField(*
this);
1187 return representations;
1192 fColumns.emplace_back(Detail::RColumn::Create<std::uint32_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
1197 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1198 fColumns.emplace_back(Detail::RColumn::Create<std::uint32_t>(RColumnModel(onDiskTypes[0]), 0));
1203 visitor.VisitUInt32Field(*
this);
1213 return representations;
1218 fColumns.emplace_back(Detail::RColumn::Create<std::uint64_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
1223 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1224 fColumns.emplace_back(Detail::RColumn::Create<std::uint64_t>(RColumnModel(onDiskTypes[0]), 0));
1229 visitor.VisitUInt64Field(*
this);
1244 return representations;
1249 fColumns.emplace_back(Detail::RColumn::Create<std::int64_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
1254 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1255 fColumns.emplace_back(Detail::RColumn::Create<std::int64_t>(RColumnModel(onDiskTypes[0]), 0));
1260 visitor.VisitInt64Field(*
this);
1273 return representations;
1278 fColumns.emplace_back(Detail::RColumn::Create<ClusterSize_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
1279 fColumns.emplace_back(Detail::RColumn::Create<char>(RColumnModel(GetColumnRepresentative()[1]), 1));
1284 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1285 fColumns.emplace_back(Detail::RColumn::Create<ClusterSize_t>(RColumnModel(onDiskTypes[0]), 0));
1286 fColumns.emplace_back(Detail::RColumn::Create<char>(RColumnModel(onDiskTypes[1]), 1));
1291 std::destroy_at(
static_cast<std::string *
>(objPtr));
1297 auto typedValue =
static_cast<const std::string *
>(from);
1298 auto length = typedValue->length();
1299 fColumns[1]->AppendV(typedValue->data(),
length);
1301 fColumns[0]->Append(&fIndex);
1302 return length + fColumns[0]->GetElement()->GetPackedSize();
1307 auto typedValue =
static_cast<std::string *
>(to);
1308 RClusterIndex collectionStart;
1310 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nChars);
1312 typedValue->clear();
1314 typedValue->resize(nChars);
1315 fColumns[1]->ReadV(collectionStart, nChars,
const_cast<char *
>(typedValue->data()));
1321 visitor.VisitStringField(*
this);
1337 throw RException(
R__FAIL(
"RField: no I/O support for type " + std::string(className)));
1345 R__FAIL(std::string(className) +
" has an associated collection proxy; use RProxiedCollectionField instead"));
1355 TClass *
c = baseClass->GetClassPointer();
1357 c->GetName()).Unwrap();
1358 fTraits &= subField->GetTraits();
1359 Attach(std::move(subField),
1368 if (!dataMember->IsPersistent()) {
1374 std::string typeName{GetNormalizedTypeName(dataMember->GetTrueTypeName())};
1375 std::string typeAlias{GetNormalizedTypeName(dataMember->GetFullTypeName())};
1377 if (dataMember->Property() &
kIsArray) {
1378 for (
int dim = 0,
n = dataMember->GetArrayDim(); dim <
n; ++dim)
1379 typeName +=
"[" + std::to_string(dataMember->GetMaxIndex(dim)) +
"]";
1382 fTraits &= subField->GetTraits();
1383 Attach(std::move(subField),
1390 fMaxAlignment = std::max(fMaxAlignment,
child->GetAlignment());
1391 fSubFieldsInfo.push_back(info);
1392 RFieldBase::Attach(std::move(
child));
1398 for (
const auto rule : rules) {
1403 auto func = rule->GetReadFunctionPointer();
1405 fReadCallbacks.emplace_back([func, classp](
void *
target) {
1409 func(
static_cast<char *
>(
target), &oldObj);
1410 oldObj.fClass =
nullptr;
1415std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
1419 SyncFieldIDs(*
this, *
result);
1425 std::size_t nbytes = 0;
1426 for (
unsigned i = 0; i < fSubFields.size(); i++) {
1427 nbytes += CallAppendOn(*fSubFields[i],
static_cast<const unsigned char *
>(from) + fSubFieldsInfo[i].fOffset);
1434 for (
unsigned i = 0; i < fSubFields.size(); i++) {
1435 CallReadOn(*fSubFields[i], globalIndex,
static_cast<unsigned char *
>(to) + fSubFieldsInfo[i].fOffset);
1441 for (
unsigned i = 0; i < fSubFields.size(); i++) {
1442 CallReadOn(*fSubFields[i], clusterIndex,
static_cast<unsigned char *
>(to) + fSubFieldsInfo[i].fOffset);
1450 const auto ruleset =
fClass->GetSchemaRules();
1454 if (rule->GetTarget() ==
nullptr)
1457 const auto dataMember = klass->GetDataMember(
target->GetString());
1458 if (!dataMember || dataMember->IsPersistent()) {
1460 << dataMember->GetName();
1467 auto rules = ruleset->FindRules(
fClass->GetName(),
static_cast<Int_t>(GetOnDiskTypeVersion()));
1468 rules.erase(std::remove_if(rules.begin(), rules.end(), referencesNonTransientMembers), rules.end());
1469 AddReadCallbacksFromIORules(rules,
fClass);
1479 fClass->Destructor(objPtr,
true );
1483std::vector<ROOT::Experimental::Detail::RFieldBase::RValue>
1486 std::vector<RValue>
result;
1487 for (
unsigned i = 0; i < fSubFields.size(); i++) {
1488 result.emplace_back(fSubFields[i]->BindValue(
value.Get<
unsigned char>() + fSubFieldsInfo[i].fOffset));
1496 return fClass->GetClassSize();
1501 return fClass->GetClassVersion();
1512 :
REnumField(fieldName, enumName,
TEnum::GetEnum(std::string(enumName).c_str()))
1519 if (enump ==
nullptr) {
1520 throw RException(
R__FAIL(
"RField: no I/O support for enum type " + std::string(enumName)));
1538 default:
throw RException(
R__FAIL(
"Unsupported underlying integral type for enum type " + std::string(enumName)));
1545 std::unique_ptr<RFieldBase> intField)
1548 Attach(std::move(intField));
1552std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
1555 auto newIntField = fSubFields[0]->Clone(fSubFields[0]->GetName());
1556 return std::unique_ptr<REnumField>(
new REnumField(newName, GetType(), std::move(newIntField)));
1559std::vector<ROOT::Experimental::Detail::RFieldBase::RValue>
1562 std::vector<RValue>
result;
1563 result.emplace_back(fSubFields[0]->BindValue(
value.GetRawPtr()));
1583 (ifuncs.
fNext !=
nullptr));
1588 std::string_view typeName,
TClass *classp)
1591 if (classp ==
nullptr)
1592 throw RException(
R__FAIL(
"RField: no I/O support for collection proxy type " + std::string(typeName)));
1594 throw RException(
R__FAIL(std::string(typeName) +
" has no associated collection proxy"));
1599 if (
fProxy->HasPointers())
1600 throw RException(
R__FAIL(
"collection proxies whose value type is a pointer are not supported"));
1601 if (!
fProxy->GetCollectionClass()->HasDictionary()) {
1603 GetNormalizedTypeName(
fProxy->GetCollectionClass()->GetName())));
1611 std::string_view typeName,
1612 std::unique_ptr<Detail::RFieldBase> itemField)
1616 Attach(std::move(itemField));
1620 std::string_view typeName)
1625 throw RException(
R__FAIL(
"custom associative collection proxies not supported"));
1627 std::unique_ptr<ROOT::Experimental::Detail::RFieldBase> itemField;
1629 if (
auto valueClass =
fProxy->GetValueClass()) {
1631 itemField = RFieldBase::Create(
"_0", valueClass->GetName()).Unwrap();
1633 switch (
fProxy->GetType()) {
1635 case EDataType::kUChar_t: itemField = std::make_unique<RField<std::uint8_t>>(
"_0");
break;
1636 case EDataType::kShort_t: itemField = std::make_unique<RField<std::int16_t>>(
"_0");
break;
1638 case EDataType::kInt_t: itemField = std::make_unique<RField<std::int32_t>>(
"_0");
break;
1639 case EDataType::kUInt_t: itemField = std::make_unique<RField<std::uint32_t>>(
"_0");
break;
1642 itemField = std::make_unique<RField<std::int64_t>>(
"_0");
1646 itemField = std::make_unique<RField<std::uint64_t>>(
"_0");
1657 Attach(std::move(itemField));
1660std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
1663 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetName());
1664 return std::unique_ptr<RProxiedCollectionField>(
1670 std::size_t nbytes = 0;
1674 (fCollectionType ==
kSTLvector ? fItemSize : 0U)}) {
1675 nbytes += CallAppendOn(*fSubFields[0], ptr);
1680 fColumns[0]->Append(&fNWritten);
1681 return nbytes + fColumns[0]->GetElement()->GetPackedSize();
1688 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
1696 (fCollectionType ==
kSTLvector || obj != to ? fItemSize : 0U)}) {
1697 CallReadOn(*fSubFields[0], collectionStart + (i++), elementPtr);
1700 fProxy->Commit(obj);
1709 return representations;
1714 fColumns.emplace_back(Detail::RColumn::Create<ClusterSize_t>(
RColumnModel(GetColumnRepresentative()[0]), 0));
1719 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1720 fColumns.emplace_back(Detail::RColumn::Create<ClusterSize_t>(
RColumnModel(onDiskTypes[0]), 0));
1733 (fCollectionType ==
kSTLvector ? fItemSize : 0U)}) {
1734 CallDestroyValueOn(*fSubFields[0], ptr,
true );
1737 fProxy->Destructor(objPtr,
true );
1741std::vector<ROOT::Experimental::Detail::RFieldBase::RValue>
1744 std::vector<RValue>
result;
1747 (fCollectionType ==
kSTLvector ? fItemSize : 0U)}) {
1748 result.emplace_back(fSubFields[0]->BindValue(ptr));
1761 std::vector<std::unique_ptr<Detail::RFieldBase>> &&itemFields,
1762 const std::vector<std::size_t> &offsets, std::string_view typeName)
1767 for (
auto &item : itemFields) {
1776 std::vector<std::unique_ptr<Detail::RFieldBase>> &&itemFields)
1780 for (
auto &item : itemFields) {
1784 fSize += item->GetValueSize();
1794 std::vector<std::unique_ptr<Detail::RFieldBase>> &itemFields)
1801 if (itemAlignment > 1) {
1802 auto remainder = baseOffset % itemAlignment;
1804 return itemAlignment - remainder;
1809std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
1812 std::vector<std::unique_ptr<Detail::RFieldBase>> cloneItems;
1813 cloneItems.reserve(fSubFields.size());
1814 for (
auto &item : fSubFields)
1815 cloneItems.emplace_back(item->Clone(item->GetName()));
1816 return std::unique_ptr<RRecordField>(
new RRecordField(newName, std::move(cloneItems), fOffsets, GetType()));
1821 std::size_t nbytes = 0;
1822 for (
unsigned i = 0; i < fSubFields.size(); ++i) {
1823 nbytes += CallAppendOn(*fSubFields[i],
static_cast<const unsigned char *
>(from) + fOffsets[i]);
1830 for (
unsigned i = 0; i < fSubFields.size(); ++i) {
1831 CallReadOn(*fSubFields[i], globalIndex,
static_cast<unsigned char *
>(to) + fOffsets[i]);
1837 for (
unsigned i = 0; i < fSubFields.size(); ++i) {
1838 CallReadOn(*fSubFields[i], clusterIndex,
static_cast<unsigned char *
>(to) + fOffsets[i]);
1844 for (
unsigned i = 0; i < fSubFields.size(); ++i) {
1845 CallGenerateValueOn(*fSubFields[i],
static_cast<unsigned char *
>(where) + fOffsets[i]);
1851 for (
unsigned i = 0; i < fSubFields.size(); ++i) {
1852 CallDestroyValueOn(*fSubFields[i],
static_cast<unsigned char *
>(objPtr) + fOffsets[i],
true );
1857std::vector<ROOT::Experimental::Detail::RFieldBase::RValue>
1860 std::vector<RValue>
result;
1861 for (
unsigned i = 0; i < fSubFields.size(); ++i) {
1862 result.emplace_back(fSubFields[i]->BindValue(
value.Get<
unsigned char>() + fOffsets[i]));
1877 std::string_view fieldName, std::unique_ptr<Detail::RFieldBase> itemField)
1878 :
ROOT::Experimental::Detail::RFieldBase(
1880 , fItemSize(itemField->GetValueSize()), fNWritten(0)
1882 Attach(std::move(itemField));
1885std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
1888 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetName());
1889 return std::make_unique<RVectorField>(newName, std::move(newItemField));
1894 auto typedValue =
static_cast<const std::vector<char> *
>(from);
1895 R__ASSERT((typedValue->size() % fItemSize) == 0);
1896 std::size_t nbytes = 0;
1897 auto count = typedValue->size() / fItemSize;
1899 if (fSubFields[0]->IsSimple() && count) {
1900 GetPrincipalColumnOf(*fSubFields[0])->AppendV(typedValue->data(), count);
1901 nbytes += count * GetPrincipalColumnOf(*fSubFields[0])->GetElement()->GetPackedSize();
1903 for (
unsigned i = 0; i < count; ++i) {
1904 nbytes += CallAppendOn(*fSubFields[0], typedValue->data() + (i * fItemSize));
1909 fColumns[0]->Append(&fNWritten);
1910 return nbytes + fColumns[0]->GetElement()->GetPackedSize();
1915 auto typedValue =
static_cast<std::vector<char> *
>(to);
1919 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
1921 if (fSubFields[0]->IsSimple()) {
1922 typedValue->resize(nItems * fItemSize);
1924 GetPrincipalColumnOf(*fSubFields[0])->ReadV(collectionStart, nItems, typedValue->data());
1929 const auto oldNItems = typedValue->size() / fItemSize;
1930 const bool canRealloc = oldNItems < nItems;
1931 bool allDeallocated =
false;
1932 if (!(fSubFields[0]->GetTraits() & kTraitTriviallyDestructible)) {
1933 allDeallocated = canRealloc;
1934 for (std::size_t i = allDeallocated ? 0 : nItems; i < oldNItems; ++i) {
1935 CallDestroyValueOn(*fSubFields[0], typedValue->data() + (i * fItemSize),
true );
1938 typedValue->resize(nItems * fItemSize);
1939 if (!(fSubFields[0]->GetTraits() & kTraitTriviallyConstructible)) {
1940 for (std::size_t i = allDeallocated ? 0 : oldNItems; i < nItems; ++i) {
1941 CallGenerateValueOn(*fSubFields[0], typedValue->data() + (i * fItemSize));
1945 for (std::size_t i = 0; i < nItems; ++i) {
1946 CallReadOn(*fSubFields[0], collectionStart + i, typedValue->data() + (i * fItemSize));
1956 return representations;
1961 fColumns.emplace_back(Detail::RColumn::Create<ClusterSize_t>(
RColumnModel(GetColumnRepresentative()[0]), 0));
1966 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1967 fColumns.emplace_back(Detail::RColumn::Create<ClusterSize_t>(
RColumnModel(onDiskTypes[0]), 0));
1972 auto vecPtr =
static_cast<std::vector<char> *
>(objPtr);
1973 R__ASSERT((vecPtr->size() % fItemSize) == 0);
1974 if (!(fSubFields[0]->GetTraits() & kTraitTriviallyDestructible)) {
1975 auto nItems = vecPtr->size() / fItemSize;
1976 for (
unsigned i = 0; i < nItems; ++i) {
1977 CallDestroyValueOn(*fSubFields[0], vecPtr->data() + (i * fItemSize),
true );
1980 std::destroy_at(vecPtr);
1985std::vector<ROOT::Experimental::Detail::RFieldBase::RValue>
1988 auto vec =
value.Get<std::vector<char>>();
1990 auto nItems =
vec->size() / fItemSize;
1991 std::vector<RValue>
result;
1992 for (
unsigned i = 0; i < nItems; ++i) {
1993 result.emplace_back(fSubFields[0]->BindValue(
vec->data() + (i * fItemSize)));
2007 :
ROOT::Experimental::Detail::RFieldBase(fieldName,
"ROOT::VecOps::RVec<" + itemField->GetType() +
">",
2009 fItemSize(itemField->GetValueSize()), fNWritten(0)
2011 Attach(std::move(itemField));
2015std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
2018 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetName());
2019 return std::make_unique<RRVecField>(newName, std::move(newItemField));
2024 auto [beginPtr, sizePtr,
_] = GetRVecDataMembers(from);
2026 std::size_t nbytes = 0;
2027 if (fSubFields[0]->IsSimple() && *sizePtr) {
2028 GetPrincipalColumnOf(*fSubFields[0])->AppendV(*beginPtr, *sizePtr);
2029 nbytes += *sizePtr * GetPrincipalColumnOf(*fSubFields[0])->GetElement()->GetPackedSize();
2031 auto begin =
reinterpret_cast<const char *
>(*beginPtr);
2032 for (std::int32_t i = 0; i < *sizePtr; ++i) {
2033 nbytes += CallAppendOn(*fSubFields[0], begin + i * fItemSize);
2037 fNWritten += *sizePtr;
2038 fColumns[0]->Append(&fNWritten);
2039 return nbytes + fColumns[0]->GetElement()->GetPackedSize();
2047 auto [beginPtr, sizePtr, capacityPtr] = GetRVecDataMembers(to);
2052 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
2053 char *begin =
reinterpret_cast<char *
>(*beginPtr);
2054 const std::size_t oldSize = *sizePtr;
2058 const bool owns = (*capacityPtr != -1);
2059 const bool needsConstruct = !(fSubFields[0]->GetTraits() & kTraitTriviallyConstructible);
2060 const bool needsDestruct = owns && !(fSubFields[0]->GetTraits() & kTraitTriviallyDestructible);
2063 if (needsDestruct) {
2064 for (std::size_t i = nItems; i < oldSize; ++i) {
2065 CallDestroyValueOn(*fSubFields[0], begin + (i * fItemSize),
true );
2070 if (std::int32_t(nItems) > *capacityPtr) {
2073 if (needsDestruct) {
2074 for (std::size_t i = 0u; i < oldSize; ++i) {
2075 CallDestroyValueOn(*fSubFields[0], begin + (i * fItemSize),
true );
2086 *beginPtr =
malloc(nItems * fItemSize);
2088 begin =
reinterpret_cast<char *
>(*beginPtr);
2089 *capacityPtr = nItems;
2092 if (needsConstruct) {
2093 for (std::size_t i = 0u; i < oldSize; ++i)
2094 CallGenerateValueOn(*fSubFields[0], begin + (i * fItemSize));
2100 if (needsConstruct) {
2101 for (std::size_t i = oldSize; i < nItems; ++i)
2102 CallGenerateValueOn(*fSubFields[0], begin + (i * fItemSize));
2105 if (fSubFields[0]->IsSimple() && nItems) {
2106 GetPrincipalColumnOf(*fSubFields[0])->ReadV(collectionStart, nItems, begin);
2111 for (std::size_t i = 0; i < nItems; ++i) {
2112 CallReadOn(*fSubFields[0], collectionStart + i, begin + (i * fItemSize));
2118 if (!fSubFields[0]->IsSimple())
2119 return RFieldBase::ReadBulkImpl(bulkSpec);
2124 bulkSpec.
fAuxData->resize(
sizeof(std::size_t));
2125 *
reinterpret_cast<std::size_t *
>(bulkSpec.
fAuxData->data()) = fSubFields[0]->GetValueSize();
2127 const auto itemValueSize = *
reinterpret_cast<std::size_t *
>(bulkSpec.
fAuxData->data());
2128 unsigned char *itemValueArray = bulkSpec.
fAuxData->data() +
sizeof(std::size_t);
2129 auto [beginPtr, sizePtr,
_] = GetRVecDataMembers(bulkSpec.
fValues);
2135 this->GetCollectionInfo(bulkSpec.
fFirstIndex, &firstItemIndex, &collectionSize);
2136 *beginPtr = itemValueArray;
2137 *sizePtr = collectionSize;
2142 auto lastOffset = firstItemIndex.
GetIndex() + collectionSize;
2144 std::size_t nValues = 1;
2145 std::size_t nItems = collectionSize;
2146 while (nRemainingValues > 0) {
2149 const std::size_t nBatch = std::min(nRemainingValues, nElementsUntilPageEnd);
2150 for (std::size_t i = 0; i < nBatch; ++i) {
2151 const auto size = offsets[i] - lastOffset;
2152 std::tie(beginPtr, sizePtr,
_) = GetRVecDataMembers(
2153 reinterpret_cast<unsigned char *
>(bulkSpec.
fValues) + (nValues + i) *
fValueSize);
2154 *beginPtr = itemValueArray + nItems * itemValueSize;
2158 lastOffset = offsets[i];
2160 nRemainingValues -= nBatch;
2164 bulkSpec.
fAuxData->resize(
sizeof(std::size_t) + nItems * itemValueSize);
2166 const auto delta = itemValueArray - (bulkSpec.
fAuxData->data() +
sizeof(std::size_t));
2168 auto beginPtrAsUChar =
reinterpret_cast<unsigned char *
>(bulkSpec.
fValues);
2169 for (std::size_t i = 0; i < bulkSpec.
fCount; ++i) {
2170 *
reinterpret_cast<unsigned char **
>(beginPtrAsUChar) -= delta;
2175 GetPrincipalColumnOf(*fSubFields[0])->ReadV(firstItemIndex, nItems, itemValueArray - delta);
2176 return RBulkSpec::kAllSet;
2185 return representations;
2190 fColumns.emplace_back(Detail::RColumn::Create<ClusterSize_t>(
RColumnModel(GetColumnRepresentative()[0]), 0));
2195 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
2196 fColumns.emplace_back(Detail::RColumn::Create<ClusterSize_t>(
RColumnModel(onDiskTypes[0]), 0));
2203 void **beginPtr =
new (where)(
void *)(
nullptr);
2204 std::int32_t *sizePtr =
new (
reinterpret_cast<void *
>(beginPtr + 1)) std::int32_t(0);
2205 new (sizePtr + 1) std::int32_t(-1);
2210 auto [beginPtr, sizePtr, capacityPtr] = GetRVecDataMembers(objPtr);
2212 char *begin =
reinterpret_cast<char *
>(*beginPtr);
2213 if (!(fSubFields[0]->GetTraits() & kTraitTriviallyDestructible)) {
2214 for (std::int32_t i = 0; i < *sizePtr; ++i) {
2215 CallDestroyValueOn(*fSubFields[0], begin + i * fItemSize,
true );
2221 constexpr auto dataMemberSz =
sizeof(
void *) + 2 *
sizeof(std::int32_t);
2222 const auto alignOfT = fSubFields[0]->GetAlignment();
2223 auto paddingMiddle = dataMemberSz % alignOfT;
2224 if (paddingMiddle != 0)
2225 paddingMiddle = alignOfT - paddingMiddle;
2226 const bool isSmall = (
reinterpret_cast<void *
>(begin) == (beginPtr + dataMemberSz + paddingMiddle));
2228 const bool owns = (*capacityPtr != -1);
2229 if (!isSmall && owns)
2236std::vector<ROOT::Experimental::Detail::RFieldBase::RValue>
2239 auto [beginPtr, sizePtr,
_] = GetRVecDataMembers(
value.GetRawPtr());
2241 std::vector<RValue>
result;
2242 char *begin =
reinterpret_cast<char *
>(*beginPtr);
2243 result.reserve(*sizePtr);
2244 for (std::int32_t i = 0; i < *sizePtr; ++i) {
2245 result.emplace_back(fSubFields[0]->BindValue(begin + i * fItemSize));
2264 constexpr auto dataMemberSz =
sizeof(
void *) + 2 *
sizeof(std::int32_t);
2265 const auto alignOfT = fSubFields[0]->GetAlignment();
2266 const auto sizeOfT = fSubFields[0]->GetValueSize();
2269 const auto inlineStorageSz = [&] {
2270#ifdef R__HAS_HARDWARE_INTERFERENCE_SIZE
2272 constexpr unsigned cacheLineSize = std::hardware_destructive_interference_size;
2274 constexpr unsigned cacheLineSize = 64u;
2276 const unsigned elementsPerCacheLine = (cacheLineSize - dataMemberSz) / sizeOfT;
2277 constexpr unsigned maxInlineByteSize = 1024;
2278 const unsigned nElements =
2279 elementsPerCacheLine >= 8 ? elementsPerCacheLine : (sizeOfT * 8 > maxInlineByteSize ? 0 : 8);
2280 return nElements * sizeOfT;
2285 auto paddingMiddle = dataMemberSz % alignOfT;
2286 if (paddingMiddle != 0)
2287 paddingMiddle = alignOfT - paddingMiddle;
2290 const auto alignOfRVecT = GetAlignment();
2291 auto paddingEnd = (dataMemberSz + paddingMiddle + inlineStorageSz) % alignOfRVecT;
2292 if (paddingEnd != 0)
2293 paddingEnd = alignOfRVecT - paddingEnd;
2295 return dataMemberSz + inlineStorageSz + paddingMiddle + paddingEnd;
2307 return std::max({
alignof(
void *),
alignof(std::int32_t), fSubFields[0]->GetAlignment()});
2326 auto typedValue =
static_cast<const std::vector<bool> *
>(from);
2327 auto count = typedValue->size();
2328 for (
unsigned i = 0; i < count; ++i) {
2329 bool bval = (*typedValue)[i];
2330 CallAppendOn(*fSubFields[0], &bval);
2333 fColumns[0]->Append(&fNWritten);
2334 return count + fColumns[0]->GetElement()->GetPackedSize();
2339 auto typedValue =
static_cast<std::vector<bool> *
>(to);
2342 RClusterIndex collectionStart;
2343 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
2345 typedValue->resize(nItems);
2346 for (
unsigned i = 0; i < nItems; ++i) {
2348 CallReadOn(*fSubFields[0], collectionStart + i, &bval);
2349 (*typedValue)[i] = bval;
2356 static RColumnRepresentations representations(
2359 return representations;
2364 fColumns.emplace_back(Detail::RColumn::Create<ClusterSize_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
2369 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
2370 fColumns.emplace_back(Detail::RColumn::Create<ClusterSize_t>(RColumnModel(onDiskTypes[0]), 0));
2373std::vector<ROOT::Experimental::Detail::RFieldBase::RValue>
2376 const static bool trueValue =
true;
2377 const static bool falseValue =
false;
2379 auto typedValue =
value.Get<std::vector<bool>>();
2380 auto count = typedValue->size();
2381 std::vector<RValue>
result;
2382 for (
unsigned i = 0; i < count; ++i) {
2383 if ((*typedValue)[i])
2384 result.emplace_back(fSubFields[0]->BindValue(
const_cast<bool *
>(&trueValue)));
2386 result.emplace_back(fSubFields[0]->BindValue(
const_cast<bool *
>(&falseValue)));
2393 std::destroy_at(
static_cast<std::vector<bool> *
>(objPtr));
2399 visitor.VisitVectorBoolField(*
this);
2407 std::string_view fieldName, std::unique_ptr<Detail::RFieldBase> itemField, std::size_t arrayLength)
2408 :
ROOT::Experimental::Detail::RFieldBase(
2409 fieldName,
"std::array<" + itemField->GetType() +
"," + std::to_string(arrayLength) +
">",
2411 , fItemSize(itemField->GetValueSize()), fArrayLength(arrayLength)
2413 fTraits |= itemField->GetTraits() & ~kTraitMappable;
2414 Attach(std::move(itemField));
2417std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
2420 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetName());
2421 return std::make_unique<RArrayField>(newName, std::move(newItemField), fArrayLength);
2426 std::size_t nbytes = 0;
2427 auto arrayPtr =
static_cast<const unsigned char *
>(from);
2428 for (
unsigned i = 0; i < fArrayLength; ++i) {
2429 nbytes += CallAppendOn(*fSubFields[0], arrayPtr + (i * fItemSize));
2436 auto arrayPtr =
static_cast<unsigned char *
>(to);
2437 for (
unsigned i = 0; i < fArrayLength; ++i) {
2438 CallReadOn(*fSubFields[0], globalIndex * fArrayLength + i, arrayPtr + (i * fItemSize));
2444 auto arrayPtr =
static_cast<unsigned char *
>(to);
2445 for (
unsigned i = 0; i < fArrayLength; ++i) {
2447 arrayPtr + (i * fItemSize));
2453 if (fSubFields[0]->GetTraits() & kTraitTriviallyConstructible)
2456 auto arrayPtr =
reinterpret_cast<unsigned char *
>(where);
2457 for (
unsigned i = 0; i < fArrayLength; ++i) {
2458 CallGenerateValueOn(*fSubFields[0], arrayPtr + (i * fItemSize));
2464 auto arrayPtr =
static_cast<unsigned char *
>(objPtr);
2465 if (!(fSubFields[0]->GetTraits() & kTraitTriviallyDestructible)) {
2466 for (
unsigned i = 0; i < fArrayLength; ++i) {
2467 CallDestroyValueOn(*fSubFields[0], arrayPtr + (i * fItemSize),
true );
2473std::vector<ROOT::Experimental::Detail::RFieldBase::RValue>
2476 auto arrayPtr =
value.Get<
unsigned char>();
2477 std::vector<RValue>
result;
2478 for (
unsigned i = 0; i < fArrayLength; ++i) {
2479 result.emplace_back(fSubFields[0]->BindValue(arrayPtr + (i * fItemSize)));
2492 :
ROOT::Experimental::Detail::RFieldBase(fieldName,
"std::bitset<" + std::to_string(
N) +
">",
2503 return representations;
2508 fColumns.emplace_back(Detail::RColumn::Create<bool>(
RColumnModel(GetColumnRepresentative()[0]), 0));
2513 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
2514 fColumns.emplace_back(Detail::RColumn::Create<bool>(
RColumnModel(onDiskTypes[0]), 0));
2519 const auto *asULongArray =
static_cast<const Word_t *
>(from);
2522 for (std::size_t word = 0; word < (fN + kBitsPerWord - 1) / kBitsPerWord; ++word) {
2523 for (std::size_t
mask = 0; (
mask < kBitsPerWord) && (i < fN); ++
mask, ++i) {
2524 elementValue = (asULongArray[word] & (
static_cast<Word_t>(1) <<
mask)) != 0;
2525 fColumns[0]->Append(&elementValue);
2533 auto *asULongArray =
static_cast<Word_t *
>(to);
2535 for (std::size_t i = 0; i < fN; ++i) {
2536 fColumns[0]->Read(globalIndex * fN + i, &elementValue);
2538 Word_t bit =
static_cast<Word_t>(elementValue) << (i % kBitsPerWord);
2539 asULongArray[i / kBitsPerWord] = (asULongArray[i / kBitsPerWord] & ~mask) | bit;
2553 for (
size_t i = 0; i < itemFields.size(); ++i) {
2554 result += itemFields[i]->GetType() +
",";
2562 std::string_view fieldName,
const std::vector<Detail::RFieldBase *> &itemFields)
2563 :
ROOT::Experimental::Detail::RFieldBase(fieldName,
2569 auto nFields = itemFields.size();
2572 for (
unsigned int i = 0; i < nFields; ++i) {
2575 fTraits &= itemFields[i]->GetTraits();
2576 Attach(std::unique_ptr<Detail::RFieldBase>(itemFields[i]));
2581std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
2584 auto nFields = fSubFields.size();
2585 std::vector<Detail::RFieldBase *> itemFields;
2586 for (
unsigned i = 0; i < nFields; ++i) {
2588 itemFields.emplace_back(fSubFields[i]->Clone(fSubFields[i]->GetName()).release());
2590 return std::make_unique<RVariantField>(newName, itemFields);
2595 auto index = *(
reinterpret_cast<const char *
>(variantPtr) + fTagOffset);
2601 auto index =
reinterpret_cast<char *
>(variantPtr) + fTagOffset;
2602 *
index =
static_cast<char>(tag - 1);
2607 auto tag = GetTag(from);
2608 std::size_t nbytes = 0;
2611 nbytes += CallAppendOn(*fSubFields[tag - 1], from);
2612 index = fNWritten[tag - 1]++;
2615 fColumns[0]->Append(&varSwitch);
2623 fPrincipalColumn->GetSwitchInfo(globalIndex, &variantIndex, &tag);
2629 CallGenerateValueOn(*fSubFields[tag - 1], to);
2630 CallReadOn(*fSubFields[tag - 1], variantIndex, to);
2639 return representations;
2644 fColumns.emplace_back(Detail::RColumn::Create<RColumnSwitch>(
RColumnModel(GetColumnRepresentative()[0]), 0));
2649 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
2650 fColumns.emplace_back(Detail::RColumn::Create<RColumnSwitch>(
RColumnModel(onDiskTypes[0]), 0));
2655 memset(where, 0, GetValueSize());
2656 CallGenerateValueOn(*fSubFields[0], where);
2662 auto tag = GetTag(objPtr);
2664 CallDestroyValueOn(*fSubFields[tag - 1], objPtr,
true );
2671 return fMaxItemSize + fMaxAlignment;
2676 std::fill(fNWritten.begin(), fNWritten.end(), 0);
2682 std::unique_ptr<Detail::RFieldBase> itemField)
2687std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
2690 auto newItemField = fSubFields[0]->
Clone(fSubFields[0]->GetName());
2691 return std::make_unique<RSetField>(newName, GetType(), std::move(newItemField));
2697 std::unique_ptr<Detail::RFieldBase> itemField)
2700 if (!
dynamic_cast<RPairField *
>(itemField.get()))
2706 Attach(std::move(itemField));
2711 std::size_t nbytes = 0;
2715 nbytes += CallAppendOn(*fSubFields[0], ptr);
2719 fColumns[0]->Append(&fNWritten);
2720 return nbytes + fColumns[0]->GetElement()->GetPackedSize();
2727 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
2735 CallReadOn(*fSubFields[0], collectionStart + i, ptr);
2740 fProxy->Commit(obj);
2743std::vector<ROOT::Experimental::Detail::RFieldBase::RValue>
2746 std::vector<RValue>
result;
2749 result.emplace_back(fSubFields[0]->BindValue(ptr));
2754std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
2757 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetName());
2758 return std::unique_ptr<RMapField>(
new RMapField(newName, GetType(), std::move(newItemField)));
2764 std::unique_ptr<Detail::RFieldBase> itemField)
2767 Attach(std::move(itemField));
2776 return representations;
2781 if (HasDefaultColumnRepresentative()) {
2782 if (fSubFields[0]->GetValueSize() < 4) {
2787 fDefaultItemValue = std::make_unique<RValue>(fSubFields[0]->GenerateValue());
2790 fColumns.emplace_back(Detail::RColumn::Create<ClusterSize_t>(
RColumnModel(GetColumnRepresentative()[0]), 0));
2796 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
2800 fColumns.emplace_back(Detail::RColumn::Create<ClusterSize_t>(
RColumnModel(onDiskTypes[0]), 0));
2808 fPrincipalColumn->Append(&
mask);
2809 return 1 + CallAppendOn(*fSubFields[0], fDefaultItemValue->GetRawPtr());
2811 fPrincipalColumn->Append(&fNWritten);
2818 auto nbytesItem = CallAppendOn(*fSubFields[0], from);
2821 fPrincipalColumn->Append(&
mask);
2822 return 1 + nbytesItem;
2825 fPrincipalColumn->Append(&fNWritten);
2834 const bool isValidItem = *fPrincipalColumn->Map<
bool>(globalIndex);
2835 return isValidItem ? fPrincipalColumn->GetClusterIndex(globalIndex) : nullIndex;
2839 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &collectionSize);
2840 return (collectionSize == 0) ? nullIndex : collectionStart;
2852 std::unique_ptr<Detail::RFieldBase> itemField)
2857std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
2860 auto newItemField = fSubFields[0]->
Clone(fSubFields[0]->GetName());
2861 return std::make_unique<RUniquePtrField>(newName, GetType(), std::move(newItemField));
2866 auto typedValue =
static_cast<const std::unique_ptr<char> *
>(from);
2868 return AppendValue(typedValue->get());
2870 return AppendNull();
2876 auto ptr =
static_cast<std::unique_ptr<char> *
>(to);
2877 bool isValidValue =
static_cast<bool>(*ptr);
2879 auto itemIndex = GetItemIndex(globalIndex);
2882 void *valuePtr =
nullptr;
2884 valuePtr = ptr->get();
2886 if (isValidValue && !isValidItem) {
2888 CallDestroyValueOn(*fSubFields[0], valuePtr,
false );
2895 if (!isValidValue) {
2896 valuePtr =
malloc(fSubFields[0]->GetValueSize());
2897 CallGenerateValueOn(*fSubFields[0], valuePtr);
2898 ptr->reset(
reinterpret_cast<char *
>(valuePtr));
2901 CallReadOn(*fSubFields[0], itemIndex, valuePtr);
2906 auto typedPtr =
static_cast<std::unique_ptr<char> *
>(objPtr);
2908 CallDestroyValueOn(*fSubFields[0], typedPtr->get(),
false );
2909 typedPtr->release();
2914std::vector<ROOT::Experimental::Detail::RFieldBase::RValue>
2917 std::vector<RValue>
result;
2918 auto ptr =
value.Get<std::unique_ptr<char>>();
2920 result.emplace_back(fSubFields[0]->BindValue(ptr->get()));
2927std::string ROOT::Experimental::RPairField::RPairField::GetTypeList(
2928 const std::array<std::unique_ptr<Detail::RFieldBase>, 2> &itemFields)
2930 return itemFields[0]->GetType() +
"," + itemFields[1]->GetType();
2934 std::array<std::unique_ptr<Detail::RFieldBase>, 2> &&itemFields,
2935 const std::array<std::size_t, 2> &offsets)
2936 :
ROOT::Experimental::
RRecordField(fieldName, std::move(itemFields), offsets,
2937 "std::pair<" + GetTypeList(itemFields) +
">")
2942 std::array<std::unique_ptr<Detail::RFieldBase>, 2> &itemFields)
2944 "std::pair<" + GetTypeList(itemFields) +
">")
2951 fOffsets[0] =
fClass->GetDataMember(
"first")->GetOffset();
2952 fOffsets[1] =
fClass->GetDataMember(
"second")->GetOffset();
2955std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
2958 std::array<std::unique_ptr<Detail::RFieldBase>, 2> items{fSubFields[0]->Clone(fSubFields[0]->GetName()),
2959 fSubFields[1]->Clone(fSubFields[1]->GetName())};
2961 std::unique_ptr<RPairField>
result(
new RPairField(newName, std::move(items), {fOffsets[0], fOffsets[1]}));
2973 fClass->Destructor(objPtr,
true );
2979std::string ROOT::Experimental::RTupleField::RTupleField::GetTypeList(
2980 const std::vector<std::unique_ptr<Detail::RFieldBase>> &itemFields)
2983 if (itemFields.empty())
2984 throw RException(
R__FAIL(
"the type list for std::tuple must have at least one element"));
2985 for (
size_t i = 0; i < itemFields.size(); ++i) {
2986 result += itemFields[i]->GetType() +
",";
2993 std::vector<std::unique_ptr<Detail::RFieldBase>> &&itemFields,
2994 const std::vector<std::size_t> &offsets)
2995 :
ROOT::Experimental::
RRecordField(fieldName, std::move(itemFields), offsets,
2996 "std::tuple<" + GetTypeList(itemFields) +
">")
3001 std::vector<std::unique_ptr<Detail::RFieldBase>> &itemFields)
3003 "std::tuple<" + GetTypeList(itemFields) +
">")
3015 for (
unsigned i = 0; i < fSubFields.size(); ++i) {
3016 std::string memberName(
"_" + std::to_string(i));
3017 auto member =
fClass->GetRealData(memberName.c_str());
3020 fOffsets.push_back(member->GetThisOffset());
3024std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
3027 std::vector<std::unique_ptr<Detail::RFieldBase>> items;
3028 items.reserve(fSubFields.size());
3029 for (
const auto &item : fSubFields)
3030 items.push_back(item->Clone(item->GetName()));
3032 std::unique_ptr<RTupleField>
result(
new RTupleField(newName, std::move(items), fOffsets));
3044 fClass->Destructor(objPtr,
true );
3051 std::string_view
name,
3052 std::shared_ptr<RCollectionNTupleWriter> collectionNTuple,
3053 std::unique_ptr<RNTupleModel> collectionModel)
3055 , fCollectionNTuple(collectionNTuple)
3057 for (
unsigned i = 0; i < collectionModel->GetFieldZero()->
fSubFields.size(); ++i) {
3058 auto& subField = collectionModel->GetFieldZero()->fSubFields[i];
3059 Attach(std::move(subField));
3070 return representations;
3075 fColumns.emplace_back(Detail::RColumn::Create<ClusterSize_t>(
RColumnModel(GetColumnRepresentative()[0]), 0));
3080 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
3081 fColumns.emplace_back(Detail::RColumn::Create<ClusterSize_t>(
RColumnModel(onDiskTypes[0]), 0));
3085std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
3089 for (
auto&
f : fSubFields) {
3090 auto clone =
f->Clone(
f->GetName());
3091 result->Attach(std::move(clone));
3098 *fCollectionNTuple->GetOffsetPtr() = 0;
3104 std::unique_ptr<Detail::RFieldBase> itemField)
3111 Attach(std::move(itemField));
3114std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
3117 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetName());
3118 return std::make_unique<RAtomicField>(newName, GetType(), std::move(newItemField));
3121std::vector<ROOT::Experimental::Detail::RFieldBase::RValue>
3124 std::vector<RValue>
result;
3125 result.emplace_back(fSubFields[0]->BindValue(
value.GetRawPtr()));
#define R__FORWARD_RESULT(res)
Short-hand to return an RResult<T> value from a subroutine to the calling stack frame.
#define R__FAIL(msg)
Short-hand to return an RResult<T> in an error state; the RError is implicitly converted into RResult...
#define R__LOG_WARNING(...)
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t mask
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t target
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h length
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t child
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
static std::string GetTypeName(EColumnType type)
Similar to RValue but manages an array of consecutive values.
void * fValues
Pointer to the start of the array.
std::unique_ptr< bool[]> fMaskAvail
Masks invalid values in the array.
void Reset(const RClusterIndex &firstIndex, std::size_t size)
Sets a new range for the bulk.
RBulk & operator=(const RBulk &)=delete
Some fields have multiple possible column representations, e.g.
TypesList_t fSerializationTypes
TypesList_t fDeserializationTypes
The union of the serialization types and the deserialization extra types.
std::vector< ColumnRepresentation_t > TypesList_t
Points to an object with RNTuple I/O support and keeps a pointer to the corresponding field.
A field translates read and write calls from/to underlying columns to/from tree values.
RFieldBase * GetParent() const
void SetOnDiskId(DescriptorId_t id)
virtual void GenerateColumnsImpl()=0
Creates the backing columns corresponsing to the field type for writing.
std::vector< std::unique_ptr< RFieldBase > > fSubFields
Collections and classes own sub fields.
RConstSchemaIterator cend() const
RFieldBase * fParent
Sub fields point to their mother field.
static RResult< std::unique_ptr< RFieldBase > > Create(const std::string &fieldName, const std::string &canonicalType, const std::string &typeAlias)
Factory method to resurrect a field from the stored on-disk type information.
std::string GetName() const
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.
void CommitCluster()
Flushes data from active columns to disk and calls CommitClusterImpl.
int fTraits
Properties of the type that allow for optimizations of collections of that type.
static constexpr int kTraitTrivialType
Shorthand for types that are both trivially constructible and destructible.
friend class ROOT::Experimental::RCollectionField
void RemoveReadCallback(size_t idx)
RValue GenerateValue()
Generates an object of the field type and allocates new initialized memory according to the type.
virtual void ReadGlobalImpl(NTupleSize_t globalIndex, void *to)
void SetDescription(std::string_view description)
static RResult< void > EnsureValidFieldName(std::string_view fieldName)
Check whether a given string is a valid field name.
bool fIsSimple
A field qualifies as simple if it is both mappable and has no post-read callback.
std::string fType
The C++ type captured by this field.
std::function< void(void *)> ReadCallback_t
virtual std::vector< RValue > SplitValue(const RValue &value) const
Creates the list of direct child values given a value for this field.
std::string fName
The field name relative to its parent field.
size_t AddReadCallback(ReadCallback_t func)
Set a user-defined function to be called after reading a value, giving a chance to inspect and/or mod...
void ConnectPageSource(RPageSource &pageSource)
virtual std::size_t ReadBulkImpl(const RBulkSpec &bulkSpec)
General implementation of bulk read.
virtual std::size_t AppendImpl(const void *from)
Operations on values of complex types, e.g.
virtual void DestroyValue(void *objPtr, bool dtorOnly=false) const
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
virtual const RColumnRepresentations & GetColumnRepresentations() const
Implementations in derived classes should return a static RColumnRepresentations object.
std::unique_ptr< RFieldBase > Clone(std::string_view newName) const
Copies the field and its sub fields using a possibly new name and a new, unconnected set of columns.
std::size_t fNRepetitions
For fixed sized arrays, the array length.
virtual void AcceptVisitor(RFieldVisitor &visitor) const
ENTupleStructure fStructure
The role of this field in the data model structure.
void AutoAdjustColumnTypes(const RNTupleWriteOptions &options)
When connecting a field to a page sink, the field's default column representation is subject to adjus...
std::string GetQualifiedFieldName() const
Returns the field name and parent field names separated by dots ("grandparent.parent....
const ColumnRepresentation_t & GetColumnRepresentative() const
Returns the fColumnRepresentative pointee or, if unset, the field's default representative.
static constexpr int kTraitMappable
A field of a fundamental type that can be directly mapped via RField<T>::Map(), i....
void Attach(std::unique_ptr< Detail::RFieldBase > child)
Add a new subfield to the list of nested fields.
std::vector< RFieldBase * > GetSubFields() const
void SetColumnRepresentative(const ColumnRepresentation_t &representative)
Fixes a column representative.
void ConnectPageSink(RPageSink &pageSink, NTupleSize_t firstEntry=0)
Fields and their columns live in the void until connected to a physical page storage.
RConstSchemaIterator cbegin() const
static constexpr int kTraitTriviallyConstructible
No constructor needs to be called, i.e.
static constexpr int kTraitTriviallyDestructible
The type is cleaned up just by freeing its memory. I.e. DestroyValue() is a no-op.
const ColumnRepresentation_t & EnsureCompatibleColumnTypes(const RNTupleDescriptor &desc) const
Returns the on-disk column types found in the provided descriptor for fOnDiskId.
NTupleSize_t EntryToColumnElementIndex(NTupleSize_t globalIndex) const
Translate an entry index to a column element index of the principal column and viceversa.
std::vector< EColumnType > ColumnRepresentation_t
RColumn * fPrincipalColumn
Points into fColumns.
Abstract base class for classes implementing the visitor design pattern.
virtual void VisitProxiedCollectionField(const RProxiedCollectionField &field)
virtual void VisitBoolField(const RField< bool > &field)
virtual void VisitBitsetField(const RBitsetField &field)
virtual void VisitNullableField(const RNullableField &field)
virtual void VisitFieldZero(const RFieldZero &field)
virtual void VisitRVecField(const RRVecField &field)
virtual void VisitCardinalityField(const RCardinalityField &field)
virtual void VisitEnumField(const REnumField &field)
virtual void VisitField(const Detail::RFieldBase &field)=0
virtual void VisitDoubleField(const RField< double > &field)
virtual void VisitCharField(const RField< char > &field)
virtual void VisitArrayField(const RArrayField &field)
virtual void VisitClassField(const RClassField &field)
virtual void VisitRecordField(const RRecordField &field)
virtual void VisitVectorField(const RVectorField &field)
virtual void VisitFloatField(const RField< float > &field)
virtual void VisitAtomicField(const RAtomicField &field)
Abstract interface to write data into an ntuple.
const RNTupleWriteOptions & GetWriteOptions() const
Returns the sink's write options.
Abstract interface to read data from an ntuple.
const RSharedDescriptorGuard GetSharedDescriptorGuard() const
Takes the read lock for the descriptor.
void DestroyValue(void *objPtr, bool dtorOnly=false) const final
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
void ReadInClusterImpl(const RClusterIndex &clusterIndex, void *to) final
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
RArrayField(std::string_view fieldName, std::unique_ptr< Detail::RFieldBase > itemField, std::size_t arrayLength)
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
std::vector< RValue > SplitValue(const RValue &value) const final
Creates the list of direct child values given a value for this field.
std::unique_ptr< Detail::RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
RAtomicField(std::string_view fieldName, std::string_view typeName, std::unique_ptr< Detail::RFieldBase > itemField)
std::unique_ptr< Detail::RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
std::vector< RValue > SplitValue(const RValue &value) const final
Creates the list of direct child values given a value for this field.
const RColumnRepresentations & GetColumnRepresentations() const final
Implementations in derived classes should return a static RColumnRepresentations object.
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type for writing.
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
RBitsetField(std::string_view fieldName, std::size_t N)
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
const RField< RNTupleCardinality< std::uint32_t > > * As32Bit() const
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type for writing.
const RColumnRepresentations & GetColumnRepresentations() const final
Implementations in derived classes should return a static RColumnRepresentations object.
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
const RField< RNTupleCardinality< std::uint64_t > > * As64Bit() const
The field for a class with dictionary.
static constexpr const char * kPrefixInherited
Prefix used in the subfield names generated for base classes.
void OnConnectPageSource() final
Called by ConnectPageSource() only once connected; derived classes may override this as appropriate.
size_t GetValueSize() const override
The number of bytes taken by a value of the appropriate type.
void Attach(std::unique_ptr< Detail::RFieldBase > child, RSubFieldInfo info)
void DestroyValue(void *objPtr, bool dtorOnly=false) const final
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
std::unique_ptr< Detail::RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
void AddReadCallbacksFromIORules(const std::span< const TSchemaRule * > rules, TClass *classp=nullptr)
Register post-read callbacks corresponding to a list of ROOT I/O customization rules.
void AcceptVisitor(Detail::RFieldVisitor &visitor) const override
std::uint32_t GetTypeVersion() const final
Indicates an evolution of the C++ type itself.
std::vector< RValue > SplitValue(const RValue &value) const final
Creates the list of direct child values given a value for this field.
void ReadInClusterImpl(const RClusterIndex &clusterIndex, void *to) final
RClassField(std::string_view fieldName, std::string_view className, TClass *classp)
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
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type for writing.
void CommitClusterImpl() final
const RColumnRepresentations & GetColumnRepresentations() const final
Implementations in derived classes should return a static RColumnRepresentations object.
std::unique_ptr< Detail::RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
Holds the static meta-data of an RNTuple column.
Holds the index and the tag of a kSwitch column.
The field for an unscoped or scoped enum with dictionary.
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
std::unique_ptr< Detail::RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
std::vector< RValue > SplitValue(const RValue &value) const final
Creates the list of direct child values given a value for this field.
REnumField(std::string_view fieldName, std::string_view enumName, TEnum *enump)
Base class for all ROOT issued exceptions.
std::uint32_t GetTypeVersion() const
The container field for an ntuple model, which itself has no physical representation.
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
std::unique_ptr< Detail::RFieldBase > CloneImpl(std::string_view newName) const override
Called by Clone(), which additionally copies the on-disk ID.
Classes with dictionaries that can be inspected by TClass.
The generic field for a std::map<KeyType, ValueType> and std::unordered_map<KeyType,...
std::vector< RValue > SplitValue(const RValue &value) const final
Creates the list of direct child values given a value for this field.
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
std::unique_ptr< Detail::RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
RMapField(std::string_view fieldName, std::string_view typeName, std::unique_ptr< Detail::RFieldBase > itemField)
The on-storage meta-data of an ntuple.
const RFieldDescriptor & GetFieldDescriptor(DescriptorId_t fieldId) const
RColumnDescriptorIterable GetColumnIterable() const
static std::unique_ptr< RNTupleModel > Create()
Common user-tunable settings for storing ntuples.
int GetCompression() const
bool GetHasSmallClusters() const
The field for values that may or may not be present in an entry.
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type for writing.
const Detail::RFieldBase::RColumnRepresentations & GetColumnRepresentations() const final
Implementations in derived classes should return a static RColumnRepresentations object.
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
RClusterIndex GetItemIndex(NTupleSize_t globalIndex)
Given the index of the nullable field, returns the corresponding global index of the subfield or,...
RNullableField(std::string_view fieldName, std::string_view typeName, std::unique_ptr< Detail::RFieldBase > itemField)
std::size_t AppendValue(const void *from)
The generic field for std::pair<T1, T2> types.
std::unique_ptr< Detail::RFieldBase > CloneImpl(std::string_view newName) const override
Called by Clone(), which additionally copies the on-disk ID.
void DestroyValue(void *objPtr, bool dtorOnly=false) const override
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
RPairField(std::string_view fieldName, std::array< std::unique_ptr< Detail::RFieldBase >, 2 > &&itemFields, const std::array< std::size_t, 2 > &offsets)
Allows for iterating over the elements of a proxied collection.
static RIteratorFuncs GetIteratorFuncs(TVirtualCollectionProxy *proxy, bool readFromDisk)
The field for a class representing a collection of elements via TVirtualCollectionProxy.
std::size_t AppendImpl(const void *from) override
Operations on values of complex types, e.g.
RCollectionIterableOnce::RIteratorFuncs fIFuncsRead
Two sets of functions to operate on iterators, to be used depending on the access type.
void AcceptVisitor(Detail::RFieldVisitor &visitor) const override
std::unique_ptr< TVirtualCollectionProxy > fProxy
RProxiedCollectionField(std::string_view fieldName, std::string_view typeName, TClass *classp)
Constructor used when the value type of the collection is not known in advance, i....
std::unique_ptr< Detail::RFieldBase > CloneImpl(std::string_view newName) const override
Called by Clone(), which additionally copies the on-disk ID.
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type for writing.
const RColumnRepresentations & GetColumnRepresentations() const final
Implementations in derived classes should return a static RColumnRepresentations object.
void DestroyValue(void *objPtr, bool dtorOnly=false) const override
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
RCollectionIterableOnce::RIteratorFuncs fIFuncsWrite
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) override
size_t GetValueSize() const override
The number of bytes taken by a value of the appropriate type.
std::vector< RValue > SplitValue(const RValue &value) const override
Creates the list of direct child values given a value for this field.
std::size_t EvalValueSize() const
Evaluate the constant returned by GetValueSize.
const RColumnRepresentations & GetColumnRepresentations() const final
Implementations in derived classes should return a static RColumnRepresentations object.
RRVecField(std::string_view fieldName, std::unique_ptr< Detail::RFieldBase > itemField)
std::vector< RValue > SplitValue(const RValue &value) const final
Creates the list of direct child values given a value for this field.
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
void DestroyValue(void *objPtr, bool dtorOnly=false) const override
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
size_t GetAlignment() const override
As a rule of thumb, the alignment is equal to the size of the type.
std::unique_ptr< Detail::RFieldBase > CloneImpl(std::string_view newName) const override
Called by Clone(), which additionally copies the on-disk ID.
size_t GetValueSize() const override
The number of bytes taken by a value of the appropriate type.
std::size_t ReadBulkImpl(const RBulkSpec &bulkSpec) final
General implementation of bulk read.
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type for writing.
std::size_t AppendImpl(const void *from) override
Operations on values of complex types, e.g.
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) override
The field for an untyped record.
std::size_t fMaxAlignment
std::unique_ptr< Detail::RFieldBase > CloneImpl(std::string_view newName) const override
Called by Clone(), which additionally copies the on-disk ID.
std::vector< std::size_t > fOffsets
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
void ReadInClusterImpl(const RClusterIndex &clusterIndex, void *to) final
RRecordField(std::string_view fieldName, std::vector< std::unique_ptr< Detail::RFieldBase > > &&itemFields, const std::vector< std::size_t > &offsets, std::string_view typeName="")
std::size_t GetItemPadding(std::size_t baseOffset, std::size_t itemAlignment) const
void DestroyValue(void *objPtr, bool dtorOnly=false) const override
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
std::vector< RValue > SplitValue(const RValue &value) const final
Creates the list of direct child values given a value for this field.
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
The class is used as a return type for operations that can fail; wraps a value of type T or an RError...
RSetField(std::string_view fieldName, std::string_view typeName, std::unique_ptr< Detail::RFieldBase > itemField)
std::unique_ptr< Detail::RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
The generic field for std::tuple<Ts...> types.
std::unique_ptr< Detail::RFieldBase > CloneImpl(std::string_view newName) const override
Called by Clone(), which additionally copies the on-disk ID.
void DestroyValue(void *objPtr, bool dtorOnly=false) const override
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
RTupleField(std::string_view fieldName, std::vector< std::unique_ptr< Detail::RFieldBase > > &&itemFields, const std::vector< std::size_t > &offsets)
RUniquePtrField(std::string_view fieldName, std::string_view typeName, std::unique_ptr< Detail::RFieldBase > itemField)
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
std::vector< RValue > SplitValue(const RValue &value) const final
Creates the list of direct child values given a value for this field.
std::unique_ptr< Detail::RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
void DestroyValue(void *objPtr, bool dtorOnly=false) const final
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
void DestroyValue(void *objPtr, bool dtorOnly=false) const final
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
const RColumnRepresentations & GetColumnRepresentations() const final
Implementations in derived classes should return a static RColumnRepresentations object.
std::vector< ClusterSize_t::ValueType > fNWritten
size_t fTagOffset
In the std::variant memory layout, at which byte number is the index stored.
void SetTag(void *variantPtr, std::uint32_t tag) const
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type for writing.
void CommitClusterImpl() final
static std::string GetTypeList(const std::vector< Detail::RFieldBase * > &itemFields)
std::uint32_t GetTag(const void *variantPtr) const
Extracts the index from an std::variant and transforms it into the 1-based index used for the switch ...
RVariantField(std::string_view fieldName, const std::vector< Detail::RFieldBase * > &itemFields)
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
size_t GetAlignment() const final
As a rule of thumb, the alignment is equal to the size of the type.
std::unique_ptr< Detail::RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
std::unique_ptr< Detail::RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
const RColumnRepresentations & GetColumnRepresentations() const final
Implementations in derived classes should return a static RColumnRepresentations object.
std::vector< RValue > SplitValue(const RValue &value) const final
Creates the list of direct child values given a value for this field.
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type for writing.
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
void DestroyValue(void *objPtr, bool dtorOnly=false) const final
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
RVectorField(std::string_view fieldName, std::unique_ptr< Detail::RFieldBase > itemField)
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.
TList * GetListOfBases()
Return list containing the TBaseClass(es) of a class.
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Int_t GetClassSize() const
Long_t ClassProperty() const
Return the C++ property of this class, eg.
Long_t Property() const override
Returns the properties of the TClass as a bit field stored as a Long_t value.
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.
The TEnum class implements the enum type.
EDataType GetUnderlyingType() const
Get the underlying integer type of the enum: enum E { kOne }; // ==> int enum F: long; // ==> long Re...
Long_t Property() const override
Get property description word. For meaning of bits see EProperty.
static TEnum * GetEnum(const std::type_info &ti, ESearchAction sa=kALoadAndInterpLookup)
RAII helper class that ensures that PushProxy() / PopProxy() are called when entering / leaving a C++...
Defines a common interface to inspect/change the contents of an object that represents a collection.
@ kNeedDelete
The collection contains directly or indirectly (via other collection) some pointers that need explici...
virtual Next_t GetFunctionNext(Bool_t read=kTRUE)=0
Return a pointer to a function that can advance an iterator (see Next_t).
virtual DeleteTwoIterators_t GetFunctionDeleteTwoIterators(Bool_t read=kTRUE)=0
virtual TVirtualCollectionProxy * Generate() const =0
Returns a clean object of the actual class that derives from TVirtualCollectionProxy.
virtual CreateIterators_t GetFunctionCreateIterators(Bool_t read=kTRUE)=0
Return a pointer to a function that can create an iterator pair, where each iterator points to the be...
Wrapper around an object and giving indirect access to its content even if the object is not of a cla...
RLogChannel & NTupleLog()
Log channel for RNTuple diagnostics.
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.
constexpr ClusterSize_t kInvalidClusterIndex(std::uint64_t(-1))
constexpr DescriptorId_t kInvalidDescriptorId
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
std::string ResolveTypedef(const char *tname, bool resolveAll=false)
std::string CleanType(const char *typeDesc, int mode=0, const char **tail=nullptr)
Cleanup type description, redundant blanks removed and redundant tail ignored return *tail = pointer ...
Input parameter to ReadBulk() and ReadBulkImpl(). See RBulk class for more information.
bool * fMaskAvail
A bool array of size fCount, indicating the valid values in fValues.
std::vector< unsigned char > * fAuxData
Reference to memory owned by the RBulk class.
const bool * fMaskReq
A bool array of size fCount, indicating the required values in the requested range.
void * fValues
The destination area, which has to be a big enough array of valid objects of the correct type.
RClusterIndex fFirstIndex
Start of the bulk range.
std::size_t fCount
Size of the bulk range.
Wrap the integer in a struct in order to avoid template specialization clash with std::uint32_t.
TVirtualCollectionProxy::Next_t fNext
TVirtualCollectionProxy::DeleteTwoIterators_t fDeleteTwoIterators
TVirtualCollectionProxy::CreateIterators_t fCreateIterators