42#include <unordered_map>
46static const std::unordered_map<std::string_view, std::string_view> typeTranslationMap{
49 {
"Double_t",
"double"},
50 {
"string",
"std::string"},
53 {
"int8_t",
"std::int8_t"},
54 {
"signed char",
"char"},
55 {
"UChar_t",
"std::uint8_t"},
56 {
"unsigned char",
"std::uint8_t"},
57 {
"uint8_t",
"std::uint8_t"},
59 {
"Short_t",
"std::int16_t"},
60 {
"int16_t",
"std::int16_t"},
61 {
"short",
"std::int16_t"},
62 {
"UShort_t",
"std::uint16_t"},
63 {
"unsigned short",
"std::uint16_t"},
64 {
"uint16_t",
"std::uint16_t"},
66 {
"Int_t",
"std::int32_t"},
67 {
"int32_t",
"std::int32_t"},
68 {
"int",
"std::int32_t"},
69 {
"UInt_t",
"std::uint32_t"},
70 {
"unsigned",
"std::uint32_t"},
71 {
"unsigned int",
"std::uint32_t"},
72 {
"uint32_t",
"std::uint32_t"},
74 {
"Long_t",
"std::int64_t"},
75 {
"Long64_t",
"std::int64_t"},
76 {
"int64_t",
"std::int64_t"},
77 {
"long",
"std::int64_t"},
78 {
"ULong64_t",
"std::uint64_t"},
79 {
"unsigned long",
"std::uint64_t"},
80 {
"uint64_t",
"std::uint64_t"}
85std::vector<std::string> TokenizeTypeList(std::string templateType) {
86 std::vector<std::string> result;
87 if (templateType.empty())
90 const char *eol = templateType.data() + templateType.length();
91 const char *typeBegin = templateType.data();
92 const char *typeCursor = templateType.data();
93 unsigned int nestingLevel = 0;
94 while (typeCursor != eol) {
95 switch (*typeCursor) {
103 if (nestingLevel == 0) {
104 result.push_back(std::string(typeBegin, typeCursor - typeBegin));
105 typeBegin = typeCursor + 1;
111 result.push_back(std::string(typeBegin, typeCursor - typeBegin));
116 std::string normalizedType(
120 auto translatedType = typeTranslationMap.find(normalizedType);
121 if (translatedType != typeTranslationMap.end())
122 normalizedType = translatedType->second;
124 if (normalizedType.substr(0, 7) ==
"vector<") normalizedType =
"std::" + normalizedType;
125 if (normalizedType.substr(0, 6) ==
"array<") normalizedType =
"std::" + normalizedType;
126 if (normalizedType.substr(0, 8) ==
"variant<") normalizedType =
"std::" + normalizedType;
128 return normalizedType;
139 : fName(
name), fType(
type), fStructure(structure), fNRepetitions(nRepetitions), fIsSimple(isSimple),
140 fParent(nullptr), fPrincipalColumn(nullptr)
151 std::string normalizedType(GetNormalizedType(typeName));
152 if (normalizedType.empty())
153 return R__FAIL(
"no type name specified for Field " + fieldName);
155 std::unique_ptr<ROOT::Experimental::Detail::RFieldBase> result;
157 if (normalizedType ==
"ROOT::Experimental::ClusterSize_t") {
158 result = std::make_unique<RField<ClusterSize_t>>(fieldName);
159 }
else if (normalizedType ==
"bool") {
160 result = std::make_unique<RField<bool>>(fieldName);
161 }
else if (normalizedType ==
"char") {
162 result = std::make_unique<RField<char>>(fieldName);
163 }
else if (normalizedType ==
"std::int8_t") {
164 result = std::make_unique<RField<std::int8_t>>(fieldName);
165 }
else if (normalizedType ==
"std::uint8_t") {
166 result = std::make_unique<RField<std::uint8_t>>(fieldName);
167 }
else if (normalizedType ==
"std::int16_t") {
168 result = std::make_unique<RField<std::int16_t>>(fieldName);
169 }
else if (normalizedType ==
"std::uint16_t") {
170 result = std::make_unique<RField<std::uint16_t>>(fieldName);
171 }
else if (normalizedType ==
"std::int32_t") {
172 result = std::make_unique<RField<std::int32_t>>(fieldName);
173 }
else if (normalizedType ==
"std::uint32_t") {
174 result = std::make_unique<RField<std::uint32_t>>(fieldName);
175 }
else if (normalizedType ==
"std::int64_t") {
176 result = std::make_unique<RField<std::int64_t>>(fieldName);
177 }
else if (normalizedType ==
"std::uint64_t") {
178 result = std::make_unique<RField<std::uint64_t>>(fieldName);
179 }
else if (normalizedType ==
"float") {
180 result = std::make_unique<RField<float>>(fieldName);
181 }
else if (normalizedType ==
"double") {
182 result = std::make_unique<RField<double>>(fieldName);
183 }
else if (normalizedType ==
"std::string") {
184 result = std::make_unique<RField<std::string>>(fieldName);
185 }
else if (normalizedType ==
"std::vector<bool>") {
186 result = std::make_unique<RField<std::vector<bool>>>(fieldName);
187 }
else if (normalizedType.substr(0, 12) ==
"std::vector<") {
188 std::string itemTypeName = normalizedType.substr(12, normalizedType.length() - 13);
189 auto itemField = Create(
"_0", itemTypeName);
190 result = std::make_unique<RVectorField>(fieldName, itemField.Unwrap());
191 }
else if (normalizedType ==
"ROOT::VecOps::RVec<bool>") {
192 result = std::make_unique<RField<ROOT::VecOps::RVec<bool>>>(fieldName);
193 }
else if (normalizedType.substr(0, 19) ==
"ROOT::VecOps::RVec<") {
195 std::string itemTypeName = normalizedType.substr(19, normalizedType.length() - 20);
196 auto itemField = Create(
"_0", itemTypeName);
197 result = std::make_unique<RVectorField>(fieldName, itemField.Unwrap());
198 }
else if (normalizedType.substr(0, 11) ==
"std::array<") {
199 auto arrayDef = TokenizeTypeList(normalizedType.substr(11, normalizedType.length() - 12));
201 auto arrayLength = std::stoi(arrayDef[1]);
202 auto itemField = Create(GetNormalizedType(arrayDef[0]), arrayDef[0]);
203 result = std::make_unique<RArrayField>(fieldName, itemField.Unwrap(), arrayLength);
205#if __cplusplus >= 201703L
206 if (normalizedType.substr(0, 13) ==
"std::variant<") {
207 auto innerTypes = TokenizeTypeList(normalizedType.substr(13, normalizedType.length() - 14));
208 std::vector<RFieldBase *> items;
209 for (
unsigned int i = 0; i < innerTypes.size(); ++i) {
210 items.emplace_back(Create(
"_" + std::to_string(i), innerTypes[i]).Unwrap().release());
212 result = std::make_unique<RVariantField>(fieldName, items);
216 if (normalizedType ==
":Collection:")
217 result = std::make_unique<RField<ClusterSize_t>>(fieldName);
222 result = std::make_unique<RClassField>(fieldName, normalizedType);
228 return R__FAIL(std::string(
"Field ") + fieldName +
" has unknown type " + normalizedType);
234 if (fieldName ==
"") {
235 return R__FAIL(
"name cannot be empty string \"\"");
236 }
else if (fieldName.find(
".") != std::string::npos) {
237 return R__FAIL(
"name '" + std::string(fieldName) +
"' cannot contain dot characters '.'");
242std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
245 auto clone = CloneImpl(newName);
246 clone->fOnDiskId = fOnDiskId;
247 clone->fDescription = fDescription;
253 R__ASSERT(
false &&
"A non-simple RField must implement its own AppendImpl");
266 void *where =
malloc(GetValueSize());
268 return GenerateValue(where);
277std::vector<ROOT::Experimental::Detail::RFieldValue>
280 return std::vector<RFieldValue>();
284 std::unique_ptr<ROOT::Experimental::Detail::RFieldBase> child)
286 child->fParent =
this;
287 fSubFields.emplace_back(std::move(child));
293 std::vector<RFieldBase *> result;
294 for (
const auto &
f : fSubFields) {
295 result.emplace_back(
f.get());
303 for (
auto& column : fColumns) {
310 const std::vector<EColumnType> &requestedTypes,
unsigned int columnIndex,
const RNTupleDescriptor &desc)
313 auto columnId = desc.
FindColumnId(fOnDiskId, columnIndex);
315 throw RException(
R__FAIL(
"Column missing: column #" + std::to_string(columnIndex) +
316 " for field " + fName));
320 for (
auto type : requestedTypes) {
321 if (
type == columnDesc.GetModel().GetType())
326 "` of column #" + std::to_string(columnIndex) +
" for field `" + fName +
327 "` is not convertible to the requested type" + [&]{
328 std::string typeStr = requestedTypes.size() > 1 ?
"s " :
" ";
329 for (std::size_t i = 0; i < requestedTypes.size(); i++) {
330 typeStr +=
"`" + RColumnElementBase::GetTypeName(requestedTypes[i]) +
"`";
331 if (i != requestedTypes.size() - 1) {
338 return columnDesc.GetModel().GetType();
345 GenerateColumnsImpl();
346 if (!fColumns.empty())
347 fPrincipalColumn = fColumns[0].get();
348 for (
auto& column : fColumns)
349 column->Connect(fOnDiskId, &pageSink);
357 if (!fColumns.empty())
358 fPrincipalColumn = fColumns[0].get();
359 for (
auto& column : fColumns)
360 column->Connect(fOnDiskId, &pageSource);
388 auto itr = fStack.rbegin();
389 if (!itr->fFieldPtr->fSubFields.empty()) {
390 fStack.emplace_back(
Position(itr->fFieldPtr->fSubFields[0].get(), 0));
394 unsigned int nextIdxInParent = ++(itr->fIdxInParent);
395 while (nextIdxInParent >= itr->fFieldPtr->fParent->fSubFields.size()) {
396 if (fStack.size() == 1) {
397 itr->fFieldPtr = itr->fFieldPtr->fParent;
398 itr->fIdxInParent = -1;
402 itr = fStack.rbegin();
403 nextIdxInParent = ++(itr->fIdxInParent);
405 itr->fFieldPtr = itr->fFieldPtr->fParent->fSubFields[nextIdxInParent].get();
412std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
415 auto result = std::make_unique<RFieldZero>();
416 for (
auto &
f : fSubFields)
417 result->Attach(
f->Clone(
f->GetName()));
424 auto entry = std::make_unique<REntry>();
425 for (
auto&
f : fSubFields) {
426 entry->AddValue(
f->GenerateValue());
443 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
444 Detail::RColumn::Create<ClusterSize_t, EColumnType::kIndex>(model, 0)));
450 GenerateColumnsImpl();
455 visitor.VisitClusterSizeField(*
this);
470 GenerateColumnsImpl();
490 GenerateColumnsImpl();
495 visitor.VisitInt8Field(*
this);
510 GenerateColumnsImpl();
515 visitor.VisitUInt8Field(*
this);
524 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
525 Detail::RColumn::Create<bool, EColumnType::kBit>(model, 0)));
531 GenerateColumnsImpl();
545 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
546 Detail::RColumn::Create<float, EColumnType::kReal32>(model, 0)));
552 GenerateColumnsImpl();
566 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
567 Detail::RColumn::Create<double, EColumnType::kReal64>(model, 0)));
573 GenerateColumnsImpl();
593 GenerateColumnsImpl();
598 visitor.VisitInt16Field(*
this);
613 GenerateColumnsImpl();
618 visitor.VisitUInt16Field(*
this);
633 GenerateColumnsImpl();
638 visitor.VisitIntField(*
this);
646 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
647 Detail::RColumn::Create<std::uint32_t, EColumnType::kInt32>(model, 0)));
653 GenerateColumnsImpl();
658 visitor.VisitUInt32Field(*
this);
666 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
667 Detail::RColumn::Create<std::uint64_t, EColumnType::kInt64>(model, 0)));
673 GenerateColumnsImpl();
678 visitor.VisitUInt64Field(*
this);
686 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
687 Detail::RColumn::Create<std::int64_t, EColumnType::kInt64>(model, 0)));
693 RColumnModel model(
type,
false );
695 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
696 Detail::RColumn::Create<std::int64_t, EColumnType::kInt64>(model, 0)));
698 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
699 Detail::RColumn::Create<std::int64_t, EColumnType::kInt32>(model, 0)));
705 visitor.VisitInt64Field(*
this);
713 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
714 Detail::RColumn::Create<ClusterSize_t, EColumnType::kIndex>(modelIndex, 0)));
717 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
718 Detail::RColumn::Create<char, EColumnType::kChar>(modelChars, 1)));
725 GenerateColumnsImpl();
730 auto typedValue = value.
Get<std::string>();
731 auto length = typedValue->length();
732 Detail::RColumnElement<char> elemChars(
const_cast<char*
>(typedValue->data()));
733 fColumns[1]->AppendV(elemChars, length);
735 fColumns[0]->Append(fElemIndex);
736 return length +
sizeof(fElemIndex);
742 auto typedValue = value->
Get<std::string>();
743 RClusterIndex collectionStart;
745 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nChars);
749 typedValue->resize(nChars);
750 Detail::RColumnElement<char> elemChars(
const_cast<char*
>(typedValue->data()));
751 fColumns[1]->ReadV(collectionStart, nChars, &elemChars);
762 visitor.VisitStringField(*
this);
778 throw std::runtime_error(
"RField: no I/O support for type " + std::string(className));
787 TClass *
c = baseClass->GetClassPointer();
789 c->GetName()).Unwrap();
790 Attach(std::move(subField),
795 if (!dataMember->IsPersistent())
798 Attach(std::move(subField),
805 fMaxAlignment = std::max(fMaxAlignment, child->GetAlignment());
806 fSubFieldsInfo.push_back(info);
807 RFieldBase::Attach(std::move(child));
810std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
813 return std::unique_ptr<RClassField>(
new RClassField(newName, GetType(),
fClass));
817 std::size_t nbytes = 0;
818 for (
unsigned i = 0; i < fSubFields.size(); i++) {
819 auto memberValue = fSubFields[i]->CaptureValue(value.
Get<
unsigned char>() + fSubFieldsInfo[i].fOffset);
820 nbytes += fSubFields[i]->Append(memberValue);
827 for (
unsigned i = 0; i < fSubFields.size(); i++) {
828 auto memberValue = fSubFields[i]->CaptureValue(value->
Get<
unsigned char>() + fSubFieldsInfo[i].fOffset);
829 fSubFields[i]->Read(globalIndex, &memberValue);
835 for (
unsigned i = 0; i < fSubFields.size(); i++) {
836 auto memberValue = fSubFields[i]->CaptureValue(value->
Get<
unsigned char>() + fSubFieldsInfo[i].fOffset);
837 fSubFields[i]->Read(clusterIndex, &memberValue);
867std::vector<ROOT::Experimental::Detail::RFieldValue>
870 std::vector<Detail::RFieldValue> result;
871 for (
unsigned i = 0; i < fSubFields.size(); i++) {
872 auto memberValue = fSubFields[i]->CaptureValue(value.
Get<
unsigned char>() + fSubFieldsInfo[i].fOffset);
873 result.emplace_back(memberValue);
881 return fClass->GetClassSize();
892 std::string_view fieldName, std::vector<std::unique_ptr<Detail::RFieldBase>> &itemFields)
895 for (
auto &item : itemFields) {
905 if (itemAlignment > 1) {
906 auto remainder = baseOffset % itemAlignment;
908 return itemAlignment - remainder;
913std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
916 std::vector<std::unique_ptr<Detail::RFieldBase>> cloneItems;
917 for (
auto &item : fSubFields)
918 cloneItems.emplace_back(item->Clone(item->GetName()));
919 return std::make_unique<RRecordField>(newName, cloneItems);
923 std::size_t nbytes = 0;
924 std::size_t offset = 0;
925 for (
auto &item : fSubFields) {
926 auto memberValue = item->CaptureValue(value.
Get<
unsigned char>() + offset);
927 nbytes += item->Append(memberValue);
928 offset += GetItemPadding(offset, item->GetAlignment()) + item->GetValueSize();
935 std::size_t offset = 0;
936 for (
auto &item : fSubFields) {
937 auto memberValue = item->CaptureValue(value->
Get<
unsigned char>() + offset);
938 item->Read(globalIndex, &memberValue);
939 offset += GetItemPadding(offset, item->GetAlignment()) + item->GetValueSize();
945 std::size_t offset = 0;
946 for (
auto &item : fSubFields) {
947 auto memberValue = item->CaptureValue(value->
Get<
unsigned char>() + offset);
948 item->Read(clusterIndex, &memberValue);
949 offset += GetItemPadding(offset, item->GetAlignment()) + item->GetValueSize();
955 std::size_t offset = 0;
956 for (
auto &item : fSubFields) {
957 item->GenerateValue(
static_cast<unsigned char *
>(where) + offset);
958 offset += GetItemPadding(offset, item->GetAlignment()) + item->GetValueSize();
965 std::size_t offset = 0;
966 for (
auto &item : fSubFields) {
967 auto memberValue = item->CaptureValue(value.
Get<
unsigned char>() + offset);
968 item->DestroyValue(memberValue,
true );
969 offset += GetItemPadding(offset, item->GetAlignment()) + item->GetValueSize();
982std::vector<ROOT::Experimental::Detail::RFieldValue>
985 std::size_t offset = 0;
986 std::vector<Detail::RFieldValue> result;
987 for (
auto &item : fSubFields) {
988 result.emplace_back(item->CaptureValue(value.
Get<
unsigned char>() + offset));
989 offset += GetItemPadding(offset, item->GetAlignment()) + item->GetValueSize();
1004 std::string_view fieldName, std::unique_ptr<Detail::RFieldBase> itemField)
1007 , fItemSize(itemField->GetValueSize()), fNWritten(0)
1009 Attach(std::move(itemField));
1012std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
1015 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetName());
1016 return std::make_unique<RVectorField>(newName, std::move(newItemField));
1020 auto typedValue = value.
Get<std::vector<char>>();
1021 R__ASSERT((typedValue->size() % fItemSize) == 0);
1022 std::size_t nbytes = 0;
1023 auto count = typedValue->size() / fItemSize;
1024 for (
unsigned i = 0; i < count; ++i) {
1025 auto itemValue = fSubFields[0]->CaptureValue(typedValue->data() + (i * fItemSize));
1026 nbytes += fSubFields[0]->Append(itemValue);
1030 fColumns[0]->Append(elemIndex);
1031 return nbytes +
sizeof(elemIndex);
1036 auto typedValue = value->
Get<std::vector<char>>();
1040 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
1042 auto oldNItems = typedValue->size() / fItemSize;
1043 for (std::size_t i = nItems; i < oldNItems; ++i) {
1044 auto itemValue = fSubFields[0]->CaptureValue(typedValue->data() + (i * fItemSize));
1045 fSubFields[0]->DestroyValue(itemValue,
true );
1047 typedValue->resize(nItems * fItemSize);
1048 for (std::size_t i = oldNItems; i < nItems; ++i) {
1049 fSubFields[0]->GenerateValue(typedValue->data() + (i * fItemSize));
1052 for (std::size_t i = 0; i < nItems; ++i) {
1053 auto itemValue = fSubFields[0]->CaptureValue(typedValue->data() + (i * fItemSize));
1054 fSubFields[0]->Read(collectionStart + i, &itemValue);
1061 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
1062 Detail::RColumn::Create<ClusterSize_t, EColumnType::kIndex>(modelIndex, 0)));
1068 GenerateColumnsImpl();
1078 auto vec =
static_cast<std::vector<char>*
>(value.
GetRawPtr());
1080 auto nItems =
vec->size() / fItemSize;
1081 for (
unsigned i = 0; i < nItems; ++i) {
1082 auto itemValue = fSubFields[0]->CaptureValue(
vec->data() + (i * fItemSize));
1083 fSubFields[0]->DestroyValue(itemValue,
true );
1095std::vector<ROOT::Experimental::Detail::RFieldValue>
1098 auto vec =
static_cast<std::vector<char>*
>(value.
GetRawPtr());
1100 auto nItems =
vec->size() / fItemSize;
1101 std::vector<Detail::RFieldValue> result;
1102 for (
unsigned i = 0; i < nItems; ++i) {
1103 result.emplace_back(fSubFields[0]->CaptureValue(
vec->data() + (i * fItemSize)));
1130 auto typedValue = value.Get<std::vector<bool>>();
1131 auto count = typedValue->size();
1132 for (
unsigned i = 0; i < count; ++i) {
1133 bool bval = (*typedValue)[i];
1135 fSubFields[0]->Append(itemValue);
1137 Detail::RColumnElement<ClusterSize_t> elemIndex(&fNWritten);
1139 fColumns[0]->Append(elemIndex);
1140 return count +
sizeof(elemIndex);
1145 auto typedValue = value->Get<std::vector<bool>>();
1148 RClusterIndex collectionStart;
1149 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
1151 typedValue->resize(nItems);
1152 for (
unsigned i = 0; i < nItems; ++i) {
1154 auto itemValue = fSubFields[0]->GenerateValue(&bval);
1155 fSubFields[0]->Read(collectionStart + i, &itemValue);
1156 (*typedValue)[i] = bval;
1163 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
1164 Detail::RColumn::Create<ClusterSize_t, EColumnType::kIndex>(modelIndex, 0)));
1170 GenerateColumnsImpl();
1173std::vector<ROOT::Experimental::Detail::RFieldValue>
1176 const static bool trueValue =
true;
1177 const static bool falseValue =
false;
1179 auto typedValue = value.Get<std::vector<bool>>();
1180 auto count = typedValue->size();
1181 std::vector<Detail::RFieldValue> result;
1182 for (
unsigned i = 0; i < count; ++i) {
1183 if ((*typedValue)[i])
1184 result.emplace_back(fSubFields[0]->CaptureValue(
const_cast<bool *
>(&trueValue)));
1186 result.emplace_back(fSubFields[0]->CaptureValue(
const_cast<bool *
>(&falseValue)));
1194 auto vec =
static_cast<std::vector<bool>*
>(value.GetRawPtr());
1202 visitor.VisitVectorBoolField(*
this);
1210 std::string_view fieldName, std::unique_ptr<Detail::RFieldBase> itemField, std::size_t arrayLength)
1212 fieldName,
"std::array<" + itemField->GetType() +
"," + std::to_string(arrayLength) +
">",
1214 , fItemSize(itemField->GetValueSize()), fArrayLength(arrayLength)
1216 Attach(std::move(itemField));
1219std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
1222 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetName());
1223 return std::make_unique<RArrayField>(newName, std::move(newItemField), fArrayLength);
1227 std::size_t nbytes = 0;
1228 auto arrayPtr = value.
Get<
unsigned char>();
1229 for (
unsigned i = 0; i < fArrayLength; ++i) {
1230 auto itemValue = fSubFields[0]->CaptureValue(arrayPtr + (i * fItemSize));
1231 nbytes += fSubFields[0]->Append(itemValue);
1238 auto arrayPtr = value->
Get<
unsigned char>();
1239 for (
unsigned i = 0; i < fArrayLength; ++i) {
1240 auto itemValue = fSubFields[0]->GenerateValue(arrayPtr + (i * fItemSize));
1241 fSubFields[0]->Read(globalIndex * fArrayLength + i, &itemValue);
1247 auto arrayPtr = value->
Get<
unsigned char>();
1248 for (
unsigned i = 0; i < fArrayLength; ++i) {
1249 auto itemValue = fSubFields[0]->GenerateValue(arrayPtr + (i * fItemSize));
1265 auto arrayPtr =
reinterpret_cast<unsigned char *
>(where);
1266 for (
unsigned i = 0; i < fArrayLength; ++i) {
1267 fSubFields[0]->GenerateValue(arrayPtr + (i * fItemSize));
1274 auto arrayPtr = value.
Get<
unsigned char>();
1275 for (
unsigned i = 0; i < fArrayLength; ++i) {
1276 auto itemValue = fSubFields[0]->CaptureValue(arrayPtr + (i * fItemSize));
1277 fSubFields[0]->DestroyValue(itemValue,
true );
1288std::vector<ROOT::Experimental::Detail::RFieldValue>
1291 auto arrayPtr = value.
Get<
unsigned char>();
1292 std::vector<Detail::RFieldValue> result;
1293 for (
unsigned i = 0; i < fArrayLength; ++i) {
1294 auto itemValue = fSubFields[0]->CaptureValue(arrayPtr + (i * fItemSize));
1295 result.emplace_back(itemValue);
1307#if __cplusplus >= 201703L
1308std::string ROOT::Experimental::RVariantField::GetTypeList(
const std::vector<Detail::RFieldBase *> &itemFields)
1311 for (
size_t i = 0; i < itemFields.size(); ++i) {
1312 result += itemFields[i]->GetType() +
",";
1319ROOT::Experimental::RVariantField::RVariantField(
1320 std::string_view fieldName,
const std::vector<Detail::RFieldBase *> &itemFields)
1324 auto nFields = itemFields.size();
1326 fNWritten.resize(nFields, 0);
1327 for (
unsigned int i = 0; i < nFields; ++i) {
1328 fMaxItemSize = std::max(fMaxItemSize, itemFields[i]->
GetValueSize());
1329 fMaxAlignment = std::max(fMaxAlignment, itemFields[i]->
GetAlignment());
1330 Attach(std::unique_ptr<Detail::RFieldBase>(itemFields[i]));
1332 fTagOffset = (fMaxItemSize < fMaxAlignment) ? fMaxAlignment : fMaxItemSize;
1335std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
1336ROOT::Experimental::RVariantField::CloneImpl(std::string_view newName)
const
1338 auto nFields = fSubFields.size();
1339 std::vector<Detail::RFieldBase *> itemFields;
1340 for (
unsigned i = 0; i < nFields; ++i) {
1342 itemFields.emplace_back(fSubFields[i]->Clone(fSubFields[i]->GetName()).release());
1344 return std::make_unique<RVariantField>(newName, itemFields);
1347std::uint32_t ROOT::Experimental::RVariantField::GetTag(
void *variantPtr)
const
1349 auto index = *(
reinterpret_cast<char *
>(variantPtr) + fTagOffset);
1350 return (index < 0) ? 0 : index + 1;
1353void ROOT::Experimental::RVariantField::SetTag(
void *variantPtr, std::uint32_t tag)
const
1355 auto index =
reinterpret_cast<char *
>(variantPtr) + fTagOffset;
1356 *index =
static_cast<char>(tag - 1);
1359std::size_t ROOT::Experimental::RVariantField::AppendImpl(
const Detail::RFieldValue& value)
1361 auto tag = GetTag(value.GetRawPtr());
1362 std::size_t nbytes = 0;
1365 auto itemValue = fSubFields[tag - 1]->CaptureValue(value.GetRawPtr());
1366 nbytes += fSubFields[tag - 1]->Append(itemValue);
1367 index = fNWritten[tag - 1]++;
1370 Detail::RColumnElement<RColumnSwitch> elemSwitch(&varSwitch);
1371 fColumns[0]->Append(elemSwitch);
1372 return nbytes +
sizeof(RColumnSwitch);
1375void ROOT::Experimental::RVariantField::ReadGlobalImpl(
NTupleSize_t globalIndex, Detail::RFieldValue *value)
1377 RClusterIndex variantIndex;
1379 fPrincipalColumn->GetSwitchInfo(globalIndex, &variantIndex, &tag);
1382 auto itemValue = fSubFields[tag - 1]->GenerateValue(value->GetRawPtr());
1383 fSubFields[tag - 1]->Read(variantIndex, &itemValue);
1384 SetTag(value->GetRawPtr(), tag);
1387void ROOT::Experimental::RVariantField::GenerateColumnsImpl()
1390 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
1391 Detail::RColumn::Create<RColumnSwitch, EColumnType::kSwitch>(modelSwitch, 0)));
1394void ROOT::Experimental::RVariantField::GenerateColumnsImpl(
const RNTupleDescriptor &desc)
1397 GenerateColumnsImpl();
1402 memset(where, 0, GetValueSize());
1403 fSubFields[0]->GenerateValue(where);
1405 return Detail::RFieldValue(
this,
reinterpret_cast<unsigned char *
>(where));
1408void ROOT::Experimental::RVariantField::DestroyValue(
const Detail::RFieldValue& value,
bool dtorOnly)
1410 auto variantPtr = value.GetRawPtr();
1411 auto tag = GetTag(variantPtr);
1413 auto itemValue = fSubFields[tag - 1]->CaptureValue(variantPtr);
1414 fSubFields[tag - 1]->DestroyValue(itemValue,
true );
1422 return Detail::RFieldValue(
true ,
this, where);
1425size_t ROOT::Experimental::RVariantField::GetValueSize()
const
1427 return fMaxItemSize + fMaxAlignment;
1430void ROOT::Experimental::RVariantField::CommitCluster()
1432 std::fill(fNWritten.begin(), fNWritten.end(), 0);
1441 std::string_view
name,
1442 std::shared_ptr<RCollectionNTupleWriter> collectionNTuple,
1443 std::unique_ptr<RNTupleModel> collectionModel)
1445 , fCollectionNTuple(collectionNTuple)
1447 for (
unsigned i = 0; i < collectionModel->GetFieldZero()->
fSubFields.size(); ++i) {
1448 auto& subField = collectionModel->GetFieldZero()->fSubFields[i];
1449 Attach(std::move(subField));
1458 fColumns.emplace_back(std::unique_ptr<Detail::RColumn>(
1459 Detail::RColumn::Create<ClusterSize_t, EColumnType::kIndex>(modelIndex, 0)));
1465 GenerateColumnsImpl();
1469std::unique_ptr<ROOT::Experimental::Detail::RFieldBase>
1472 auto result = std::make_unique<RCollectionField>(newName, fCollectionNTuple,
RNTupleModel::Create());
1473 for (
auto&
f : fSubFields) {
1474 auto clone =
f->Clone(
f->GetName());
1475 result->Attach(std::move(clone));
1482 *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...
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.
virtual void DestroyValue(const RFieldValue &value, bool dtorOnly=false)
Releases the resources acquired during GenerateValue (memory and constructor) This implementation wor...
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 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.
void ConnectPageSource(RPageSource &pageSource)
virtual std::size_t AppendImpl(const RFieldValue &value)
Operations on values of complex types, e.g.
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
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 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 RNTupleDescriptor & GetDescriptor() const
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.
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...
size_t GetAlignment() const final
For many types, the alignment requirement is equal to the size; otherwise override.
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
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.
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
Called by Clone(), which additionally copies the on-disk ID.
std::unique_ptr< REntry > GenerateEntry() const
Generates managed values for the top-level sub fields.
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()
std::size_t fMaxAlignment
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 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) final
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
RRecordField(std::string_view fieldName, std::vector< std::unique_ptr< Detail::RFieldBase > > &itemFields)
The class is used as a return type for operations that can fail; wraps a value of type T or an RError...
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.
Long_t Property() const
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.
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
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
std::string ResolveTypedef(const char *tname, bool resolveAll=false)
std::string CleanType(const char *typeDesc, int mode=0, const char **tail=0)
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...