46#include <unordered_map>
50static const std::unordered_map<std::string_view, std::string_view> typeTranslationMap{
53 {
"Double_t",
"double"},
54 {
"string",
"std::string"},
57 {
"int8_t",
"std::int8_t"},
58 {
"signed char",
"char"},
59 {
"UChar_t",
"std::uint8_t"},
60 {
"unsigned char",
"std::uint8_t"},
61 {
"uint8_t",
"std::uint8_t"},
63 {
"Short_t",
"std::int16_t"},
64 {
"int16_t",
"std::int16_t"},
65 {
"short",
"std::int16_t"},
66 {
"UShort_t",
"std::uint16_t"},
67 {
"unsigned short",
"std::uint16_t"},
68 {
"uint16_t",
"std::uint16_t"},
70 {
"Int_t",
"std::int32_t"},
71 {
"int32_t",
"std::int32_t"},
72 {
"int",
"std::int32_t"},
73 {
"UInt_t",
"std::uint32_t"},
74 {
"unsigned",
"std::uint32_t"},
75 {
"unsigned int",
"std::uint32_t"},
76 {
"uint32_t",
"std::uint32_t"},
78 {
"Long_t",
"std::int64_t"},
79 {
"Long64_t",
"std::int64_t"},
80 {
"int64_t",
"std::int64_t"},
81 {
"long",
"std::int64_t"},
82 {
"ULong64_t",
"std::uint64_t"},
83 {
"unsigned long",
"std::uint64_t"},
84 {
"uint64_t",
"std::uint64_t"}
89std::vector<std::string> TokenizeTypeList(std::string templateType) {
90 std::vector<std::string>
result;
91 if (templateType.empty())
94 const char *eol = templateType.data() + templateType.length();
95 const char *typeBegin = templateType.data();
96 const char *typeCursor = templateType.data();
97 unsigned int nestingLevel = 0;
98 while (typeCursor != eol) {
99 switch (*typeCursor) {
107 if (nestingLevel == 0) {
108 result.push_back(std::string(typeBegin, typeCursor - typeBegin));
109 typeBegin = typeCursor + 1;
115 result.push_back(std::string(typeBegin, typeCursor - typeBegin));
124std::tuple<std::string, std::vector<size_t>> ParseArrayType(std::string_view typeName)
126 std::vector<size_t> sizeVec;
129 while (typeName.back() ==
']') {
130 auto posRBrace = typeName.size() - 1;
131 auto posLBrace = typeName.find_last_of(
"[", posRBrace);
132 if (posLBrace == std::string_view::npos)
136 if (std::from_chars(typeName.data() + posLBrace + 1, typeName.data() + posRBrace,
size).ec != std::errc{})
138 sizeVec.insert(sizeVec.begin(),
size);
139 typeName.remove_suffix(typeName.size() - posLBrace);
141 return std::make_tuple(std::string{typeName}, sizeVec);
145 std::string normalizedType(
149 auto translatedType = typeTranslationMap.find(normalizedType);
150 if (translatedType != typeTranslationMap.end())
151 normalizedType = translatedType->second;
153 if (normalizedType.substr(0, 7) ==
"vector<") normalizedType =
"std::" + normalizedType;
154 if (normalizedType.substr(0, 6) ==
"array<") normalizedType =
"std::" + normalizedType;
155 if (normalizedType.substr(0, 8) ==
"variant<") normalizedType =
"std::" + normalizedType;
156 if (normalizedType.substr(0, 5) ==
"pair<") normalizedType =
"std::" + normalizedType;
157 if (normalizedType.substr(0, 6) ==
"tuple<") normalizedType =
"std::" + normalizedType;
159 return normalizedType;
164std::tuple<void **, std::int32_t *, std::int32_t *> GetRVecDataMembers(
void *rvecPtr)
166 void **begin =
reinterpret_cast<void **
>(rvecPtr);
168 std::int32_t *
size =
reinterpret_cast<std::int32_t *
>(begin + 1);
171 std::int32_t *capacity =
size + 1;
173 return {begin,
size, capacity};
183 : fName(
name), fType(
type), fStructure(structure), fNRepetitions(nRepetitions), fIsSimple(isSimple),
184 fParent(nullptr), fPrincipalColumn(nullptr), fTraits(isSimple ? kTraitMappable : 0)
195 std::string normalizedType(GetNormalizedType(typeName));
196 if (normalizedType.empty())
197 return R__FAIL(
"no type name specified for Field " + fieldName);
199 std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
result;
201 if (
auto [arrayBaseType, arraySize] = ParseArrayType(normalizedType); !arraySize.empty()) {
203 if (arraySize.size() > 1)
204 return R__FAIL(
"multi-dimensional array type not supported " + normalizedType);
205 auto itemField = Create(GetNormalizedType(arrayBaseType), arrayBaseType);
206 return {std::make_unique<RArrayField>(fieldName, itemField.Unwrap(), arraySize[0])};
209 if (normalizedType ==
"ROOT::Experimental::ClusterSize_t") {
210 result = std::make_unique<RField<ClusterSize_t>>(fieldName);
211 }
else if (normalizedType ==
"bool") {
212 result = std::make_unique<RField<bool>>(fieldName);
213 }
else if (normalizedType ==
"char") {
214 result = std::make_unique<RField<char>>(fieldName);
215 }
else if (normalizedType ==
"std::int8_t") {
216 result = std::make_unique<RField<std::int8_t>>(fieldName);
217 }
else if (normalizedType ==
"std::uint8_t") {
218 result = std::make_unique<RField<std::uint8_t>>(fieldName);
219 }
else if (normalizedType ==
"std::int16_t") {
220 result = std::make_unique<RField<std::int16_t>>(fieldName);
221 }
else if (normalizedType ==
"std::uint16_t") {
222 result = std::make_unique<RField<std::uint16_t>>(fieldName);
223 }
else if (normalizedType ==
"std::int32_t") {
224 result = std::make_unique<RField<std::int32_t>>(fieldName);
225 }
else if (normalizedType ==
"std::uint32_t") {
226 result = std::make_unique<RField<std::uint32_t>>(fieldName);
227 }
else if (normalizedType ==
"std::int64_t") {
228 result = std::make_unique<RField<std::int64_t>>(fieldName);
229 }
else if (normalizedType ==
"std::uint64_t") {
230 result = std::make_unique<RField<std::uint64_t>>(fieldName);
231 }
else if (normalizedType ==
"float") {
232 result = std::make_unique<RField<float>>(fieldName);
233 }
else if (normalizedType ==
"double") {
234 result = std::make_unique<RField<double>>(fieldName);
235 }
else if (normalizedType ==
"std::string") {
236 result = std::make_unique<RField<std::string>>(fieldName);
237 }
else if (normalizedType ==
"std::vector<bool>") {
238 result = std::make_unique<RField<std::vector<bool>>>(fieldName);
239 }
else if (normalizedType.substr(0, 12) ==
"std::vector<") {
240 std::string itemTypeName = normalizedType.substr(12, normalizedType.length() - 13);
241 auto itemField = Create(
"_0", itemTypeName);
242 result = std::make_unique<RVectorField>(fieldName, itemField.Unwrap());
243 }
else if (normalizedType.substr(0, 19) ==
"ROOT::VecOps::RVec<") {
244 std::string itemTypeName = normalizedType.substr(19, normalizedType.length() - 20);
245 auto itemField = Create(
"_0", itemTypeName);
246 result = std::make_unique<RRVecField>(fieldName, itemField.Unwrap());
247 }
else if (normalizedType.substr(0, 11) ==
"std::array<") {
248 auto arrayDef = TokenizeTypeList(normalizedType.substr(11, normalizedType.length() - 12));
250 auto arrayLength = std::stoi(arrayDef[1]);
251 auto itemField = Create(GetNormalizedType(arrayDef[0]), arrayDef[0]);
252 result = std::make_unique<RArrayField>(fieldName, itemField.Unwrap(), arrayLength);
254 if (normalizedType.substr(0, 13) ==
"std::variant<") {
255 auto innerTypes = TokenizeTypeList(normalizedType.substr(13, normalizedType.length() - 14));
256 std::vector<RFieldBase *> items;
257 for (
unsigned int i = 0; i < innerTypes.size(); ++i) {
258 items.emplace_back(Create(
"_" + std::to_string(i), innerTypes[i]).Unwrap().release());
260 result = std::make_unique<RVariantField>(fieldName, items);
262 if (normalizedType.substr(0, 10) ==
"std::pair<") {
263 auto innerTypes = TokenizeTypeList(normalizedType.substr(10, normalizedType.length() - 11));
264 if (innerTypes.size() != 2)
265 return R__FAIL(
"the type list for std::pair must have exactly two elements");
266 std::array<std::unique_ptr<RFieldBase>, 2> items{Create(
"_0", innerTypes[0]).Unwrap(),
267 Create(
"_1", innerTypes[1]).Unwrap()};
268 result = std::make_unique<RPairField>(fieldName, items);
270 if (normalizedType.substr(0, 11) ==
"std::tuple<") {
271 auto innerTypes = TokenizeTypeList(normalizedType.substr(11, normalizedType.length() - 12));
272 std::vector<std::unique_ptr<RFieldBase>> items;
273 for (
unsigned int i = 0; i < innerTypes.size(); ++i) {
274 items.emplace_back(Create(
"_" + std::to_string(i), innerTypes[i]).Unwrap());
276 result = std::make_unique<RTupleField>(fieldName, items);
279 if (normalizedType ==
":Collection:")
280 result = std::make_unique<RField<ClusterSize_t>>(fieldName);
285 if (cl->GetCollectionProxy())
286 result = std::make_unique<RCollectionClassField>(fieldName, normalizedType);
288 result = std::make_unique<RClassField>(fieldName, normalizedType);
294 return R__FAIL(std::string(
"Field ") + fieldName +
" has unknown type " + normalizedType);
300 if (fieldName ==
"") {
301 return R__FAIL(
"name cannot be empty string \"\"");
302 }
else if (fieldName.find(
".") != std::string::npos) {
303 return R__FAIL(
"name '" + std::string(fieldName) +
"' cannot contain dot characters '.'");
308std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
311 auto clone = CloneImpl(newName);
312 clone->fOnDiskId = fOnDiskId;
313 clone->fDescription = fDescription;
319 R__ASSERT(
false &&
"A non-simple RField must implement its own AppendImpl");
332 void *where =
malloc(GetValueSize());
334 return GenerateValue(where);
343std::vector<ROOT::Experimental::Detail::RFieldValue>
346 return std::vector<RFieldValue>();
350 std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
child)
352 child->fParent =
this;
353 fSubFields.emplace_back(std::move(
child));
359 std::vector<RFieldBase *>
result;
360 for (
const auto &
f : fSubFields) {
369 for (
auto& column : fColumns) {
376 const std::vector<EColumnType> &requestedTypes,
unsigned int columnIndex,
const RNTupleDescriptor &desc)
379 auto columnId = desc.
FindColumnId(fOnDiskId, columnIndex);
381 throw RException(
R__FAIL(
"Column missing: column #" + std::to_string(columnIndex) +
382 " for field " + fName));
386 for (
auto type : requestedTypes) {
387 if (
type == columnDesc.GetModel().GetType())
392 "` of column #" + std::to_string(columnIndex) +
" for field `" + fName +
393 "` is not convertible to the requested type" + [&]{
394 std::string typeStr = requestedTypes.size() > 1 ?
"s " :
" ";
395 for (std::size_t i = 0; i < requestedTypes.size(); i++) {
396 typeStr +=
"`" + RColumnElementBase::GetTypeName(requestedTypes[i]) +
"`";
397 if (i != requestedTypes.size() - 1) {
404 return columnDesc.GetModel().GetType();
409 fReadCallbacks.push_back(func);
411 return fReadCallbacks.size() - 1;
416 fReadCallbacks.erase(fReadCallbacks.begin() + idx);
417 fIsSimple = (fTraits & kTraitMappable) && fReadCallbacks.empty();
423 GenerateColumnsImpl();
424 if (!fColumns.empty())
425 fPrincipalColumn = fColumns[0].get();
426 for (
auto& column : fColumns)
427 column->Connect(fOnDiskId, &pageSink);
436 GenerateColumnsImpl(descriptorGuard.GetRef());
438 if (!fColumns.empty())
439 fPrincipalColumn = fColumns[0].get();
440 for (
auto& column : fColumns)
441 column->Connect(fOnDiskId, &pageSource);
469 auto itr = fStack.rbegin();
470 if (!itr->fFieldPtr->fSubFields.empty()) {
471 fStack.emplace_back(
Position(itr->fFieldPtr->fSubFields[0].get(), 0));
475 unsigned int nextIdxInParent = ++(itr->fIdxInParent);
476 while (nextIdxInParent >= itr->fFieldPtr->fParent->fSubFields.size()) {
477 if (fStack.size() == 1) {
478 itr->fFieldPtr = itr->fFieldPtr->fParent;
479 itr->fIdxInParent = -1;
483 itr = fStack.rbegin();
484 nextIdxInParent = ++(itr->fIdxInParent);
486 itr->fFieldPtr = itr->fFieldPtr->fParent->fSubFields[nextIdxInParent].get();
493std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
496 auto result = std::make_unique<RFieldZero>();
497 for (
auto &
f : fSubFields)
498 result->Attach(
f->Clone(
f->GetName()));
515 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
516 Detail::RColumn::Create<ClusterSize_t, EColumnType::kIndex>(model, 0)));
522 GenerateColumnsImpl();
527 visitor.VisitClusterSizeField(*
this);
542 GenerateColumnsImpl();
562 GenerateColumnsImpl();
567 visitor.VisitInt8Field(*
this);
582 GenerateColumnsImpl();
587 visitor.VisitUInt8Field(*
this);
596 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
597 Detail::RColumn::Create<bool, EColumnType::kBit>(model, 0)));
603 GenerateColumnsImpl();
617 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
618 Detail::RColumn::Create<float, EColumnType::kReal32>(model, 0)));
624 GenerateColumnsImpl();
638 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
639 Detail::RColumn::Create<double, EColumnType::kReal64>(model, 0)));
645 GenerateColumnsImpl();
665 GenerateColumnsImpl();
670 visitor.VisitInt16Field(*
this);
685 GenerateColumnsImpl();
690 visitor.VisitUInt16Field(*
this);
705 GenerateColumnsImpl();
710 visitor.VisitIntField(*
this);
718 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
719 Detail::RColumn::Create<std::uint32_t, EColumnType::kInt32>(model, 0)));
725 GenerateColumnsImpl();
730 visitor.VisitUInt32Field(*
this);
738 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
739 Detail::RColumn::Create<std::uint64_t, EColumnType::kInt64>(model, 0)));
745 GenerateColumnsImpl();
750 visitor.VisitUInt64Field(*
this);
758 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
759 Detail::RColumn::Create<std::int64_t, EColumnType::kInt64>(model, 0)));
765 RColumnModel model(
type,
false );
767 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
768 Detail::RColumn::Create<std::int64_t, EColumnType::kInt64>(model, 0)));
770 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
771 Detail::RColumn::Create<std::int64_t, EColumnType::kInt32>(model, 0)));
777 visitor.VisitInt64Field(*
this);
785 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
786 Detail::RColumn::Create<ClusterSize_t, EColumnType::kIndex>(modelIndex, 0)));
789 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
790 Detail::RColumn::Create<char, EColumnType::kChar>(modelChars, 1)));
797 GenerateColumnsImpl();
802 auto typedValue =
value.Get<std::string>();
803 auto length = typedValue->length();
804 Detail::RColumnElement<char> elemChars(
const_cast<char*
>(typedValue->data()));
805 fColumns[1]->AppendV(elemChars,
length);
807 fColumns[0]->Append(fElemIndex);
808 return length +
sizeof(fElemIndex);
814 auto typedValue =
value->Get<std::string>();
815 RClusterIndex collectionStart;
817 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nChars);
821 typedValue->resize(nChars);
822 Detail::RColumnElement<char> elemChars(
const_cast<char*
>(typedValue->data()));
823 fColumns[1]->ReadV(collectionStart, nChars, &elemChars);
834 visitor.VisitStringField(*
this);
850 throw RException(
R__FAIL(
"RField: no I/O support for type " + std::string(className)));
858 R__FAIL(std::string(className) +
" has an associated collection proxy; use RCollectionClassField instead"));
868 TClass *
c = baseClass->GetClassPointer();
870 c->GetName()).Unwrap();
871 fTraits &= subField->GetTraits();
872 Attach(std::move(subField),
881 if (!dataMember->IsPersistent()) {
887 std::string typeName{dataMember->GetFullTypeName()};
889 if (dataMember->Property() &
kIsArray) {
890 for (
int dim = 0,
n = dataMember->GetArrayDim(); dim <
n; ++dim)
891 typeName +=
"[" + std::to_string(dataMember->GetMaxIndex(dim)) +
"]";
894 fTraits &= subField->GetTraits();
895 Attach(std::move(subField),
902 fMaxAlignment = std::max(fMaxAlignment,
child->GetAlignment());
903 fSubFieldsInfo.push_back(info);
904 RFieldBase::Attach(std::move(
child));
907std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
910 return std::unique_ptr<RClassField>(
new RClassField(newName, GetType(),
fClass));
914 std::size_t nbytes = 0;
915 for (
unsigned i = 0; i < fSubFields.size(); i++) {
916 auto memberValue = fSubFields[i]->CaptureValue(
value.Get<
unsigned char>() + fSubFieldsInfo[i].fOffset);
917 nbytes += fSubFields[i]->Append(memberValue);
924 for (
unsigned i = 0; i < fSubFields.size(); i++) {
925 auto memberValue = fSubFields[i]->CaptureValue(
value->Get<
unsigned char>() + fSubFieldsInfo[i].fOffset);
926 fSubFields[i]->Read(globalIndex, &memberValue);
932 for (
unsigned i = 0; i < fSubFields.size(); i++) {
933 auto memberValue = fSubFields[i]->CaptureValue(
value->Get<
unsigned char>() + fSubFieldsInfo[i].fOffset);
934 fSubFields[i]->Read(clusterIndex, &memberValue);
964std::vector<ROOT::Experimental::Detail::RFieldValue>
967 std::vector<Detail::RFieldValue>
result;
968 for (
unsigned i = 0; i < fSubFields.size(); i++) {
969 auto memberValue = fSubFields[i]->CaptureValue(
value.Get<
unsigned char>() + fSubFieldsInfo[i].fOffset);
970 result.emplace_back(memberValue);
978 return fClass->GetClassSize();
998 if (classp ==
nullptr)
999 throw RException(
R__FAIL(
"RField: no I/O support for collection proxy type " + std::string(className)));
1001 throw RException(
R__FAIL(std::string(className) +
" has no associated collection proxy"));
1004 if (
fProxy->HasPointers())
1005 throw RException(
R__FAIL(
"collection proxies whose value type is a pointer are not supported"));
1009 std::unique_ptr<ROOT::Experimental::Detail::RFieldBase> itemField;
1010 if (
auto valueClass =
fProxy->GetValueClass()) {
1012 itemField = RFieldBase::Create(
"_0", valueClass->GetName()).Unwrap();
1014 switch (
fProxy->GetType()) {
1016 case EDataType::kUChar_t: itemField = std::make_unique<RField<std::uint8_t>>(
"_0");
break;
1017 case EDataType::kShort_t: itemField = std::make_unique<RField<std::int16_t>>(
"_0");
break;
1019 case EDataType::kInt_t: itemField = std::make_unique<RField<std::int32_t>>(
"_0");
break;
1020 case EDataType::kUInt_t: itemField = std::make_unique<RField<std::uint32_t>>(
"_0");
break;
1023 itemField = std::make_unique<RField<std::int64_t>>(
"_0");
1027 itemField = std::make_unique<RField<std::uint64_t>>(
"_0");
1037 Attach(std::move(itemField));
1040std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
1043 return std::unique_ptr<RCollectionClassField>(
1050 std::size_t nbytes = 0;
1051 auto count = fProxy->Size();
1052 for (
unsigned i = 0; i < count; ++i) {
1053 auto itemValue = fSubFields[0]->CaptureValue(fProxy->At(i));
1054 nbytes += fSubFields[0]->Append(itemValue);
1058 fColumns[0]->Append(elemIndex);
1059 return nbytes +
sizeof(elemIndex);
1068 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
1071 fProxy->Clear(
"force");
1074 const size_t buffSize = std::max(kReadChunkSize, fItemSize);
1075 const std::uint32_t nItemsPerChunk = buffSize / fItemSize;
1076 auto buff = std::make_unique<unsigned char[]>(buffSize);
1078 auto nItemsLeft =
static_cast<std::uint32_t
>(nItems);
1079 while (nItemsLeft > 0) {
1080 auto count = std::min(nItemsLeft, nItemsPerChunk);
1081 for (std::size_t i = 0; i < count; ++i) {
1082 auto itemValue = fSubFields[0]->GenerateValue(buff.get() + (i * fItemSize));
1083 fSubFields[0]->Read(collectionStart + i, &itemValue);
1085 fProxy->Insert(buff.get(),
value->GetRawPtr(), count);
1086 for (std::size_t i = 0; i < count; ++i) {
1087 auto itemValue = fSubFields[0]->CaptureValue(buff.get() + (i * fItemSize));
1088 fSubFields[0]->DestroyValue(itemValue,
true );
1090 collectionStart = collectionStart + count;
1091 nItemsLeft -= count;
1098 fColumns.emplace_back(
1099 std::unique_ptr<Detail::RColumn>(Detail::RColumn::Create<ClusterSize_t, EColumnType::kIndex>(modelIndex, 0)));
1105 GenerateColumnsImpl();
1117 auto nItems = fProxy->Size();
1118 for (
unsigned i = 0; i < nItems; ++i) {
1119 auto itemValue = fSubFields[0]->CaptureValue(fProxy->At(i));
1120 fSubFields[0]->DestroyValue(itemValue,
true );
1123 fProxy->Destructor(
value.GetRawPtr(),
true );
1133std::vector<ROOT::Experimental::Detail::RFieldValue>
1137 auto nItems = fProxy->Size();
1138 std::vector<Detail::RFieldValue>
result;
1139 for (
unsigned i = 0; i < nItems; ++i) {
1140 result.emplace_back(fSubFields[0]->CaptureValue(fProxy->At(i)));
1158 std::vector<std::unique_ptr<Detail::RFieldBase>> &&itemFields,
1159 const std::vector<std::size_t> &offsets, std::string_view typeName)
1164 for (
auto &item : itemFields) {
1173 std::vector<std::unique_ptr<Detail::RFieldBase>> &&itemFields)
1177 for (
auto &item : itemFields) {
1181 fSize += item->GetValueSize();
1191 std::vector<std::unique_ptr<Detail::RFieldBase>> &itemFields)
1198 if (itemAlignment > 1) {
1199 auto remainder = baseOffset % itemAlignment;
1201 return itemAlignment - remainder;
1206std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
1209 std::vector<std::unique_ptr<Detail::RFieldBase>> cloneItems;
1210 for (
auto &item : fSubFields)
1211 cloneItems.emplace_back(item->Clone(item->GetName()));
1212 return std::unique_ptr<RRecordField>(
new RRecordField(newName, std::move(cloneItems), fOffsets, GetType()));
1216 std::size_t nbytes = 0;
1217 for (
unsigned i = 0; i < fSubFields.size(); ++i) {
1218 auto memberValue = fSubFields[i]->CaptureValue(
value.Get<
unsigned char>() + fOffsets[i]);
1219 nbytes += fSubFields[i]->Append(memberValue);
1226 for (
unsigned i = 0; i < fSubFields.size(); ++i) {
1227 auto memberValue = fSubFields[i]->CaptureValue(
value->Get<
unsigned char>() + fOffsets[i]);
1228 fSubFields[i]->Read(globalIndex, &memberValue);
1234 for (
unsigned i = 0; i < fSubFields.size(); ++i) {
1235 auto memberValue = fSubFields[i]->CaptureValue(
value->Get<
unsigned char>() + fOffsets[i]);
1236 fSubFields[i]->Read(clusterIndex, &memberValue);
1242 for (
unsigned i = 0; i < fSubFields.size(); ++i) {
1243 fSubFields[i]->GenerateValue(
static_cast<unsigned char *
>(where) + fOffsets[i]);
1250 for (
unsigned i = 0; i < fSubFields.size(); ++i) {
1251 auto memberValue = fSubFields[i]->CaptureValue(
value.Get<
unsigned char>() + fOffsets[i]);
1252 fSubFields[i]->DestroyValue(memberValue,
true );
1265std::vector<ROOT::Experimental::Detail::RFieldValue>
1268 std::vector<Detail::RFieldValue>
result;
1269 for (
unsigned i = 0; i < fSubFields.size(); ++i) {
1270 result.emplace_back(fSubFields[i]->CaptureValue(
value.Get<
unsigned char>() + fOffsets[i]));
1285 std::string_view fieldName, std::unique_ptr<Detail::RFieldBase> itemField)
1288 , fItemSize(itemField->GetValueSize()), fNWritten(0)
1290 Attach(std::move(itemField));
1293std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
1296 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetName());
1297 return std::make_unique<RVectorField>(newName, std::move(newItemField));
1301 auto typedValue =
value.Get<std::vector<char>>();
1302 R__ASSERT((typedValue->size() % fItemSize) == 0);
1303 std::size_t nbytes = 0;
1304 auto count = typedValue->size() / fItemSize;
1305 for (
unsigned i = 0; i < count; ++i) {
1306 auto itemValue = fSubFields[0]->CaptureValue(typedValue->data() + (i * fItemSize));
1307 nbytes += fSubFields[0]->Append(itemValue);
1311 fColumns[0]->Append(elemIndex);
1312 return nbytes +
sizeof(elemIndex);
1317 auto typedValue =
value->Get<std::vector<char>>();
1321 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
1323 if (fSubFields[0]->GetTraits() & kTraitTrivialType) {
1324 typedValue->resize(nItems * fItemSize);
1327 const auto oldNItems = typedValue->size() / fItemSize;
1328 const bool canRealloc = oldNItems < nItems;
1329 bool allDeallocated =
false;
1330 if (!(fSubFields[0]->GetTraits() & kTraitTriviallyDestructible)) {
1331 allDeallocated = canRealloc;
1332 for (std::size_t i = allDeallocated ? 0 : nItems; i < oldNItems; ++i) {
1333 auto itemValue = fSubFields[0]->CaptureValue(typedValue->data() + (i * fItemSize));
1334 fSubFields[0]->DestroyValue(itemValue,
true );
1337 typedValue->resize(nItems * fItemSize);
1338 if (!(fSubFields[0]->GetTraits() & kTraitTriviallyConstructible)) {
1339 for (std::size_t i = allDeallocated ? 0 : oldNItems; i < nItems; ++i) {
1340 fSubFields[0]->GenerateValue(typedValue->data() + (i * fItemSize));
1345 for (std::size_t i = 0; i < nItems; ++i) {
1346 auto itemValue = fSubFields[0]->CaptureValue(typedValue->data() + (i * fItemSize));
1347 fSubFields[0]->Read(collectionStart + i, &itemValue);
1354 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
1355 Detail::RColumn::Create<ClusterSize_t, EColumnType::kIndex>(modelIndex, 0)));
1361 GenerateColumnsImpl();
1371 auto vec =
static_cast<std::vector<char>*
>(
value.GetRawPtr());
1373 if (!(fSubFields[0]->GetTraits() & kTraitTriviallyDestructible)) {
1374 auto nItems =
vec->size() / fItemSize;
1375 for (
unsigned i = 0; i < nItems; ++i) {
1376 auto itemValue = fSubFields[0]->CaptureValue(
vec->data() + (i * fItemSize));
1377 fSubFields[0]->DestroyValue(itemValue,
true );
1390std::vector<ROOT::Experimental::Detail::RFieldValue>
1393 auto vec =
static_cast<std::vector<char>*
>(
value.GetRawPtr());
1395 auto nItems =
vec->size() / fItemSize;
1396 std::vector<Detail::RFieldValue>
result;
1397 for (
unsigned i = 0; i < nItems; ++i) {
1398 result.emplace_back(fSubFields[0]->CaptureValue(
vec->data() + (i * fItemSize)));
1417 :
ROOT::Experimental::Detail::
RFieldBase(fieldName,
"ROOT::VecOps::RVec<" + itemField->GetType() +
">",
1419 fItemSize(itemField->GetValueSize()), fNWritten(0)
1421 Attach(std::move(itemField));
1425std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
1428 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetName());
1429 return std::make_unique<RRVecField>(newName, std::move(newItemField));
1434 auto [beginPtr, sizePtr,
_] = GetRVecDataMembers(
value.GetRawPtr());
1436 std::size_t nbytes = 0;
1437 char *begin =
reinterpret_cast<char *
>(*beginPtr);
1438 for (std::int32_t i = 0; i < *sizePtr; ++i) {
1439 auto elementValue = fSubFields[0]->CaptureValue(begin + i * fItemSize);
1440 nbytes += fSubFields[0]->Append(elementValue);
1444 fNWritten += *sizePtr;
1445 fColumns[0]->Append(elemIndex);
1446 return nbytes +
sizeof(elemIndex);
1454 auto [beginPtr, sizePtr, capacityPtr] = GetRVecDataMembers(
value->GetRawPtr());
1459 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
1460 char *begin =
reinterpret_cast<char *
>(*beginPtr);
1461 const std::size_t oldSize = *sizePtr;
1465 const bool needsConstruct = !(fSubFields[0]->GetTraits() & kTraitTriviallyConstructible);
1466 const bool needsDestruct = !(fSubFields[0]->GetTraits() & kTraitTriviallyDestructible);
1469 if (needsDestruct) {
1470 for (std::size_t i = nItems; i < oldSize; ++i) {
1471 auto itemValue = fSubFields[0]->CaptureValue(begin + (i * fItemSize));
1472 fSubFields[0]->DestroyValue(itemValue,
true );
1477 if (std::int32_t(nItems) > *capacityPtr) {
1480 if (needsDestruct) {
1481 for (std::size_t i = 0u; i < oldSize; ++i) {
1482 auto itemValue = fSubFields[0]->CaptureValue(begin + (i * fItemSize));
1483 fSubFields[0]->DestroyValue(itemValue,
true );
1491 *beginPtr =
malloc(nItems * fItemSize);
1493 begin =
reinterpret_cast<char *
>(*beginPtr);
1494 *capacityPtr = nItems;
1497 if (needsConstruct) {
1498 for (std::size_t i = 0u; i < oldSize; ++i)
1499 fSubFields[0]->GenerateValue(begin + (i * fItemSize));
1505 if (needsConstruct) {
1506 for (std::size_t i = oldSize; i < nItems; ++i)
1507 fSubFields[0]->GenerateValue(begin + (i * fItemSize));
1511 for (std::size_t i = 0; i < nItems; ++i) {
1512 auto itemValue = fSubFields[0]->CaptureValue(begin + (i * fItemSize));
1513 fSubFields[0]->Read(collectionStart + i, &itemValue);
1520 fColumns.emplace_back(
1521 std::unique_ptr<Detail::RColumn>(Detail::RColumn::Create<ClusterSize_t, EColumnType::kIndex>(modelIndex, 0)));
1527 GenerateColumnsImpl();
1534 void **beginPtr =
new (where)(
void *)(
nullptr);
1535 std::int32_t *sizePtr =
new (
reinterpret_cast<void *
>(beginPtr + 1)) std::int32_t(0);
1536 new (sizePtr + 1) std::int32_t(0);
1543 auto [beginPtr, sizePtr, capacityPtr] = GetRVecDataMembers(
value.GetRawPtr());
1545 char *begin =
reinterpret_cast<char *
>(*beginPtr);
1546 if (!(fSubFields[0]->GetTraits() & kTraitTriviallyDestructible)) {
1547 for (std::int32_t i = 0; i < *sizePtr; ++i) {
1548 auto elementValue = fSubFields[0]->CaptureValue(begin + i * fItemSize);
1549 fSubFields[0]->DestroyValue(elementValue,
true );
1555 constexpr auto dataMemberSz =
sizeof(
void *) + 2 *
sizeof(std::int32_t);
1556 const auto alignOfT = fSubFields[0]->GetAlignment();
1557 auto paddingMiddle = dataMemberSz % alignOfT;
1558 if (paddingMiddle != 0)
1559 paddingMiddle = alignOfT - paddingMiddle;
1560 const bool isSmall = (
reinterpret_cast<void *
>(begin) == (beginPtr + dataMemberSz + paddingMiddle));
1562 const bool owns = (*capacityPtr != -1);
1563 if (!isSmall && owns)
1575std::vector<ROOT::Experimental::Detail::RFieldValue>
1578 auto [beginPtr, sizePtr,
_] = GetRVecDataMembers(
value.GetRawPtr());
1580 std::vector<Detail::RFieldValue>
result;
1581 char *begin =
reinterpret_cast<char *
>(*beginPtr);
1582 for (std::int32_t i = 0; i < *sizePtr; ++i) {
1583 auto elementValue = fSubFields[0]->CaptureValue(begin + i * fItemSize);
1584 result.emplace_back(std::move(elementValue));
1603 constexpr auto dataMemberSz =
sizeof(
void *) + 2 *
sizeof(std::int32_t);
1604 const auto alignOfT = fSubFields[0]->GetAlignment();
1605 const auto sizeOfT = fSubFields[0]->GetValueSize();
1608 const auto inlineStorageSz = [&] {
1609#ifdef R__HAS_HARDWARE_INTERFERENCE_SIZE
1611 constexpr unsigned cacheLineSize = std::hardware_destructive_interference_size;
1613 constexpr unsigned cacheLineSize = 64u;
1615 const unsigned elementsPerCacheLine = (cacheLineSize - dataMemberSz) / sizeOfT;
1616 constexpr unsigned maxInlineByteSize = 1024;
1617 const unsigned nElements =
1618 elementsPerCacheLine >= 8 ? elementsPerCacheLine : (sizeOfT * 8 > maxInlineByteSize ? 0 : 8);
1619 return nElements * sizeOfT;
1624 auto paddingMiddle = dataMemberSz % alignOfT;
1625 if (paddingMiddle != 0)
1626 paddingMiddle = alignOfT - paddingMiddle;
1629 const auto alignOfRVecT = GetAlignment();
1630 auto paddingEnd = (dataMemberSz + paddingMiddle + inlineStorageSz) % alignOfRVecT;
1631 if (paddingEnd != 0)
1632 paddingEnd = alignOfRVecT - paddingEnd;
1634 return dataMemberSz + inlineStorageSz + paddingMiddle + paddingEnd;
1646 return std::max({
alignof(
void *),
alignof(std::int32_t), fSubFields[0]->GetAlignment()});
1669 auto typedValue =
value.Get<std::vector<bool>>();
1670 auto count = typedValue->size();
1671 for (
unsigned i = 0; i < count; ++i) {
1672 bool bval = (*typedValue)[i];
1673 auto itemValue = fSubFields[0]->CaptureValue(&bval);
1674 fSubFields[0]->Append(itemValue);
1676 Detail::RColumnElement<ClusterSize_t> elemIndex(&fNWritten);
1678 fColumns[0]->Append(elemIndex);
1679 return count +
sizeof(elemIndex);
1684 auto typedValue =
value->Get<std::vector<bool>>();
1687 RClusterIndex collectionStart;
1688 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
1690 typedValue->resize(nItems);
1691 for (
unsigned i = 0; i < nItems; ++i) {
1693 auto itemValue = fSubFields[0]->GenerateValue(&bval);
1694 fSubFields[0]->Read(collectionStart + i, &itemValue);
1695 (*typedValue)[i] = bval;
1702 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
1703 Detail::RColumn::Create<ClusterSize_t, EColumnType::kIndex>(modelIndex, 0)));
1709 GenerateColumnsImpl();
1712std::vector<ROOT::Experimental::Detail::RFieldValue>
1715 const static bool trueValue =
true;
1716 const static bool falseValue =
false;
1718 auto typedValue =
value.Get<std::vector<bool>>();
1719 auto count = typedValue->size();
1720 std::vector<Detail::RFieldValue>
result;
1721 for (
unsigned i = 0; i < count; ++i) {
1722 if ((*typedValue)[i])
1723 result.emplace_back(fSubFields[0]->CaptureValue(
const_cast<bool *
>(&trueValue)));
1725 result.emplace_back(fSubFields[0]->CaptureValue(
const_cast<bool *
>(&falseValue)));
1733 auto vec =
static_cast<std::vector<bool>*
>(
value.GetRawPtr());
1741 visitor.VisitVectorBoolField(*
this);
1749 std::string_view fieldName, std::unique_ptr<Detail::RFieldBase> itemField, std::size_t arrayLength)
1751 fieldName,
"std::array<" + itemField->GetType() +
"," + std::to_string(arrayLength) +
">",
1753 , fItemSize(itemField->GetValueSize()), fArrayLength(arrayLength)
1755 fTraits |= itemField->GetTraits() & ~kTraitMappable;
1756 Attach(std::move(itemField));
1759std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
1762 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetName());
1763 return std::make_unique<RArrayField>(newName, std::move(newItemField), fArrayLength);
1767 std::size_t nbytes = 0;
1768 auto arrayPtr =
value.Get<
unsigned char>();
1769 for (
unsigned i = 0; i < fArrayLength; ++i) {
1770 auto itemValue = fSubFields[0]->CaptureValue(arrayPtr + (i * fItemSize));
1771 nbytes += fSubFields[0]->Append(itemValue);
1778 auto arrayPtr =
value->Get<
unsigned char>();
1779 for (
unsigned i = 0; i < fArrayLength; ++i) {
1780 auto itemValue = fSubFields[0]->CaptureValue(arrayPtr + (i * fItemSize));
1781 fSubFields[0]->Read(globalIndex * fArrayLength + i, &itemValue);
1787 auto arrayPtr =
value->Get<
unsigned char>();
1788 for (
unsigned i = 0; i < fArrayLength; ++i) {
1789 auto itemValue = fSubFields[0]->CaptureValue(arrayPtr + (i * fItemSize));
1805 if (fSubFields[0]->GetTraits() & kTraitTriviallyConstructible)
1808 auto arrayPtr =
reinterpret_cast<unsigned char *
>(where);
1809 for (
unsigned i = 0; i < fArrayLength; ++i) {
1810 fSubFields[0]->GenerateValue(arrayPtr + (i * fItemSize));
1817 auto arrayPtr =
value.Get<
unsigned char>();
1818 if (!(fSubFields[0]->GetTraits() & kTraitTriviallyDestructible)) {
1819 for (
unsigned i = 0; i < fArrayLength; ++i) {
1820 auto itemValue = fSubFields[0]->CaptureValue(arrayPtr + (i * fItemSize));
1821 fSubFields[0]->DestroyValue(itemValue,
true );
1833std::vector<ROOT::Experimental::Detail::RFieldValue>
1836 auto arrayPtr =
value.Get<
unsigned char>();
1837 std::vector<Detail::RFieldValue>
result;
1838 for (
unsigned i = 0; i < fArrayLength; ++i) {
1839 auto itemValue = fSubFields[0]->CaptureValue(arrayPtr + (i * fItemSize));
1840 result.emplace_back(itemValue);
1855 for (
size_t i = 0; i < itemFields.size(); ++i) {
1856 result += itemFields[i]->GetType() +
",";
1864 std::string_view fieldName,
const std::vector<Detail::RFieldBase *> &itemFields)
1871 auto nFields = itemFields.size();
1874 for (
unsigned int i = 0; i < nFields; ++i) {
1877 fTraits &= itemFields[i]->GetTraits();
1878 Attach(std::unique_ptr<Detail::RFieldBase>(itemFields[i]));
1883std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
1886 auto nFields = fSubFields.size();
1887 std::vector<Detail::RFieldBase *> itemFields;
1888 for (
unsigned i = 0; i < nFields; ++i) {
1890 itemFields.emplace_back(fSubFields[i]->Clone(fSubFields[i]->GetName()).release());
1892 return std::make_unique<RVariantField>(newName, itemFields);
1897 auto index = *(
reinterpret_cast<char *
>(variantPtr) + fTagOffset);
1903 auto index =
reinterpret_cast<char *
>(variantPtr) + fTagOffset;
1904 *
index =
static_cast<char>(tag - 1);
1909 auto tag = GetTag(
value.GetRawPtr());
1910 std::size_t nbytes = 0;
1913 auto itemValue = fSubFields[tag - 1]->CaptureValue(
value.GetRawPtr());
1914 nbytes += fSubFields[tag - 1]->Append(itemValue);
1915 index = fNWritten[tag - 1]++;
1919 fColumns[0]->Append(elemSwitch);
1927 fPrincipalColumn->GetSwitchInfo(globalIndex, &variantIndex, &tag);
1930 auto itemValue = fSubFields[tag - 1]->GenerateValue(
value->GetRawPtr());
1931 fSubFields[tag - 1]->Read(variantIndex, &itemValue);
1932 SetTag(
value->GetRawPtr(), tag);
1938 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
1939 Detail::RColumn::Create<RColumnSwitch, EColumnType::kSwitch>(modelSwitch, 0)));
1945 GenerateColumnsImpl();
1950 memset(where, 0, GetValueSize());
1951 fSubFields[0]->GenerateValue(where);
1958 auto variantPtr =
value.GetRawPtr();
1959 auto tag = GetTag(variantPtr);
1961 auto itemValue = fSubFields[tag - 1]->CaptureValue(variantPtr);
1962 fSubFields[tag - 1]->DestroyValue(itemValue,
true );
1975 return fMaxItemSize + fMaxAlignment;
1980 std::fill(fNWritten.begin(), fNWritten.end(), 0);
1985std::string ROOT::Experimental::RPairField::RPairField::GetTypeList(
1986 const std::array<std::unique_ptr<Detail::RFieldBase>, 2> &itemFields)
1988 return itemFields[0]->GetType() +
"," + itemFields[1]->GetType();
1992 std::array<std::unique_ptr<Detail::RFieldBase>, 2> &&itemFields,
1993 const std::array<std::size_t, 2> &offsets)
1994 :
ROOT::Experimental::
RRecordField(fieldName, std::move(itemFields), offsets,
1995 "std::pair<" + GetTypeList(itemFields) +
">")
2000 std::array<std::unique_ptr<Detail::RFieldBase>, 2> &itemFields)
2002 "std::pair<" + GetTypeList(itemFields) +
">")
2009 fOffsets[0] =
fClass->GetDataMember(
"first")->GetOffset();
2010 fOffsets[1] =
fClass->GetDataMember(
"second")->GetOffset();
2013std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
2016 std::array<std::unique_ptr<Detail::RFieldBase>, 2> items{fSubFields[0]->Clone(fSubFields[0]->GetName()),
2017 fSubFields[1]->Clone(fSubFields[1]->GetName())};
2019 std::unique_ptr<RPairField>
result(
new RPairField(newName, std::move(items), {fOffsets[0], fOffsets[1]}));
2038std::string ROOT::Experimental::RTupleField::RTupleField::GetTypeList(
2039 const std::vector<std::unique_ptr<Detail::RFieldBase>> &itemFields)
2042 if (itemFields.empty())
2043 throw RException(
R__FAIL(
"the type list for std::tuple must have at least one element"));
2044 for (
size_t i = 0; i < itemFields.size(); ++i) {
2045 result += itemFields[i]->GetType() +
",";
2052 std::vector<std::unique_ptr<Detail::RFieldBase>> &&itemFields,
2053 const std::vector<std::size_t> &offsets)
2054 :
ROOT::Experimental::
RRecordField(fieldName, std::move(itemFields), offsets,
2055 "std::tuple<" + GetTypeList(itemFields) +
">")
2060 std::vector<std::unique_ptr<Detail::RFieldBase>> &itemFields)
2062 "std::tuple<" + GetTypeList(itemFields) +
">")
2074 for (
unsigned i = 0; i < fSubFields.size(); ++i) {
2075 std::string memberName(
"_" + std::to_string(i));
2076 auto member =
fClass->GetRealData(memberName.c_str());
2079 fOffsets.push_back(member->GetThisOffset());
2083std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
2086 std::vector<std::unique_ptr<Detail::RFieldBase>> items;
2087 for (
const auto &item : fSubFields)
2088 items.push_back(item->Clone(item->GetName()));
2090 std::unique_ptr<RTupleField>
result(
new RTupleField(newName, std::move(items), fOffsets));
2110 std::string_view
name,
2111 std::shared_ptr<RCollectionNTupleWriter> collectionNTuple,
2112 std::unique_ptr<RNTupleModel> collectionModel)
2114 , fCollectionNTuple(collectionNTuple)
2116 for (
unsigned i = 0; i < collectionModel->GetFieldZero()->
fSubFields.size(); ++i) {
2117 auto& subField = collectionModel->GetFieldZero()->fSubFields[i];
2118 Attach(std::move(subField));
2127 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
2128 Detail::RColumn::Create<ClusterSize_t, EColumnType::kIndex>(modelIndex, 0)));
2134 GenerateColumnsImpl();
2138std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
2142 for (
auto&
f : fSubFields) {
2143 auto clone =
f->Clone(
f->GetName());
2144 result->Attach(std::move(clone));
2151 *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...
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 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)
Pairs of C++ type and column type, like float and EColumnType::kReal32.
static RColumn * Create(const RColumnModel &model, std::uint32_t index)
Iterates over the sub tree of fields in depth-first search order.
void Advance()
Given that the iterator points to a valid field which is not the end iterator, go to the next field i...
virtual void GenerateColumnsImpl()=0
Creates the backing columns corresponsing to the field type for writing.
std::vector< std::unique_ptr< RFieldBase > > fSubFields
Collections and classes own sub fields.
RFieldBase(std::string_view name, std::string_view type, ENTupleStructure structure, bool isSimple, std::size_t nRepetitions=0)
The constructor creates the underlying column objects and connects them to either a sink or a source.
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.
ROOT::Experimental::EColumnType EnsureColumnType(const std::vector< EColumnType > &requestedTypes, unsigned int columnIndex, const RNTupleDescriptor &desc)
Throws an exception if the column given by fOnDiskId and the columnIndex in the provided descriptor i...
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.
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.
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
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.
virtual void AcceptVisitor(RFieldVisitor &visitor) const
virtual void ReadGlobalImpl(NTupleSize_t globalIndex, RFieldValue *value)
void Attach(std::unique_ptr< Detail::RFieldBase > child)
Add a new subfield to the list of nested fields.
std::vector< RFieldBase * > GetSubFields() 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.
RFieldValue GenerateValue()
Generates an object of the field type and allocates new initialized memory according to the type.
Abstract base class for classes implementing the visitor design pattern.
virtual void VisitBoolField(const RField< bool > &field)
virtual void VisitFieldZero(const RFieldZero &field)
virtual void 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.
Abstract interface to read data from an ntuple.
const RSharedDescriptorGuard GetSharedDescriptorGuard() const
Takes the read lock for the descriptor.
The available trivial, native content types of a column.
std::vector< Detail::RFieldValue > SplitValue(const Detail::RFieldValue &value) const final
Creates the list of direct child values given a value for this field.
Detail::RFieldValue CaptureValue(void *where) final
Creates a value from a memory location with an already constructed object.
void ReadInClusterImpl(const RClusterIndex &clusterIndex, Detail::RFieldValue *value) final
void ReadGlobalImpl(NTupleSize_t globalIndex, Detail::RFieldValue *value) final
RArrayField(std::string_view fieldName, std::unique_ptr< Detail::RFieldBase > itemField, std::size_t arrayLength)
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type for writing.
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.
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.
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 AcceptVisitor(Detail::RFieldVisitor &visitor) const override
void ReadInClusterImpl(const RClusterIndex &clusterIndex, Detail::RFieldValue *value) final
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type for writing.
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
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.
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type for writing.
void CommitCluster() final
Perform housekeeping tasks for global to cluster-local index translation.
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.
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 a column in a tree.
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.
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.
const RColumnDescriptor & GetColumnDescriptor(DescriptorId_t columnId) const
DescriptorId_t FindColumnId(DescriptorId_t fieldId, std::uint32_t columnIndex) const
static std::unique_ptr< RNTupleModel > Create()
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...
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
For many types, the alignment requirement is equal to the size; otherwise override.
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...
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.
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
For many types, the alignment requirement is equal to the size; otherwise override.
Detail::RFieldValue CaptureValue(void *where) final
Creates a value from a memory location with an already constructed object.
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.
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 TVirtualCollectionProxy * Generate() const =0
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 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 32bit integer in a struct in order to avoid template specialization clash with std::uint32_t...