51#include <unordered_map>
55static const std::unordered_map<std::string_view, std::string_view> typeTranslationMap{
58 {
"Double_t",
"double"},
59 {
"string",
"std::string"},
62 {
"int8_t",
"std::int8_t"},
63 {
"signed char",
"char"},
64 {
"UChar_t",
"std::uint8_t"},
65 {
"unsigned char",
"std::uint8_t"},
66 {
"uint8_t",
"std::uint8_t"},
68 {
"Short_t",
"std::int16_t"},
69 {
"int16_t",
"std::int16_t"},
70 {
"short",
"std::int16_t"},
71 {
"UShort_t",
"std::uint16_t"},
72 {
"unsigned short",
"std::uint16_t"},
73 {
"uint16_t",
"std::uint16_t"},
75 {
"Int_t",
"std::int32_t"},
76 {
"int32_t",
"std::int32_t"},
77 {
"int",
"std::int32_t"},
78 {
"UInt_t",
"std::uint32_t"},
79 {
"unsigned",
"std::uint32_t"},
80 {
"unsigned int",
"std::uint32_t"},
81 {
"uint32_t",
"std::uint32_t"},
83 {
"Long_t",
"std::int64_t"},
84 {
"Long64_t",
"std::int64_t"},
85 {
"int64_t",
"std::int64_t"},
86 {
"long",
"std::int64_t"},
87 {
"ULong64_t",
"std::uint64_t"},
88 {
"unsigned long",
"std::uint64_t"},
89 {
"uint64_t",
"std::uint64_t"}
94std::vector<std::string> TokenizeTypeList(std::string templateType) {
95 std::vector<std::string>
result;
96 if (templateType.empty())
99 const char *eol = templateType.data() + templateType.length();
100 const char *typeBegin = templateType.data();
101 const char *typeCursor = templateType.data();
102 unsigned int nestingLevel = 0;
103 while (typeCursor != eol) {
104 switch (*typeCursor) {
112 if (nestingLevel == 0) {
113 result.push_back(std::string(typeBegin, typeCursor - typeBegin));
114 typeBegin = typeCursor + 1;
120 result.push_back(std::string(typeBegin, typeCursor - typeBegin));
129std::tuple<std::string, std::vector<size_t>> ParseArrayType(std::string_view typeName)
131 std::vector<size_t> sizeVec;
134 while (typeName.back() ==
']') {
135 auto posRBrace = typeName.size() - 1;
136 auto posLBrace = typeName.find_last_of(
"[", posRBrace);
137 if (posLBrace == std::string_view::npos)
141 if (std::from_chars(typeName.data() + posLBrace + 1, typeName.data() + posRBrace,
size).ec != std::errc{})
143 sizeVec.insert(sizeVec.begin(),
size);
144 typeName.remove_suffix(typeName.size() - posLBrace);
146 return std::make_tuple(std::string{typeName}, sizeVec);
152 if (normalizedType ==
"ROOT::Experimental::ClusterSize_t")
153 return normalizedType;
156 auto translatedType = typeTranslationMap.find(normalizedType);
157 if (translatedType != typeTranslationMap.end())
158 normalizedType = translatedType->second;
160 if (normalizedType.substr(0, 7) ==
"vector<")
161 normalizedType =
"std::" + normalizedType;
162 if (normalizedType.substr(0, 6) ==
"array<")
163 normalizedType =
"std::" + normalizedType;
164 if (normalizedType.substr(0, 8) ==
"variant<")
165 normalizedType =
"std::" + normalizedType;
166 if (normalizedType.substr(0, 5) ==
"pair<")
167 normalizedType =
"std::" + normalizedType;
168 if (normalizedType.substr(0, 6) ==
"tuple<")
169 normalizedType =
"std::" + normalizedType;
170 if (normalizedType.substr(0, 7) ==
"bitset<")
171 normalizedType =
"std::" + normalizedType;
172 if (normalizedType.substr(0, 11) ==
"unique_ptr<")
173 normalizedType =
"std::" + normalizedType;
175 return normalizedType;
180std::tuple<void **, std::int32_t *, std::int32_t *> GetRVecDataMembers(
void *rvecPtr)
182 void **begin =
reinterpret_cast<void **
>(rvecPtr);
184 std::int32_t *
size =
reinterpret_cast<std::int32_t *
>(begin + 1);
187 std::int32_t *capacity =
size + 1;
189 return {begin,
size, capacity};
205 : fSerializationTypes(serializationTypes), fDeserializationTypes(serializationTypes)
208 deserializationExtraTypes.begin(), deserializationExtraTypes.end());
226 std::string
result = GetName();
228 while (parent && !parent->
GetName().empty()) {
238 std::string normalizedType(GetNormalizedType(typeName));
239 if (normalizedType.empty())
240 return R__FAIL(
"no type name specified for Field " + fieldName);
242 std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
result;
244 if (
auto [arrayBaseType, arraySize] = ParseArrayType(normalizedType); !arraySize.empty()) {
246 if (arraySize.size() > 1)
247 return R__FAIL(
"multi-dimensional array type not supported " + normalizedType);
248 auto itemField = Create(GetNormalizedType(arrayBaseType), arrayBaseType);
249 return {std::make_unique<RArrayField>(fieldName, itemField.Unwrap(), arraySize[0])};
252 if (normalizedType ==
"ROOT::Experimental::ClusterSize_t") {
253 result = std::make_unique<RField<ClusterSize_t>>(fieldName);
254 }
else if (normalizedType ==
"ROOT::Experimental::RNTupleCardinality") {
255 result = std::make_unique<RField<RNTupleCardinality>>(fieldName);
256 }
else if (normalizedType ==
"bool") {
257 result = std::make_unique<RField<bool>>(fieldName);
258 }
else if (normalizedType ==
"char") {
259 result = std::make_unique<RField<char>>(fieldName);
260 }
else if (normalizedType ==
"std::int8_t") {
261 result = std::make_unique<RField<std::int8_t>>(fieldName);
262 }
else if (normalizedType ==
"std::uint8_t") {
263 result = std::make_unique<RField<std::uint8_t>>(fieldName);
264 }
else if (normalizedType ==
"std::int16_t") {
265 result = std::make_unique<RField<std::int16_t>>(fieldName);
266 }
else if (normalizedType ==
"std::uint16_t") {
267 result = std::make_unique<RField<std::uint16_t>>(fieldName);
268 }
else if (normalizedType ==
"std::int32_t") {
269 result = std::make_unique<RField<std::int32_t>>(fieldName);
270 }
else if (normalizedType ==
"std::uint32_t") {
271 result = std::make_unique<RField<std::uint32_t>>(fieldName);
272 }
else if (normalizedType ==
"std::int64_t") {
273 result = std::make_unique<RField<std::int64_t>>(fieldName);
274 }
else if (normalizedType ==
"std::uint64_t") {
275 result = std::make_unique<RField<std::uint64_t>>(fieldName);
276 }
else if (normalizedType ==
"float") {
277 result = std::make_unique<RField<float>>(fieldName);
278 }
else if (normalizedType ==
"double") {
279 result = std::make_unique<RField<double>>(fieldName);
280 }
else if (normalizedType ==
"std::string") {
281 result = std::make_unique<RField<std::string>>(fieldName);
282 }
else if (normalizedType ==
"std::vector<bool>") {
283 result = std::make_unique<RField<std::vector<bool>>>(fieldName);
284 }
else if (normalizedType.substr(0, 12) ==
"std::vector<") {
285 std::string itemTypeName = normalizedType.substr(12, normalizedType.length() - 13);
286 auto itemField = Create(
"_0", itemTypeName);
287 result = std::make_unique<RVectorField>(fieldName, itemField.Unwrap());
288 }
else if (normalizedType.substr(0, 19) ==
"ROOT::VecOps::RVec<") {
289 std::string itemTypeName = normalizedType.substr(19, normalizedType.length() - 20);
290 auto itemField = Create(
"_0", itemTypeName);
291 result = std::make_unique<RRVecField>(fieldName, itemField.Unwrap());
292 }
else if (normalizedType.substr(0, 11) ==
"std::array<") {
293 auto arrayDef = TokenizeTypeList(normalizedType.substr(11, normalizedType.length() - 12));
295 auto arrayLength = std::stoi(arrayDef[1]);
296 auto itemField = Create(GetNormalizedType(arrayDef[0]), arrayDef[0]);
297 result = std::make_unique<RArrayField>(fieldName, itemField.Unwrap(), arrayLength);
299 if (normalizedType.substr(0, 13) ==
"std::variant<") {
300 auto innerTypes = TokenizeTypeList(normalizedType.substr(13, normalizedType.length() - 14));
301 std::vector<RFieldBase *> items;
302 for (
unsigned int i = 0; i < innerTypes.size(); ++i) {
303 items.emplace_back(Create(
"_" + std::to_string(i), innerTypes[i]).Unwrap().release());
305 result = std::make_unique<RVariantField>(fieldName, items);
307 if (normalizedType.substr(0, 10) ==
"std::pair<") {
308 auto innerTypes = TokenizeTypeList(normalizedType.substr(10, normalizedType.length() - 11));
309 if (innerTypes.size() != 2)
310 return R__FAIL(
"the type list for std::pair must have exactly two elements");
311 std::array<std::unique_ptr<RFieldBase>, 2> items{Create(
"_0", innerTypes[0]).Unwrap(),
312 Create(
"_1", innerTypes[1]).Unwrap()};
313 result = std::make_unique<RPairField>(fieldName, items);
315 if (normalizedType.substr(0, 11) ==
"std::tuple<") {
316 auto innerTypes = TokenizeTypeList(normalizedType.substr(11, normalizedType.length() - 12));
317 std::vector<std::unique_ptr<RFieldBase>> items;
318 for (
unsigned int i = 0; i < innerTypes.size(); ++i) {
319 items.emplace_back(Create(
"_" + std::to_string(i), innerTypes[i]).Unwrap());
321 result = std::make_unique<RTupleField>(fieldName, items);
323 if (normalizedType.substr(0, 12) ==
"std::bitset<") {
324 auto size = std::stoull(normalizedType.substr(12, normalizedType.length() - 13));
325 result = std::make_unique<RBitsetField>(fieldName,
size);
327 if (normalizedType.substr(0, 16) ==
"std::unique_ptr<") {
328 std::string itemTypeName = normalizedType.substr(16, normalizedType.length() - 17);
329 auto itemField = Create(
"_0", itemTypeName).Unwrap();
330 auto normalizedInnerTypeName = itemField->GetType();
331 result = std::make_unique<RUniquePtrField>(fieldName,
"std::unique_ptr<" + normalizedInnerTypeName +
">",
332 std::move(itemField));
335 if (normalizedType ==
":Collection:")
336 result = std::make_unique<RField<ClusterSize_t>>(fieldName);
341 if (cl->GetCollectionProxy())
342 result = std::make_unique<RCollectionClassField>(fieldName, normalizedType);
344 result = std::make_unique<RClassField>(fieldName, normalizedType);
350 return R__FAIL(std::string(
"Field ") + fieldName +
" has unknown type " + normalizedType);
356 if (fieldName ==
"") {
357 return R__FAIL(
"name cannot be empty string \"\"");
358 }
else if (fieldName.find(
".") != std::string::npos) {
359 return R__FAIL(
"name '" + std::string(fieldName) +
"' cannot contain dot characters '.'");
368 return representations;
371std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
374 auto clone = CloneImpl(newName);
375 clone->fOnDiskId = fOnDiskId;
376 clone->fDescription = fDescription;
378 clone->fColumnRepresentative = fColumnRepresentative;
384 R__ASSERT(
false &&
"A non-simple RField must implement its own AppendImpl");
397 void *where =
malloc(GetValueSize());
399 return GenerateValue(where);
408std::vector<ROOT::Experimental::Detail::RFieldValue>
411 return std::vector<RFieldValue>();
415 std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
child)
417 child->fParent =
this;
418 fSubFields.emplace_back(std::move(
child));
424 std::vector<RFieldBase *>
result;
425 for (
const auto &
f : fSubFields) {
434 for (
auto& column : fColumns) {
442 if (fColumnRepresentative)
443 return *fColumnRepresentative;
444 return GetColumnRepresentations().GetSerializationDefault();
449 if (!fColumns.empty())
450 throw RException(
R__FAIL(
"cannot set column representative once field is connected"));
451 const auto &validTypes = GetColumnRepresentations().GetSerializationTypes();
452 auto itRepresentative = std::find(validTypes.begin(), validTypes.end(), representative);
453 if (itRepresentative == std::end(validTypes))
455 fColumnRepresentative = &(*itRepresentative);
462 throw RException(
R__FAIL(
"No on-disk column information for for field `" + GetQualifiedFieldName() +
"`"));
466 onDiskTypes.emplace_back(
c.GetModel().GetType());
468 for (
const auto &t : GetColumnRepresentations().GetDeserializationTypes()) {
469 if (t == onDiskTypes)
473 std::string columnTypeNames;
474 for (
const auto &t : onDiskTypes) {
475 if (!columnTypeNames.empty())
476 columnTypeNames +=
", ";
479 throw RException(
R__FAIL(
"On-disk column types `" + columnTypeNames +
"` for field `" + GetQualifiedFieldName() +
480 "` cannot be matched."));
485 fReadCallbacks.push_back(func);
487 return fReadCallbacks.size() - 1;
492 fReadCallbacks.erase(fReadCallbacks.begin() + idx);
493 fIsSimple = (fTraits & kTraitMappable) && fReadCallbacks.empty();
498 if ((options.
GetCompression() == 0) && HasDefaultColumnRepresentative()) {
500 for (
auto &colType : rep) {
512 SetColumnRepresentative(rep);
517 for (
auto &colType : rep) {
524 SetColumnRepresentative(rep);
534 GenerateColumnsImpl();
535 if (!fColumns.empty())
536 fPrincipalColumn = fColumns[0].get();
537 for (
auto& column : fColumns)
538 column->Connect(fOnDiskId, &pageSink);
545 if (fColumnRepresentative)
546 throw RException(
R__FAIL(
"fixed column representative only valid when connecting to a page sink"));
551 GenerateColumnsImpl(desc);
553 for (
const auto &
c : fColumns) {
554 onDiskColumnTypes.emplace_back(
c->GetModel().GetType());
556 for (
const auto &t : GetColumnRepresentations().GetDeserializationTypes()) {
557 if (t == onDiskColumnTypes)
558 fColumnRepresentative = &t;
564 if (!fColumns.empty())
565 fPrincipalColumn = fColumns[0].get();
566 for (
auto& column : fColumns)
567 column->Connect(fOnDiskId, &pageSource);
568 OnConnectPageSource();
596 auto itr = fStack.rbegin();
597 if (!itr->fFieldPtr->fSubFields.empty()) {
598 fStack.emplace_back(
Position(itr->fFieldPtr->fSubFields[0].get(), 0));
602 unsigned int nextIdxInParent = ++(itr->fIdxInParent);
603 while (nextIdxInParent >= itr->fFieldPtr->fParent->fSubFields.size()) {
604 if (fStack.size() == 1) {
605 itr->fFieldPtr = itr->fFieldPtr->fParent;
606 itr->fIdxInParent = -1;
610 itr = fStack.rbegin();
611 nextIdxInParent = ++(itr->fIdxInParent);
613 itr->fFieldPtr = itr->fFieldPtr->fParent->fSubFields[nextIdxInParent].get();
620std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
623 auto result = std::make_unique<RFieldZero>();
624 for (
auto &
f : fSubFields)
625 result->Attach(
f->Clone(
f->GetName()));
641 static RColumnRepresentations representations(
644 return representations;
649 fColumns.emplace_back(Detail::RColumn::Create<ClusterSize_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
654 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
655 fColumns.emplace_back(Detail::RColumn::Create<ClusterSize_t>(RColumnModel(onDiskTypes[0]), 0));
660 visitor.VisitClusterSizeField(*
this);
668 static RColumnRepresentations representations(
671 return representations;
675 const RNTupleDescriptor &desc)
677 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
678 fColumns.emplace_back(Detail::RColumn::Create<ClusterSize_t>(RColumnModel(onDiskTypes[0]), 0));
682 Detail::RFieldVisitor &visitor)
const
684 visitor.VisitCardinalityField(*
this);
693 return representations;
698 fColumns.emplace_back(Detail::RColumn::Create<char>(
RColumnModel(GetColumnRepresentative()[0]), 0));
703 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
704 fColumns.emplace_back(Detail::RColumn::Create<char>(
RColumnModel(onDiskTypes[0]), 0));
718 return representations;
723 fColumns.emplace_back(Detail::RColumn::Create<std::int8_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
728 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
729 fColumns.emplace_back(Detail::RColumn::Create<std::int8_t>(RColumnModel(onDiskTypes[0]), 0));
734 visitor.VisitInt8Field(*
this);
743 return representations;
748 fColumns.emplace_back(Detail::RColumn::Create<std::uint8_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
753 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
754 fColumns.emplace_back(Detail::RColumn::Create<std::uint8_t>(RColumnModel(onDiskTypes[0]), 0));
759 visitor.VisitUInt8Field(*
this);
768 return representations;
773 fColumns.emplace_back(Detail::RColumn::Create<bool>(
RColumnModel(GetColumnRepresentative()[0]), 0));
778 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
779 fColumns.emplace_back(Detail::RColumn::Create<bool>(
RColumnModel(onDiskTypes[0]), 0));
793 return representations;
798 fColumns.emplace_back(Detail::RColumn::Create<float>(
RColumnModel(GetColumnRepresentative()[0]), 0));
803 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
804 fColumns.emplace_back(Detail::RColumn::Create<float>(
RColumnModel(onDiskTypes[0]), 0));
819 return representations;
824 fColumns.emplace_back(Detail::RColumn::Create<double>(
RColumnModel(GetColumnRepresentative()[0]), 0));
829 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
830 fColumns.emplace_back(Detail::RColumn::Create<double>(
RColumnModel(onDiskTypes[0]), 0));
844 return representations;
849 fColumns.emplace_back(Detail::RColumn::Create<std::int16_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
854 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
855 fColumns.emplace_back(Detail::RColumn::Create<std::int16_t>(RColumnModel(onDiskTypes[0]), 0));
860 visitor.VisitInt16Field(*
this);
869 return representations;
874 fColumns.emplace_back(Detail::RColumn::Create<std::uint16_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
879 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
880 fColumns.emplace_back(Detail::RColumn::Create<std::uint16_t>(RColumnModel(onDiskTypes[0]), 0));
885 visitor.VisitUInt16Field(*
this);
894 return representations;
899 fColumns.emplace_back(Detail::RColumn::Create<std::int32_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
904 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
905 fColumns.emplace_back(Detail::RColumn::Create<std::int32_t>(RColumnModel(onDiskTypes[0]), 0));
910 visitor.VisitIntField(*
this);
919 return representations;
924 fColumns.emplace_back(Detail::RColumn::Create<std::uint32_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
929 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
930 fColumns.emplace_back(Detail::RColumn::Create<std::uint32_t>(RColumnModel(onDiskTypes[0]), 0));
935 visitor.VisitUInt32Field(*
this);
944 return representations;
949 fColumns.emplace_back(Detail::RColumn::Create<std::uint64_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
954 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
955 fColumns.emplace_back(Detail::RColumn::Create<std::uint64_t>(RColumnModel(onDiskTypes[0]), 0));
960 visitor.VisitUInt64Field(*
this);
970 return representations;
975 fColumns.emplace_back(Detail::RColumn::Create<std::int64_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
980 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
981 fColumns.emplace_back(Detail::RColumn::Create<std::int64_t>(RColumnModel(onDiskTypes[0]), 0));
986 visitor.VisitInt64Field(*
this);
999 return representations;
1004 fColumns.emplace_back(Detail::RColumn::Create<ClusterSize_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
1005 fColumns.emplace_back(Detail::RColumn::Create<char>(RColumnModel(GetColumnRepresentative()[1]), 1));
1010 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1011 fColumns.emplace_back(Detail::RColumn::Create<ClusterSize_t>(RColumnModel(onDiskTypes[0]), 0));
1012 fColumns.emplace_back(Detail::RColumn::Create<char>(RColumnModel(onDiskTypes[1]), 1));
1017 auto typedValue =
value.Get<std::string>();
1018 auto length = typedValue->length();
1019 Detail::RColumnElement<char> elemChars(
const_cast<char*
>(typedValue->data()));
1020 fColumns[1]->AppendV(elemChars,
length);
1022 fColumns[0]->Append(fElemIndex);
1023 return length +
sizeof(fElemIndex);
1029 auto typedValue =
value->Get<std::string>();
1030 RClusterIndex collectionStart;
1032 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nChars);
1034 typedValue->clear();
1036 typedValue->resize(nChars);
1037 Detail::RColumnElement<char> elemChars(
const_cast<char*
>(typedValue->data()));
1038 fColumns[1]->ReadV(collectionStart, nChars, &elemChars);
1049 visitor.VisitStringField(*
this);
1065 throw RException(
R__FAIL(
"RField: no I/O support for type " + std::string(className)));
1073 R__FAIL(std::string(className) +
" has an associated collection proxy; use RCollectionClassField instead"));
1083 TClass *
c = baseClass->GetClassPointer();
1085 c->GetName()).Unwrap();
1086 fTraits &= subField->GetTraits();
1087 Attach(std::move(subField),
1096 if (!dataMember->IsPersistent()) {
1102 std::string typeName{dataMember->GetFullTypeName()};
1104 if (dataMember->Property() &
kIsArray) {
1105 for (
int dim = 0,
n = dataMember->GetArrayDim(); dim <
n; ++dim)
1106 typeName +=
"[" + std::to_string(dataMember->GetMaxIndex(dim)) +
"]";
1109 fTraits &= subField->GetTraits();
1110 Attach(std::move(subField),
1117 fMaxAlignment = std::max(fMaxAlignment,
child->GetAlignment());
1118 fSubFieldsInfo.push_back(info);
1119 RFieldBase::Attach(std::move(
child));
1125 for (
const auto rule : rules) {
1130 auto func = rule->GetReadFunctionPointer();
1135 oldObj.fObject =
value.GetRawPtr();
1136 func(
static_cast<char *
>(
value.GetRawPtr()), &oldObj);
1137 oldObj.fClass =
nullptr;
1142std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
1145 return std::unique_ptr<RClassField>(
new RClassField(newName, GetType(),
fClass));
1149 std::size_t nbytes = 0;
1150 for (
unsigned i = 0; i < fSubFields.size(); i++) {
1151 auto memberValue = fSubFields[i]->CaptureValue(
value.Get<
unsigned char>() + fSubFieldsInfo[i].fOffset);
1152 nbytes += fSubFields[i]->Append(memberValue);
1159 for (
unsigned i = 0; i < fSubFields.size(); i++) {
1160 auto memberValue = fSubFields[i]->CaptureValue(
value->Get<
unsigned char>() + fSubFieldsInfo[i].fOffset);
1161 fSubFields[i]->Read(globalIndex, &memberValue);
1167 for (
unsigned i = 0; i < fSubFields.size(); i++) {
1168 auto memberValue = fSubFields[i]->CaptureValue(
value->Get<
unsigned char>() + fSubFieldsInfo[i].fOffset);
1169 fSubFields[i]->Read(clusterIndex, &memberValue);
1177 const auto ruleset =
fClass->GetSchemaRules();
1181 if (rule->GetTarget() ==
nullptr)
1184 const auto dataMember = klass->GetDataMember(
target->GetString());
1185 if (!dataMember || dataMember->IsPersistent()) {
1187 << dataMember->GetName();
1194 auto rules = ruleset->FindRules(
fClass->GetName(),
static_cast<Int_t>(GetOnDiskTypeVersion()));
1195 rules.erase(std::remove_if(rules.begin(), rules.end(), referencesNonTransientMembers), rules.end());
1196 AddReadCallbacksFromIORules(rules,
fClass);
1217std::vector<ROOT::Experimental::Detail::RFieldValue>
1220 std::vector<Detail::RFieldValue>
result;
1221 for (
unsigned i = 0; i < fSubFields.size(); i++) {
1222 auto memberValue = fSubFields[i]->CaptureValue(
value.Get<
unsigned char>() + fSubFieldsInfo[i].fOffset);
1223 result.emplace_back(memberValue);
1231 return fClass->GetClassSize();
1236 return fClass->GetClassVersion();
1255 (ifuncs.
fNext !=
nullptr));
1269 if (classp ==
nullptr)
1270 throw RException(
R__FAIL(
"RField: no I/O support for collection proxy type " + std::string(className)));
1272 throw RException(
R__FAIL(std::string(className) +
" has no associated collection proxy"));
1276 if (
fProxy->HasPointers())
1277 throw RException(
R__FAIL(
"collection proxies whose value type is a pointer are not supported"));
1284 std::unique_ptr<ROOT::Experimental::Detail::RFieldBase> itemField;
1285 if (
auto valueClass =
fProxy->GetValueClass()) {
1287 itemField = RFieldBase::Create(
"_0", valueClass->GetName()).Unwrap();
1289 switch (
fProxy->GetType()) {
1291 case EDataType::kUChar_t: itemField = std::make_unique<RField<std::uint8_t>>(
"_0");
break;
1292 case EDataType::kShort_t: itemField = std::make_unique<RField<std::int16_t>>(
"_0");
break;
1294 case EDataType::kInt_t: itemField = std::make_unique<RField<std::int32_t>>(
"_0");
break;
1295 case EDataType::kUInt_t: itemField = std::make_unique<RField<std::uint32_t>>(
"_0");
break;
1298 itemField = std::make_unique<RField<std::int64_t>>(
"_0");
1302 itemField = std::make_unique<RField<std::uint64_t>>(
"_0");
1312 Attach(std::move(itemField));
1315std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
1318 return std::unique_ptr<RCollectionClassField>(
1324 std::size_t nbytes = 0;
1328 auto itemValue = fSubFields[0]->CaptureValue(ptr);
1329 nbytes += fSubFields[0]->Append(itemValue);
1335 fColumns[0]->Append(elemIndex);
1336 return nbytes +
sizeof(elemIndex);
1343 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
1351 auto itemValue = fSubFields[0]->CaptureValue(ptr);
1352 fSubFields[0]->Read(collectionStart + i, &itemValue);
1355 if (obj !=
value->GetRawPtr())
1356 fProxy->Commit(obj);
1365 return representations;
1370 fColumns.emplace_back(Detail::RColumn::Create<ClusterSize_t>(
RColumnModel(GetColumnRepresentative()[0]), 0));
1375 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1376 fColumns.emplace_back(Detail::RColumn::Create<ClusterSize_t>(
RColumnModel(onDiskTypes[0]), 0));
1389 auto itemValue = fSubFields[0]->CaptureValue(ptr);
1390 fSubFields[0]->DestroyValue(itemValue,
true );
1393 fProxy->Destructor(
value.GetRawPtr(),
true );
1403std::vector<ROOT::Experimental::Detail::RFieldValue>
1406 std::vector<Detail::RFieldValue>
result;
1409 result.emplace_back(fSubFields[0]->CaptureValue(ptr));
1427 std::vector<std::unique_ptr<Detail::RFieldBase>> &&itemFields,
1428 const std::vector<std::size_t> &offsets, std::string_view typeName)
1433 for (
auto &item : itemFields) {
1442 std::vector<std::unique_ptr<Detail::RFieldBase>> &&itemFields)
1446 for (
auto &item : itemFields) {
1450 fSize += item->GetValueSize();
1460 std::vector<std::unique_ptr<Detail::RFieldBase>> &itemFields)
1467 if (itemAlignment > 1) {
1468 auto remainder = baseOffset % itemAlignment;
1470 return itemAlignment - remainder;
1475std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
1478 std::vector<std::unique_ptr<Detail::RFieldBase>> cloneItems;
1479 for (
auto &item : fSubFields)
1480 cloneItems.emplace_back(item->Clone(item->GetName()));
1481 return std::unique_ptr<RRecordField>(
new RRecordField(newName, std::move(cloneItems), fOffsets, GetType()));
1485 std::size_t nbytes = 0;
1486 for (
unsigned i = 0; i < fSubFields.size(); ++i) {
1487 auto memberValue = fSubFields[i]->CaptureValue(
value.Get<
unsigned char>() + fOffsets[i]);
1488 nbytes += fSubFields[i]->Append(memberValue);
1495 for (
unsigned i = 0; i < fSubFields.size(); ++i) {
1496 auto memberValue = fSubFields[i]->CaptureValue(
value->Get<
unsigned char>() + fOffsets[i]);
1497 fSubFields[i]->Read(globalIndex, &memberValue);
1503 for (
unsigned i = 0; i < fSubFields.size(); ++i) {
1504 auto memberValue = fSubFields[i]->CaptureValue(
value->Get<
unsigned char>() + fOffsets[i]);
1505 fSubFields[i]->Read(clusterIndex, &memberValue);
1511 for (
unsigned i = 0; i < fSubFields.size(); ++i) {
1512 fSubFields[i]->GenerateValue(
static_cast<unsigned char *
>(where) + fOffsets[i]);
1519 for (
unsigned i = 0; i < fSubFields.size(); ++i) {
1520 auto memberValue = fSubFields[i]->CaptureValue(
value.Get<
unsigned char>() + fOffsets[i]);
1521 fSubFields[i]->DestroyValue(memberValue,
true );
1534std::vector<ROOT::Experimental::Detail::RFieldValue>
1537 std::vector<Detail::RFieldValue>
result;
1538 for (
unsigned i = 0; i < fSubFields.size(); ++i) {
1539 result.emplace_back(fSubFields[i]->CaptureValue(
value.Get<
unsigned char>() + fOffsets[i]));
1554 std::string_view fieldName, std::unique_ptr<Detail::RFieldBase> itemField)
1557 , fItemSize(itemField->GetValueSize()), fNWritten(0)
1559 Attach(std::move(itemField));
1562std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
1565 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetName());
1566 return std::make_unique<RVectorField>(newName, std::move(newItemField));
1570 auto typedValue =
value.Get<std::vector<char>>();
1571 R__ASSERT((typedValue->size() % fItemSize) == 0);
1572 std::size_t nbytes = 0;
1573 auto count = typedValue->size() / fItemSize;
1574 for (
unsigned i = 0; i < count; ++i) {
1575 auto itemValue = fSubFields[0]->CaptureValue(typedValue->data() + (i * fItemSize));
1576 nbytes += fSubFields[0]->Append(itemValue);
1580 fColumns[0]->Append(elemIndex);
1581 return nbytes +
sizeof(elemIndex);
1586 auto typedValue =
value->Get<std::vector<char>>();
1590 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
1592 if (fSubFields[0]->GetTraits() & kTraitTrivialType) {
1593 typedValue->resize(nItems * fItemSize);
1596 const auto oldNItems = typedValue->size() / fItemSize;
1597 const bool canRealloc = oldNItems < nItems;
1598 bool allDeallocated =
false;
1599 if (!(fSubFields[0]->GetTraits() & kTraitTriviallyDestructible)) {
1600 allDeallocated = canRealloc;
1601 for (std::size_t i = allDeallocated ? 0 : nItems; i < oldNItems; ++i) {
1602 auto itemValue = fSubFields[0]->CaptureValue(typedValue->data() + (i * fItemSize));
1603 fSubFields[0]->DestroyValue(itemValue,
true );
1606 typedValue->resize(nItems * fItemSize);
1607 if (!(fSubFields[0]->GetTraits() & kTraitTriviallyConstructible)) {
1608 for (std::size_t i = allDeallocated ? 0 : oldNItems; i < nItems; ++i) {
1609 fSubFields[0]->GenerateValue(typedValue->data() + (i * fItemSize));
1614 for (std::size_t i = 0; i < nItems; ++i) {
1615 auto itemValue = fSubFields[0]->CaptureValue(typedValue->data() + (i * fItemSize));
1616 fSubFields[0]->Read(collectionStart + i, &itemValue);
1626 return representations;
1631 fColumns.emplace_back(Detail::RColumn::Create<ClusterSize_t>(
RColumnModel(GetColumnRepresentative()[0]), 0));
1636 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1637 fColumns.emplace_back(Detail::RColumn::Create<ClusterSize_t>(
RColumnModel(onDiskTypes[0]), 0));
1647 auto vec =
static_cast<std::vector<char>*
>(
value.GetRawPtr());
1649 if (!(fSubFields[0]->GetTraits() & kTraitTriviallyDestructible)) {
1650 auto nItems =
vec->size() / fItemSize;
1651 for (
unsigned i = 0; i < nItems; ++i) {
1652 auto itemValue = fSubFields[0]->CaptureValue(
vec->data() + (i * fItemSize));
1653 fSubFields[0]->DestroyValue(itemValue,
true );
1666std::vector<ROOT::Experimental::Detail::RFieldValue>
1669 auto vec =
static_cast<std::vector<char>*
>(
value.GetRawPtr());
1671 auto nItems =
vec->size() / fItemSize;
1672 std::vector<Detail::RFieldValue>
result;
1673 for (
unsigned i = 0; i < nItems; ++i) {
1674 result.emplace_back(fSubFields[0]->CaptureValue(
vec->data() + (i * fItemSize)));
1693 :
ROOT::Experimental::Detail::
RFieldBase(fieldName,
"ROOT::VecOps::RVec<" + itemField->GetType() +
">",
1695 fItemSize(itemField->GetValueSize()), fNWritten(0)
1697 Attach(std::move(itemField));
1701std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
1704 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetName());
1705 return std::make_unique<RRVecField>(newName, std::move(newItemField));
1710 auto [beginPtr, sizePtr,
_] = GetRVecDataMembers(
value.GetRawPtr());
1712 std::size_t nbytes = 0;
1713 char *begin =
reinterpret_cast<char *
>(*beginPtr);
1714 for (std::int32_t i = 0; i < *sizePtr; ++i) {
1715 auto elementValue = fSubFields[0]->CaptureValue(begin + i * fItemSize);
1716 nbytes += fSubFields[0]->Append(elementValue);
1720 fNWritten += *sizePtr;
1721 fColumns[0]->Append(elemIndex);
1722 return nbytes +
sizeof(elemIndex);
1730 auto [beginPtr, sizePtr, capacityPtr] = GetRVecDataMembers(
value->GetRawPtr());
1735 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
1736 char *begin =
reinterpret_cast<char *
>(*beginPtr);
1737 const std::size_t oldSize = *sizePtr;
1741 const bool needsConstruct = !(fSubFields[0]->GetTraits() & kTraitTriviallyConstructible);
1742 const bool needsDestruct = !(fSubFields[0]->GetTraits() & kTraitTriviallyDestructible);
1745 if (needsDestruct) {
1746 for (std::size_t i = nItems; i < oldSize; ++i) {
1747 auto itemValue = fSubFields[0]->CaptureValue(begin + (i * fItemSize));
1748 fSubFields[0]->DestroyValue(itemValue,
true );
1753 if (std::int32_t(nItems) > *capacityPtr) {
1756 if (needsDestruct) {
1757 for (std::size_t i = 0u; i < oldSize; ++i) {
1758 auto itemValue = fSubFields[0]->CaptureValue(begin + (i * fItemSize));
1759 fSubFields[0]->DestroyValue(itemValue,
true );
1767 *beginPtr =
malloc(nItems * fItemSize);
1769 begin =
reinterpret_cast<char *
>(*beginPtr);
1770 *capacityPtr = nItems;
1773 if (needsConstruct) {
1774 for (std::size_t i = 0u; i < oldSize; ++i)
1775 fSubFields[0]->GenerateValue(begin + (i * fItemSize));
1781 if (needsConstruct) {
1782 for (std::size_t i = oldSize; i < nItems; ++i)
1783 fSubFields[0]->GenerateValue(begin + (i * fItemSize));
1787 for (std::size_t i = 0; i < nItems; ++i) {
1788 auto itemValue = fSubFields[0]->CaptureValue(begin + (i * fItemSize));
1789 fSubFields[0]->Read(collectionStart + i, &itemValue);
1799 return representations;
1804 fColumns.emplace_back(Detail::RColumn::Create<ClusterSize_t>(
RColumnModel(GetColumnRepresentative()[0]), 0));
1809 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1810 fColumns.emplace_back(Detail::RColumn::Create<ClusterSize_t>(
RColumnModel(onDiskTypes[0]), 0));
1817 void **beginPtr =
new (where)(
void *)(
nullptr);
1818 std::int32_t *sizePtr =
new (
reinterpret_cast<void *
>(beginPtr + 1)) std::int32_t(0);
1819 new (sizePtr + 1) std::int32_t(0);
1826 auto [beginPtr, sizePtr, capacityPtr] = GetRVecDataMembers(
value.GetRawPtr());
1828 char *begin =
reinterpret_cast<char *
>(*beginPtr);
1829 if (!(fSubFields[0]->GetTraits() & kTraitTriviallyDestructible)) {
1830 for (std::int32_t i = 0; i < *sizePtr; ++i) {
1831 auto elementValue = fSubFields[0]->CaptureValue(begin + i * fItemSize);
1832 fSubFields[0]->DestroyValue(elementValue,
true );
1838 constexpr auto dataMemberSz =
sizeof(
void *) + 2 *
sizeof(std::int32_t);
1839 const auto alignOfT = fSubFields[0]->GetAlignment();
1840 auto paddingMiddle = dataMemberSz % alignOfT;
1841 if (paddingMiddle != 0)
1842 paddingMiddle = alignOfT - paddingMiddle;
1843 const bool isSmall = (
reinterpret_cast<void *
>(begin) == (beginPtr + dataMemberSz + paddingMiddle));
1845 const bool owns = (*capacityPtr != -1);
1846 if (!isSmall && owns)
1858std::vector<ROOT::Experimental::Detail::RFieldValue>
1861 auto [beginPtr, sizePtr,
_] = GetRVecDataMembers(
value.GetRawPtr());
1863 std::vector<Detail::RFieldValue>
result;
1864 char *begin =
reinterpret_cast<char *
>(*beginPtr);
1865 for (std::int32_t i = 0; i < *sizePtr; ++i) {
1866 auto elementValue = fSubFields[0]->CaptureValue(begin + i * fItemSize);
1867 result.emplace_back(std::move(elementValue));
1886 constexpr auto dataMemberSz =
sizeof(
void *) + 2 *
sizeof(std::int32_t);
1887 const auto alignOfT = fSubFields[0]->GetAlignment();
1888 const auto sizeOfT = fSubFields[0]->GetValueSize();
1891 const auto inlineStorageSz = [&] {
1892#ifdef R__HAS_HARDWARE_INTERFERENCE_SIZE
1894 constexpr unsigned cacheLineSize = std::hardware_destructive_interference_size;
1896 constexpr unsigned cacheLineSize = 64u;
1898 const unsigned elementsPerCacheLine = (cacheLineSize - dataMemberSz) / sizeOfT;
1899 constexpr unsigned maxInlineByteSize = 1024;
1900 const unsigned nElements =
1901 elementsPerCacheLine >= 8 ? elementsPerCacheLine : (sizeOfT * 8 > maxInlineByteSize ? 0 : 8);
1902 return nElements * sizeOfT;
1907 auto paddingMiddle = dataMemberSz % alignOfT;
1908 if (paddingMiddle != 0)
1909 paddingMiddle = alignOfT - paddingMiddle;
1912 const auto alignOfRVecT = GetAlignment();
1913 auto paddingEnd = (dataMemberSz + paddingMiddle + inlineStorageSz) % alignOfRVecT;
1914 if (paddingEnd != 0)
1915 paddingEnd = alignOfRVecT - paddingEnd;
1917 return dataMemberSz + inlineStorageSz + paddingMiddle + paddingEnd;
1929 return std::max({
alignof(
void *),
alignof(std::int32_t), fSubFields[0]->GetAlignment()});
1952 auto typedValue =
value.Get<std::vector<bool>>();
1953 auto count = typedValue->size();
1954 for (
unsigned i = 0; i < count; ++i) {
1955 bool bval = (*typedValue)[i];
1956 auto itemValue = fSubFields[0]->CaptureValue(&bval);
1957 fSubFields[0]->Append(itemValue);
1959 Detail::RColumnElement<ClusterSize_t> elemIndex(&fNWritten);
1961 fColumns[0]->Append(elemIndex);
1962 return count +
sizeof(elemIndex);
1967 auto typedValue =
value->Get<std::vector<bool>>();
1970 RClusterIndex collectionStart;
1971 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
1973 typedValue->resize(nItems);
1974 for (
unsigned i = 0; i < nItems; ++i) {
1976 auto itemValue = fSubFields[0]->GenerateValue(&bval);
1977 fSubFields[0]->Read(collectionStart + i, &itemValue);
1978 (*typedValue)[i] = bval;
1985 static RColumnRepresentations representations(
1988 return representations;
1993 fColumns.emplace_back(Detail::RColumn::Create<ClusterSize_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
1998 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1999 fColumns.emplace_back(Detail::RColumn::Create<ClusterSize_t>(RColumnModel(onDiskTypes[0]), 0));
2002std::vector<ROOT::Experimental::Detail::RFieldValue>
2005 const static bool trueValue =
true;
2006 const static bool falseValue =
false;
2008 auto typedValue =
value.Get<std::vector<bool>>();
2009 auto count = typedValue->size();
2010 std::vector<Detail::RFieldValue>
result;
2011 for (
unsigned i = 0; i < count; ++i) {
2012 if ((*typedValue)[i])
2013 result.emplace_back(fSubFields[0]->CaptureValue(
const_cast<bool *
>(&trueValue)));
2015 result.emplace_back(fSubFields[0]->CaptureValue(
const_cast<bool *
>(&falseValue)));
2023 auto vec =
static_cast<std::vector<bool>*
>(
value.GetRawPtr());
2031 visitor.VisitVectorBoolField(*
this);
2039 std::string_view fieldName, std::unique_ptr<Detail::RFieldBase> itemField, std::size_t arrayLength)
2041 fieldName,
"std::array<" + itemField->GetType() +
"," + std::to_string(arrayLength) +
">",
2043 , fItemSize(itemField->GetValueSize()), fArrayLength(arrayLength)
2045 fTraits |= itemField->GetTraits() & ~kTraitMappable;
2046 Attach(std::move(itemField));
2049std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
2052 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetName());
2053 return std::make_unique<RArrayField>(newName, std::move(newItemField), fArrayLength);
2057 std::size_t nbytes = 0;
2058 auto arrayPtr =
value.Get<
unsigned char>();
2059 for (
unsigned i = 0; i < fArrayLength; ++i) {
2060 auto itemValue = fSubFields[0]->CaptureValue(arrayPtr + (i * fItemSize));
2061 nbytes += fSubFields[0]->Append(itemValue);
2068 auto arrayPtr =
value->Get<
unsigned char>();
2069 for (
unsigned i = 0; i < fArrayLength; ++i) {
2070 auto itemValue = fSubFields[0]->CaptureValue(arrayPtr + (i * fItemSize));
2071 fSubFields[0]->Read(globalIndex * fArrayLength + i, &itemValue);
2077 auto arrayPtr =
value->Get<
unsigned char>();
2078 for (
unsigned i = 0; i < fArrayLength; ++i) {
2079 auto itemValue = fSubFields[0]->CaptureValue(arrayPtr + (i * fItemSize));
2087 if (fSubFields[0]->GetTraits() & kTraitTriviallyConstructible)
2090 auto arrayPtr =
reinterpret_cast<unsigned char *
>(where);
2091 for (
unsigned i = 0; i < fArrayLength; ++i) {
2092 fSubFields[0]->GenerateValue(arrayPtr + (i * fItemSize));
2099 auto arrayPtr =
value.Get<
unsigned char>();
2100 if (!(fSubFields[0]->GetTraits() & kTraitTriviallyDestructible)) {
2101 for (
unsigned i = 0; i < fArrayLength; ++i) {
2102 auto itemValue = fSubFields[0]->CaptureValue(arrayPtr + (i * fItemSize));
2103 fSubFields[0]->DestroyValue(itemValue,
true );
2115std::vector<ROOT::Experimental::Detail::RFieldValue>
2118 auto arrayPtr =
value.Get<
unsigned char>();
2119 std::vector<Detail::RFieldValue>
result;
2120 for (
unsigned i = 0; i < fArrayLength; ++i) {
2121 auto itemValue = fSubFields[0]->CaptureValue(arrayPtr + (i * fItemSize));
2122 result.emplace_back(itemValue);
2135 :
ROOT::Experimental::Detail::
RFieldBase(fieldName,
"std::bitset<" + std::to_string(
N) +
">",
2146 return representations;
2151 fColumns.emplace_back(Detail::RColumn::Create<bool>(
RColumnModel(GetColumnRepresentative()[0]), 0));
2156 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
2157 fColumns.emplace_back(Detail::RColumn::Create<bool>(
RColumnModel(onDiskTypes[0]), 0));
2166 for (std::size_t word = 0; word < (fN + kBitsPerWord - 1) / kBitsPerWord; ++word) {
2167 for (std::size_t
mask = 0; (
mask < kBitsPerWord) && (i < fN); ++
mask, ++i) {
2168 elementValue = (asULongArray[word] & (
static_cast<Word_t>(1) <<
mask)) != 0;
2169 fColumns[0]->Append(element);
2180 for (std::size_t i = 0; i < fN; ++i) {
2181 fColumns[0]->Read(globalIndex * fN + i, &element);
2183 Word_t bit =
static_cast<Word_t>(elementValue) << (i % kBitsPerWord);
2184 asULongArray[i / kBitsPerWord] = (asULongArray[i / kBitsPerWord] & ~mask) | bit;
2198 for (
size_t i = 0; i < itemFields.size(); ++i) {
2199 result += itemFields[i]->GetType() +
",";
2207 std::string_view fieldName,
const std::vector<Detail::RFieldBase *> &itemFields)
2214 auto nFields = itemFields.size();
2217 for (
unsigned int i = 0; i < nFields; ++i) {
2220 fTraits &= itemFields[i]->GetTraits();
2221 Attach(std::unique_ptr<Detail::RFieldBase>(itemFields[i]));
2226std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
2229 auto nFields = fSubFields.size();
2230 std::vector<Detail::RFieldBase *> itemFields;
2231 for (
unsigned i = 0; i < nFields; ++i) {
2233 itemFields.emplace_back(fSubFields[i]->Clone(fSubFields[i]->GetName()).release());
2235 return std::make_unique<RVariantField>(newName, itemFields);
2240 auto index = *(
reinterpret_cast<char *
>(variantPtr) + fTagOffset);
2246 auto index =
reinterpret_cast<char *
>(variantPtr) + fTagOffset;
2247 *
index =
static_cast<char>(tag - 1);
2252 auto tag = GetTag(
value.GetRawPtr());
2253 std::size_t nbytes = 0;
2256 auto itemValue = fSubFields[tag - 1]->CaptureValue(
value.GetRawPtr());
2257 nbytes += fSubFields[tag - 1]->Append(itemValue);
2258 index = fNWritten[tag - 1]++;
2262 fColumns[0]->Append(elemSwitch);
2270 fPrincipalColumn->GetSwitchInfo(globalIndex, &variantIndex, &tag);
2273 auto itemValue = fSubFields[tag - 1]->GenerateValue(
value->GetRawPtr());
2274 fSubFields[tag - 1]->Read(variantIndex, &itemValue);
2275 SetTag(
value->GetRawPtr(), tag);
2282 return representations;
2287 fColumns.emplace_back(Detail::RColumn::Create<RColumnSwitch>(
RColumnModel(GetColumnRepresentative()[0]), 0));
2292 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
2293 fColumns.emplace_back(Detail::RColumn::Create<RColumnSwitch>(
RColumnModel(onDiskTypes[0]), 0));
2298 memset(where, 0, GetValueSize());
2299 fSubFields[0]->GenerateValue(where);
2306 auto variantPtr =
value.GetRawPtr();
2307 auto tag = GetTag(variantPtr);
2309 auto itemValue = fSubFields[tag - 1]->CaptureValue(variantPtr);
2310 fSubFields[tag - 1]->DestroyValue(itemValue,
true );
2323 return fMaxItemSize + fMaxAlignment;
2328 std::fill(fNWritten.begin(), fNWritten.end(), 0);
2334 std::unique_ptr<Detail::RFieldBase> itemField)
2337 Attach(std::move(itemField));
2342 if (fDefaultItemValue.GetField()) {
2343 fDefaultItemValue.GetField()->DestroyValue(fDefaultItemValue);
2353 return representations;
2358 if (HasDefaultColumnRepresentative()) {
2359 if (fSubFields[0]->GetValueSize() < 4) {
2364 fDefaultItemValue = fSubFields[0]->GenerateValue();
2367 fColumns.emplace_back(Detail::RColumn::Create<ClusterSize_t>(
RColumnModel(GetColumnRepresentative()[0]), 0));
2373 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
2377 fColumns.emplace_back(Detail::RColumn::Create<ClusterSize_t>(
RColumnModel(onDiskTypes[0]), 0));
2386 fPrincipalColumn->Append(maskElement);
2387 return 1 + fSubFields[0]->Append(fDefaultItemValue);
2390 fPrincipalColumn->Append(offsetElement);
2397 auto nbytesItem = fSubFields[0]->Append(
value);
2401 fPrincipalColumn->Append(maskElement);
2402 return 1 + nbytesItem;
2406 fPrincipalColumn->Append(offsetElement);
2415 const bool isValidItem = *fPrincipalColumn->Map<
bool>(globalIndex);
2416 return isValidItem ? fPrincipalColumn->GetClusterIndex(globalIndex) : nullIndex;
2420 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &collectionSize);
2421 return (collectionSize == 0) ? nullIndex : collectionStart;
2433 std::unique_ptr<Detail::RFieldBase> itemField)
2438std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
2441 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetName());
2442 return std::make_unique<RUniquePtrField>(newName, GetType(), std::move(newItemField));
2447 auto typedValue =
value.Get<std::unique_ptr<char>>();
2449 auto itemValue = fSubFields[0]->CaptureValue(typedValue->get());
2450 return AppendValue(itemValue);
2452 return AppendNull();
2458 auto ptr =
value->Get<std::unique_ptr<char>>();
2459 bool isValidValue =
static_cast<bool>(*ptr);
2461 auto itemIndex = GetItemIndex(globalIndex);
2466 itemValue = fSubFields[0]->CaptureValue(ptr->get());
2468 if (isValidValue && !isValidItem) {
2470 fSubFields[0]->DestroyValue(itemValue,
false );
2477 if (!isValidValue) {
2478 itemValue = fSubFields[0]->GenerateValue();
2479 ptr->reset(itemValue.
Get<
char>());
2482 fSubFields[0]->Read(itemIndex, &itemValue);
2492 auto ptr =
value.Get<std::unique_ptr<char>>();
2494 auto itemValue = fSubFields[0]->CaptureValue(ptr->get());
2495 fSubFields[0]->DestroyValue(itemValue,
false );
2507std::vector<ROOT::Experimental::Detail::RFieldValue>
2510 std::vector<Detail::RFieldValue>
result;
2511 auto ptr =
value.Get<std::unique_ptr<char>>();
2513 auto itemValue = fSubFields[0]->CaptureValue(ptr->get());
2514 result.emplace_back(itemValue);
2521std::string ROOT::Experimental::RPairField::RPairField::GetTypeList(
2522 const std::array<std::unique_ptr<Detail::RFieldBase>, 2> &itemFields)
2524 return itemFields[0]->GetType() +
"," + itemFields[1]->GetType();
2528 std::array<std::unique_ptr<Detail::RFieldBase>, 2> &&itemFields,
2529 const std::array<std::size_t, 2> &offsets)
2530 :
ROOT::Experimental::
RRecordField(fieldName, std::move(itemFields), offsets,
2531 "std::pair<" + GetTypeList(itemFields) +
">")
2536 std::array<std::unique_ptr<Detail::RFieldBase>, 2> &itemFields)
2538 "std::pair<" + GetTypeList(itemFields) +
">")
2545 fOffsets[0] =
fClass->GetDataMember(
"first")->GetOffset();
2546 fOffsets[1] =
fClass->GetDataMember(
"second")->GetOffset();
2549std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
2552 std::array<std::unique_ptr<Detail::RFieldBase>, 2> items{fSubFields[0]->Clone(fSubFields[0]->GetName()),
2553 fSubFields[1]->Clone(fSubFields[1]->GetName())};
2555 std::unique_ptr<RPairField>
result(
new RPairField(newName, std::move(items), {fOffsets[0], fOffsets[1]}));
2574std::string ROOT::Experimental::RTupleField::RTupleField::GetTypeList(
2575 const std::vector<std::unique_ptr<Detail::RFieldBase>> &itemFields)
2578 if (itemFields.empty())
2579 throw RException(
R__FAIL(
"the type list for std::tuple must have at least one element"));
2580 for (
size_t i = 0; i < itemFields.size(); ++i) {
2581 result += itemFields[i]->GetType() +
",";
2588 std::vector<std::unique_ptr<Detail::RFieldBase>> &&itemFields,
2589 const std::vector<std::size_t> &offsets)
2590 :
ROOT::Experimental::
RRecordField(fieldName, std::move(itemFields), offsets,
2591 "std::tuple<" + GetTypeList(itemFields) +
">")
2596 std::vector<std::unique_ptr<Detail::RFieldBase>> &itemFields)
2598 "std::tuple<" + GetTypeList(itemFields) +
">")
2610 for (
unsigned i = 0; i < fSubFields.size(); ++i) {
2611 std::string memberName(
"_" + std::to_string(i));
2612 auto member =
fClass->GetRealData(memberName.c_str());
2615 fOffsets.push_back(member->GetThisOffset());
2619std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
2622 std::vector<std::unique_ptr<Detail::RFieldBase>> items;
2623 for (
const auto &item : fSubFields)
2624 items.push_back(item->Clone(item->GetName()));
2626 std::unique_ptr<RTupleField>
result(
new RTupleField(newName, std::move(items), fOffsets));
2646 std::string_view
name,
2647 std::shared_ptr<RCollectionNTupleWriter> collectionNTuple,
2648 std::unique_ptr<RNTupleModel> collectionModel)
2650 , fCollectionNTuple(collectionNTuple)
2652 for (
unsigned i = 0; i < collectionModel->GetFieldZero()->
fSubFields.size(); ++i) {
2653 auto& subField = collectionModel->GetFieldZero()->fSubFields[i];
2654 Attach(std::move(subField));
2665 return representations;
2670 fColumns.emplace_back(Detail::RColumn::Create<ClusterSize_t>(
RColumnModel(GetColumnRepresentative()[0]), 0));
2675 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
2676 fColumns.emplace_back(Detail::RColumn::Create<ClusterSize_t>(
RColumnModel(onDiskTypes[0]), 0));
2680std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
2684 for (
auto&
f : fSubFields) {
2685 auto clone =
f->Clone(
f->GetName());
2686 result->Attach(std::move(clone));
2693 *fCollectionNTuple->GetOffsetPtr() = 0;
#define R__FAIL(msg)
Short-hand to return an RResult<T> in an error state; the RError is implicitly converted into RResult...
#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 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)
A column element points either to the content of an RFieldValue or into a memory mapped page.
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
Iterates over the sub tree of fields in depth-first search order.
void Advance()
Given that the iterator points to a valid field which is not the end iterator, go to the next field i...
RFieldBase * GetParent() const
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.
RFieldBase * fParent
Sub fields point to their mother field.
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.
int fTraits
Properties of the type that allow for optimizations of collections of that type.
virtual void DestroyValue(const RFieldValue &value, bool dtorOnly=false)
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
static constexpr int kTraitTrivialType
Shorthand for types that are both trivially constructible and destructible.
friend class ROOT::Experimental::RCollectionField
void ConnectPageSink(RPageSink &pageSink)
Fields and their columns live in the void until connected to a physical page storage.
void RemoveReadCallback(size_t idx)
void Flush() const
Ensure that all received items are written from page buffers to the storage.
virtual void CommitCluster()
Perform housekeeping tasks for global to cluster-local index translation.
void SetDescription(std::string_view description)
virtual std::vector< RFieldValue > SplitValue(const RFieldValue &value) const
Creates the list of direct child values given a value for this field.
static RResult< void > EnsureValidFieldName(std::string_view fieldName)
Check whether a given string is a valid field name.
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.
static RResult< std::unique_ptr< RFieldBase > > Create(const std::string &fieldName, const std::string &typeName)
Factory method to resurrect a field from the stored on-disk type information.
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 AppendImpl(const RFieldValue &value)
Operations on values of complex types, e.g.
std::function< void(RFieldValue &)> ReadCallback_t
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
virtual void ReadGlobalImpl(NTupleSize_t globalIndex, RFieldValue *value)
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.
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.
RFieldValue GenerateValue()
Generates an object of the field type and allocates new initialized memory according to the type.
std::vector< EColumnType > ColumnRepresentation_t
RColumn * fPrincipalColumn
Points into fColumns.
Abstract base class for classes implementing the visitor design pattern.
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 VisitCollectionClassField(const RCollectionClassField &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)
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.
std::vector< Detail::RFieldValue > SplitValue(const Detail::RFieldValue &value) const final
Creates the list of direct child values given a value for this field.
Detail::RFieldValue CaptureValue(void *where) final
Creates a value from a memory location with an already constructed object.
void ReadInClusterImpl(const RClusterIndex &clusterIndex, Detail::RFieldValue *value) final
void ReadGlobalImpl(NTupleSize_t globalIndex, Detail::RFieldValue *value) final
RArrayField(std::string_view fieldName, std::unique_ptr< Detail::RFieldBase > itemField, std::size_t arrayLength)
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
void DestroyValue(const Detail::RFieldValue &value, bool dtorOnly=false) final
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
std::size_t AppendImpl(const Detail::RFieldValue &value) 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, Detail::RFieldValue *value) final
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.
RBitsetField(std::string_view fieldName, std::size_t N)
std::size_t AppendImpl(const Detail::RFieldValue &value) final
Operations on values of complex types, e.g.
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
The field for a class with dictionary.
Detail::RFieldValue CaptureValue(void *where) final
Creates a value from a memory location with an already constructed object.
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)
std::vector< Detail::RFieldValue > SplitValue(const Detail::RFieldValue &value) const final
Creates the list of direct child values given a value for this field.
std::unique_ptr< Detail::RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
std::size_t AppendImpl(const Detail::RFieldValue &value) final
Operations on values of complex types, e.g.
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.
void ReadInClusterImpl(const RClusterIndex &clusterIndex, Detail::RFieldValue *value) final
RClassField(std::string_view fieldName, std::string_view className, TClass *classp)
void ReadGlobalImpl(NTupleSize_t globalIndex, Detail::RFieldValue *value) final
void DestroyValue(const Detail::RFieldValue &value, bool dtorOnly=false) final
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
Addresses a column element or field item relative to a particular cluster, instead of a global NTuple...
DescriptorId_t GetClusterId() const
ClusterSize_t::ValueType GetIndex() const
Allows for iterating over the elements of a proxied collection.
static RIteratorFuncs GetIteratorFuncs(TVirtualCollectionProxy *proxy, bool readOnly)
The field for a class representing a collection of elements via TVirtualCollectionProxy.
void DestroyValue(const Detail::RFieldValue &value, bool dtorOnly=false) final
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
std::vector< Detail::RFieldValue > SplitValue(const Detail::RFieldValue &value) const final
Creates the list of direct child values given a value for this field.
std::unique_ptr< TVirtualCollectionProxy > fProxy
RCollectionClassField(std::string_view fieldName, std::string_view className, TClass *classp)
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, Detail::RFieldValue *value) final
Detail::RFieldValue CaptureValue(void *where) override
Creates a value from a memory location with an already constructed object.
std::size_t AppendImpl(const Detail::RFieldValue &value) final
Operations on values of complex types, e.g.
RCollectionIterableOnce::RIteratorFuncs fIFuncsWrite
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type for writing.
RCollectionIterableOnce::RIteratorFuncs fIFuncsRead
Two sets of functions to operate on iterators, to be used depending on the access type.
void CommitCluster() final
Perform housekeeping tasks for global to cluster-local index translation.
const RColumnRepresentations & GetColumnRepresentations() const final
Implementations in derived classes should return a static RColumnRepresentations object.
void CommitCluster() final
Perform housekeeping tasks for global to cluster-local index translation.
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type for writing.
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.
Base class for all ROOT issued exceptions.
A field translates read and write calls from/to underlying columns to/from tree values.
std::uint32_t GetTypeVersion() const
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 on-storage meta-data of an ntuple.
RColumnDescriptorIterable GetColumnIterable(const RFieldDescriptor &fieldDesc) const
const RFieldDescriptor & GetFieldDescriptor(DescriptorId_t fieldId) 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 Detail::RFieldValue &value)
~RNullableField() override
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(const Detail::RFieldValue &value, bool dtorOnly=false) 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)
Detail::RFieldValue CaptureValue(void *where) override
Creates a value from a memory location with an already constructed object.
std::size_t EvalValueSize() const
Evaluate the constant returned by GetValueSize.
void DestroyValue(const Detail::RFieldValue &value, bool dtorOnly=false) override
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
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)
void CommitCluster() final
Perform housekeeping tasks for global to cluster-local index translation.
void ReadGlobalImpl(NTupleSize_t globalIndex, Detail::RFieldValue *value) override
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
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 AppendImpl(const Detail::RFieldValue &value) override
Operations on values of complex types, e.g.
std::vector< Detail::RFieldValue > SplitValue(const Detail::RFieldValue &value) const final
Creates the list of direct child values given a value for this field.
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type for writing.
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
std::size_t AppendImpl(const Detail::RFieldValue &value) final
Operations on values of complex types, e.g.
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 ReadGlobalImpl(NTupleSize_t globalIndex, Detail::RFieldValue *value) final
Detail::RFieldValue CaptureValue(void *where) final
Creates a value from a memory location with an already constructed object.
std::vector< Detail::RFieldValue > SplitValue(const Detail::RFieldValue &value) const final
Creates the list of direct child values given a value for this field.
void DestroyValue(const Detail::RFieldValue &value, bool dtorOnly=false) override
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
void ReadInClusterImpl(const RClusterIndex &clusterIndex, Detail::RFieldValue *value) final
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...
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.
RTupleField(std::string_view fieldName, std::vector< std::unique_ptr< Detail::RFieldBase > > &&itemFields, const std::vector< std::size_t > &offsets)
void DestroyValue(const Detail::RFieldValue &value, bool dtorOnly=false) override
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
RUniquePtrField(std::string_view fieldName, std::string_view typeName, std::unique_ptr< Detail::RFieldBase > itemField)
void ReadGlobalImpl(NTupleSize_t globalIndex, Detail::RFieldValue *value) final
Detail::RFieldValue CaptureValue(void *where) final
Creates a value from a memory location with an already constructed object.
std::vector< Detail::RFieldValue > SplitValue(const Detail::RFieldValue &value) const final
Creates the list of direct child values given a value for this field.
void DestroyValue(const Detail::RFieldValue &value, bool dtorOnly=false) final
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
std::size_t AppendImpl(const Detail::RFieldValue &value) 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.
std::size_t AppendImpl(const Detail::RFieldValue &value) final
Operations on values of complex types, e.g.
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.
void DestroyValue(const Detail::RFieldValue &value, bool dtorOnly=false) final
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
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.
std::uint32_t GetTag(void *variantPtr) const
Extracts the index from an std::variant and transforms it into the 1-based index used for the switch ...
static std::string GetTypeList(const std::vector< Detail::RFieldBase * > &itemFields)
RVariantField(std::string_view fieldName, const std::vector< Detail::RFieldBase * > &itemFields)
void ReadGlobalImpl(NTupleSize_t globalIndex, Detail::RFieldValue *value) final
size_t GetAlignment() const final
As a rule of thumb, the alignment is equal to the size of the type.
Detail::RFieldValue CaptureValue(void *where) final
Creates a value from a memory location with an already constructed object.
std::unique_ptr< Detail::RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
void CommitCluster() final
Perform housekeeping tasks for global to cluster-local index translation.
Detail::RFieldValue CaptureValue(void *where) override
Creates a value from a memory location with an already constructed object.
void CommitCluster() final
Perform housekeeping tasks for global to cluster-local index translation.
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< Detail::RFieldValue > SplitValue(const Detail::RFieldValue &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 ReadGlobalImpl(NTupleSize_t globalIndex, Detail::RFieldValue *value) final
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type for writing.
RVectorField(std::string_view fieldName, std::unique_ptr< Detail::RFieldBase > itemField)
void DestroyValue(const Detail::RFieldValue &value, bool dtorOnly=false) final
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
std::size_t AppendImpl(const Detail::RFieldValue &value) final
Operations on values of complex types, e.g.
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).
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.
virtual Next_t GetFunctionNext(Bool_t read=kTRUE)=0
virtual DeleteTwoIterators_t GetFunctionDeleteTwoIterators(Bool_t read=kTRUE)=0
virtual TVirtualCollectionProxy * Generate() const =0
virtual CreateIterators_t GetFunctionCreateIterators(Bool_t read=kTRUE)=0
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.
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 ...
Wrap the integer in a struct in order to avoid template specialization clash with std::uint32_t.
TVirtualCollectionProxy::DeleteTwoIterators_t fDeleteTwoIterators
TVirtualCollectionProxy::CreateIterators_t fCreateIterators
TVirtualCollectionProxy::Next_t fNext