52#include <unordered_map>
56const std::unordered_map<std::string_view, std::string_view> typeTranslationMap{
59 {
"Double_t",
"double"},
60 {
"string",
"std::string"},
62 {
"byte",
"std::byte"},
64 {
"int8_t",
"std::int8_t"},
65 {
"signed char",
"char"},
66 {
"UChar_t",
"std::uint8_t"},
67 {
"unsigned char",
"std::uint8_t"},
68 {
"uint8_t",
"std::uint8_t"},
70 {
"Short_t",
"std::int16_t"},
71 {
"int16_t",
"std::int16_t"},
72 {
"short",
"std::int16_t"},
73 {
"UShort_t",
"std::uint16_t"},
74 {
"unsigned short",
"std::uint16_t"},
75 {
"uint16_t",
"std::uint16_t"},
77 {
"Int_t",
"std::int32_t"},
78 {
"int32_t",
"std::int32_t"},
79 {
"int",
"std::int32_t"},
80 {
"UInt_t",
"std::uint32_t"},
81 {
"unsigned",
"std::uint32_t"},
82 {
"unsigned int",
"std::uint32_t"},
83 {
"uint32_t",
"std::uint32_t"},
86 {
"Long_t",
"std::int64_t"},
87 {
"Long64_t",
"std::int64_t"},
88 {
"int64_t",
"std::int64_t"},
89 {
"long",
"std::int64_t"},
90 {
"ULong_t",
"std::uint64_t"},
91 {
"ULong64_t",
"std::uint64_t"},
92 {
"unsigned long",
"std::uint64_t"},
93 {
"uint64_t",
"std::uint64_t"}
98std::vector<std::string> TokenizeTypeList(std::string templateType) {
99 std::vector<std::string>
result;
100 if (templateType.empty())
103 const char *eol = templateType.data() + templateType.length();
104 const char *typeBegin = templateType.data();
105 const char *typeCursor = templateType.data();
106 unsigned int nestingLevel = 0;
107 while (typeCursor != eol) {
108 switch (*typeCursor) {
116 if (nestingLevel == 0) {
117 result.push_back(std::string(typeBegin, typeCursor - typeBegin));
118 typeBegin = typeCursor + 1;
124 result.push_back(std::string(typeBegin, typeCursor - typeBegin));
133std::tuple<std::string, std::vector<size_t>> ParseArrayType(std::string_view typeName)
135 std::vector<size_t> sizeVec;
138 while (typeName.back() ==
']') {
139 auto posRBrace = typeName.size() - 1;
140 auto posLBrace = typeName.find_last_of(
'[', posRBrace);
141 if (posLBrace == std::string_view::npos)
145 if (std::from_chars(typeName.data() + posLBrace + 1, typeName.data() + posRBrace,
size).ec != std::errc{})
147 sizeVec.insert(sizeVec.begin(),
size);
148 typeName.remove_suffix(typeName.size() - posLBrace);
150 return std::make_tuple(std::string{typeName}, sizeVec);
155std::string GetCanonicalTypeName(
const std::string &typeName)
158 if (typeName ==
"ROOT::Experimental::ClusterSize_t" || typeName.substr(0, 5) ==
"std::" ||
159 typeName.substr(0, 39) ==
"ROOT::Experimental::RNTupleCardinality<")
170std::string GetNormalizedTypeName(
const std::string &typeName)
174 if (
auto it = typeTranslationMap.find(normalizedType); it != typeTranslationMap.end())
175 normalizedType = it->second;
177 if (normalizedType.substr(0, 7) ==
"vector<")
178 normalizedType =
"std::" + normalizedType;
179 if (normalizedType.substr(0, 6) ==
"array<")
180 normalizedType =
"std::" + normalizedType;
181 if (normalizedType.substr(0, 8) ==
"variant<")
182 normalizedType =
"std::" + normalizedType;
183 if (normalizedType.substr(0, 5) ==
"pair<")
184 normalizedType =
"std::" + normalizedType;
185 if (normalizedType.substr(0, 6) ==
"tuple<")
186 normalizedType =
"std::" + normalizedType;
187 if (normalizedType.substr(0, 7) ==
"bitset<")
188 normalizedType =
"std::" + normalizedType;
189 if (normalizedType.substr(0, 11) ==
"unique_ptr<")
190 normalizedType =
"std::" + normalizedType;
191 if (normalizedType.substr(0, 4) ==
"set<")
192 normalizedType =
"std::" + normalizedType;
193 if (normalizedType.substr(0, 14) ==
"unordered_set<")
194 normalizedType =
"std::" + normalizedType;
195 if (normalizedType.substr(0, 4) ==
"map<")
196 normalizedType =
"std::" + normalizedType;
197 if (normalizedType.substr(0, 14) ==
"unordered_map<")
198 normalizedType =
"std::" + normalizedType;
199 if (normalizedType.substr(0, 7) ==
"atomic<")
200 normalizedType =
"std::" + normalizedType;
202 if (normalizedType.substr(0, 11) ==
"ROOT::RVec<")
203 normalizedType =
"ROOT::VecOps::RVec<" + normalizedType.substr(11);
205 return normalizedType;
209class CreateContextGuard;
211 friend class CreateContextGuard;
213 std::vector<std::string> fClassesOnStack;
216 bool fContinueOnError =
false;
219 CreateContext() =
default;
220 bool GetContinueOnError()
const {
return fContinueOnError; }
224class CreateContextGuard {
225 CreateContext &fCreateContext;
226 std::size_t fNOriginalClassesOnStack;
227 bool fOriginalContinueOnError;
230 CreateContextGuard(CreateContext &ctx)
231 : fCreateContext(ctx),
232 fNOriginalClassesOnStack(ctx.fClassesOnStack.
size()),
233 fOriginalContinueOnError(ctx.fContinueOnError)
236 ~CreateContextGuard()
238 fCreateContext.fClassesOnStack.resize(fNOriginalClassesOnStack);
239 fCreateContext.fContinueOnError = fOriginalContinueOnError;
242 void AddClassToStack(
const std::string &cl)
244 if (std::find(fCreateContext.fClassesOnStack.begin(), fCreateContext.fClassesOnStack.end(), cl) !=
245 fCreateContext.fClassesOnStack.end()) {
246 throw ROOT::Experimental::RException(
R__FAIL(
"cyclic class definition: " + cl));
248 fCreateContext.fClassesOnStack.emplace_back(cl);
251 void SetContinueOnError(
bool value) { fCreateContext.fContinueOnError =
value; }
256std::tuple<void **, std::int32_t *, std::int32_t *> GetRVecDataMembers(
void *rvecPtr)
258 void **begin =
reinterpret_cast<void **
>(rvecPtr);
260 std::int32_t *
size =
reinterpret_cast<std::int32_t *
>(begin + 1);
263 std::int32_t *capacity =
size + 1;
265 return {begin,
size, capacity};
268std::tuple<const void *const *, const std::int32_t *, const std::int32_t *> GetRVecDataMembers(
const void *rvecPtr)
270 return {GetRVecDataMembers(
const_cast<void *
>(rvecPtr))};
278 auto iFrom = from.
cbegin();
279 auto iTo = to.
begin();
280 for (; iFrom != from.
cend(); ++iFrom, ++iTo) {
281 iTo->SetOnDiskId(iFrom->GetOnDiskId());
285std::size_t EvalRVecValueSize(std::size_t alignOfT, std::size_t sizeOfT, std::size_t alignOfRVecT)
299 constexpr auto dataMemberSz =
sizeof(
void *) + 2 *
sizeof(std::int32_t);
302 const auto inlineStorageSz = [&] {
303#ifdef R__HAS_HARDWARE_INTERFERENCE_SIZE
305 constexpr unsigned cacheLineSize = std::hardware_destructive_interference_size;
307 constexpr unsigned cacheLineSize = 64u;
309 const unsigned elementsPerCacheLine = (cacheLineSize - dataMemberSz) / sizeOfT;
310 constexpr unsigned maxInlineByteSize = 1024;
311 const unsigned nElements =
312 elementsPerCacheLine >= 8 ? elementsPerCacheLine : (sizeOfT * 8 > maxInlineByteSize ? 0 : 8);
313 return nElements * sizeOfT;
318 auto paddingMiddle = dataMemberSz % alignOfT;
319 if (paddingMiddle != 0)
320 paddingMiddle = alignOfT - paddingMiddle;
323 auto paddingEnd = (dataMemberSz + paddingMiddle + inlineStorageSz) % alignOfRVecT;
325 paddingEnd = alignOfRVecT - paddingEnd;
327 return dataMemberSz + inlineStorageSz + paddingMiddle + paddingEnd;
330std::size_t EvalRVecAlignment(std::size_t alignOfSubField)
334 return std::max({
alignof(
void *),
alignof(std::int32_t), alignOfSubField});
337void DestroyRVecWithChecks(std::size_t alignOfT,
void **beginPtr,
char *begin, std::int32_t *capacityPtr)
341 constexpr auto dataMemberSz =
sizeof(
void *) + 2 *
sizeof(std::int32_t);
342 auto paddingMiddle = dataMemberSz % alignOfT;
343 if (paddingMiddle != 0)
344 paddingMiddle = alignOfT - paddingMiddle;
345 const bool isSmall = (
reinterpret_cast<void *
>(begin) == (beginPtr + dataMemberSz + paddingMiddle));
347 const bool owns = (*capacityPtr != -1);
348 if (!isSmall && owns)
382 deserializationExtraTypes.begin(), deserializationExtraTypes.end());
405 std::swap(
fDeleter, other.fDeleter);
406 std::swap(
fValues, other.fValues);
412 std::swap(
fField, other.fField);
413 std::swap(
fDeleter, other.fDeleter);
414 std::swap(
fValues, other.fValues);
417 std::swap(
fSize, other.fSize);
451 throw RException(
R__FAIL(
"invalid attempt to bulk read beyond the adopted buffer"));
457 for (std::size_t
i = 0;
i <
size; ++
i) {
476 for (std::size_t
i = 0;
i <
fSize; ++
i)
487 fMaskAvail = std::make_unique<bool[]>(capacity);
502std::unique_ptr<void, typename ROOT::Experimental::RFieldBase::RCreateObjectDeleter<void>::deleter>
505 static RCreateObjectDeleter<void>::deleter gDeleter;
506 return std::unique_ptr<void, RCreateObjectDeleter<void>::deleter>(
CreateObjectRawPtr(), gDeleter);
512 bool isSimple, std::size_t nRepetitions)
528 while (parent && !parent->GetFieldName().empty()) {
530 parent = parent->GetParent();
538 auto typeAlias = GetNormalizedTypeName(typeName);
539 auto canonicalType = GetNormalizedTypeName(GetCanonicalTypeName(typeAlias));
543std::vector<ROOT::Experimental::RFieldBase::RCheckResult>
546 auto typeAlias = GetNormalizedTypeName(typeName);
547 auto canonicalType = GetNormalizedTypeName(GetCanonicalTypeName(typeAlias));
552 std::vector<RCheckResult>
result;
553 for (
const auto &
f : fieldZero) {
559 RCheckResult{invalidField->GetQualifiedFieldName(), invalidField->GetTypeName(), invalidField->GetError()});
566 const std::string &typeAlias,
bool continueOnError)
568 thread_local CreateContext createContext;
569 CreateContextGuard createContextGuard(createContext);
571 createContextGuard.SetContinueOnError(
true);
573 auto fnFail = [&fieldName, &canonicalType](
const std::string &errMsg) ->
RResult<std::unique_ptr<RFieldBase>> {
574 if (createContext.GetContinueOnError()) {
575 return std::unique_ptr<RFieldBase>(std::make_unique<RInvalidField>(fieldName, canonicalType, errMsg));
581 if (canonicalType.empty())
582 return R__FORWARD_RESULT(fnFail(
"no type name specified for field '" + fieldName +
"'"));
584 if (
auto [arrayBaseType, arraySizes] = ParseArrayType(canonicalType); !arraySizes.empty()) {
585 std::unique_ptr<RFieldBase> arrayField =
Create(
"_0", arrayBaseType).Unwrap();
586 for (
int i = arraySizes.size() - 1;
i >= 0; --
i) {
587 arrayField = std::make_unique<RArrayField>((
i == 0) ? fieldName :
"_0", std::move(arrayField), arraySizes[
i]);
592 std::unique_ptr<ROOT::Experimental::RFieldBase>
result;
594 if (canonicalType ==
"ROOT::Experimental::ClusterSize_t") {
595 result = std::make_unique<RField<ClusterSize_t>>(fieldName);
596 }
else if (canonicalType ==
"bool") {
597 result = std::make_unique<RField<bool>>(fieldName);
598 }
else if (canonicalType ==
"char") {
599 result = std::make_unique<RField<char>>(fieldName);
600 }
else if (canonicalType ==
"std::byte") {
601 result = std::make_unique<RField<std::byte>>(fieldName);
602 }
else if (canonicalType ==
"std::int8_t") {
603 result = std::make_unique<RField<std::int8_t>>(fieldName);
604 }
else if (canonicalType ==
"std::uint8_t") {
605 result = std::make_unique<RField<std::uint8_t>>(fieldName);
606 }
else if (canonicalType ==
"std::int16_t") {
607 result = std::make_unique<RField<std::int16_t>>(fieldName);
608 }
else if (canonicalType ==
"std::uint16_t") {
609 result = std::make_unique<RField<std::uint16_t>>(fieldName);
610 }
else if (canonicalType ==
"std::int32_t") {
611 result = std::make_unique<RField<std::int32_t>>(fieldName);
612 }
else if (canonicalType ==
"std::uint32_t") {
613 result = std::make_unique<RField<std::uint32_t>>(fieldName);
614 }
else if (canonicalType ==
"std::int64_t") {
615 result = std::make_unique<RField<std::int64_t>>(fieldName);
616 }
else if (canonicalType ==
"std::uint64_t") {
617 result = std::make_unique<RField<std::uint64_t>>(fieldName);
618 }
else if (canonicalType ==
"float") {
619 result = std::make_unique<RField<float>>(fieldName);
620 }
else if (canonicalType ==
"double") {
621 result = std::make_unique<RField<double>>(fieldName);
622 }
else if (canonicalType ==
"Double32_t") {
623 result = std::make_unique<RField<double>>(fieldName);
627 }
else if (canonicalType ==
"std::string") {
628 result = std::make_unique<RField<std::string>>(fieldName);
629 }
else if (canonicalType ==
"std::vector<bool>") {
630 result = std::make_unique<RField<std::vector<bool>>>(fieldName);
631 }
else if (canonicalType.substr(0, 12) ==
"std::vector<") {
632 std::string itemTypeName = canonicalType.substr(12, canonicalType.length() - 13);
633 auto itemField =
Create(
"_0", itemTypeName);
634 result = std::make_unique<RVectorField>(fieldName, itemField.Unwrap());
635 }
else if (canonicalType.substr(0, 19) ==
"ROOT::VecOps::RVec<") {
636 std::string itemTypeName = canonicalType.substr(19, canonicalType.length() - 20);
637 auto itemField =
Create(
"_0", itemTypeName);
638 result = std::make_unique<RRVecField>(fieldName, itemField.Unwrap());
639 }
else if (canonicalType.substr(0, 11) ==
"std::array<") {
640 auto arrayDef = TokenizeTypeList(canonicalType.substr(11, canonicalType.length() - 12));
641 if (arrayDef.size() != 2) {
642 return R__FORWARD_RESULT(fnFail(
"the template list for std::array must have exactly two elements"));
644 auto arrayLength = std::stoi(arrayDef[1]);
645 auto itemField =
Create(
"_0", arrayDef[0]);
646 result = std::make_unique<RArrayField>(fieldName, itemField.Unwrap(), arrayLength);
647 }
else if (canonicalType.substr(0, 13) ==
"std::variant<") {
648 auto innerTypes = TokenizeTypeList(canonicalType.substr(13, canonicalType.length() - 14));
649 std::vector<RFieldBase *> items;
650 for (
unsigned int i = 0;
i < innerTypes.size(); ++
i) {
651 items.emplace_back(
Create(
"_" + std::to_string(
i), innerTypes[
i]).Unwrap().release());
653 result = std::make_unique<RVariantField>(fieldName, items);
654 }
else if (canonicalType.substr(0, 10) ==
"std::pair<") {
655 auto innerTypes = TokenizeTypeList(canonicalType.substr(10, canonicalType.length() - 11));
656 if (innerTypes.size() != 2) {
657 return R__FORWARD_RESULT(fnFail(
"the type list for std::pair must have exactly two elements"));
659 std::array<std::unique_ptr<RFieldBase>, 2> items{
Create(
"_0", innerTypes[0]).Unwrap(),
660 Create(
"_1", innerTypes[1]).Unwrap()};
661 result = std::make_unique<RPairField>(fieldName, items);
662 }
else if (canonicalType.substr(0, 11) ==
"std::tuple<") {
663 auto innerTypes = TokenizeTypeList(canonicalType.substr(11, canonicalType.length() - 12));
664 std::vector<std::unique_ptr<RFieldBase>> items;
665 for (
unsigned int i = 0;
i < innerTypes.size(); ++
i) {
666 items.emplace_back(
Create(
"_" + std::to_string(
i), innerTypes[
i]).Unwrap());
668 result = std::make_unique<RTupleField>(fieldName, items);
669 }
else if (canonicalType.substr(0, 12) ==
"std::bitset<") {
670 auto size = std::stoull(canonicalType.substr(12, canonicalType.length() - 13));
671 result = std::make_unique<RBitsetField>(fieldName,
size);
672 }
else if (canonicalType.substr(0, 16) ==
"std::unique_ptr<") {
673 std::string itemTypeName = canonicalType.substr(16, canonicalType.length() - 17);
674 auto itemField =
Create(
"_0", itemTypeName).Unwrap();
675 auto normalizedInnerTypeName = itemField->GetTypeName();
676 result = std::make_unique<RUniquePtrField>(fieldName,
"std::unique_ptr<" + normalizedInnerTypeName +
">",
677 std::move(itemField));
678 }
else if (canonicalType.substr(0, 9) ==
"std::set<") {
679 std::string itemTypeName = canonicalType.substr(9, canonicalType.length() - 10);
680 auto itemField =
Create(
"_0", itemTypeName).Unwrap();
681 auto normalizedInnerTypeName = itemField->GetTypeName();
683 std::make_unique<RSetField>(fieldName,
"std::set<" + normalizedInnerTypeName +
">", std::move(itemField));
684 }
else if (canonicalType.substr(0, 19) ==
"std::unordered_set<") {
685 std::string itemTypeName = canonicalType.substr(19, canonicalType.length() - 20);
686 auto itemField =
Create(
"_0", itemTypeName).Unwrap();
687 auto normalizedInnerTypeName = itemField->GetTypeName();
688 result = std::make_unique<RSetField>(fieldName,
"std::unordered_set<" + normalizedInnerTypeName +
">",
689 std::move(itemField));
690 }
else if (canonicalType.substr(0, 9) ==
"std::map<") {
691 auto innerTypes = TokenizeTypeList(canonicalType.substr(9, canonicalType.length() - 10));
692 if (innerTypes.size() != 2) {
693 return R__FORWARD_RESULT(fnFail(
"the type list for std::map must have exactly two elements"));
696 auto normalizedKeyTypeName = GetNormalizedTypeName(innerTypes[0]);
697 auto normalizedValueTypeName = GetNormalizedTypeName(innerTypes[1]);
700 Create(
"_0",
"std::pair<" + normalizedKeyTypeName +
"," + normalizedValueTypeName +
">").Unwrap();
701 result = std::make_unique<RMapField>(
702 fieldName,
"std::map<" + normalizedKeyTypeName +
"," + normalizedValueTypeName +
">", std::move(itemField));
703 }
else if (canonicalType.substr(0, 19) ==
"std::unordered_map<") {
704 auto innerTypes = TokenizeTypeList(canonicalType.substr(19, canonicalType.length() - 20));
705 if (innerTypes.size() != 2)
706 return R__FORWARD_RESULT(fnFail(
"the type list for std::unordered_map must have exactly two elements"));
708 auto normalizedKeyTypeName = GetNormalizedTypeName(innerTypes[0]);
709 auto normalizedValueTypeName = GetNormalizedTypeName(innerTypes[1]);
712 Create(
"_0",
"std::pair<" + normalizedKeyTypeName +
"," + normalizedValueTypeName +
">").Unwrap();
713 result = std::make_unique<RMapField>(
714 fieldName,
"std::unordered_map<" + normalizedKeyTypeName +
"," + normalizedValueTypeName +
">",
715 std::move(itemField));
716 }
else if (canonicalType.substr(0, 12) ==
"std::atomic<") {
717 std::string itemTypeName = canonicalType.substr(12, canonicalType.length() - 13);
718 auto itemField =
Create(
"_0", itemTypeName).Unwrap();
719 auto normalizedInnerTypeName = itemField->GetTypeName();
720 result = std::make_unique<RAtomicField>(fieldName,
"std::atomic<" + normalizedInnerTypeName +
">",
721 std::move(itemField));
722 }
else if (canonicalType.substr(0, 39) ==
"ROOT::Experimental::RNTupleCardinality<") {
723 auto innerTypes = TokenizeTypeList(canonicalType.substr(39, canonicalType.length() - 40));
724 if (innerTypes.size() != 1)
725 return R__FORWARD_RESULT(fnFail(
"invalid cardinality template: " + canonicalType));
726 if (innerTypes[0] ==
"std::uint32_t") {
727 result = std::make_unique<RField<RNTupleCardinality<std::uint32_t>>>(fieldName);
728 }
else if (innerTypes[0] ==
"std::uint64_t") {
729 result = std::make_unique<RField<RNTupleCardinality<std::uint64_t>>>(fieldName);
731 return R__FORWARD_RESULT(fnFail(
"invalid cardinality template: " + canonicalType));
739 result = std::make_unique<REnumField>(fieldName, canonicalType);
746 createContextGuard.AddClassToStack(canonicalType);
747 if (cl->GetCollectionProxy()) {
748 result = std::make_unique<RProxiedCollectionField>(fieldName, canonicalType);
750 result = std::make_unique<RClassField>(fieldName, canonicalType);
755 auto error =
e.GetError();
756 if (createContext.GetContinueOnError()) {
757 std::unique_ptr<RFieldBase>(std::make_unique<RInvalidField>(fieldName, canonicalType, error.GetReport()));
764 if (typeAlias != canonicalType)
765 result->fTypeAlias = typeAlias;
773 if (fieldName.empty()) {
774 return R__FAIL(
"name cannot be empty string \"\"");
775 }
else if (fieldName.find(
'.') != std::string::npos) {
776 return R__FAIL(
"name '" + std::string(fieldName) +
"' cannot contain dot characters '.'");
785 return representations;
801 R__ASSERT(
false &&
"A non-simple RField must implement its own AppendImpl");
813 std::size_t nRead = 0;
814 for (std::size_t
i = 0;
i < bulkSpec.
fCount; ++
i) {
844std::vector<ROOT::Experimental::RFieldBase::RValue>
847 return std::vector<RValue>();
855 throw RException(
R__FAIL(
"invalid attempt to attach subfield to already connected field"));
856 child->fParent =
this;
863 std::size_t
result = globalIndex;
864 for (
auto f =
this;
f !=
nullptr;
f =
f->GetParent()) {
865 auto parent =
f->GetParent();
866 if (parent && (parent->GetStructure() ==
kCollection || parent->GetStructure() ==
kVariant))
868 result *= std::max(
f->GetNRepetitions(), std::size_t{1U});
875 std::vector<RFieldBase *>
result;
885 std::vector<const RFieldBase *>
result;
904 throw RException(
R__FAIL(
"cannot set field description once field is connected"));
926 throw RException(
R__FAIL(
"cannot set column representative once field is connected"));
928 auto itRepresentative = std::find(validTypes.begin(), validTypes.end(), representative);
929 if (itRepresentative == std::end(validTypes))
942 onDiskTypes.emplace_back(
c.GetModel().GetType());
945 if (t == onDiskTypes)
949 std::string columnTypeNames;
950 for (
const auto &t : onDiskTypes) {
951 if (!columnTypeNames.empty())
952 columnTypeNames +=
", ";
956 "` cannot be matched."));
976 for (
auto &colType : rep) {
993 for (
auto &colType : rep) {
1010 throw RException(
R__FAIL(
"invalid attempt to connect zero field to page sink"));
1012 throw RException(
R__FAIL(
"invalid attempt to connect an already connected field to a page sink"));
1021 column->ConnectPageSink(
fOnDiskId, pageSink, firstElementIndex);
1030 throw RException(
R__FAIL(
"invalid attempt to connect zero field to page source"));
1032 throw RException(
R__FAIL(
"invalid attempt to connect an already connected field to a page source"));
1035 throw RException(
R__FAIL(
"fixed column representative only valid when connecting to a page sink"));
1037 throw RException(
R__FAIL(
"setting description only valid when connecting to a page sink"));
1043 f->ConnectPageSource(pageSource);
1052 onDiskColumnTypes.emplace_back(
c->GetModel().GetType());
1055 if (t == onDiskColumnTypes)
1065 column->ConnectPageSource(
fOnDiskId, pageSource);
1078std::unique_ptr<ROOT::Experimental::RFieldBase>
1081 auto result = std::make_unique<RFieldZero>();
1083 result->Attach(
f->Clone(
f->GetFieldName()));
1099 static RColumnRepresentations representations(
1102 return representations;
1112 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1118 visitor.VisitClusterSizeField(*
this);
1123const ROOT::Experimental::RFieldBase::RColumnRepresentations &
1129 return representations;
1161 return representations;
1186 return representations;
1196 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1202 visitor.VisitByteField(*
this);
1207const ROOT::Experimental::RFieldBase::RColumnRepresentations &
1211 return representations;
1221 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1227 visitor.VisitInt8Field(*
this);
1232const ROOT::Experimental::RFieldBase::RColumnRepresentations &
1236 return representations;
1246 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1252 visitor.VisitUInt8Field(*
this);
1257const ROOT::Experimental::RFieldBase::RColumnRepresentations &
1261 return representations;
1287 return representations;
1318 return representations;
1349 return representations;
1359 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1365 visitor.VisitInt16Field(*
this);
1370const ROOT::Experimental::RFieldBase::RColumnRepresentations &
1375 return representations;
1385 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1391 visitor.VisitUInt16Field(*
this);
1396const ROOT::Experimental::RFieldBase::RColumnRepresentations &
1401 return representations;
1411 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1417 visitor.VisitIntField(*
this);
1422const ROOT::Experimental::RFieldBase::RColumnRepresentations &
1427 return representations;
1437 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1443 visitor.VisitUInt32Field(*
this);
1448const ROOT::Experimental::RFieldBase::RColumnRepresentations &
1453 return representations;
1463 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1469 visitor.VisitUInt64Field(*
this);
1474const ROOT::Experimental::RFieldBase::RColumnRepresentations &
1484 return representations;
1494 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1500 visitor.VisitInt64Field(*
this);
1505const ROOT::Experimental::RFieldBase::RColumnRepresentations &
1513 return representations;
1524 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1531 auto typedValue =
static_cast<const std::string *
>(from);
1532 auto length = typedValue->length();
1533 fColumns[1]->AppendV(typedValue->data(),
length);
1535 fColumns[0]->Append(&fIndex);
1536 return length + fColumns[0]->GetElement()->GetPackedSize();
1541 auto typedValue =
static_cast<std::string *
>(to);
1544 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nChars);
1546 typedValue->clear();
1548 typedValue->resize(nChars);
1549 fColumns[1]->ReadV(collectionStart, nChars,
const_cast<char *
>(typedValue->data()));
1555 visitor.VisitStringField(*
this);
1570 throw RException(
R__FAIL(
"RField: no I/O support for type " + std::string(className)));
1574 throw RException(R__FAIL(std::string(className) +
" is not supported"));
1576 if (
fClass->GetCollectionProxy()) {
1578 R__FAIL(std::string(className) +
" has an associated collection proxy; use RProxiedCollectionField instead"));
1582 throw RException(R__FAIL(std::string(className) +
" cannot be split"));
1592 if (baseClass->GetDelta() < 0) {
1593 throw RException(R__FAIL(std::string(
"virtual inheritance is not supported: ") + std::string(className) +
1594 " virtually inherits from " + baseClass->GetName()));
1596 TClass *
c = baseClass->GetClassPointer();
1599 fTraits &= subField->GetTraits();
1600 Attach(std::move(subField),
1606 if (dataMember->Property() & kIsStatic)
1609 if (!dataMember->IsPersistent()) {
1611 fTraits &= ~(kTraitTriviallyConstructible | kTraitTriviallyDestructible);
1615 std::string typeName{GetNormalizedTypeName(dataMember->GetTrueTypeName())};
1616 std::string typeAlias{GetNormalizedTypeName(dataMember->GetFullTypeName())};
1619 for (int dim = 0, n = dataMember->GetArrayDim(); dim < n; ++dim)
1620 typeName +=
"[" + std::to_string(dataMember->GetMaxIndex(dim)) +
"]";
1622 auto subField =
RFieldBase::Create(dataMember->GetName(), typeName, typeAlias).Unwrap();
1623 fTraits &= subField->GetTraits();
1624 Attach(std::move(subField),
1625 RSubFieldInfo{kDataMember,
static_cast<std::size_t
>(dataMember->GetOffset())});
1639 for (
const auto rule : rules) {
1644 auto func = rule->GetReadFunctionPointer();
1650 func(
static_cast<char *
>(
target), &oldObj);
1651 oldObj.fClass =
nullptr;
1656std::unique_ptr<ROOT::Experimental::RFieldBase>
1660 SyncFieldIDs(*
this, *
result);
1666 std::size_t nbytes = 0;
1691 const auto ruleset =
fClass->GetSchemaRules();
1695 if (rule->GetTarget() ==
nullptr)
1698 const auto dataMember = klass->GetDataMember(
target->GetString());
1699 if (!dataMember || dataMember->IsPersistent()) {
1701 << dataMember->GetName();
1709 rules.erase(std::remove_if(rules.begin(), rules.end(), referencesNonTransientMembers), rules.end());
1720 fClass->Destructor(objPtr,
true );
1721 RDeleter::operator()(objPtr, dtorOnly);
1724std::vector<ROOT::Experimental::RFieldBase::RValue>
1727 std::vector<RValue>
result;
1728 auto basePtr =
value.GetPtr<
unsigned char>().get();
1739 return fClass->GetClassSize();
1744 return fClass->GetClassVersion();
1762 if (enump ==
nullptr) {
1763 throw RException(
R__FAIL(
"RField: no I/O support for enum type " + std::string(enumName)));
1767 throw RException(R__FAIL(std::string(enumName) +
" is not supported"));
1771 case kChar_t: Attach(std::make_unique<RField<int8_t>>(
"_0")); break;
1772 case kUChar_t: Attach(std::make_unique<RField<uint8_t>>(
"_0")); break;
1773 case kShort_t: Attach(std::make_unique<RField<int16_t>>(
"_0")); break;
1774 case kUShort_t: Attach(std::make_unique<RField<uint16_t>>(
"_0")); break;
1775 case kInt_t: Attach(std::make_unique<RField<int32_t>>(
"_0")); break;
1776 case kUInt_t: Attach(std::make_unique<RField<uint32_t>>(
"_0")); break;
1778 case kLong64_t: Attach(std::make_unique<RField<int64_t>>(
"_0")); break;
1780 case kULong64_t: Attach(std::make_unique<RField<uint64_t>>(
"_0")); break;
1781 default: throw RException(R__FAIL(
"Unsupported underlying integral type for enum type " + std::string(enumName)));
1788 std::unique_ptr<RFieldBase> intField)
1791 Attach(std::move(intField));
1795std::unique_ptr<ROOT::Experimental::RFieldBase>
1802std::vector<ROOT::Experimental::RFieldBase::RValue>
1805 std::vector<RValue>
result;
1826 (ifuncs.
fNext !=
nullptr));
1831 std::string_view typeName,
TClass *classp)
1834 if (classp ==
nullptr)
1835 throw RException(
R__FAIL(
"RField: no I/O support for collection proxy type " + std::string(typeName)));
1837 throw RException(
R__FAIL(std::string(typeName) +
" has no associated collection proxy"));
1843 throw RException(
R__FAIL(
"collection proxies whose value type is a pointer are not supported"));
1844 if (!
fProxy->GetCollectionClass()->HasDictionary()) {
1845 throw RException(R__FAIL(
"dictionary not available for type " +
1846 GetNormalizedTypeName(fProxy->GetCollectionClass()->GetName())));
1854 std::string_view typeName,
1855 std::unique_ptr<RFieldBase> itemField)
1859 Attach(std::move(itemField));
1863 std::string_view typeName)
1868 throw RException(
R__FAIL(
"custom associative collection proxies not supported"));
1870 std::unique_ptr<ROOT::Experimental::RFieldBase> itemField;
1872 if (
auto valueClass =
fProxy->GetValueClass()) {
1874 itemField = RFieldBase::Create(
"_0", valueClass->GetName()).Unwrap();
1876 switch (fProxy->GetType()) {
1877 case EDataType::kChar_t: itemField = std::make_unique<RField<char>>(
"_0"); break;
1878 case EDataType::kUChar_t: itemField = std::make_unique<RField<std::uint8_t>>(
"_0"); break;
1879 case EDataType::kShort_t: itemField = std::make_unique<RField<std::int16_t>>(
"_0"); break;
1880 case EDataType::kUShort_t: itemField = std::make_unique<RField<std::uint16_t>>(
"_0"); break;
1881 case EDataType::kInt_t: itemField = std::make_unique<RField<std::int32_t>>(
"_0"); break;
1882 case EDataType::kUInt_t: itemField = std::make_unique<RField<std::uint32_t>>(
"_0"); break;
1883 case EDataType::kLong_t:
1884 case EDataType::kLong64_t:
1885 itemField = std::make_unique<RField<std::int64_t>>(
"_0");
1887 case EDataType::kULong_t:
1888 case EDataType::kULong64_t:
1889 itemField = std::make_unique<RField<std::uint64_t>>(
"_0");
1891 case EDataType::kFloat_t: itemField = std::make_unique<RField<float>>(
"_0"); break;
1892 case EDataType::kDouble_t: itemField = std::make_unique<RField<double>>(
"_0"); break;
1893 case EDataType::kBool_t: itemField = std::make_unique<RField<bool>>(
"_0"); break;
1895 throw RException(R__FAIL(
"unsupported value type"));
1899 fItemSize = itemField->GetValueSize();
1900 Attach(std::move(itemField));
1903std::unique_ptr<ROOT::Experimental::RFieldBase>
1907 return std::unique_ptr<RProxiedCollectionField>(
1913 std::size_t nbytes = 0;
1924 return nbytes +
fColumns[0]->GetElement()->GetPackedSize();
1931 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
1952 return representations;
1971std::unique_ptr<ROOT::Experimental::RFieldBase::RDeleter>
1978 return std::make_unique<RProxiedCollectionDeleter>(
fProxy);
1989 fProxy->Destructor(objPtr,
true );
1990 RDeleter::operator()(objPtr, dtorOnly);
1993std::vector<ROOT::Experimental::RFieldBase::RValue>
1996 std::vector<RValue>
result;
1997 auto valueRawPtr =
value.GetPtr<
void>().get();
2014 std::vector<std::unique_ptr<RFieldBase>> &&itemFields,
2015 const std::vector<std::size_t> &offsets, std::string_view typeName)
2020 for (
auto &item : itemFields) {
2029 std::vector<std::unique_ptr<RFieldBase>> &&itemFields)
2033 for (
auto &item : itemFields) {
2037 fSize += item->GetValueSize();
2047 std::vector<std::unique_ptr<RFieldBase>> &itemFields)
2054 if (itemAlignment > 1) {
2055 auto remainder = baseOffset % itemAlignment;
2057 return itemAlignment - remainder;
2062std::unique_ptr<ROOT::Experimental::RFieldBase>
2065 std::vector<std::unique_ptr<RFieldBase>> cloneItems;
2068 cloneItems.emplace_back(item->Clone(item->GetFieldName()));
2074 std::size_t nbytes = 0;
2107 RDeleter::operator()(objPtr, dtorOnly);
2112 std::vector<std::unique_ptr<RDeleter>> itemDeleters;
2113 itemDeleters.reserve(
fOffsets.size());
2117 return std::make_unique<RRecordDeleter>(itemDeleters,
fOffsets);
2120std::vector<ROOT::Experimental::RFieldBase::RValue>
2123 auto basePtr =
value.GetPtr<
unsigned char>().get();
2124 std::vector<RValue>
result;
2147 Attach(std::move(itemField));
2150std::unique_ptr<ROOT::Experimental::RFieldBase>
2154 return std::make_unique<RVectorField>(newName, std::move(newItemField));
2159 auto typedValue =
static_cast<const std::vector<char> *
>(from);
2161 std::size_t nbytes = 0;
2162 auto count = typedValue->size() /
fItemSize;
2168 for (
unsigned i = 0;
i < count; ++
i) {
2175 return nbytes +
fColumns[0]->GetElement()->GetPackedSize();
2180 auto typedValue =
static_cast<std::vector<char> *
>(to);
2184 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
2194 const auto oldNItems = typedValue->size() /
fItemSize;
2195 const bool canRealloc = oldNItems < nItems;
2196 bool allDeallocated =
false;
2198 allDeallocated = canRealloc;
2199 for (std::size_t
i = allDeallocated ? 0 : nItems;
i < oldNItems; ++
i) {
2205 for (std::size_t
i = allDeallocated ? 0 : oldNItems;
i < nItems; ++
i) {
2210 for (std::size_t
i = 0;
i < nItems; ++
i) {
2221 return representations;
2237 auto vecPtr =
static_cast<std::vector<char> *
>(objPtr);
2240 auto nItems = vecPtr->size() /
fItemSize;
2241 for (std::size_t
i = 0;
i < nItems; ++
i) {
2245 std::destroy_at(vecPtr);
2246 RDeleter::operator()(objPtr, dtorOnly);
2253 return std::make_unique<RVectorDeleter>();
2256std::vector<ROOT::Experimental::RFieldBase::RValue>
2259 auto vec =
value.GetPtr<std::vector<char>>();
2262 std::vector<RValue>
result;
2263 for (
unsigned i = 0;
i < nItems; ++
i) {
2286 Attach(std::move(itemField));
2290std::unique_ptr<ROOT::Experimental::RFieldBase>
2294 return std::make_unique<RRVecField>(newName, std::move(newItemField));
2299 auto [beginPtr, sizePtr,
_] = GetRVecDataMembers(from);
2301 std::size_t nbytes = 0;
2306 auto begin =
reinterpret_cast<const char *
>(*beginPtr);
2307 for (std::int32_t
i = 0;
i < *sizePtr; ++
i) {
2314 return nbytes +
fColumns[0]->GetElement()->GetPackedSize();
2322 auto [beginPtr, sizePtr, capacityPtr] = GetRVecDataMembers(to);
2327 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
2328 char *
begin =
reinterpret_cast<char *
>(*beginPtr);
2329 const std::size_t oldSize = *sizePtr;
2333 const bool owns = (*capacityPtr != -1);
2338 if (needsDestruct) {
2339 for (std::size_t
i = nItems;
i < oldSize; ++
i) {
2345 if (std::int32_t(nItems) > *capacityPtr) {
2348 if (needsDestruct) {
2349 for (std::size_t
i = 0u;
i < oldSize; ++
i) {
2363 begin =
reinterpret_cast<char *
>(*beginPtr);
2364 *capacityPtr = nItems;
2367 if (needsConstruct) {
2368 for (std::size_t
i = 0u;
i < oldSize; ++
i)
2375 if (needsConstruct) {
2376 for (std::size_t
i = oldSize;
i < nItems; ++
i)
2386 for (std::size_t
i = 0;
i < nItems; ++
i) {
2399 bulkSpec.
fAuxData->resize(
sizeof(std::size_t));
2400 *
reinterpret_cast<std::size_t *
>(bulkSpec.
fAuxData->data()) =
fSubFields[0]->GetValueSize();
2402 const auto itemValueSize = *
reinterpret_cast<std::size_t *
>(bulkSpec.
fAuxData->data());
2403 unsigned char *itemValueArray = bulkSpec.
fAuxData->data() +
sizeof(std::size_t);
2404 auto [beginPtr, sizePtr, capacityPtr] = GetRVecDataMembers(bulkSpec.
fValues);
2411 *beginPtr = itemValueArray;
2412 *sizePtr = collectionSize;
2418 auto lastOffset = firstItemIndex.
GetIndex() + collectionSize;
2420 std::size_t nValues = 1;
2421 std::size_t nItems = collectionSize;
2422 while (nRemainingValues > 0) {
2425 const std::size_t nBatch = std::min(nRemainingValues, nElementsUntilPageEnd);
2426 for (std::size_t
i = 0;
i < nBatch; ++
i) {
2427 const auto size = offsets[
i] - lastOffset;
2428 std::tie(beginPtr, sizePtr, capacityPtr) =
2429 GetRVecDataMembers(
reinterpret_cast<unsigned char *
>(bulkSpec.
fValues) + (nValues +
i) *
fValueSize);
2430 *beginPtr = itemValueArray + nItems * itemValueSize;
2435 lastOffset = offsets[
i];
2437 nRemainingValues -= nBatch;
2441 bulkSpec.
fAuxData->resize(
sizeof(std::size_t) + nItems * itemValueSize);
2443 const auto delta = itemValueArray - (bulkSpec.
fAuxData->data() +
sizeof(std::size_t));
2445 auto beginPtrAsUChar =
reinterpret_cast<unsigned char *
>(bulkSpec.
fValues);
2446 for (std::size_t
i = 0;
i < bulkSpec.
fCount; ++
i) {
2447 *
reinterpret_cast<unsigned char **
>(beginPtrAsUChar) -= delta;
2453 return RBulkSpec::kAllSet;
2462 return representations;
2480 void **beginPtr =
new (where)(
void *)(
nullptr);
2481 std::int32_t *sizePtr =
new (
reinterpret_cast<void *
>(beginPtr + 1)) std::int32_t(0);
2482 new (sizePtr + 1) std::int32_t(-1);
2487 auto [beginPtr, sizePtr, capacityPtr] = GetRVecDataMembers(objPtr);
2489 char *
begin =
reinterpret_cast<char *
>(*beginPtr);
2491 for (std::int32_t
i = 0;
i < *sizePtr; ++
i) {
2497 RDeleter::operator()(objPtr, dtorOnly);
2507std::vector<ROOT::Experimental::RFieldBase::RValue>
2510 auto [beginPtr, sizePtr,
_] = GetRVecDataMembers(
value.GetPtr<
void>().get());
2512 std::vector<RValue>
result;
2513 char *
begin =
reinterpret_cast<char *
>(*beginPtr);
2514 result.reserve(*sizePtr);
2515 for (std::int32_t
i = 0;
i < *sizePtr; ++
i) {
2546 auto typedValue =
static_cast<const std::vector<bool> *
>(from);
2547 auto count = typedValue->size();
2548 for (
unsigned i = 0;
i < count; ++
i) {
2549 bool bval = (*typedValue)[
i];
2550 CallAppendOn(*fSubFields[0], &bval);
2553 fColumns[0]->
Append(&fNWritten);
2554 return count + fColumns[0]->GetElement()->GetPackedSize();
2557void ROOT::Experimental::RField<std::vector<bool>>::ReadGlobalImpl(
NTupleSize_t globalIndex,
void *to)
2559 auto typedValue =
static_cast<std::vector<bool> *
>(to);
2563 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
2565 typedValue->resize(nItems);
2566 for (
unsigned i = 0;
i < nItems; ++
i) {
2568 CallReadOn(*fSubFields[0], collectionStart +
i, &bval);
2569 (*typedValue)[
i] = bval;
2573const ROOT::Experimental::RFieldBase::RColumnRepresentations &
2574ROOT::Experimental::RField<std::vector<bool>>::GetColumnRepresentations()
const
2576 static RColumnRepresentations representations(
2579 return representations;
2582void ROOT::Experimental::RField<std::vector<bool>>::GenerateColumnsImpl()
2587void ROOT::Experimental::RField<std::vector<bool>>::GenerateColumnsImpl(
const RNTupleDescriptor &desc)
2589 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
2593std::vector<ROOT::Experimental::RFieldBase::RValue>
2594ROOT::Experimental::RField<std::vector<bool>>::SplitValue(
const RValue &
value)
const
2596 const auto &typedValue =
value.GetRef<std::vector<bool>>();
2597 auto count = typedValue.size();
2598 std::vector<RValue>
result;
2599 for (
unsigned i = 0;
i < count; ++
i) {
2601 result.emplace_back(fSubFields[0]->BindValue(std::shared_ptr<bool>(
new bool(
true))));
2603 result.emplace_back(fSubFields[0]->BindValue(std::shared_ptr<bool>(
new bool(
false))));
2608void ROOT::Experimental::RField<std::vector<bool>>::AcceptVisitor(
Detail::RFieldVisitor &visitor)
const
2610 visitor.VisitVectorBoolField(*
this);
2617 std::size_t arrayLength)
2619 "std::array<" + itemField->
GetTypeName() +
"," + std::to_string(arrayLength) +
">",
2625 Attach(std::move(itemField));
2628std::unique_ptr<ROOT::Experimental::RFieldBase>
2632 return std::make_unique<RArrayField>(newName, std::move(newItemField),
fArrayLength);
2637 std::size_t nbytes = 0;
2638 auto arrayPtr =
static_cast<const unsigned char *
>(from);
2647 auto arrayPtr =
static_cast<unsigned char *
>(to);
2655 auto arrayPtr =
static_cast<unsigned char *
>(to);
2667 auto arrayPtr =
reinterpret_cast<unsigned char *
>(where);
2680 RDeleter::operator()(objPtr, dtorOnly);
2687 return std::make_unique<RDeleter>();
2690std::vector<ROOT::Experimental::RFieldBase::RValue>
2693 auto arrayPtr =
value.GetPtr<
unsigned char>().get();
2694 std::vector<RValue>
result;
2711 std::unique_ptr<ROOT::Experimental::RFieldBase> itemField,
2712 std::size_t arrayLength)
2718 Attach(std::move(itemField));
2724std::unique_ptr<ROOT::Experimental::RFieldBase>
2728 return std::make_unique<RArrayAsRVecField>(newName, std::move(newItemField),
fArrayLength);
2734 void **beginPtr =
new (where)(
void *)(
nullptr);
2735 std::int32_t *sizePtr =
new (
reinterpret_cast<void *
>(beginPtr + 1)) std::int32_t(0);
2736 std::int32_t *capacityPtr =
new (sizePtr + 1) std::int32_t(0);
2740 char *
begin =
reinterpret_cast<char *
>(*beginPtr);
2749 const bool owns = (*capacityPtr != -1);
2755 if (needsDestruct) {
2756 for (std::int32_t
i = 0;
i < *sizePtr; ++
i) {
2770 begin =
reinterpret_cast<char *
>(*beginPtr);
2776 if (needsConstruct) {
2794 auto [beginPtr,
_, __] = GetRVecDataMembers(to);
2795 auto rvecBeginPtr =
reinterpret_cast<char *
>(*beginPtr);
2810 auto [beginPtr,
_, __] = GetRVecDataMembers(to);
2811 auto rvecBeginPtr =
reinterpret_cast<char *
>(*beginPtr);
2814 const auto &clusterIndexIndex = clusterIndex.
GetIndex();
2834std::vector<ROOT::Experimental::RFieldBase::RValue>
2837 auto arrayPtr =
value.GetPtr<
unsigned char>().get();
2838 std::vector<ROOT::Experimental::RFieldBase::RValue>
result;
2868 return representations;
2884 const auto *asULongArray =
static_cast<const Word_t *
>(from);
2889 elementValue = (asULongArray[word] & (
static_cast<Word_t>(1) <<
mask)) != 0;
2890 fColumns[0]->Append(&elementValue);
2898 auto *asULongArray =
static_cast<Word_t *
>(to);
2900 for (std::size_t
i = 0;
i <
fN; ++
i) {
2901 fColumns[0]->Read(globalIndex *
fN +
i, &elementValue);
2918 for (
size_t i = 0;
i < itemFields.size(); ++
i) {
2919 result += itemFields[
i]->GetTypeName() +
",";
2927 const std::vector<RFieldBase *> &itemFields)
2934 auto nFields = itemFields.size();
2937 for (
unsigned int i = 0;
i < nFields; ++
i) {
2940 fTraits &= itemFields[
i]->GetTraits();
2941 Attach(std::unique_ptr<RFieldBase>(itemFields[
i]));
2946std::unique_ptr<ROOT::Experimental::RFieldBase>
2950 std::vector<RFieldBase *> itemFields;
2951 for (
unsigned i = 0;
i < nFields; ++
i) {
2955 return std::make_unique<RVariantField>(newName, itemFields);
2960 auto index = *(
reinterpret_cast<const char *
>(variantPtr) + tagOffset);
2966 auto index =
reinterpret_cast<char *
>(variantPtr) + tagOffset;
2967 *
index =
static_cast<char>(tag - 1);
2973 std::size_t nbytes = 0;
3004 return representations;
3031 RDeleter::operator()(objPtr, dtorOnly);
3036 std::vector<std::unique_ptr<RDeleter>> itemDeleters;
3041 return std::make_unique<RVariantDeleter>(
fTagOffset, itemDeleters);
3057 std::unique_ptr<RFieldBase> itemField)
3065 return std::make_unique<RSetField>(newName,
GetTypeName(), std::move(newItemField));
3071 std::unique_ptr<RFieldBase> itemField)
3074 if (!
dynamic_cast<RPairField *
>(itemField.get()))
3080 Attach(std::move(itemField));
3085 std::size_t nbytes = 0;
3094 return nbytes +
fColumns[0]->GetElement()->GetPackedSize();
3101 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
3119 std::vector<RValue>
result;
3120 auto valueRawPtr =
value.GetPtr<
void>().get();
3131 return std::unique_ptr<RMapField>(
new RMapField(newName,
GetTypeName(), std::move(newItemField)));
3137 std::unique_ptr<RFieldBase> itemField)
3140 Attach(std::move(itemField));
3149 return representations;
3195 return 1 + nbytesItem;
3208 return isValidItem ?
fPrincipalColumn->GetClusterIndex(globalIndex) : nullIndex;
3212 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &collectionSize);
3213 return (collectionSize == 0) ? nullIndex : collectionStart;
3225 std::unique_ptr<RFieldBase> itemField)
3230std::unique_ptr<ROOT::Experimental::RFieldBase>
3234 return std::make_unique<RUniquePtrField>(newName,
GetTypeName(), std::move(newItemField));
3239 auto typedValue =
static_cast<const std::unique_ptr<char> *
>(from);
3249 auto ptr =
static_cast<std::unique_ptr<char> *
>(to);
3250 bool isValidValue =
static_cast<bool>(*ptr);
3255 void *valuePtr =
nullptr;
3257 valuePtr = ptr->get();
3259 if (isValidValue && !isValidItem) {
3268 if (!isValidValue) {
3271 ptr->reset(
reinterpret_cast<char *
>(valuePtr));
3279 auto typedPtr =
static_cast<std::unique_ptr<char> *
>(objPtr);
3282 typedPtr->release();
3284 RDeleter::operator()(objPtr, dtorOnly);
3292std::vector<ROOT::Experimental::RFieldBase::RValue>
3295 std::vector<RValue>
result;
3296 const auto &ptr =
value.GetRef<std::unique_ptr<char>>();
3306ROOT::Experimental::RPairField::RPairField::GetTypeList(
const std::array<std::unique_ptr<RFieldBase>, 2> &itemFields)
3308 return itemFields[0]->GetTypeName() +
"," + itemFields[1]->GetTypeName();
3312 std::array<std::unique_ptr<RFieldBase>, 2> &&itemFields,
3313 const std::array<std::size_t, 2> &offsets)
3320 std::array<std::unique_ptr<RFieldBase>, 2> &itemFields)
3322 "std::pair<" + GetTypeList(itemFields) +
">")
3328 fSize = fClass->Size();
3330 auto firstElem = fClass->GetRealData(
"first");
3333 fOffsets[0] = firstElem->GetThisOffset();
3335 auto secondElem = fClass->GetRealData(
"second");
3338 fOffsets[1] = secondElem->GetThisOffset();
3341std::unique_ptr<ROOT::Experimental::RFieldBase>
3359 fClass->Destructor(objPtr,
true );
3360 RDeleter::operator()(objPtr, dtorOnly);
3366ROOT::Experimental::RTupleField::RTupleField::GetTypeList(
const std::vector<std::unique_ptr<RFieldBase>> &itemFields)
3369 if (itemFields.empty())
3370 throw RException(
R__FAIL(
"the type list for std::tuple must have at least one element"));
3371 for (
size_t i = 0;
i < itemFields.size(); ++
i) {
3372 result += itemFields[
i]->GetTypeName() +
",";
3379 std::vector<std::unique_ptr<RFieldBase>> &&itemFields,
3380 const std::vector<std::size_t> &offsets)
3387 std::vector<std::unique_ptr<RFieldBase>> &itemFields)
3389 "std::tuple<" + GetTypeList(itemFields) +
">")
3394 fSize = fClass->Size();
3401 for (
unsigned i = 0;
i < fSubFields.size(); ++
i) {
3402 std::string memberName(
"_" + std::to_string(
i));
3403 auto member = fClass->GetRealData(memberName.c_str());
3406 fOffsets.push_back(member->GetThisOffset());
3410std::unique_ptr<ROOT::Experimental::RFieldBase>
3413 std::vector<std::unique_ptr<RFieldBase>> items;
3416 items.push_back(item->Clone(item->GetFieldName()));
3430 fClass->Destructor(objPtr,
true );
3431 RDeleter::operator()(objPtr, dtorOnly);
3437 std::shared_ptr<RNTupleCollectionWriter> collectionWriter,
3438 std::unique_ptr<RFieldZero> collectionParent)
3441 const std::size_t
N = collectionParent->fSubFields.size();
3442 for (std::size_t
i = 0;
i <
N; ++
i) {
3443 Attach(std::move(collectionParent->fSubFields[
i]));
3453 return representations;
3467std::unique_ptr<ROOT::Experimental::RFieldBase>
3470 auto parent = std::make_unique<RFieldZero>();
3472 parent->Attach(
f->Clone(
f->GetFieldName()));
3474 return std::make_unique<RCollectionField>(newName,
fCollectionWriter, std::move(parent));
3485 return bytesWritten +
fColumns[0]->GetElement()->GetPackedSize();
3490 R__ASSERT(
false &&
"should never read an RCollectionField");
3501 std::unique_ptr<RFieldBase> itemField)
3508 Attach(std::move(itemField));
3511std::unique_ptr<ROOT::Experimental::RFieldBase>
3515 return std::make_unique<RAtomicField>(newName,
GetTypeName(), std::move(newItemField));
3518std::vector<ROOT::Experimental::RFieldBase::RValue>
3521 std::vector<RValue>
result;
#define R__FORWARD_RESULT(res)
Short-hand to return an RResult<T> value from a subroutine to the calling stack frame.
#define R__FAIL(msg)
Short-hand to return an RResult<T> in an error state; the RError is implicitly converted into RResult...
ROOT::Experimental::RField< T > RField
#define R__LOG_WARNING(...)
TObject * clone(const char *newname) const override
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
if(isa< VarDecl >(D)||isa< FieldDecl >(D)||isa< EnumConstantDecl >(D))
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t mask
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t target
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h length
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t child
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
Abstract base class for classes implementing the visitor design pattern.
virtual void VisitProxiedCollectionField(const RProxiedCollectionField &field)
virtual void VisitBoolField(const RField< bool > &field)
virtual void VisitBitsetField(const RBitsetField &field)
virtual void VisitNullableField(const RNullableField &field)
virtual void VisitFieldZero(const RFieldZero &field)
virtual void VisitRVecField(const RRVecField &field)
virtual void VisitCardinalityField(const RCardinalityField &field)
virtual void VisitEnumField(const REnumField &field)
virtual void VisitArrayAsRVecField(const RArrayAsRVecField &field)
virtual void VisitDoubleField(const RField< double > &field)
virtual void VisitField(const RFieldBase &field)=0
virtual void VisitCharField(const RField< char > &field)
virtual void VisitArrayField(const RArrayField &field)
virtual void VisitClassField(const RClassField &field)
virtual void VisitRecordField(const RRecordField &field)
virtual void VisitVectorField(const RVectorField &field)
virtual void VisitFloatField(const RField< float > &field)
virtual void VisitAtomicField(const RAtomicField &field)
static std::string GetTypeName(EColumnType type)
static std::unique_ptr< RColumn > Create(const RColumnModel &model, std::uint32_t index)
Abstract interface to write data into an ntuple.
const RNTupleWriteOptions & GetWriteOptions() const
Returns the sink's write options.
Abstract interface to read data from an ntuple.
const RSharedDescriptorGuard GetSharedDescriptorGuard() const
Takes the read lock for the descriptor.
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
The size of a value of this field, i.e. an RVec.
std::size_t GetAlignment() const final
As a rule of thumb, the alignment is equal to the size of the type.
std::size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
std::size_t fArrayLength
The size of a child field's item.
std::size_t fValueSize
The length of the arrays in this field.
std::unique_ptr< RDeleter > GetDeleter() const final
Returns an RRVecField::RRVecDeleter.
RArrayAsRVecField(std::string_view fieldName, std::unique_ptr< RFieldBase > itemField, std::size_t arrayLength)
Constructor of the field.
void ConstructValue(void *where) const final
Constructs value in a given location of size at least GetValueSize(). Called by the base class' Creat...
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
std::size_t fItemSize
Sub field deleter or nullptr for simple fields.
void ReadInClusterImpl(RClusterIndex clusterIndex, void *to) final
std::vector< RFieldBase::RValue > SplitValue(const RFieldBase::RValue &value) const final
Creates the list of direct child values given a value for this field.
std::unique_ptr< RDeleter > fItemDeleter
void operator()(void *objPtr, bool dtorOnly) final
std::unique_ptr< RDeleter > fItemDeleter
std::vector< RValue > SplitValue(const RValue &value) const final
Creates the list of direct child values given a value for this field.
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
void ReadInClusterImpl(RClusterIndex clusterIndex, void *to) final
std::unique_ptr< RDeleter > GetDeleter() const final
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
void ConstructValue(void *where) const override
Constructs value in a given location of size at least GetValueSize(). Called by the base class' Creat...
RArrayField(std::string_view fieldName, std::unique_ptr< RFieldBase > itemField, std::size_t arrayLength)
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
RAtomicField(std::string_view fieldName, std::string_view typeName, std::unique_ptr< RFieldBase > itemField)
std::vector< RValue > SplitValue(const RValue &value) const final
Creates the list of direct child values given a value for this field.
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type for writing.
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
static constexpr std::size_t kBitsPerWord
RBitsetField(std::string_view fieldName, std::size_t N)
const RColumnRepresentations & GetColumnRepresentations() const final
Implementations in derived classes should return a static RColumnRepresentations object.
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
const RColumnRepresentations & GetColumnRepresentations() const final
Implementations in derived classes should return a static RColumnRepresentations object.
const RField< RNTupleCardinality< std::uint32_t > > * As32Bit() const
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type for writing.
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
const RField< RNTupleCardinality< std::uint64_t > > * As64Bit() const
void operator()(void *objPtr, bool dtorOnly) final
void ReadInClusterImpl(RClusterIndex clusterIndex, void *to) final
static constexpr const char * kPrefixInherited
Prefix used in the subfield names generated for base classes.
void Attach(std::unique_ptr< RFieldBase > child, RSubFieldInfo info)
void OnConnectPageSource() final
Called by ConnectPageSource() only once connected; derived classes may override this as appropriate.
size_t GetValueSize() const override
The number of bytes taken by a value of the appropriate type.
void ConstructValue(void *where) const override
Constructs value in a given location of size at least GetValueSize(). Called by the base class' Creat...
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
void AddReadCallbacksFromIORules(const std::span< const TSchemaRule * > rules, TClass *classp=nullptr)
Register post-read callbacks corresponding to a list of ROOT I/O customization rules.
void AcceptVisitor(Detail::RFieldVisitor &visitor) const override
std::uint32_t GetTypeVersion() const final
Indicates an evolution of the C++ type itself.
RClassField(std::string_view fieldName, std::string_view className, TClass *classp)
std::vector< RValue > SplitValue(const RValue &value) const final
Creates the list of direct child values given a value for this field.
std::vector< RSubFieldInfo > fSubFieldsInfo
Additional information kept for each entry in fSubFields
std::size_t fMaxAlignment
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
std::shared_ptr< RNTupleCollectionWriter > fCollectionWriter
Save the link to the collection ntuple in order to reset the offset counter when committing the clust...
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type for writing.
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
void CommitClusterImpl() final
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
const RColumnRepresentations & GetColumnRepresentations() const final
Implementations in derived classes should return a static RColumnRepresentations object.
Holds the static meta-data of an RNTuple column.
Holds the index and the tag of a kSwitch column.
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
REnumField(std::string_view fieldName, std::string_view enumName, TEnum *enump)
std::vector< RValue > SplitValue(const RValue &value) const final
Creates the list of direct child values given a value for this field.
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
Base class for all ROOT issued exceptions.
Similar to RValue but manages an array of consecutive values.
bool fIsAdopted
True if the user provides the memory buffer for fValues.
RFieldBase * fField
The field that created the array of values.
std::size_t fCapacity
The size of the array memory block in number of values.
std::unique_ptr< bool[]> fMaskAvail
Masks invalid values in the array.
std::size_t fValueSize
Cached copy of fField->GetValueSize()
void AdoptBuffer(void *buf, std::size_t capacity)
void * GetValuePtrAt(std::size_t idx) const
RBulk & operator=(const RBulk &)=delete
void Reset(RClusterIndex firstIndex, std::size_t size)
Sets a new range for the bulk.
std::size_t fNValidValues
The sum of non-zero elements in the fMask.
RClusterIndex fFirstIndex
Index of the first value of the array.
std::size_t fSize
The number of available values in the array (provided their mask is set)
void * fValues
Cached deleter of fField.
std::unique_ptr< RFieldBase::RDeleter > fDeleter
Some fields have multiple possible column representations, e.g.
std::vector< ColumnRepresentation_t > TypesList_t
TypesList_t fSerializationTypes
TypesList_t fDeserializationTypes
The union of the serialization types and the deserialization extra types.
Points to an object with RNTuple I/O support and keeps a pointer to the corresponding field.
std::shared_ptr< void > fObjPtr
Set by Bind() or by RFieldBase::CreateValue(), SplitValue() or BindValue()
void BindRawPtr(void *rawPtr)
A field translates read and write calls from/to underlying columns to/from tree values.
virtual void GenerateColumnsImpl()=0
Creates the backing columns corresponsing to the field type for writing.
static constexpr int kTraitTriviallyDestructible
The type is cleaned up just by freeing its memory. I.e. the destructor performs a no-op.
const RFieldBase * GetParent() const
std::string GetFieldName() const
void Attach(std::unique_ptr< RFieldBase > child)
Add a new subfield to the list of nested fields.
bool HasDefaultColumnRepresentative() const
Whether or not an explicit column representative was set.
std::uint32_t fOnDiskTypeVersion
C++ type version cached from the descriptor after a call to ConnectPageSource()
void AutoAdjustColumnTypes(const RNTupleWriteOptions &options)
When connecting a field to a page sink, the field's default column representation is subject to adjus...
const ColumnRepresentation_t & EnsureCompatibleColumnTypes(const RNTupleDescriptor &desc) const
Returns the on-disk column types found in the provided descriptor for fOnDiskId.
ENTupleStructure fStructure
The role of this field in the data model structure.
std::vector< RFieldBase * > GetSubFields()
static std::vector< RCheckResult > Check(const std::string &fieldName, const std::string &typeName)
Checks if the given type is supported by RNTuple.
static constexpr int kTraitMappable
A field of a fundamental type that can be directly mapped via RField<T>::Map(), i....
std::function< void(void *)> ReadCallback_t
EState fState
Changed by ConnectTo[Sink,Source], reset by Clone()
static constexpr int kTraitTriviallyConstructible
No constructor needs to be called, i.e.
std::string fTypeAlias
A typedef or using name that was used when creating the field.
std::vector< std::unique_ptr< Internal::RColumn > > fColumns
The columns are connected either to a sink or to a source (not to both); they are owned by the field.
RConstSchemaIterator cbegin() const
RValue BindValue(std::shared_ptr< void > objPtr)
Creates a value from a memory location with an already constructed object.
std::string GetTypeName() const
virtual void AcceptVisitor(Detail::RFieldVisitor &visitor) const
std::string fDescription
Free text set by the user.
static Internal::RColumn * GetPrincipalColumnOf(const RFieldBase &other)
Fields may need direct access to the principal column of their sub fields, e.g. in RRVecField::ReadBu...
std::size_t fNRepetitions
For fixed sized arrays, the array length.
friend class ROOT::Experimental::RCollectionField
RFieldBase * fParent
Sub fields point to their mother field.
std::unique_ptr< T, typename RCreateObjectDeleter< T >::deleter > CreateObject() const
Generates an object of the field type and allocates new initialized memory according to the type.
static std::size_t CallAppendOn(RFieldBase &other, const void *from)
Allow derived classes to call Append and Read on other (sub) fields.
int fTraits
Properties of the type that allow for optimizations of collections of that type.
static std::unique_ptr< RDeleter > GetDeleterOf(const RFieldBase &other)
void ConnectPageSink(Internal::RPageSink &pageSink, NTupleSize_t firstEntry=0)
Fields and their columns live in the void until connected to a physical page storage.
DescriptorId_t fOnDiskId
When the columns are connected to a page source or page sink, the field represents a field id in the ...
virtual std::size_t AppendImpl(const void *from)
Operations on values of complex types, e.g.
RConstSchemaIterator cend() const
const ColumnRepresentation_t * fColumnRepresentative
Points into the static vector GetColumnRepresentations().GetSerializationTypes() when SetColumnRepres...
void Read(NTupleSize_t globalIndex, void *to)
Populate a single value with data from the field.
bool fIsSimple
A field qualifies as simple if it is both mappable and has no post-read callback.
std::uint32_t GetOnDiskTypeVersion() const
Return the C++ type version stored in the field descriptor; only valid after a call to ConnectPageSou...
std::string GetQualifiedFieldName() const
Returns the field name and parent field names separated by dots ("grandparent.parent....
std::vector< EColumnType > ColumnRepresentation_t
virtual std::size_t ReadBulkImpl(const RBulkSpec &bulkSpec)
General implementation of bulk read.
virtual std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const =0
Called by Clone(), which additionally copies the on-disk ID.
std::size_t Append(const void *from)
Write the given value into columns.
void RemoveReadCallback(size_t idx)
void * CreateObjectRawPtr() const
Factory method for the field's type. The caller owns the returned pointer.
void CommitCluster()
Flushes data from active columns to disk and calls CommitClusterImpl.
void ConnectPageSource(Internal::RPageSource &pageSource)
Connects the field and its sub field tree to the given page source.
RValue CreateValue()
Generates an object of the field type and wraps the created object in a shared pointer and returns it...
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 std::unique_ptr< RDeleter > GetDeleter() const
static void CallReadOn(RFieldBase &other, RClusterIndex clusterIndex, void *to)
virtual void ConstructValue(void *where) const =0
Constructs value in a given location of size at least GetValueSize(). Called by the base class' Creat...
static RResult< std::unique_ptr< RFieldBase > > Create(const std::string &fieldName, const std::string &canonicalType, const std::string &typeAlias, bool fContinueOnError=false)
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...
virtual std::vector< RValue > SplitValue(const RValue &value) const
Creates the list of direct child values given a value for this field.
void SetOnDiskId(DescriptorId_t id)
std::string fName
The field name relative to its parent field.
virtual void OnConnectPageSource()
Called by ConnectPageSource() only once connected; derived classes may override this as appropriate.
void SetColumnRepresentative(const ColumnRepresentation_t &representative)
Fixes a column representative.
static void CallConstructValueOn(const RFieldBase &other, void *where)
Allow derived classes to call ConstructValue(void *) and GetDeleter on other (sub) fields.
std::vector< std::unique_ptr< RFieldBase > > fSubFields
Collections and classes own sub fields.
std::string fType
The C++ type captured by this field.
Internal::RColumn * fPrincipalColumn
Points into fColumns.
DescriptorId_t GetOnDiskId() const
virtual size_t GetValueSize() const =0
The number of bytes taken by a value of the appropriate type.
static constexpr int kTraitTrivialType
Shorthand for types that are both trivially constructible and destructible.
const ColumnRepresentation_t & GetColumnRepresentative() const
Returns the fColumnRepresentative pointee or, if unset, the field's default representative.
std::vector< ReadCallback_t > fReadCallbacks
List of functions to be called after reading a value.
void SetDescription(std::string_view description)
static RResult< void > EnsureValidFieldName(std::string_view fieldName)
Check whether a given string is a valid field name.
NTupleSize_t EntryToColumnElementIndex(NTupleSize_t globalIndex) const
Translate an entry index to a column element index of the principal column and viceversa.
virtual void ReadGlobalImpl(NTupleSize_t globalIndex, void *to)
virtual void CommitClusterImpl()
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 const RColumnRepresentations & GetColumnRepresentations() const
Implementations in derived classes should return a static RColumnRepresentations object.
std::uint32_t GetTypeVersion() const
The container field for an ntuple model, which itself has no physical representation.
void Attach(std::unique_ptr< RFieldBase > child)
Add a new subfield to the list of nested fields.
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
std::unique_ptr< 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.
Used in RFieldBase::Check() to record field creation failures.
RMapField(std::string_view fieldName, std::string_view typeName, std::unique_ptr< RFieldBase > itemField)
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
std::vector< RValue > SplitValue(const RValue &value) const final
Creates the list of direct child values given a value for this field.
The on-storage meta-data of an ntuple.
DescriptorId_t FindFieldId(std::string_view fieldName, DescriptorId_t parentId) const
const RFieldDescriptor & GetFieldDescriptor(DescriptorId_t fieldId) const
RColumnDescriptorIterable GetColumnIterable() const
Common user-tunable settings for storing ntuples.
int GetCompression() const
bool GetHasSmallClusters() const
ClusterSize_t fNWritten
For a sparse nullable field, the number of written non-null items in this cluster.
const RFieldBase::RColumnRepresentations & GetColumnRepresentations() const final
Implementations in derived classes should return a static RColumnRepresentations object.
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type for writing.
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
RClusterIndex GetItemIndex(NTupleSize_t globalIndex)
Given the index of the nullable field, returns the corresponding global index of the subfield or,...
RNullableField(std::string_view fieldName, std::string_view typeName, std::unique_ptr< RFieldBase > itemField)
std::unique_ptr< RValue > fDefaultItemValue
For a dense nullable field, used to write a default-constructed item for missing ones.
std::size_t AppendValue(const void *from)
void operator()(void *objPtr, bool dtorOnly) final
The generic field for std::pair<T1, T2> types.
void ConstructValue(void *where) const override
Constructs value in a given location of size at least GetValueSize(). Called by the base class' Creat...
RPairField(std::string_view fieldName, std::array< std::unique_ptr< RFieldBase >, 2 > &&itemFields, const std::array< std::size_t, 2 > &offsets)
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const override
Called by Clone(), which additionally copies the on-disk ID.
static std::string GetTypeList(const std::array< std::unique_ptr< RFieldBase >, 2 > &itemFields)
Allows for iterating over the elements of a proxied collection.
static RIteratorFuncs GetIteratorFuncs(TVirtualCollectionProxy *proxy, bool readFromDisk)
void operator()(void *objPtr, bool dtorOnly) final
std::shared_ptr< TVirtualCollectionProxy > fProxy
std::unique_ptr< RDeleter > fItemDeleter
RCollectionIterableOnce::RIteratorFuncs fIFuncsWrite
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const override
Called by Clone(), which additionally copies the on-disk ID.
void ConstructValue(void *where) const override
Constructs value in a given location of size at least GetValueSize(). Called by the base class' Creat...
std::size_t AppendImpl(const void *from) override
Operations on values of complex types, e.g.
std::shared_ptr< TVirtualCollectionProxy > fProxy
The collection proxy is needed by the deleters and thus defined as a shared pointer.
RCollectionIterableOnce::RIteratorFuncs fIFuncsRead
Two sets of functions to operate on iterators, to be used depending on the access type.
void AcceptVisitor(Detail::RFieldVisitor &visitor) const override
std::unique_ptr< RDeleter > GetDeleter() const override
RProxiedCollectionField(std::string_view fieldName, std::string_view typeName, TClass *classp)
Constructor used when the value type of the collection is not known in advance, i....
const RColumnRepresentations & GetColumnRepresentations() const final
Implementations in derived classes should return a static RColumnRepresentations object.
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type for writing.
std::vector< RValue > SplitValue(const RValue &value) const override
Creates the list of direct child values given a value for this field.
RCollectionIterableOnce::RIteratorFuncs fIFuncsWrite
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) override
std::size_t fItemAlignment
void operator()(void *objPtr, bool dtorOnly) final
std::unique_ptr< RDeleter > fItemDeleter
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const override
Called by Clone(), which additionally copies the on-disk ID.
std::unique_ptr< RDeleter > fItemDeleter
std::unique_ptr< RDeleter > GetDeleter() const override
void ConstructValue(void *where) const override
Constructs value in a given location of size at least GetValueSize(). Called by the base class' Creat...
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
std::vector< RValue > SplitValue(const RValue &value) const final
Creates the list of direct child values given a value for this field.
size_t GetAlignment() const override
As a rule of thumb, the alignment is equal to the size of the type.
size_t GetValueSize() const override
The number of bytes taken by a value of the appropriate type.
RRVecField(std::string_view fieldName, std::unique_ptr< RFieldBase > itemField)
const RColumnRepresentations & GetColumnRepresentations() const final
Implementations in derived classes should return a static RColumnRepresentations object.
std::size_t ReadBulkImpl(const RBulkSpec &bulkSpec) final
General implementation of bulk read.
void GetCollectionInfo(NTupleSize_t globalIndex, RClusterIndex *collectionStart, ClusterSize_t *size) const
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type for writing.
std::size_t AppendImpl(const void *from) override
Operations on values of complex types, e.g.
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) override
std::vector< std::size_t > fOffsets
void operator()(void *objPtr, bool dtorOnly) final
std::vector< std::unique_ptr< RDeleter > > fItemDeleters
std::size_t fMaxAlignment
RRecordField(std::string_view fieldName, std::vector< std::unique_ptr< RFieldBase > > &&itemFields, const std::vector< std::size_t > &offsets, std::string_view typeName="")
std::vector< std::size_t > fOffsets
void ReadInClusterImpl(RClusterIndex clusterIndex, void *to) final
std::unique_ptr< RDeleter > GetDeleter() const override
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
std::vector< RValue > SplitValue(const RValue &value) const final
Creates the list of direct child values given a value for this field.
std::size_t GetItemPadding(std::size_t baseOffset, std::size_t itemAlignment) const
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
void ConstructValue(void *where) const override
Constructs value in a given location of size at least GetValueSize(). Called by the base class' Creat...
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const override
Called by Clone(), which additionally copies the on-disk ID.
The class is used as a return type for operations that can fail; wraps a value of type T or an RError...
RSetField(std::string_view fieldName, std::string_view typeName, std::unique_ptr< RFieldBase > itemField)
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
void operator()(void *objPtr, bool dtorOnly) final
RTupleField(std::string_view fieldName, std::vector< std::unique_ptr< RFieldBase > > &&itemFields, const std::vector< std::size_t > &offsets)
static std::string GetTypeList(const std::vector< std::unique_ptr< RFieldBase > > &itemFields)
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const override
Called by Clone(), which additionally copies the on-disk ID.
void ConstructValue(void *where) const override
Constructs value in a given location of size at least GetValueSize(). Called by the base class' Creat...
void operator()(void *objPtr, bool dtorOnly) final
std::unique_ptr< RDeleter > fItemDeleter
std::unique_ptr< RDeleter > fItemDeleter
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
std::vector< RValue > SplitValue(const RValue &value) const final
Creates the list of direct child values given a value for this field.
RUniquePtrField(std::string_view fieldName, std::string_view typeName, std::unique_ptr< RFieldBase > itemField)
std::unique_ptr< RDeleter > GetDeleter() const final
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
void operator()(void *objPtr, bool dtorOnly) final
std::vector< std::unique_ptr< RDeleter > > fItemDeleters
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
static void SetTag(void *variantPtr, std::size_t tagOffset, std::uint32_t tag)
const RColumnRepresentations & GetColumnRepresentations() const final
Implementations in derived classes should return a static RColumnRepresentations object.
void ConstructValue(void *where) const override
Constructs value in a given location of size at least GetValueSize(). Called by the base class' Creat...
static std::string GetTypeList(const std::vector< RFieldBase * > &itemFields)
std::vector< ClusterSize_t::ValueType > fNWritten
size_t fTagOffset
In the std::variant memory layout, at which byte number is the index stored.
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type for writing.
void CommitClusterImpl() final
std::unique_ptr< RDeleter > GetDeleter() const final
static std::uint32_t GetTag(const void *variantPtr, std::size_t tagOffset)
Extracts the index from an std::variant and transforms it into the 1-based index used for the switch ...
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
size_t GetAlignment() const final
As a rule of thumb, the alignment is equal to the size of the type.
RVariantField(std::string_view fieldName, const std::vector< RFieldBase * > &itemFields)
std::unique_ptr< RDeleter > fItemDeleter
void operator()(void *objPtr, bool dtorOnly) final
std::vector< RValue > SplitValue(const RValue &value) const final
Creates the list of direct child values given a value for this field.
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
std::unique_ptr< RDeleter > fItemDeleter
size_t GetValueSize() const override
The number of bytes taken by a value of the appropriate type.
std::unique_ptr< RDeleter > GetDeleter() const final
RVectorField(std::string_view fieldName, std::unique_ptr< RFieldBase > itemField)
const RColumnRepresentations & GetColumnRepresentations() const final
Implementations in derived classes should return a static RColumnRepresentations object.
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type for writing.
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
TClass instances represent classes, structs and namespaces in the ROOT type system.
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
The TEnum class implements the enum type.
EDataType GetUnderlyingType() const
Get the underlying integer type of the enum: enum E { kOne }; // ==> int enum F: long; // ==> long Re...
Long_t Property() const override
Get property description word. For meaning of bits see EProperty.
static TEnum * GetEnum(const std::type_info &ti, ESearchAction sa=kALoadAndInterpLookup)
RAII helper class that ensures that PushProxy() / PopProxy() are called when entering / leaving a C++...
Defines a common interface to inspect/change the contents of an object that represents a collection.
@ kNeedDelete
The collection contains directly or indirectly (via other collection) some pointers that need explici...
virtual Next_t GetFunctionNext(Bool_t read=kTRUE)=0
Return a pointer to a function that can advance an iterator (see Next_t).
virtual DeleteTwoIterators_t GetFunctionDeleteTwoIterators(Bool_t read=kTRUE)=0
virtual TVirtualCollectionProxy * Generate() const =0
Returns a clean object of the actual class that derives from TVirtualCollectionProxy.
virtual CreateIterators_t GetFunctionCreateIterators(Bool_t read=kTRUE)=0
Return a pointer to a function that can create an iterator pair, where each iterator points to the be...
Wrapper around an object and giving indirect access to its content even if the object is not of a cla...
TRangeCast< T, false > TRangeStaticCast
TRangeStaticCast is an adapter class that allows the typed iteration through a TCollection.
auto MakeAliasedSharedPtr(T *rawPtr)
void CallConnectPageSinkOnField(RFieldBase &, RPageSink &, NTupleSize_t firstEntry=0)
void CallConnectPageSourceOnField(RFieldBase &, RPageSource &)
void CallCommitClusterOnField(RFieldBase &)
RLogChannel & NTupleLog()
Log channel for RNTuple diagnostics.
RClusterSize ClusterSize_t
ENTupleStructure
The fields in the ntuple model tree can carry different structural information about the type system.
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
std::uint64_t DescriptorId_t
Distriniguishes elements of the same type within a descriptor, e.g. different fields.
constexpr ClusterSize_t kInvalidClusterIndex(std::uint64_t(-1))
constexpr DescriptorId_t kInvalidDescriptorId
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=nullptr)
Cleanup type description, redundant blanks removed and redundant tail ignored return *tail = pointer ...
Input parameter to ReadBulk() and ReadBulkImpl(). See RBulk class for more information.
void * fValues
The destination area, which has to be a big enough array of valid objects of the correct type.
const bool * fMaskReq
A bool array of size fCount, indicating the required values in the requested range.
bool * fMaskAvail
A bool array of size fCount, indicating the valid values in fValues.
std::size_t fCount
Size of the bulk range.
RClusterIndex fFirstIndex
Start of the bulk range.
std::vector< unsigned char > * fAuxData
Reference to memory owned by the RBulk class.
Used in the return value of the Check() method.
TVirtualCollectionProxy::Next_t fNext
TVirtualCollectionProxy::DeleteTwoIterators_t fDeleteTwoIterators
TVirtualCollectionProxy::CreateIterators_t fCreateIterators