58#include <unordered_map>
62const std::unordered_map<std::string_view, std::string_view> typeTranslationMap{
65 {
"Double_t",
"double"},
66 {
"string",
"std::string"},
68 {
"byte",
"std::byte"},
70 {
"int8_t",
"std::int8_t"},
71 {
"signed char",
"char"},
72 {
"UChar_t",
"std::uint8_t"},
73 {
"unsigned char",
"std::uint8_t"},
74 {
"uint8_t",
"std::uint8_t"},
76 {
"Short_t",
"std::int16_t"},
77 {
"int16_t",
"std::int16_t"},
78 {
"short",
"std::int16_t"},
79 {
"UShort_t",
"std::uint16_t"},
80 {
"unsigned short",
"std::uint16_t"},
81 {
"uint16_t",
"std::uint16_t"},
83 {
"Int_t",
"std::int32_t"},
84 {
"int32_t",
"std::int32_t"},
85 {
"int",
"std::int32_t"},
86 {
"UInt_t",
"std::uint32_t"},
87 {
"unsigned",
"std::uint32_t"},
88 {
"unsigned int",
"std::uint32_t"},
89 {
"uint32_t",
"std::uint32_t"},
92 {
"Long_t",
"std::int64_t"},
93 {
"Long64_t",
"std::int64_t"},
94 {
"int64_t",
"std::int64_t"},
95 {
"long",
"std::int64_t"},
96 {
"ULong_t",
"std::uint64_t"},
97 {
"ULong64_t",
"std::uint64_t"},
98 {
"unsigned long",
"std::uint64_t"},
99 {
"uint64_t",
"std::uint64_t"}
104std::vector<std::string> TokenizeTypeList(std::string templateType) {
105 std::vector<std::string>
result;
106 if (templateType.empty())
109 const char *eol = templateType.data() + templateType.length();
110 const char *typeBegin = templateType.data();
111 const char *typeCursor = templateType.data();
112 unsigned int nestingLevel = 0;
113 while (typeCursor != eol) {
114 switch (*typeCursor) {
122 if (nestingLevel == 0) {
123 result.push_back(std::string(typeBegin, typeCursor - typeBegin));
124 typeBegin = typeCursor + 1;
130 result.push_back(std::string(typeBegin, typeCursor - typeBegin));
139std::tuple<std::string, std::vector<size_t>> ParseArrayType(std::string_view typeName)
141 std::vector<size_t> sizeVec;
144 while (typeName.back() ==
']') {
145 auto posRBrace = typeName.size() - 1;
146 auto posLBrace = typeName.find_last_of(
'[', posRBrace);
147 if (posLBrace == std::string_view::npos)
151 if (std::from_chars(typeName.data() + posLBrace + 1, typeName.data() + posRBrace,
size).ec != std::errc{})
153 sizeVec.insert(sizeVec.begin(),
size);
154 typeName.remove_suffix(typeName.size() - posLBrace);
156 return std::make_tuple(std::string{typeName}, sizeVec);
161std::string GetCanonicalTypeName(
const std::string &typeName)
164 if (typeName ==
"ROOT::Experimental::ClusterSize_t" || typeName.substr(0, 5) ==
"std::" ||
165 typeName.substr(0, 39) ==
"ROOT::Experimental::RNTupleCardinality<")
176std::string GetNormalizedTypeName(
const std::string &typeName)
180 if (
auto it = typeTranslationMap.find(normalizedType); it != typeTranslationMap.end())
181 normalizedType = it->second;
183 if (normalizedType.substr(0, 7) ==
"vector<")
184 normalizedType =
"std::" + normalizedType;
185 if (normalizedType.substr(0, 6) ==
"array<")
186 normalizedType =
"std::" + normalizedType;
187 if (normalizedType.substr(0, 8) ==
"variant<")
188 normalizedType =
"std::" + normalizedType;
189 if (normalizedType.substr(0, 5) ==
"pair<")
190 normalizedType =
"std::" + normalizedType;
191 if (normalizedType.substr(0, 6) ==
"tuple<")
192 normalizedType =
"std::" + normalizedType;
193 if (normalizedType.substr(0, 7) ==
"bitset<")
194 normalizedType =
"std::" + normalizedType;
195 if (normalizedType.substr(0, 11) ==
"unique_ptr<")
196 normalizedType =
"std::" + normalizedType;
197 if (normalizedType.substr(0, 4) ==
"set<")
198 normalizedType =
"std::" + normalizedType;
199 if (normalizedType.substr(0, 14) ==
"unordered_set<")
200 normalizedType =
"std::" + normalizedType;
201 if (normalizedType.substr(0, 4) ==
"map<")
202 normalizedType =
"std::" + normalizedType;
203 if (normalizedType.substr(0, 14) ==
"unordered_map<")
204 normalizedType =
"std::" + normalizedType;
205 if (normalizedType.substr(0, 7) ==
"atomic<")
206 normalizedType =
"std::" + normalizedType;
208 if (normalizedType.substr(0, 11) ==
"ROOT::RVec<")
209 normalizedType =
"ROOT::VecOps::RVec<" + normalizedType.substr(11);
211 return normalizedType;
215class CreateContextGuard;
217 friend class CreateContextGuard;
219 std::vector<std::string> fClassesOnStack;
222 bool fContinueOnError =
false;
225 CreateContext() =
default;
226 bool GetContinueOnError()
const {
return fContinueOnError; }
230class CreateContextGuard {
231 CreateContext &fCreateContext;
232 std::size_t fNOriginalClassesOnStack;
233 bool fOriginalContinueOnError;
236 CreateContextGuard(CreateContext &ctx)
237 : fCreateContext(ctx),
238 fNOriginalClassesOnStack(ctx.fClassesOnStack.
size()),
239 fOriginalContinueOnError(ctx.fContinueOnError)
242 ~CreateContextGuard()
244 fCreateContext.fClassesOnStack.resize(fNOriginalClassesOnStack);
245 fCreateContext.fContinueOnError = fOriginalContinueOnError;
248 void AddClassToStack(
const std::string &cl)
250 if (std::find(fCreateContext.fClassesOnStack.begin(), fCreateContext.fClassesOnStack.end(), cl) !=
251 fCreateContext.fClassesOnStack.end()) {
254 fCreateContext.fClassesOnStack.emplace_back(cl);
257 void SetContinueOnError(
bool value) { fCreateContext.fContinueOnError =
value; }
262std::tuple<void **, std::int32_t *, std::int32_t *> GetRVecDataMembers(
void *rvecPtr)
264 void **begin =
reinterpret_cast<void **
>(rvecPtr);
266 std::int32_t *
size =
reinterpret_cast<std::int32_t *
>(begin + 1);
269 std::int32_t *capacity =
size + 1;
271 return {begin,
size, capacity};
274std::tuple<const void *const *, const std::int32_t *, const std::int32_t *> GetRVecDataMembers(
const void *rvecPtr)
276 return {GetRVecDataMembers(
const_cast<void *
>(rvecPtr))};
284 auto iFrom = from.
cbegin();
285 auto iTo = to.
begin();
286 for (; iFrom != from.
cend(); ++iFrom, ++iTo) {
287 iTo->SetOnDiskId(iFrom->GetOnDiskId());
291std::size_t EvalRVecValueSize(std::size_t alignOfT, std::size_t sizeOfT, std::size_t alignOfRVecT)
305 constexpr auto dataMemberSz =
sizeof(
void *) + 2 *
sizeof(std::int32_t);
308 const auto inlineStorageSz = [&] {
309#ifdef R__HAS_HARDWARE_INTERFERENCE_SIZE
311 constexpr unsigned cacheLineSize = std::hardware_destructive_interference_size;
313 constexpr unsigned cacheLineSize = 64u;
315 const unsigned elementsPerCacheLine = (cacheLineSize - dataMemberSz) / sizeOfT;
316 constexpr unsigned maxInlineByteSize = 1024;
317 const unsigned nElements =
318 elementsPerCacheLine >= 8 ? elementsPerCacheLine : (sizeOfT * 8 > maxInlineByteSize ? 0 : 8);
319 return nElements * sizeOfT;
324 auto paddingMiddle = dataMemberSz % alignOfT;
325 if (paddingMiddle != 0)
326 paddingMiddle = alignOfT - paddingMiddle;
329 auto paddingEnd = (dataMemberSz + paddingMiddle + inlineStorageSz) % alignOfRVecT;
331 paddingEnd = alignOfRVecT - paddingEnd;
333 return dataMemberSz + inlineStorageSz + paddingMiddle + paddingEnd;
336std::size_t EvalRVecAlignment(std::size_t alignOfSubField)
340 return std::max({
alignof(
void *),
alignof(std::int32_t), alignOfSubField});
343void DestroyRVecWithChecks(std::size_t alignOfT,
void **beginPtr,
char *begin, std::int32_t *capacityPtr)
347 constexpr auto dataMemberSz =
sizeof(
void *) + 2 *
sizeof(std::int32_t);
348 auto paddingMiddle = dataMemberSz % alignOfT;
349 if (paddingMiddle != 0)
350 paddingMiddle = alignOfT - paddingMiddle;
351 const bool isSmall = (
reinterpret_cast<void *
>(begin) == (beginPtr + dataMemberSz + paddingMiddle));
353 const bool owns = (*capacityPtr != -1);
354 if (!isSmall && owns)
359enum class ERNTupleUnsplitSetting { kForceSplit, kForceUnsplit,
kUnset };
361ERNTupleUnsplitSetting GetRNTupleUnsplitSetting(
TClass *cl)
364 if (!am || !am->HasKey(
"rntuple.split"))
365 return ERNTupleUnsplitSetting::kUnset;
367 std::string
value = am->GetPropertyAsString(
"rntuple.split");
369 if (
value ==
"TRUE") {
370 return ERNTupleUnsplitSetting::kForceSplit;
371 }
else if (
value ==
"FALSE") {
372 return ERNTupleUnsplitSetting::kForceUnsplit;
375 <<
"invalid setting for 'rntuple.split' class attribute: " << am->GetPropertyAsString(
"rntuple.split");
376 return ERNTupleUnsplitSetting::kUnset;
381constexpr std::size_t GetVariantTagSize()
384 std::variant<char> t;
385 constexpr auto sizeOfT =
sizeof(t);
387 static_assert(sizeOfT == 2 || sizeOfT == 8,
"unsupported std::variant layout");
388 return sizeOfT == 2 ? 1 : 4;
391template <std::
size_t VariantSizeT>
393 using ValueType_t =
typename std::conditional_t<VariantSizeT == 1, std::uint8_t,
394 typename std::conditional_t<VariantSizeT == 4, std::uint32_t, void>>;
403 RCallbackStreamerInfo fCallbackStreamerInfo;
407 :
TBufferFile(
mode, bufsiz), fCallbackStreamerInfo(callbackStreamerInfo)
440 : fSerializationTypes(serializationTypes), fDeserializationTypes(serializationTypes)
443 deserializationExtraTypes.begin(), deserializationExtraTypes.end());
458 : fField(other.fField),
460 fCapacity(other.fCapacity),
462 fIsAdopted(other.fIsAdopted),
463 fNValidValues(other.fNValidValues),
464 fFirstIndex(other.fFirstIndex)
466 std::swap(
fDeleter, other.fDeleter);
467 std::swap(
fValues, other.fValues);
473 std::swap(fField, other.fField);
474 std::swap(fDeleter, other.fDeleter);
475 std::swap(fValues, other.fValues);
477 std::swap(fCapacity, other.fCapacity);
478 std::swap(
fSize, other.fSize);
479 std::swap(fIsAdopted, other.fIsAdopted);
480 std::swap(fMaskAvail, other.fMaskAvail);
481 std::swap(fNValidValues, other.fNValidValues);
482 std::swap(fFirstIndex, other.fFirstIndex);
502 for (std::size_t i = 0; i < fCapacity; ++i) {
503 fDeleter->operator()(GetValuePtrAt(i),
true );
510 if (fCapacity <
size) {
512 throw RException(
R__FAIL(
"invalid attempt to bulk read beyond the adopted buffer"));
518 for (std::size_t i = 0; i <
size; ++i) {
519 fField->ConstructValue(GetValuePtrAt(i));
523 fMaskAvail = std::make_unique<bool[]>(
size);
527 std::fill(fMaskAvail.get(), fMaskAvail.get() +
size,
false);
530 fFirstIndex = firstIndex;
537 for (std::size_t i = 0; i <
fSize; ++i)
538 fNValidValues +=
static_cast<std::size_t
>(fMaskAvail[i]);
545 fCapacity = capacity;
548 fMaskAvail = std::make_unique<bool[]>(capacity);
563std::unique_ptr<void, typename ROOT::Experimental::RFieldBase::RCreateObjectDeleter<void>::deleter>
564ROOT::Experimental::RFieldBase::CreateObject<void>()
const
567 return std::unique_ptr<void, RCreateObjectDeleter<void>::deleter>(
CreateObjectRawPtr(), gDeleter);
573 bool isSimple, std::size_t nRepetitions)
587 std::string
result = GetFieldName();
588 auto parent = GetParent();
589 while (parent && !parent->GetFieldName().empty()) {
591 parent = parent->GetParent();
599 auto typeAlias = GetNormalizedTypeName(typeName);
600 auto canonicalType = GetNormalizedTypeName(GetCanonicalTypeName(typeAlias));
604std::vector<ROOT::Experimental::RFieldBase::RCheckResult>
607 auto typeAlias = GetNormalizedTypeName(typeName);
608 auto canonicalType = GetNormalizedTypeName(GetCanonicalTypeName(typeAlias));
613 std::vector<RCheckResult>
result;
614 for (
const auto &
f : fieldZero) {
620 RCheckResult{invalidField->GetQualifiedFieldName(), invalidField->GetTypeName(), invalidField->GetError()});
627 const std::string &typeAlias,
bool continueOnError)
629 thread_local CreateContext createContext;
630 CreateContextGuard createContextGuard(createContext);
632 createContextGuard.SetContinueOnError(
true);
634 auto fnFail = [&fieldName, &canonicalType](
const std::string &errMsg) ->
RResult<std::unique_ptr<RFieldBase>> {
635 if (createContext.GetContinueOnError()) {
636 return std::unique_ptr<RFieldBase>(std::make_unique<RInvalidField>(fieldName, canonicalType, errMsg));
642 if (canonicalType.empty())
643 return R__FORWARD_RESULT(fnFail(
"no type name specified for field '" + fieldName +
"'"));
645 if (
auto [arrayBaseType, arraySizes] = ParseArrayType(canonicalType); !arraySizes.empty()) {
646 std::unique_ptr<RFieldBase> arrayField = Create(
"_0", arrayBaseType).Unwrap();
647 for (
int i = arraySizes.size() - 1; i >= 0; --i) {
648 arrayField = std::make_unique<RArrayField>((i == 0) ? fieldName :
"_0", std::move(arrayField), arraySizes[i]);
653 std::unique_ptr<ROOT::Experimental::RFieldBase>
result;
655 if (canonicalType ==
"ROOT::Experimental::ClusterSize_t") {
656 result = std::make_unique<RField<ClusterSize_t>>(fieldName);
657 }
else if (canonicalType ==
"bool") {
658 result = std::make_unique<RField<bool>>(fieldName);
659 }
else if (canonicalType ==
"char") {
660 result = std::make_unique<RField<char>>(fieldName);
661 }
else if (canonicalType ==
"std::byte") {
662 result = std::make_unique<RField<std::byte>>(fieldName);
663 }
else if (canonicalType ==
"std::int8_t") {
664 result = std::make_unique<RField<std::int8_t>>(fieldName);
665 }
else if (canonicalType ==
"std::uint8_t") {
666 result = std::make_unique<RField<std::uint8_t>>(fieldName);
667 }
else if (canonicalType ==
"std::int16_t") {
668 result = std::make_unique<RField<std::int16_t>>(fieldName);
669 }
else if (canonicalType ==
"std::uint16_t") {
670 result = std::make_unique<RField<std::uint16_t>>(fieldName);
671 }
else if (canonicalType ==
"std::int32_t") {
672 result = std::make_unique<RField<std::int32_t>>(fieldName);
673 }
else if (canonicalType ==
"std::uint32_t") {
674 result = std::make_unique<RField<std::uint32_t>>(fieldName);
675 }
else if (canonicalType ==
"std::int64_t") {
676 result = std::make_unique<RField<std::int64_t>>(fieldName);
677 }
else if (canonicalType ==
"std::uint64_t") {
678 result = std::make_unique<RField<std::uint64_t>>(fieldName);
679 }
else if (canonicalType ==
"float") {
680 result = std::make_unique<RField<float>>(fieldName);
681 }
else if (canonicalType ==
"double") {
682 result = std::make_unique<RField<double>>(fieldName);
683 }
else if (canonicalType ==
"Double32_t") {
684 result = std::make_unique<RField<double>>(fieldName);
688 }
else if (canonicalType ==
"std::string") {
689 result = std::make_unique<RField<std::string>>(fieldName);
690 }
else if (canonicalType ==
"TObject") {
691 result = std::make_unique<RField<TObject>>(fieldName);
692 }
else if (canonicalType ==
"std::vector<bool>") {
693 result = std::make_unique<RField<std::vector<bool>>>(fieldName);
694 }
else if (canonicalType.substr(0, 12) ==
"std::vector<") {
695 std::string itemTypeName = canonicalType.substr(12, canonicalType.length() - 13);
696 auto itemField = Create(
"_0", itemTypeName);
697 result = std::make_unique<RVectorField>(fieldName, itemField.Unwrap());
698 }
else if (canonicalType.substr(0, 19) ==
"ROOT::VecOps::RVec<") {
699 std::string itemTypeName = canonicalType.substr(19, canonicalType.length() - 20);
700 auto itemField = Create(
"_0", itemTypeName);
701 result = std::make_unique<RRVecField>(fieldName, itemField.Unwrap());
702 }
else if (canonicalType.substr(0, 11) ==
"std::array<") {
703 auto arrayDef = TokenizeTypeList(canonicalType.substr(11, canonicalType.length() - 12));
704 if (arrayDef.size() != 2) {
705 return R__FORWARD_RESULT(fnFail(
"the template list for std::array must have exactly two elements"));
707 auto arrayLength = std::stoi(arrayDef[1]);
708 auto itemField = Create(
"_0", arrayDef[0]);
709 result = std::make_unique<RArrayField>(fieldName, itemField.Unwrap(), arrayLength);
710 }
else if (canonicalType.substr(0, 13) ==
"std::variant<") {
711 auto innerTypes = TokenizeTypeList(canonicalType.substr(13, canonicalType.length() - 14));
712 std::vector<RFieldBase *> items;
713 items.reserve(innerTypes.size());
714 for (
unsigned int i = 0; i < innerTypes.size(); ++i) {
715 items.emplace_back(Create(
"_" + std::to_string(i), innerTypes[i]).Unwrap().release());
717 result = std::make_unique<RVariantField>(fieldName, items);
718 }
else if (canonicalType.substr(0, 10) ==
"std::pair<") {
719 auto innerTypes = TokenizeTypeList(canonicalType.substr(10, canonicalType.length() - 11));
720 if (innerTypes.size() != 2) {
721 return R__FORWARD_RESULT(fnFail(
"the type list for std::pair must have exactly two elements"));
723 std::array<std::unique_ptr<RFieldBase>, 2> items{Create(
"_0", innerTypes[0]).Unwrap(),
724 Create(
"_1", innerTypes[1]).Unwrap()};
725 result = std::make_unique<RPairField>(fieldName, items);
726 }
else if (canonicalType.substr(0, 11) ==
"std::tuple<") {
727 auto innerTypes = TokenizeTypeList(canonicalType.substr(11, canonicalType.length() - 12));
728 std::vector<std::unique_ptr<RFieldBase>> items;
729 items.reserve(innerTypes.size());
730 for (
unsigned int i = 0; i < innerTypes.size(); ++i) {
731 items.emplace_back(Create(
"_" + std::to_string(i), innerTypes[i]).Unwrap());
733 result = std::make_unique<RTupleField>(fieldName, items);
734 }
else if (canonicalType.substr(0, 12) ==
"std::bitset<") {
735 auto size = std::stoull(canonicalType.substr(12, canonicalType.length() - 13));
736 result = std::make_unique<RBitsetField>(fieldName,
size);
737 }
else if (canonicalType.substr(0, 16) ==
"std::unique_ptr<") {
738 std::string itemTypeName = canonicalType.substr(16, canonicalType.length() - 17);
739 auto itemField = Create(
"_0", itemTypeName).Unwrap();
740 auto normalizedInnerTypeName = itemField->GetTypeName();
741 result = std::make_unique<RUniquePtrField>(fieldName,
"std::unique_ptr<" + normalizedInnerTypeName +
">",
742 std::move(itemField));
743 }
else if (canonicalType.substr(0, 14) ==
"std::optional<") {
744 std::string itemTypeName = canonicalType.substr(14, canonicalType.length() - 15);
745 auto itemField = Create(
"_0", itemTypeName).Unwrap();
746 auto normalizedInnerTypeName = itemField->GetTypeName();
747 result = std::make_unique<ROptionalField>(fieldName,
"std::optional<" + normalizedInnerTypeName +
">",
748 std::move(itemField));
749 }
else if (canonicalType.substr(0, 9) ==
"std::set<") {
750 std::string itemTypeName = canonicalType.substr(9, canonicalType.length() - 10);
751 auto itemField = Create(
"_0", itemTypeName).Unwrap();
752 auto normalizedInnerTypeName = itemField->GetTypeName();
754 std::make_unique<RSetField>(fieldName,
"std::set<" + normalizedInnerTypeName +
">", std::move(itemField));
755 }
else if (canonicalType.substr(0, 19) ==
"std::unordered_set<") {
756 std::string itemTypeName = canonicalType.substr(19, canonicalType.length() - 20);
757 auto itemField = Create(
"_0", itemTypeName).Unwrap();
758 auto normalizedInnerTypeName = itemField->GetTypeName();
759 result = std::make_unique<RSetField>(fieldName,
"std::unordered_set<" + normalizedInnerTypeName +
">",
760 std::move(itemField));
761 }
else if (canonicalType.substr(0, 9) ==
"std::map<") {
762 auto innerTypes = TokenizeTypeList(canonicalType.substr(9, canonicalType.length() - 10));
763 if (innerTypes.size() != 2) {
764 return R__FORWARD_RESULT(fnFail(
"the type list for std::map must have exactly two elements"));
767 auto normalizedKeyTypeName = GetNormalizedTypeName(innerTypes[0]);
768 auto normalizedValueTypeName = GetNormalizedTypeName(innerTypes[1]);
771 Create(
"_0",
"std::pair<" + normalizedKeyTypeName +
"," + normalizedValueTypeName +
">").Unwrap();
772 result = std::make_unique<RMapField>(
773 fieldName,
"std::map<" + normalizedKeyTypeName +
"," + normalizedValueTypeName +
">", std::move(itemField));
774 }
else if (canonicalType.substr(0, 19) ==
"std::unordered_map<") {
775 auto innerTypes = TokenizeTypeList(canonicalType.substr(19, canonicalType.length() - 20));
776 if (innerTypes.size() != 2)
777 return R__FORWARD_RESULT(fnFail(
"the type list for std::unordered_map must have exactly two elements"));
779 auto normalizedKeyTypeName = GetNormalizedTypeName(innerTypes[0]);
780 auto normalizedValueTypeName = GetNormalizedTypeName(innerTypes[1]);
783 Create(
"_0",
"std::pair<" + normalizedKeyTypeName +
"," + normalizedValueTypeName +
">").Unwrap();
784 result = std::make_unique<RMapField>(
785 fieldName,
"std::unordered_map<" + normalizedKeyTypeName +
"," + normalizedValueTypeName +
">",
786 std::move(itemField));
787 }
else if (canonicalType.substr(0, 12) ==
"std::atomic<") {
788 std::string itemTypeName = canonicalType.substr(12, canonicalType.length() - 13);
789 auto itemField = Create(
"_0", itemTypeName).Unwrap();
790 auto normalizedInnerTypeName = itemField->GetTypeName();
791 result = std::make_unique<RAtomicField>(fieldName,
"std::atomic<" + normalizedInnerTypeName +
">",
792 std::move(itemField));
793 }
else if (canonicalType.substr(0, 39) ==
"ROOT::Experimental::RNTupleCardinality<") {
794 auto innerTypes = TokenizeTypeList(canonicalType.substr(39, canonicalType.length() - 40));
795 if (innerTypes.size() != 1)
796 return R__FORWARD_RESULT(fnFail(
"invalid cardinality template: " + canonicalType));
797 if (innerTypes[0] ==
"std::uint32_t") {
798 result = std::make_unique<RField<RNTupleCardinality<std::uint32_t>>>(fieldName);
799 }
else if (innerTypes[0] ==
"std::uint64_t") {
800 result = std::make_unique<RField<RNTupleCardinality<std::uint64_t>>>(fieldName);
802 return R__FORWARD_RESULT(fnFail(
"invalid cardinality template: " + canonicalType));
810 result = std::make_unique<REnumField>(fieldName, canonicalType);
817 createContextGuard.AddClassToStack(canonicalType);
819 result = std::make_unique<RProxiedCollectionField>(fieldName, canonicalType);
821 if (GetRNTupleUnsplitSetting(cl) == ERNTupleUnsplitSetting::kForceUnsplit) {
822 result = std::make_unique<RUnsplitField>(fieldName, canonicalType);
824 result = std::make_unique<RClassField>(fieldName, canonicalType);
830 auto error =
e.GetError();
831 if (createContext.GetContinueOnError()) {
832 std::unique_ptr<RFieldBase>(std::make_unique<RInvalidField>(fieldName, canonicalType, error.GetReport()));
839 if (typeAlias != canonicalType)
840 result->fTypeAlias = typeAlias;
848 if (fieldName.empty()) {
849 return R__FAIL(
"name cannot be empty string \"\"");
850 }
else if (fieldName.find(
'.') != std::string::npos) {
851 return R__FAIL(
"name '" + std::string(fieldName) +
"' cannot contain dot characters '.'");
860 return representations;
865 auto clone = CloneImpl(newName);
866 clone->fTypeAlias = fTypeAlias;
867 clone->fOnDiskId = fOnDiskId;
868 clone->fDescription = fDescription;
870 clone->fColumnRepresentative = fColumnRepresentative;
876 R__ASSERT(
false &&
"A non-simple RField must implement its own AppendImpl");
887 const auto valueSize = GetValueSize();
888 std::size_t nRead = 0;
889 for (std::size_t i = 0; i < bulkSpec.
fCount; ++i) {
898 Read(bulkSpec.
fFirstIndex + i,
reinterpret_cast<unsigned char *
>(bulkSpec.
fValues) + i * valueSize);
907 void *where =
operator new(GetValueSize());
909 ConstructValue(where);
915 void *obj = CreateObjectRawPtr();
919std::vector<ROOT::Experimental::RFieldBase::RValue>
922 return std::vector<RValue>();
929 if (fState != EState::kUnconnected)
930 throw RException(
R__FAIL(
"invalid attempt to attach subfield to already connected field"));
931 child->fParent =
this;
932 fSubFields.emplace_back(std::move(
child));
938 std::size_t
result = globalIndex;
939 for (
auto f =
this;
f !=
nullptr;
f =
f->GetParent()) {
940 auto parent =
f->GetParent();
941 if (parent && (parent->GetStructure() ==
kCollection || parent->GetStructure() ==
kVariant))
943 result *= std::max(
f->GetNRepetitions(), std::size_t{1U});
950 std::vector<RFieldBase *>
result;
951 result.reserve(fSubFields.size());
952 for (
const auto &
f : fSubFields) {
960 std::vector<const RFieldBase *>
result;
961 result.reserve(fSubFields.size());
962 for (
const auto &
f : fSubFields) {
970 for (
auto& column : fColumns) {
978 if (fState != EState::kUnconnected)
979 throw RException(
R__FAIL(
"cannot set field description once field is connected"));
980 fDescription = std::string(description);
985 if (fState != EState::kUnconnected)
993 if (fColumnRepresentative)
994 return *fColumnRepresentative;
995 return GetColumnRepresentations().GetSerializationDefault();
1000 if (fState != EState::kUnconnected)
1001 throw RException(
R__FAIL(
"cannot set column representative once field is connected"));
1002 const auto &validTypes = GetColumnRepresentations().GetSerializationTypes();
1003 auto itRepresentative = std::find(validTypes.begin(), validTypes.end(), representative);
1004 if (itRepresentative == std::end(validTypes))
1006 fColumnRepresentative = &(*itRepresentative);
1013 throw RException(
R__FAIL(
"No on-disk column information for field `" + GetQualifiedFieldName() +
"`"));
1017 onDiskTypes.emplace_back(
c.GetModel().GetType());
1019 for (
const auto &t : GetColumnRepresentations().GetDeserializationTypes()) {
1020 if (t == onDiskTypes)
1024 std::string columnTypeNames;
1025 for (
const auto &t : onDiskTypes) {
1026 if (!columnTypeNames.empty())
1027 columnTypeNames +=
", ";
1030 throw RException(
R__FAIL(
"On-disk column types `" + columnTypeNames +
"` for field `" + GetQualifiedFieldName() +
1031 "` cannot be matched."));
1036 fReadCallbacks.push_back(func);
1038 return fReadCallbacks.size() - 1;
1043 fReadCallbacks.erase(fReadCallbacks.begin() + idx);
1044 fIsSimple = (fTraits & kTraitMappable) && fReadCallbacks.empty();
1049 if ((options.
GetCompression() == 0) && HasDefaultColumnRepresentative()) {
1051 for (
auto &colType : rep) {
1063 SetColumnRepresentative(rep);
1068 for (
auto &colType : rep) {
1075 SetColumnRepresentative(rep);
1078 if (fTypeAlias ==
"Double32_t")
1085 throw RException(
R__FAIL(
"invalid attempt to connect zero field to page sink"));
1086 if (fState != EState::kUnconnected)
1087 throw RException(
R__FAIL(
"invalid attempt to connect an already connected field to a page sink"));
1091 GenerateColumnsImpl();
1092 if (!fColumns.empty())
1093 fPrincipalColumn = fColumns[0].get();
1094 for (
auto &column : fColumns) {
1095 auto firstElementIndex = (column.get() == fPrincipalColumn) ? EntryToColumnElementIndex(firstEntry) : 0;
1096 column->ConnectPageSink(fOnDiskId, pageSink, firstElementIndex);
1099 if (HasExtraTypeInfo()) {
1104 fState = EState::kConnectedToSink;
1110 throw RException(
R__FAIL(
"invalid attempt to connect zero field to page source"));
1111 if (fState != EState::kUnconnected)
1112 throw RException(
R__FAIL(
"invalid attempt to connect an already connected field to a page source"));
1114 if (fColumnRepresentative)
1115 throw RException(
R__FAIL(
"fixed column representative only valid when connecting to a page sink"));
1116 if (!fDescription.empty())
1117 throw RException(
R__FAIL(
"setting description only valid when connecting to a page sink"));
1119 for (
auto &
f : fSubFields) {
1123 f->ConnectPageSource(pageSource);
1129 GenerateColumnsImpl(desc);
1131 onDiskColumnTypes.reserve(fColumns.size());
1132 for (
const auto &
c : fColumns) {
1133 onDiskColumnTypes.emplace_back(
c->GetModel().GetType());
1135 for (
const auto &t : GetColumnRepresentations().GetDeserializationTypes()) {
1136 if (t == onDiskColumnTypes)
1137 fColumnRepresentative = &t;
1143 if (!fColumns.empty())
1144 fPrincipalColumn = fColumns[0].get();
1145 for (
auto& column : fColumns)
1146 column->ConnectPageSource(fOnDiskId, pageSource);
1147 OnConnectPageSource();
1149 fState = EState::kConnectedToSource;
1159std::unique_ptr<ROOT::Experimental::RFieldBase>
1162 auto result = std::make_unique<RFieldZero>();
1163 for (
auto &
f : fSubFields)
1164 result->Attach(
f->Clone(
f->GetFieldName()));
1180 static RColumnRepresentations representations(
1183 return representations;
1188 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
1193 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1194 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(RColumnModel(onDiskTypes[0]), 0));
1199 visitor.VisitClusterSizeField(*
this);
1210 return representations;
1215 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1216 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(
RColumnModel(onDiskTypes[0]), 0));
1242 return representations;
1247 fColumns.emplace_back(Internal::RColumn::Create<char>(
RColumnModel(GetColumnRepresentative()[0]), 0));
1252 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1253 fColumns.emplace_back(Internal::RColumn::Create<char>(
RColumnModel(onDiskTypes[0]), 0));
1267 return representations;
1272 fColumns.emplace_back(Internal::RColumn::Create<char>(RColumnModel(GetColumnRepresentative()[0]), 0));
1277 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1278 fColumns.emplace_back(Internal::RColumn::Create<char>(RColumnModel(onDiskTypes[0]), 0));
1283 visitor.VisitByteField(*
this);
1292 return representations;
1297 fColumns.emplace_back(Internal::RColumn::Create<std::int8_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
1302 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1303 fColumns.emplace_back(Internal::RColumn::Create<std::int8_t>(RColumnModel(onDiskTypes[0]), 0));
1308 visitor.VisitInt8Field(*
this);
1317 return representations;
1322 fColumns.emplace_back(Internal::RColumn::Create<std::uint8_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
1327 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1328 fColumns.emplace_back(Internal::RColumn::Create<std::uint8_t>(RColumnModel(onDiskTypes[0]), 0));
1333 visitor.VisitUInt8Field(*
this);
1342 return representations;
1347 fColumns.emplace_back(Internal::RColumn::Create<bool>(
RColumnModel(GetColumnRepresentative()[0]), 0));
1352 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1353 fColumns.emplace_back(Internal::RColumn::Create<bool>(
RColumnModel(onDiskTypes[0]), 0));
1368 return representations;
1373 fColumns.emplace_back(Internal::RColumn::Create<float>(
RColumnModel(GetColumnRepresentative()[0]), 0));
1378 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1379 fColumns.emplace_back(Internal::RColumn::Create<float>(
RColumnModel(onDiskTypes[0]), 0));
1403 return representations;
1408 fColumns.emplace_back(Internal::RColumn::Create<double>(
RColumnModel(GetColumnRepresentative()[0]), 0));
1413 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1414 fColumns.emplace_back(Internal::RColumn::Create<double>(
RColumnModel(onDiskTypes[0]), 0));
1424 fTypeAlias =
"Double32_t";
1434 return representations;
1439 fColumns.emplace_back(Internal::RColumn::Create<std::int16_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
1444 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1445 fColumns.emplace_back(Internal::RColumn::Create<std::int16_t>(RColumnModel(onDiskTypes[0]), 0));
1450 visitor.VisitInt16Field(*
this);
1460 return representations;
1465 fColumns.emplace_back(Internal::RColumn::Create<std::uint16_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
1470 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1471 fColumns.emplace_back(Internal::RColumn::Create<std::uint16_t>(RColumnModel(onDiskTypes[0]), 0));
1476 visitor.VisitUInt16Field(*
this);
1486 return representations;
1491 fColumns.emplace_back(Internal::RColumn::Create<std::int32_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
1496 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1497 fColumns.emplace_back(Internal::RColumn::Create<std::int32_t>(RColumnModel(onDiskTypes[0]), 0));
1502 visitor.VisitInt32Field(*
this);
1512 return representations;
1517 fColumns.emplace_back(Internal::RColumn::Create<std::uint32_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
1522 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1523 fColumns.emplace_back(Internal::RColumn::Create<std::uint32_t>(RColumnModel(onDiskTypes[0]), 0));
1528 visitor.VisitUInt32Field(*
this);
1538 return representations;
1543 fColumns.emplace_back(Internal::RColumn::Create<std::uint64_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
1548 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1549 fColumns.emplace_back(Internal::RColumn::Create<std::uint64_t>(RColumnModel(onDiskTypes[0]), 0));
1554 visitor.VisitUInt64Field(*
this);
1569 return representations;
1574 fColumns.emplace_back(Internal::RColumn::Create<std::int64_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
1579 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1580 fColumns.emplace_back(Internal::RColumn::Create<std::int64_t>(RColumnModel(onDiskTypes[0]), 0));
1585 visitor.VisitInt64Field(*
this);
1598 return representations;
1603 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
1604 fColumns.emplace_back(Internal::RColumn::Create<char>(RColumnModel(GetColumnRepresentative()[1]), 1));
1609 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1610 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(RColumnModel(onDiskTypes[0]), 0));
1611 fColumns.emplace_back(Internal::RColumn::Create<char>(RColumnModel(onDiskTypes[1]), 1));
1616 auto typedValue =
static_cast<const std::string *
>(from);
1617 auto length = typedValue->length();
1618 fColumns[1]->AppendV(typedValue->data(),
length);
1620 fColumns[0]->Append(&fIndex);
1621 return length + fColumns[0]->GetElement()->GetPackedSize();
1626 auto typedValue =
static_cast<std::string *
>(to);
1627 RClusterIndex collectionStart;
1629 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nChars);
1631 typedValue->clear();
1633 typedValue->resize(nChars);
1634 fColumns[1]->ReadV(collectionStart, nChars,
const_cast<char *
>(typedValue->data()));
1640 visitor.VisitStringField(*
this);
1655 throw RException(
R__FAIL(
"RField: no I/O support for type " + std::string(className)));
1661 if (className ==
"TObject") {
1666 R__FAIL(std::string(className) +
" has an associated collection proxy; use RProxiedCollectionField instead"));
1671 GetRNTupleUnsplitSetting(
fClass) != ERNTupleUnsplitSetting::kForceSplit) {
1674 if (GetRNTupleUnsplitSetting(
fClass) == ERNTupleUnsplitSetting::kForceUnsplit) {
1676 R__FAIL(std::string(className) +
" has unsplit mode enforced, not supported as native RNTuple class"));
1686 if (baseClass->GetDelta() < 0) {
1687 throw RException(
R__FAIL(std::string(
"virtual inheritance is not supported: ") + std::string(className) +
1688 " virtually inherits from " + baseClass->GetName()));
1690 TClass *
c = baseClass->GetClassPointer();
1693 fTraits &= subField->GetTraits();
1694 Attach(std::move(subField),
1703 if (!dataMember->IsPersistent()) {
1709 std::string typeName{GetNormalizedTypeName(dataMember->GetTrueTypeName())};
1710 std::string typeAlias{GetNormalizedTypeName(dataMember->GetFullTypeName())};
1713 if (dataMember->Property() &
kIsArray) {
1714 for (
int dim = 0,
n = dataMember->GetArrayDim(); dim <
n; ++dim)
1715 typeName +=
"[" + std::to_string(dataMember->GetMaxIndex(dim)) +
"]";
1718 std::unique_ptr<RFieldBase> subField;
1721 fTraits &= subField->GetTraits();
1722 Attach(std::move(subField),
1729 fMaxAlignment = std::max(fMaxAlignment,
child->GetAlignment());
1730 fSubFieldsInfo.push_back(info);
1737 for (
const auto rule : rules) {
1742 auto func = rule->GetReadFunctionPointer();
1744 fReadCallbacks.emplace_back([func, classp](
void *
target) {
1748 func(
static_cast<char *
>(
target), &oldObj);
1749 oldObj.fClass =
nullptr;
1754std::unique_ptr<ROOT::Experimental::RFieldBase>
1758 SyncFieldIDs(*
this, *
result);
1764 std::size_t nbytes = 0;
1765 for (
unsigned i = 0; i < fSubFields.size(); i++) {
1766 nbytes += CallAppendOn(*fSubFields[i],
static_cast<const unsigned char *
>(from) + fSubFieldsInfo[i].fOffset);
1773 for (
unsigned i = 0; i < fSubFields.size(); i++) {
1774 CallReadOn(*fSubFields[i], globalIndex,
static_cast<unsigned char *
>(to) + fSubFieldsInfo[i].fOffset);
1780 for (
unsigned i = 0; i < fSubFields.size(); i++) {
1781 CallReadOn(*fSubFields[i], clusterIndex,
static_cast<unsigned char *
>(to) + fSubFieldsInfo[i].fOffset);
1789 const auto ruleset =
fClass->GetSchemaRules();
1793 if (rule->GetTarget() ==
nullptr)
1796 const auto dataMember = klass->GetDataMember(
target->GetString());
1797 if (!dataMember || dataMember->IsPersistent()) {
1799 << dataMember->GetName();
1806 auto rules = ruleset->FindRules(
fClass->GetName(),
static_cast<Int_t>(GetOnDiskTypeVersion()));
1807 rules.erase(std::remove_if(rules.begin(), rules.end(), referencesNonTransientMembers), rules.end());
1808 AddReadCallbacksFromIORules(rules,
fClass);
1818 fClass->Destructor(objPtr,
true );
1819 RDeleter::operator()(objPtr, dtorOnly);
1822std::vector<ROOT::Experimental::RFieldBase::RValue>
1825 std::vector<RValue>
result;
1826 auto basePtr =
value.GetPtr<
unsigned char>().get();
1827 result.reserve(fSubFields.size());
1828 for (
unsigned i = 0; i < fSubFields.size(); i++) {
1830 fSubFields[i]->BindValue(std::shared_ptr<void>(
value.GetPtr<
void>(), basePtr + fSubFieldsInfo[i].fOffset)));
1838 return fClass->GetClassSize();
1843 return fClass->GetClassVersion();
1856 return dataMember->GetOffset();
1870std::unique_ptr<ROOT::Experimental::RFieldBase>
1873 auto result = std::make_unique<RField<TObject>>(newName);
1874 SyncFieldIDs(*
this, *
result);
1882 auto *obj =
static_cast<const TObject *
>(from);
1887 std::size_t nbytes = 0;
1888 nbytes += CallAppendOn(*fSubFields[0],
reinterpret_cast<const unsigned char *
>(from) + GetOffsetUniqueID());
1890 UInt_t bits = *
reinterpret_cast<const UInt_t *
>(
reinterpret_cast<const unsigned char *
>(from) + GetOffsetBits());
1892 nbytes += CallAppendOn(*fSubFields[1], &bits);
1901 auto *obj =
static_cast<TObject *
>(to);
1906 CallReadOn(*fSubFields[0], globalIndex,
static_cast<unsigned char *
>(to) + GetOffsetUniqueID());
1910 CallReadOn(*fSubFields[1], globalIndex, &bits);
1912 *
reinterpret_cast<UInt_t *
>(
reinterpret_cast<unsigned char *
>(to) + GetOffsetBits()) = bits;
1917 if (GetTypeVersion() != 1) {
1918 throw RException(
R__FAIL(
"unsupported on-disk version of TObject: " + std::to_string(GetTypeVersion())));
1932std::vector<ROOT::Experimental::RFieldBase::RValue>
1935 std::vector<RValue>
result;
1936 auto basePtr =
value.GetPtr<
unsigned char>().get();
1938 fSubFields[0]->BindValue(std::shared_ptr<void>(
value.GetPtr<
void>(), basePtr + GetOffsetUniqueID())));
1940 fSubFields[1]->BindValue(std::shared_ptr<void>(
value.GetPtr<
void>(), basePtr + GetOffsetBits())));
1962 std::string_view typeAlias)
1974 throw RException(
R__FAIL(
"RUnsplitField: no I/O support for type " + std::string(className)));
1983std::unique_ptr<ROOT::Experimental::RFieldBase>
1986 return std::unique_ptr<RUnsplitField>(
new RUnsplitField(newName, GetTypeName(), GetTypeAlias()));
1993 fClass->Streamer(
const_cast<void *
>(from), buffer);
1995 auto nbytes = buffer.Length();
1996 fColumns[1]->AppendV(buffer.Buffer(), buffer.Length());
1998 fColumns[0]->Append(&fIndex);
1999 return nbytes + fColumns[0]->GetElement()->GetPackedSize();
2006 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nbytes);
2009 fColumns[1]->ReadV(collectionStart, nbytes, buffer.
Buffer());
2010 fClass->Streamer(to, buffer);
2021 return representations;
2026 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(
RColumnModel(GetColumnRepresentative()[0]), 0));
2027 fColumns.emplace_back(Internal::RColumn::Create<std::byte>(
RColumnModel(GetColumnRepresentative()[1]), 1));
2032 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
2033 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(
RColumnModel(onDiskTypes[0]), 0));
2034 fColumns.emplace_back(Internal::RColumn::Create<std::byte>(
RColumnModel(onDiskTypes[1]), 1));
2044 fClass->Destructor(objPtr,
true );
2045 RDeleter::operator()(objPtr, dtorOnly);
2061 return std::min(
alignof(std::max_align_t), GetValueSize());
2066 return fClass->GetClassSize();
2071 return fClass->GetClassVersion();
2082 :
REnumField(fieldName, enumName,
TEnum::GetEnum(std::string(enumName).c_str()))
2089 if (enump ==
nullptr) {
2090 throw RException(
R__FAIL(
"RField: no I/O support for enum type " + std::string(enumName)));
2108 default:
throw RException(
R__FAIL(
"Unsupported underlying integral type for enum type " + std::string(enumName)));
2115 std::unique_ptr<RFieldBase> intField)
2118 Attach(std::move(intField));
2122std::unique_ptr<ROOT::Experimental::RFieldBase>
2125 auto newIntField = fSubFields[0]->Clone(fSubFields[0]->GetFieldName());
2126 return std::unique_ptr<REnumField>(
new REnumField(newName, GetTypeName(), std::move(newIntField)));
2129std::vector<ROOT::Experimental::RFieldBase::RValue>
2132 std::vector<RValue>
result;
2133 result.emplace_back(fSubFields[0]->BindValue(
value.GetPtr<
void>()));
2153 (ifuncs.
fNext !=
nullptr));
2158 std::string_view typeName,
TClass *classp)
2161 if (classp ==
nullptr)
2162 throw RException(
R__FAIL(
"RField: no I/O support for collection proxy type " + std::string(typeName)));
2164 throw RException(
R__FAIL(std::string(typeName) +
" has no associated collection proxy"));
2169 if (
fProxy->HasPointers())
2170 throw RException(
R__FAIL(
"collection proxies whose value type is a pointer are not supported"));
2171 if (!
fProxy->GetCollectionClass()->HasDictionary()) {
2173 GetNormalizedTypeName(
fProxy->GetCollectionClass()->GetName())));
2181 std::string_view typeName,
2182 std::unique_ptr<RFieldBase> itemField)
2186 Attach(std::move(itemField));
2190 std::string_view typeName)
2195 throw RException(
R__FAIL(
"custom associative collection proxies not supported"));
2197 std::unique_ptr<ROOT::Experimental::RFieldBase> itemField;
2199 if (
auto valueClass =
fProxy->GetValueClass()) {
2203 switch (
fProxy->GetType()) {
2205 case EDataType::kUChar_t: itemField = std::make_unique<RField<std::uint8_t>>(
"_0");
break;
2206 case EDataType::kShort_t: itemField = std::make_unique<RField<std::int16_t>>(
"_0");
break;
2208 case EDataType::kInt_t: itemField = std::make_unique<RField<std::int32_t>>(
"_0");
break;
2209 case EDataType::kUInt_t: itemField = std::make_unique<RField<std::uint32_t>>(
"_0");
break;
2212 itemField = std::make_unique<RField<std::int64_t>>(
"_0");
2216 itemField = std::make_unique<RField<std::uint64_t>>(
"_0");
2227 Attach(std::move(itemField));
2230std::unique_ptr<ROOT::Experimental::RFieldBase>
2233 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetFieldName());
2234 return std::unique_ptr<RProxiedCollectionField>(
2240 std::size_t nbytes = 0;
2244 (fCollectionType ==
kSTLvector ? fItemSize : 0U)}) {
2245 nbytes += CallAppendOn(*fSubFields[0], ptr);
2250 fColumns[0]->Append(&fNWritten);
2251 return nbytes + fColumns[0]->GetElement()->GetPackedSize();
2258 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
2266 (fCollectionType ==
kSTLvector || obj != to ? fItemSize : 0U)}) {
2267 CallReadOn(*fSubFields[0], collectionStart + (i++), elementPtr);
2270 fProxy->Commit(obj);
2279 return representations;
2284 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(
RColumnModel(GetColumnRepresentative()[0]), 0));
2289 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
2290 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(
RColumnModel(onDiskTypes[0]), 0));
2298std::unique_ptr<ROOT::Experimental::RFieldBase::RDeleter>
2302 std::size_t itemSize = fCollectionType ==
kSTLvector ? fItemSize : 0U;
2303 return std::make_unique<RProxiedCollectionDeleter>(fProxy, GetDeleterOf(*fSubFields[0]), itemSize);
2305 return std::make_unique<RProxiedCollectionDeleter>(fProxy);
2313 fItemDeleter->operator()(ptr,
true );
2316 fProxy->Destructor(objPtr,
true );
2317 RDeleter::operator()(objPtr, dtorOnly);
2320std::vector<ROOT::Experimental::RFieldBase::RValue>
2323 std::vector<RValue>
result;
2324 auto valueRawPtr =
value.GetPtr<
void>().get();
2327 (fCollectionType ==
kSTLvector ? fItemSize : 0U)}) {
2328 result.emplace_back(fSubFields[0]->BindValue(std::shared_ptr<void>(
value.GetPtr<
void>(), ptr)));
2341 std::vector<std::unique_ptr<RFieldBase>> &&itemFields,
2342 const std::vector<std::size_t> &offsets, std::string_view typeName)
2347 for (
auto &item : itemFields) {
2356 std::vector<std::unique_ptr<RFieldBase>> &&itemFields)
2360 fOffsets.reserve(itemFields.size());
2361 for (
auto &item : itemFields) {
2365 fSize += item->GetValueSize();
2375 std::vector<std::unique_ptr<RFieldBase>> &itemFields)
2382 if (itemAlignment > 1) {
2383 auto remainder = baseOffset % itemAlignment;
2385 return itemAlignment - remainder;
2390std::unique_ptr<ROOT::Experimental::RFieldBase>
2393 std::vector<std::unique_ptr<RFieldBase>> cloneItems;
2394 cloneItems.reserve(fSubFields.size());
2395 for (
auto &item : fSubFields)
2396 cloneItems.emplace_back(item->Clone(item->GetFieldName()));
2397 return std::unique_ptr<RRecordField>(
new RRecordField(newName, std::move(cloneItems), fOffsets, GetTypeName()));
2402 std::size_t nbytes = 0;
2403 for (
unsigned i = 0; i < fSubFields.size(); ++i) {
2404 nbytes += CallAppendOn(*fSubFields[i],
static_cast<const unsigned char *
>(from) + fOffsets[i]);
2411 for (
unsigned i = 0; i < fSubFields.size(); ++i) {
2412 CallReadOn(*fSubFields[i], globalIndex,
static_cast<unsigned char *
>(to) + fOffsets[i]);
2418 for (
unsigned i = 0; i < fSubFields.size(); ++i) {
2419 CallReadOn(*fSubFields[i], clusterIndex,
static_cast<unsigned char *
>(to) + fOffsets[i]);
2425 for (
unsigned i = 0; i < fSubFields.size(); ++i) {
2426 CallConstructValueOn(*fSubFields[i],
static_cast<unsigned char *
>(where) + fOffsets[i]);
2432 for (
unsigned i = 0; i < fItemDeleters.size(); ++i) {
2433 fItemDeleters[i]->operator()(
reinterpret_cast<unsigned char *
>(objPtr) + fOffsets[i],
true );
2435 RDeleter::operator()(objPtr, dtorOnly);
2440 std::vector<std::unique_ptr<RDeleter>> itemDeleters;
2441 itemDeleters.reserve(fOffsets.size());
2442 for (
const auto &
f : fSubFields) {
2443 itemDeleters.emplace_back(GetDeleterOf(*
f));
2445 return std::make_unique<RRecordDeleter>(itemDeleters, fOffsets);
2448std::vector<ROOT::Experimental::RFieldBase::RValue>
2451 auto basePtr =
value.GetPtr<
unsigned char>().get();
2452 std::vector<RValue>
result;
2453 result.reserve(fSubFields.size());
2454 for (
unsigned i = 0; i < fSubFields.size(); ++i) {
2455 result.emplace_back(fSubFields[i]->BindValue(std::shared_ptr<void>(
value.GetPtr<
void>(), basePtr + fOffsets[i])));
2469 :
ROOT::Experimental::
RFieldBase(fieldName,
"std::vector<" + itemField->GetTypeName() +
">",
2471 fItemSize(itemField->GetValueSize()),
2476 Attach(std::move(itemField));
2479std::unique_ptr<ROOT::Experimental::RFieldBase>
2482 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetFieldName());
2483 return std::make_unique<RVectorField>(newName, std::move(newItemField));
2488 auto typedValue =
static_cast<const std::vector<char> *
>(from);
2491 if ((typedValue->size() % fItemSize) != 0) {
2492 const auto &subfield0 = *fSubFields[0];
2493 std::string errMsg{
"(typedValue->size() % fItemSize) != 0 in RVectorField::AppendImpl\n"};
2494 errMsg +=
"Field name: " + GetQualifiedFieldName() +
"\n";
2495 errMsg +=
"Type name: " + GetTypeName() +
"\n";
2496 errMsg +=
"Type alias: " + GetTypeAlias() +
"\n";
2497 errMsg +=
"fItemSize: " + std::to_string(fItemSize);
2498 errMsg +=
" typedValue->size(): " + std::to_string(typedValue->size());
2499 errMsg +=
" fNWritten: " + std::to_string(fNWritten) +
"\n";
2500 errMsg +=
"Item type: " + subfield0.GetTypeName() +
"\n";
2501 errMsg +=
"Item alias: " + subfield0.GetTypeAlias() +
"\n";
2502 errMsg +=
"Item field traits: " + std::to_string(subfield0.GetTraits()) +
"\n";
2503 errMsg +=
"Item field size: " + std::to_string(subfield0.GetValueSize()) +
"\n";
2504 errMsg +=
"Item field alignment: " + std::to_string(subfield0.GetAlignment()) +
"\n";
2505 errMsg +=
"Item field type: " + std::string(
typeid(subfield0).
name());
2507 errMsg +=
"*from type: " + std::string(
typeid(*typedValue).name());
2511 std::size_t nbytes = 0;
2512 auto count = typedValue->size() / fItemSize;
2514 if (fSubFields[0]->IsSimple() && count) {
2515 GetPrincipalColumnOf(*fSubFields[0])->AppendV(typedValue->data(), count);
2516 nbytes += count * GetPrincipalColumnOf(*fSubFields[0])->GetElement()->GetPackedSize();
2518 for (
unsigned i = 0; i < count; ++i) {
2519 nbytes += CallAppendOn(*fSubFields[0], typedValue->data() + (i * fItemSize));
2524 fColumns[0]->Append(&fNWritten);
2525 return nbytes + fColumns[0]->GetElement()->GetPackedSize();
2530 auto typedValue =
static_cast<std::vector<char> *
>(to);
2534 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
2536 if (fSubFields[0]->IsSimple()) {
2537 typedValue->resize(nItems * fItemSize);
2539 GetPrincipalColumnOf(*fSubFields[0])->ReadV(collectionStart, nItems, typedValue->data());
2544 const auto oldNItems = typedValue->size() / fItemSize;
2545 const bool canRealloc = oldNItems < nItems;
2546 bool allDeallocated =
false;
2548 allDeallocated = canRealloc;
2549 for (std::size_t i = allDeallocated ? 0 : nItems; i < oldNItems; ++i) {
2550 fItemDeleter->operator()(typedValue->data() + (i * fItemSize),
true );
2553 typedValue->resize(nItems * fItemSize);
2554 if (!(fSubFields[0]->GetTraits() & kTraitTriviallyConstructible)) {
2555 for (std::size_t i = allDeallocated ? 0 : oldNItems; i < nItems; ++i) {
2556 CallConstructValueOn(*fSubFields[0], typedValue->data() + (i * fItemSize));
2560 for (std::size_t i = 0; i < nItems; ++i) {
2561 CallReadOn(*fSubFields[0], collectionStart + i, typedValue->data() + (i * fItemSize));
2571 return representations;
2576 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(
RColumnModel(GetColumnRepresentative()[0]), 0));
2581 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
2582 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(
RColumnModel(onDiskTypes[0]), 0));
2587 auto vecPtr =
static_cast<std::vector<char> *
>(objPtr);
2589 R__ASSERT((vecPtr->size() % fItemSize) == 0);
2590 auto nItems = vecPtr->size() / fItemSize;
2591 for (std::size_t i = 0; i < nItems; ++i) {
2592 fItemDeleter->operator()(vecPtr->data() + (i * fItemSize),
true );
2595 std::destroy_at(vecPtr);
2596 RDeleter::operator()(objPtr, dtorOnly);
2602 return std::make_unique<RVectorDeleter>(fItemSize, GetDeleterOf(*fSubFields[0]));
2603 return std::make_unique<RVectorDeleter>();
2606std::vector<ROOT::Experimental::RFieldBase::RValue>
2609 auto vec =
value.GetPtr<std::vector<char>>();
2611 auto nItems =
vec->size() / fItemSize;
2612 std::vector<RValue>
result;
2614 for (
unsigned i = 0; i < nItems; ++i) {
2616 fSubFields[0]->BindValue(std::shared_ptr<void>(
value.GetPtr<
void>(),
vec->data() + (i * fItemSize))));
2630 :
ROOT::Experimental::
RFieldBase(fieldName,
"ROOT::VecOps::RVec<" + itemField->GetTypeName() +
">",
2632 fItemSize(itemField->GetValueSize()),
2637 Attach(std::move(itemField));
2641std::unique_ptr<ROOT::Experimental::RFieldBase>
2644 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetFieldName());
2645 return std::make_unique<RRVecField>(newName, std::move(newItemField));
2650 auto [beginPtr, sizePtr,
_] = GetRVecDataMembers(from);
2652 std::size_t nbytes = 0;
2653 if (fSubFields[0]->IsSimple() && *sizePtr) {
2654 GetPrincipalColumnOf(*fSubFields[0])->AppendV(*beginPtr, *sizePtr);
2655 nbytes += *sizePtr * GetPrincipalColumnOf(*fSubFields[0])->GetElement()->GetPackedSize();
2657 auto begin =
reinterpret_cast<const char *
>(*beginPtr);
2658 for (std::int32_t i = 0; i < *sizePtr; ++i) {
2659 nbytes += CallAppendOn(*fSubFields[0], begin + i * fItemSize);
2663 fNWritten += *sizePtr;
2664 fColumns[0]->Append(&fNWritten);
2665 return nbytes + fColumns[0]->GetElement()->GetPackedSize();
2673 auto [beginPtr, sizePtr, capacityPtr] = GetRVecDataMembers(to);
2678 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
2679 char *begin =
reinterpret_cast<char *
>(*beginPtr);
2680 const std::size_t oldSize = *sizePtr;
2684 const bool owns = (*capacityPtr != -1);
2685 const bool needsConstruct = !(fSubFields[0]->GetTraits() & kTraitTriviallyConstructible);
2686 const bool needsDestruct = owns && fItemDeleter;
2689 if (needsDestruct) {
2690 for (std::size_t i = nItems; i < oldSize; ++i) {
2691 fItemDeleter->operator()(begin + (i * fItemSize),
true );
2696 if (std::int32_t(nItems) > *capacityPtr) {
2699 if (needsDestruct) {
2700 for (std::size_t i = 0u; i < oldSize; ++i) {
2701 fItemDeleter->operator()(begin + (i * fItemSize),
true );
2712 *beginPtr =
malloc(nItems * fItemSize);
2714 begin =
reinterpret_cast<char *
>(*beginPtr);
2715 *capacityPtr = nItems;
2718 if (needsConstruct) {
2719 for (std::size_t i = 0u; i < oldSize; ++i)
2720 CallConstructValueOn(*fSubFields[0], begin + (i * fItemSize));
2726 if (needsConstruct) {
2727 for (std::size_t i = oldSize; i < nItems; ++i)
2728 CallConstructValueOn(*fSubFields[0], begin + (i * fItemSize));
2731 if (fSubFields[0]->IsSimple() && nItems) {
2732 GetPrincipalColumnOf(*fSubFields[0])->ReadV(collectionStart, nItems, begin);
2737 for (std::size_t i = 0; i < nItems; ++i) {
2738 CallReadOn(*fSubFields[0], collectionStart + i, begin + (i * fItemSize));
2744 if (!fSubFields[0]->IsSimple())
2750 bulkSpec.
fAuxData->resize(
sizeof(std::size_t));
2751 *
reinterpret_cast<std::size_t *
>(bulkSpec.
fAuxData->data()) = fSubFields[0]->GetValueSize();
2753 const auto itemValueSize = *
reinterpret_cast<std::size_t *
>(bulkSpec.
fAuxData->data());
2754 unsigned char *itemValueArray = bulkSpec.
fAuxData->data() +
sizeof(std::size_t);
2755 auto [beginPtr, sizePtr, capacityPtr] = GetRVecDataMembers(bulkSpec.
fValues);
2761 this->GetCollectionInfo(bulkSpec.
fFirstIndex, &firstItemIndex, &collectionSize);
2762 *beginPtr = itemValueArray;
2763 *sizePtr = collectionSize;
2769 auto lastOffset = firstItemIndex.
GetIndex() + collectionSize;
2771 std::size_t nValues = 1;
2772 std::size_t nItems = collectionSize;
2773 while (nRemainingValues > 0) {
2776 const std::size_t nBatch = std::min(nRemainingValues, nElementsUntilPageEnd);
2777 for (std::size_t i = 0; i < nBatch; ++i) {
2778 const auto size = offsets[i] - lastOffset;
2779 std::tie(beginPtr, sizePtr, capacityPtr) =
2780 GetRVecDataMembers(
reinterpret_cast<unsigned char *
>(bulkSpec.
fValues) + (nValues + i) *
fValueSize);
2781 *beginPtr = itemValueArray + nItems * itemValueSize;
2786 lastOffset = offsets[i];
2788 nRemainingValues -= nBatch;
2792 bulkSpec.
fAuxData->resize(
sizeof(std::size_t) + nItems * itemValueSize);
2794 const auto delta = itemValueArray - (bulkSpec.
fAuxData->data() +
sizeof(std::size_t));
2796 auto beginPtrAsUChar =
reinterpret_cast<unsigned char *
>(bulkSpec.
fValues);
2797 for (std::size_t i = 0; i < bulkSpec.
fCount; ++i) {
2798 *
reinterpret_cast<unsigned char **
>(beginPtrAsUChar) -= delta;
2803 GetPrincipalColumnOf(*fSubFields[0])->ReadV(firstItemIndex, nItems, itemValueArray - delta);
2804 return RBulkSpec::kAllSet;
2813 return representations;
2818 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(
RColumnModel(GetColumnRepresentative()[0]), 0));
2823 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
2824 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(
RColumnModel(onDiskTypes[0]), 0));
2831 void **beginPtr =
new (where)(
void *)(
nullptr);
2832 std::int32_t *sizePtr =
new (
reinterpret_cast<void *
>(beginPtr + 1)) std::int32_t(0);
2833 new (sizePtr + 1) std::int32_t(-1);
2838 auto [beginPtr, sizePtr, capacityPtr] = GetRVecDataMembers(objPtr);
2840 char *begin =
reinterpret_cast<char *
>(*beginPtr);
2842 for (std::int32_t i = 0; i < *sizePtr; ++i) {
2843 fItemDeleter->operator()(begin + i * fItemSize,
true );
2847 DestroyRVecWithChecks(fItemAlignment, beginPtr, begin, capacityPtr);
2848 RDeleter::operator()(objPtr, dtorOnly);
2854 return std::make_unique<RRVecDeleter>(fSubFields[0]->GetAlignment(), fItemSize, GetDeleterOf(*fSubFields[0]));
2855 return std::make_unique<RRVecDeleter>(fSubFields[0]->GetAlignment());
2858std::vector<ROOT::Experimental::RFieldBase::RValue>
2861 auto [beginPtr, sizePtr,
_] = GetRVecDataMembers(
value.GetPtr<
void>().get());
2863 std::vector<RValue>
result;
2864 char *begin =
reinterpret_cast<char *
>(*beginPtr);
2865 result.reserve(*sizePtr);
2866 for (std::int32_t i = 0; i < *sizePtr; ++i) {
2867 result.emplace_back(fSubFields[0]->BindValue(std::shared_ptr<void>(
value.GetPtr<
void>(), begin + i * fItemSize)));
2879 return EvalRVecAlignment(fSubFields[0]->GetAlignment());
2897 auto typedValue =
static_cast<const std::vector<bool> *
>(from);
2898 auto count = typedValue->size();
2899 for (
unsigned i = 0; i < count; ++i) {
2900 bool bval = (*typedValue)[i];
2901 CallAppendOn(*fSubFields[0], &bval);
2904 fColumns[0]->Append(&fNWritten);
2905 return count + fColumns[0]->GetElement()->GetPackedSize();
2910 auto typedValue =
static_cast<std::vector<bool> *
>(to);
2913 RClusterIndex collectionStart;
2914 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
2916 typedValue->resize(nItems);
2917 for (
unsigned i = 0; i < nItems; ++i) {
2919 CallReadOn(*fSubFields[0], collectionStart + i, &bval);
2920 (*typedValue)[i] = bval;
2927 static RColumnRepresentations representations(
2930 return representations;
2935 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
2940 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
2941 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(RColumnModel(onDiskTypes[0]), 0));
2944std::vector<ROOT::Experimental::RFieldBase::RValue>
2947 const auto &typedValue =
value.GetRef<std::vector<bool>>();
2948 auto count = typedValue.size();
2949 std::vector<RValue>
result;
2951 for (
unsigned i = 0; i < count; ++i) {
2953 result.emplace_back(fSubFields[0]->BindValue(std::shared_ptr<bool>(
new bool(
true))));
2955 result.emplace_back(fSubFields[0]->BindValue(std::shared_ptr<bool>(
new bool(
false))));
2962 visitor.VisitVectorBoolField(*
this);
2969 std::size_t arrayLength)
2971 "std::array<" + itemField->GetTypeName() +
"," + std::to_string(arrayLength) +
">",
2973 fItemSize(itemField->GetValueSize()),
2974 fArrayLength(arrayLength)
2976 fTraits |= itemField->GetTraits() & ~kTraitMappable;
2977 Attach(std::move(itemField));
2980std::unique_ptr<ROOT::Experimental::RFieldBase>
2983 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetFieldName());
2984 return std::make_unique<RArrayField>(newName, std::move(newItemField), fArrayLength);
2989 std::size_t nbytes = 0;
2990 auto arrayPtr =
static_cast<const unsigned char *
>(from);
2991 for (
unsigned i = 0; i < fArrayLength; ++i) {
2992 nbytes += CallAppendOn(*fSubFields[0], arrayPtr + (i * fItemSize));
2999 auto arrayPtr =
static_cast<unsigned char *
>(to);
3000 for (
unsigned i = 0; i < fArrayLength; ++i) {
3001 CallReadOn(*fSubFields[0], globalIndex * fArrayLength + i, arrayPtr + (i * fItemSize));
3007 auto arrayPtr =
static_cast<unsigned char *
>(to);
3008 for (
unsigned i = 0; i < fArrayLength; ++i) {
3010 arrayPtr + (i * fItemSize));
3016 if (fSubFields[0]->GetTraits() & kTraitTriviallyConstructible)
3019 auto arrayPtr =
reinterpret_cast<unsigned char *
>(where);
3020 for (
unsigned i = 0; i < fArrayLength; ++i) {
3021 CallConstructValueOn(*fSubFields[0], arrayPtr + (i * fItemSize));
3028 for (
unsigned i = 0; i < fArrayLength; ++i) {
3029 fItemDeleter->operator()(
reinterpret_cast<unsigned char *
>(objPtr) + i * fItemSize,
true );
3032 RDeleter::operator()(objPtr, dtorOnly);
3037 if (!(fSubFields[0]->GetTraits() & kTraitTriviallyDestructible))
3038 return std::make_unique<RArrayDeleter>(fItemSize, fArrayLength, GetDeleterOf(*fSubFields[0]));
3039 return std::make_unique<RDeleter>();
3042std::vector<ROOT::Experimental::RFieldBase::RValue>
3045 auto arrayPtr =
value.GetPtr<
unsigned char>().get();
3046 std::vector<RValue>
result;
3047 result.reserve(fArrayLength);
3048 for (
unsigned i = 0; i < fArrayLength; ++i) {
3050 fSubFields[0]->BindValue(std::shared_ptr<void>(
value.GetPtr<
void>(), arrayPtr + (i * fItemSize))));
3064 std::unique_ptr<ROOT::Experimental::RFieldBase> itemField,
3065 std::size_t arrayLength)
3066 :
ROOT::Experimental::
RFieldBase(fieldName,
"ROOT::VecOps::RVec<" + itemField->GetTypeName() +
">",
3068 fItemSize(itemField->GetValueSize()),
3069 fArrayLength(arrayLength)
3071 Attach(std::move(itemField));
3077std::unique_ptr<ROOT::Experimental::RFieldBase>
3080 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetFieldName());
3081 return std::make_unique<RArrayAsRVecField>(newName, std::move(newItemField), fArrayLength);
3087 void **beginPtr =
new (where)(
void *)(
nullptr);
3088 std::int32_t *sizePtr =
new (
reinterpret_cast<void *
>(beginPtr + 1)) std::int32_t(0);
3089 std::int32_t *capacityPtr =
new (sizePtr + 1) std::int32_t(0);
3093 char *begin =
reinterpret_cast<char *
>(*beginPtr);
3096 if (*sizePtr == std::int32_t(fArrayLength))
3102 const bool owns = (*capacityPtr != -1);
3103 const bool needsConstruct = !(fSubFields[0]->GetTraits() & kTraitTriviallyConstructible);
3104 const bool needsDestruct = owns && fItemDeleter;
3108 if (needsDestruct) {
3109 for (std::int32_t i = 0; i < *sizePtr; ++i) {
3110 fItemDeleter->operator()(begin + (i * fItemSize),
true );
3120 *beginPtr =
malloc(fArrayLength * fItemSize);
3123 begin =
reinterpret_cast<char *
>(*beginPtr);
3125 *sizePtr = fArrayLength;
3126 *capacityPtr = fArrayLength;
3129 if (needsConstruct) {
3130 for (std::size_t i = 0; i < fArrayLength; ++i)
3131 CallConstructValueOn(*fSubFields[0], begin + (i * fItemSize));
3138 return std::make_unique<RRVecField::RRVecDeleter>(fSubFields[0]->GetAlignment(), fItemSize,
3139 GetDeleterOf(*fSubFields[0]));
3141 return std::make_unique<RRVecField::RRVecDeleter>(fSubFields[0]->GetAlignment());
3147 auto [beginPtr,
_, __] = GetRVecDataMembers(to);
3148 auto rvecBeginPtr =
reinterpret_cast<char *
>(*beginPtr);
3150 if (fSubFields[0]->IsSimple()) {
3151 GetPrincipalColumnOf(*fSubFields[0])->ReadV(globalIndex*fArrayLength, fArrayLength, rvecBeginPtr);
3156 for (std::size_t i = 0; i < fArrayLength; ++i) {
3157 CallReadOn(*fSubFields[0], globalIndex * fArrayLength + i, rvecBeginPtr + (i * fItemSize));
3163 auto [beginPtr,
_, __] = GetRVecDataMembers(to);
3164 auto rvecBeginPtr =
reinterpret_cast<char *
>(*beginPtr);
3167 const auto &clusterIndexIndex = clusterIndex.
GetIndex();
3169 if (fSubFields[0]->IsSimple()) {
3170 GetPrincipalColumnOf(*fSubFields[0])
3171 ->ReadV(
RClusterIndex(clusterId, clusterIndexIndex * fArrayLength), fArrayLength, rvecBeginPtr);
3176 for (std::size_t i = 0; i < fArrayLength; ++i) {
3177 CallReadOn(*fSubFields[0],
RClusterIndex(clusterId, clusterIndexIndex * fArrayLength + i),
3178 rvecBeginPtr + (i * fItemSize));
3184 return EvalRVecAlignment(fSubFields[0]->GetAlignment());
3187std::vector<ROOT::Experimental::RFieldBase::RValue>
3190 auto arrayPtr =
value.GetPtr<
unsigned char>().get();
3191 std::vector<ROOT::Experimental::RFieldBase::RValue>
result;
3192 result.reserve(fArrayLength);
3193 for (
unsigned i = 0; i < fArrayLength; ++i) {
3195 fSubFields[0]->BindValue(std::shared_ptr<void>(
value.GetPtr<
void>(), arrayPtr + (i * fItemSize))));
3222 return representations;
3227 fColumns.emplace_back(Internal::RColumn::Create<bool>(
RColumnModel(GetColumnRepresentative()[0]), 0));
3232 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
3233 fColumns.emplace_back(Internal::RColumn::Create<bool>(
RColumnModel(onDiskTypes[0]), 0));
3238 const auto *asULongArray =
static_cast<const Word_t *
>(from);
3241 for (std::size_t word = 0; word < (fN + kBitsPerWord - 1) / kBitsPerWord; ++word) {
3242 for (std::size_t
mask = 0; (
mask < kBitsPerWord) && (i < fN); ++
mask, ++i) {
3243 elementValue = (asULongArray[word] & (
static_cast<Word_t>(1) <<
mask)) != 0;
3244 fColumns[0]->Append(&elementValue);
3252 auto *asULongArray =
static_cast<Word_t *
>(to);
3254 for (std::size_t i = 0; i < fN; ++i) {
3255 fColumns[0]->Read(globalIndex * fN + i, &elementValue);
3257 Word_t bit =
static_cast<Word_t>(elementValue) << (i % kBitsPerWord);
3258 asULongArray[i / kBitsPerWord] = (asULongArray[i / kBitsPerWord] & ~mask) | bit;
3272 for (
size_t i = 0; i < itemFields.size(); ++i) {
3273 result += itemFields[i]->GetTypeName() +
",";
3281 const std::vector<RFieldBase *> &itemFields)
3282 :
ROOT::Experimental::
RFieldBase(fieldName,
"std::variant<" + GetTypeList(itemFields) +
">",
3288 auto nFields = itemFields.size();
3293 for (
unsigned int i = 0; i < nFields; ++i) {
3296 fTraits &= itemFields[i]->GetTraits();
3297 Attach(std::unique_ptr<RFieldBase>(itemFields[i]));
3308 const auto tagSize = GetVariantTagSize();
3309 const auto padding = tagSize - (
fMaxItemSize % tagSize);
3313std::unique_ptr<ROOT::Experimental::RFieldBase>
3316 auto nFields = fSubFields.size();
3317 std::vector<RFieldBase *> itemFields;
3318 itemFields.reserve(nFields);
3319 for (
unsigned i = 0; i < nFields; ++i) {
3321 itemFields.emplace_back(fSubFields[i]->Clone(fSubFields[i]->GetFieldName()).release());
3323 return std::make_unique<RVariantField>(newName, itemFields);
3328 using TagType_t = RVariantTag<GetVariantTagSize()>::ValueType_t;
3329 auto tag = *
reinterpret_cast<const TagType_t *
>(
reinterpret_cast<const unsigned char *
>(variantPtr) + tagOffset);
3330 return (tag == TagType_t(-1)) ? 0 : tag + 1;
3335 using TagType_t = RVariantTag<GetVariantTagSize()>::ValueType_t;
3336 auto tagPtr =
reinterpret_cast<TagType_t *
>(
reinterpret_cast<unsigned char *
>(variantPtr) + tagOffset);
3337 *tagPtr = (tag == 0) ? TagType_t(-1) :
static_cast<TagType_t
>(tag - 1);
3342 auto tag = GetTag(from, fTagOffset);
3343 std::size_t nbytes = 0;
3346 nbytes += CallAppendOn(*fSubFields[tag - 1],
reinterpret_cast<const unsigned char *
>(from) + fVariantOffset);
3347 index = fNWritten[tag - 1]++;
3350 fColumns[0]->Append(&varSwitch);
3358 fPrincipalColumn->GetSwitchInfo(globalIndex, &variantIndex, &tag);
3365 void *varPtr =
reinterpret_cast<unsigned char *
>(to) + fVariantOffset;
3366 CallConstructValueOn(*fSubFields[tag - 1], varPtr);
3367 CallReadOn(*fSubFields[tag - 1], variantIndex, varPtr);
3369 SetTag(to, fTagOffset, tag);
3376 return representations;
3381 fColumns.emplace_back(Internal::RColumn::Create<RColumnSwitch>(
RColumnModel(GetColumnRepresentative()[0]), 0));
3386 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
3387 fColumns.emplace_back(Internal::RColumn::Create<RColumnSwitch>(
RColumnModel(onDiskTypes[0]), 0));
3392 memset(where, 0, GetValueSize());
3393 CallConstructValueOn(*fSubFields[0],
reinterpret_cast<unsigned char *
>(where) + fVariantOffset);
3394 SetTag(where, fTagOffset, 1);
3399 auto tag = GetTag(objPtr, fTagOffset);
3401 fItemDeleters[tag - 1]->operator()(
reinterpret_cast<unsigned char *
>(objPtr) + fVariantOffset,
true );
3403 RDeleter::operator()(objPtr, dtorOnly);
3408 std::vector<std::unique_ptr<RDeleter>> itemDeleters;
3409 itemDeleters.reserve(fSubFields.size());
3410 for (
const auto &
f : fSubFields) {
3411 itemDeleters.emplace_back(GetDeleterOf(*
f));
3413 return std::make_unique<RVariantDeleter>(fTagOffset, fVariantOffset, itemDeleters);
3418 return std::max(fMaxAlignment,
alignof(RVariantTag<GetVariantTagSize()>::ValueType_t));
3424 const auto actualSize = fTagOffset + GetVariantTagSize();
3426 return actualSize + ((padding ==
alignment) ? 0 : padding);
3431 std::fill(fNWritten.begin(), fNWritten.end(), 0);
3437 std::unique_ptr<RFieldBase> itemField)
3444 auto newItemField = fSubFields[0]->
Clone(fSubFields[0]->GetFieldName());
3445 return std::make_unique<RSetField>(newName, GetTypeName(), std::move(newItemField));
3451 std::unique_ptr<RFieldBase> itemField)
3454 if (!
dynamic_cast<RPairField *
>(itemField.get()))
3460 Attach(std::move(itemField));
3465 std::size_t nbytes = 0;
3469 nbytes += CallAppendOn(*fSubFields[0], ptr);
3473 fColumns[0]->Append(&fNWritten);
3474 return nbytes + fColumns[0]->GetElement()->GetPackedSize();
3481 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
3489 CallReadOn(*fSubFields[0], collectionStart + i, ptr);
3494 fProxy->Commit(obj);
3499 std::vector<RValue>
result;
3500 auto valueRawPtr =
value.GetPtr<
void>().get();
3503 result.emplace_back(fSubFields[0]->BindValue(std::shared_ptr<void>(
value.GetPtr<
void>(), ptr)));
3510 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetFieldName());
3511 return std::unique_ptr<RMapField>(
new RMapField(newName, GetTypeName(), std::move(newItemField)));
3517 std::unique_ptr<RFieldBase> itemField)
3520 Attach(std::move(itemField));
3529 return representations;
3534 if (HasDefaultColumnRepresentative()) {
3535 if (fSubFields[0]->GetValueSize() < 4) {
3540 fDefaultItemValue = std::make_unique<RValue>(fSubFields[0]->CreateValue());
3543 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(
RColumnModel(GetColumnRepresentative()[0]), 0));
3549 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
3553 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(
RColumnModel(onDiskTypes[0]), 0));
3561 fPrincipalColumn->Append(&
mask);
3562 return 1 + CallAppendOn(*fSubFields[0], fDefaultItemValue->GetPtr<
void>().get());
3564 fPrincipalColumn->Append(&fNWritten);
3571 auto nbytesItem = CallAppendOn(*fSubFields[0], from);
3574 fPrincipalColumn->Append(&
mask);
3575 return 1 + nbytesItem;
3578 fPrincipalColumn->Append(&fNWritten);
3587 const bool isValidItem = *fPrincipalColumn->Map<
bool>(globalIndex);
3588 return isValidItem ? fPrincipalColumn->GetClusterIndex(globalIndex) : nullIndex;
3592 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &collectionSize);
3593 return (collectionSize == 0) ? nullIndex : collectionStart;
3605 std::unique_ptr<RFieldBase> itemField)
3606 :
RNullableField(fieldName, typeName, std::move(itemField)), fItemDeleter(GetDeleterOf(*fSubFields[0]))
3610std::unique_ptr<ROOT::Experimental::RFieldBase>
3613 auto newItemField = fSubFields[0]->
Clone(fSubFields[0]->GetFieldName());
3614 return std::make_unique<RUniquePtrField>(newName, GetTypeName(), std::move(newItemField));
3619 auto typedValue =
static_cast<const std::unique_ptr<char> *
>(from);
3621 return AppendValue(typedValue->get());
3623 return AppendNull();
3629 auto ptr =
static_cast<std::unique_ptr<char> *
>(to);
3630 bool isValidValue =
static_cast<bool>(*ptr);
3632 auto itemIndex = GetItemIndex(globalIndex);
3635 void *valuePtr =
nullptr;
3637 valuePtr = ptr->get();
3639 if (isValidValue && !isValidItem) {
3641 fItemDeleter->operator()(valuePtr,
false );
3648 if (!isValidValue) {
3649 valuePtr =
malloc(fSubFields[0]->GetValueSize());
3650 CallConstructValueOn(*fSubFields[0], valuePtr);
3651 ptr->reset(
reinterpret_cast<char *
>(valuePtr));
3654 CallReadOn(*fSubFields[0], itemIndex, valuePtr);
3659 auto typedPtr =
static_cast<std::unique_ptr<char> *
>(objPtr);
3661 fItemDeleter->operator()(typedPtr->get(),
false );
3662 typedPtr->release();
3664 RDeleter::operator()(objPtr, dtorOnly);
3669 return std::make_unique<RUniquePtrDeleter>(GetDeleterOf(*fSubFields[0]));
3672std::vector<ROOT::Experimental::RFieldBase::RValue>
3675 std::vector<RValue>
result;
3676 const auto &ptr =
value.GetRef<std::unique_ptr<char>>();
3678 result.emplace_back(fSubFields[0]->BindValue(std::shared_ptr<void>(
value.GetPtr<
void>(), ptr.get())));
3686 std::unique_ptr<RFieldBase> itemField)
3687 :
RNullableField(fieldName, typeName, std::move(itemField)), fItemDeleter(GetDeleterOf(*fSubFields[0]))
3695 void *
value = optionalPtr;
3697 reinterpret_cast<bool *
>(
reinterpret_cast<unsigned char *
>(optionalPtr) + fSubFields[0]->GetValueSize());
3698 return {
value, engagement};
3701std::pair<const void *, const bool *>
3704 return GetValueAndEngagementPtrs(
const_cast<void *
>(optionalPtr));
3707std::unique_ptr<ROOT::Experimental::RFieldBase>
3710 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetFieldName());
3711 return std::make_unique<ROptionalField>(newName, GetTypeName(), std::move(newItemField));
3716 const auto [valuePtr, engagementPtr] = GetValueAndEngagementPtrs(from);
3717 if (*engagementPtr) {
3718 return AppendValue(valuePtr);
3720 return AppendNull();
3726 auto [valuePtr, engagementPtr] = GetValueAndEngagementPtrs(to);
3727 auto itemIndex = GetItemIndex(globalIndex);
3729 *engagementPtr =
false;
3731 CallReadOn(*fSubFields[0], itemIndex, valuePtr);
3732 *engagementPtr =
true;
3738 auto [valuePtr, engagementPtr] = GetValueAndEngagementPtrs(where);
3739 CallConstructValueOn(*fSubFields[0], valuePtr);
3740 *engagementPtr =
false;
3745 fItemDeleter->operator()(objPtr,
true );
3746 RDeleter::operator()(objPtr, dtorOnly);
3751 return std::make_unique<ROptionalDeleter>(GetDeleterOf(*fSubFields[0]));
3754std::vector<ROOT::Experimental::RFieldBase::RValue>
3757 std::vector<RValue>
result;
3758 const auto [valuePtr, engagementPtr] = GetValueAndEngagementPtrs(
value.GetPtr<
void>().get());
3759 if (*engagementPtr) {
3760 result.emplace_back(fSubFields[0]->BindValue(std::shared_ptr<void>(
value.GetPtr<
void>(), valuePtr)));
3769 const auto actualSize = fSubFields[0]->GetValueSize() +
sizeof(
bool);
3772 auto remainder = actualSize %
alignment;
3776 return actualSize + padding;
3781 return fSubFields[0]->GetAlignment();
3787ROOT::Experimental::RPairField::RPairField::GetTypeList(
const std::array<std::unique_ptr<RFieldBase>, 2> &itemFields)
3789 return itemFields[0]->GetTypeName() +
"," + itemFields[1]->GetTypeName();
3793 std::array<std::unique_ptr<RFieldBase>, 2> &&itemFields,
3794 const std::array<std::size_t, 2> &offsets)
3795 :
ROOT::Experimental::
RRecordField(fieldName, std::move(itemFields), offsets,
3796 "std::pair<" + GetTypeList(itemFields) +
">")
3801 std::array<std::unique_ptr<RFieldBase>, 2> &itemFields)
3803 "std::pair<" + GetTypeList(itemFields) +
">")
3811 auto firstElem =
fClass->GetRealData(
"first");
3814 fOffsets[0] = firstElem->GetThisOffset();
3816 auto secondElem =
fClass->GetRealData(
"second");
3819 fOffsets[1] = secondElem->GetThisOffset();
3822std::unique_ptr<ROOT::Experimental::RFieldBase>
3825 std::array<std::unique_ptr<RFieldBase>, 2> items{fSubFields[0]->Clone(fSubFields[0]->GetFieldName()),
3826 fSubFields[1]->Clone(fSubFields[1]->GetFieldName())};
3828 std::unique_ptr<RPairField>
result(
new RPairField(newName, std::move(items), {fOffsets[0], fOffsets[1]}));
3840 fClass->Destructor(objPtr,
true );
3841 RDeleter::operator()(objPtr, dtorOnly);
3847ROOT::Experimental::RTupleField::RTupleField::GetTypeList(
const std::vector<std::unique_ptr<RFieldBase>> &itemFields)
3850 if (itemFields.empty())
3851 throw RException(
R__FAIL(
"the type list for std::tuple must have at least one element"));
3852 for (
size_t i = 0; i < itemFields.size(); ++i) {
3853 result += itemFields[i]->GetTypeName() +
",";
3860 std::vector<std::unique_ptr<RFieldBase>> &&itemFields,
3861 const std::vector<std::size_t> &offsets)
3862 :
ROOT::Experimental::
RRecordField(fieldName, std::move(itemFields), offsets,
3863 "std::tuple<" + GetTypeList(itemFields) +
">")
3868 std::vector<std::unique_ptr<RFieldBase>> &itemFields)
3870 "std::tuple<" + GetTypeList(itemFields) +
">")
3882 for (
unsigned i = 0; i < fSubFields.size(); ++i) {
3883 std::string memberName(
"_" + std::to_string(i));
3884 auto member =
fClass->GetRealData(memberName.c_str());
3887 fOffsets.push_back(member->GetThisOffset());
3891std::unique_ptr<ROOT::Experimental::RFieldBase>
3894 std::vector<std::unique_ptr<RFieldBase>> items;
3895 items.reserve(fSubFields.size());
3896 for (
const auto &item : fSubFields)
3897 items.push_back(item->Clone(item->GetFieldName()));
3899 std::unique_ptr<RTupleField>
result(
new RTupleField(newName, std::move(items), fOffsets));
3911 fClass->Destructor(objPtr,
true );
3912 RDeleter::operator()(objPtr, dtorOnly);
3918 std::shared_ptr<RNTupleCollectionWriter> collectionWriter,
3919 std::unique_ptr<RFieldZero> collectionParent)
3922 const std::size_t
N = collectionParent->
fSubFields.size();
3923 for (std::size_t i = 0; i <
N; ++i) {
3924 Attach(std::move(collectionParent->fSubFields[i]));
3934 return representations;
3939 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(
RColumnModel(GetColumnRepresentative()[0]), 0));
3944 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
3945 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(
RColumnModel(onDiskTypes[0]), 0));
3948std::unique_ptr<ROOT::Experimental::RFieldBase>
3951 auto parent = std::make_unique<RFieldZero>();
3952 for (
auto&
f : fSubFields) {
3953 parent->Attach(
f->Clone(
f->GetFieldName()));
3955 return std::make_unique<RCollectionField>(newName, fCollectionWriter, std::move(parent));
3962 std::size_t bytesWritten = fCollectionWriter->fBytesWritten;
3963 fCollectionWriter->fBytesWritten = 0;
3965 fColumns[0]->Append(from);
3966 return bytesWritten + fColumns[0]->GetElement()->GetPackedSize();
3971 R__ASSERT(
false &&
"should never read an RCollectionField");
3976 *fCollectionWriter->GetOffsetPtr() = 0;
3982 std::unique_ptr<RFieldBase> itemField)
3989 Attach(std::move(itemField));
3992std::unique_ptr<ROOT::Experimental::RFieldBase>
3995 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetFieldName());
3996 return std::make_unique<RAtomicField>(newName, GetTypeName(), std::move(newItemField));
3999std::vector<ROOT::Experimental::RFieldBase::RValue>
4002 std::vector<RValue>
result;
4003 result.emplace_back(fSubFields[0]->BindValue(
value.GetPtr<
void>()));
#define R__FORWARD_RESULT(res)
Short-hand to return an RResult<T> value from a subroutine to the calling stack frame.
#define R__FAIL(msg)
Short-hand to return an RResult<T> in an error state; the RError is implicitly converted into RResult...
#define R__LOG_WARNING(...)
TObject * clone(const char *newname) const override
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
void Fatal(const char *location, const char *msgfmt,...)
Use this function in case of a fatal error. It will abort the program.
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 mode
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 VisitUnsplitField(const RUnsplitField &field)
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 VisitTObjectField(const RField< TObject > &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::string SerializeStreamerInfos(const StreamerInfoMap_t &infos)
Abstract interface to write data into an ntuple.
virtual void UpdateExtraTypeInfo(const RExtraTypeInfoDescriptor &extraTypeInfo)=0
Adds an extra type information record to schema.
const RNTupleWriteOptions & GetWriteOptions() const
Returns the sink's write options.
void RegisterOnCommitDatasetCallback(Callback_t callback)
The registered callback is executed at the beginning of CommitDataset();.
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 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
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::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
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
Implementations in derived classes should create the backing columns corresponsing to the field type ...
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
RBitsetField(std::string_view fieldName, std::size_t N)
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
Implementations in derived classes should create the backing columns corresponsing to the field type ...
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
const RField< RNTupleCardinality< std::uint64_t > > * As64Bit() const
void operator()(void *objPtr, bool dtorOnly) final
The field for a class with dictionary.
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() 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.
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::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
void GenerateColumnsImpl() final
Implementations in derived classes should create the backing columns corresponsing to the field type ...
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.
The field for an unscoped or scoped enum with dictionary.
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.
std::unique_ptr< bool[]> fMaskAvail
Masks invalid values in the array.
void AdoptBuffer(void *buf, std::size_t capacity)
RBulk & operator=(const RBulk &)=delete
void Reset(RClusterIndex firstIndex, std::size_t size)
Sets a new range for the bulk.
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.
void BindRawPtr(void *rawPtr)
A field translates read and write calls from/to underlying columns to/from tree values.
static constexpr int kTraitTriviallyDestructible
The type is cleaned up just by freeing its memory. I.e. the destructor performs a no-op.
void Attach(std::unique_ptr< RFieldBase > child)
Add a new subfield to the list of nested fields.
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
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.
RConstSchemaIterator cbegin() const
std::string GetTypeName() const
virtual void AcceptVisitor(Detail::RFieldVisitor &visitor) const
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.
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.
virtual std::size_t AppendImpl(const void *from)
Operations on values of complex types, e.g.
RConstSchemaIterator cend() const
bool fIsSimple
A field qualifies as simple if it is both mappable and has no post-read callback.
std::string GetQualifiedFieldName() const
Returns the field name and parent field names separated by dots ("grandparent.parent....
virtual std::uint32_t GetTypeVersion() const
Indicates an evolution of the C++ type itself.
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.
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.
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.
virtual void GenerateColumnsImpl()
Implementations in derived classes should create the backing columns corresponsing to the field type ...
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 size_t GetAlignment() const =0
As a rule of thumb, the alignment is equal to the size of the type.
virtual void OnConnectPageSource()
Called by ConnectPageSource() once connected; derived classes may override this as appropriate.
void SetColumnRepresentative(const ColumnRepresentation_t &representative)
Fixes a column representative.
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.
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.
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)
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.
RField(std::string_view name)
void ConstructValue(void *where) const final
Constructs value in a given location of size at least GetValueSize(). Called by the base class' Creat...
Used in RFieldBase::Check() to record field creation failures.
The generic field for a std::map<KeyType, ValueType> and std::unordered_map<KeyType,...
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
The field for values that may or may not be present in an entry.
const RFieldBase::RColumnRepresentations & GetColumnRepresentations() const final
Implementations in derived classes should return a static RColumnRepresentations object.
void GenerateColumnsImpl() final
Implementations in derived classes should create the backing columns corresponsing to the field type ...
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::size_t AppendValue(const void *from)
void operator()(void *objPtr, bool dtorOnly) final
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
void ConstructValue(void *where) const final
Constructs value in a given location of size at least GetValueSize(). Called by the base class' Creat...
std::unique_ptr< RDeleter > GetDeleter() const final
size_t GetAlignment() const final
As a rule of thumb, the alignment is equal to the size of the type.
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
std::pair< const void *, const bool * > GetValueAndEngagementPtrs(const void *optionalPtr) const
Given a pointer to an std::optional<T> in optionalPtr, extract a pointer to the value T* and a pointe...
ROptionalField(std::string_view fieldName, std::string_view typeName, std::unique_ptr< RFieldBase > itemField)
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
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.
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.
Allows for iterating over the elements of a proxied collection.
static RIteratorFuncs GetIteratorFuncs(TVirtualCollectionProxy *proxy, bool readFromDisk)
void operator()(void *objPtr, bool dtorOnly) final
The field for a class representing a collection of elements via TVirtualCollectionProxy.
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
Implementations in derived classes should create the backing columns corresponsing to the field type ...
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
size_t GetValueSize() const override
The number of bytes taken by a value of the appropriate type.
void operator()(void *objPtr, bool dtorOnly) final
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 GenerateColumnsImpl() final
Implementations in derived classes should create the backing columns corresponsing to the field type ...
std::size_t AppendImpl(const void *from) override
Operations on values of complex types, e.g.
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) override
void operator()(void *objPtr, bool dtorOnly) final
The field for an untyped record.
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
The generic field for std::tuple<Ts...> types.
RTupleField(std::string_view fieldName, std::vector< std::unique_ptr< RFieldBase > > &&itemFields, const std::vector< std::size_t > &offsets)
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< 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
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
void operator()(void *objPtr, bool dtorOnly) final
The field for a class in unsplit mode, which is using ROOT standard streaming.
const RColumnRepresentations & GetColumnRepresentations() const final
Implementations in derived classes should return a static RColumnRepresentations object.
void ConstructValue(void *where) const final
Constructs value in a given location of size at least GetValueSize(). Called by the base class' Creat...
void GenerateColumnsImpl() final
Implementations in derived classes should create the backing columns corresponsing to the field type ...
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
RExtraTypeInfoDescriptor GetExtraTypeInfo() const final
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
size_t GetAlignment() const final
As a rule of thumb, the alignment is equal to the size of the type.
std::uint32_t GetTypeVersion() const final
Indicates an evolution of the C++ type itself.
RUnsplitField(std::string_view fieldName, std::string_view className, TClass *classp)
void operator()(void *objPtr, bool dtorOnly) final
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
const RColumnRepresentations & GetColumnRepresentations() const final
Implementations in derived classes should return a static RColumnRepresentations object.
static void SetTag(void *variantPtr, std::size_t tagOffset, std::uint8_t tag)
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
Implementations in derived classes should create the backing columns corresponsing to the field type ...
void CommitClusterImpl() final
static constexpr std::size_t kMaxVariants
static std::uint8_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 ...
size_t fVariantOffset
In the std::variant memory layout, the actual union of types may start at an offset > 0.
std::unique_ptr< RDeleter > GetDeleter() const final
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)
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
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
Implementations in derived classes should create the backing columns corresponsing to the field type ...
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
The concrete implementation of TBuffer for writing/reading to/from a ROOT file or socket.
void TagStreamerInfo(TVirtualStreamerInfo *info) override
Mark the classindex of the current file as using this TStreamerInfo.
TClass instances represent classes, structs and namespaces in the ROOT type system.
Bool_t CanSplit() const
Return true if the data member of this TClass can be saved separately.
TList * GetListOfDataMembers(Bool_t load=kTRUE)
Return list containing the TDataMembers of a class.
Int_t Size() const
Return size of object of this class.
TList * GetListOfBases()
Return list containing the TBaseClass(es) of a class.
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Int_t GetClassSize() const
Long_t ClassProperty() const
Return the C++ property of this class, eg.
Long_t Property() const override
Returns the properties of the TClass as a bit field stored as a Long_t value.
Version_t GetClassVersion() const
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.
All ROOT classes may have RTTI (run time type identification) support added.
Longptr_t GetOffset() const
Get offset from "this".
TDictAttributeMap * GetAttributeMap() const
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)
TObject * First() const override
Return the first object in the list. Returns 0 when list is empty.
Mother of all ROOT objects.
@ kIsOnHeap
object is on heap
@ kNotDeleted
object has not been deleted
@ kIsReferenced
if object is referenced by a TRef or TRefArray
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...
Abstract Interface class describing Streamer information for one class.
virtual Int_t GetNumber() const =0
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.
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
RClusterSize ClusterSize_t
ENTupleStructure
The fields in the ntuple model tree can carry different structural information about the type system.
std::uint64_t DescriptorId_t
Distriniguishes elements of the same type within a descriptor, e.g. different fields.
constexpr ClusterSize_t kInvalidClusterIndex(std::uint64_t(-1))
constexpr DescriptorId_t kInvalidDescriptorId
void(off) SmallVectorTemplateBase< T
std::string GetDemangledTypeName(const std::type_info &t)
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 ...
Wrap the integer in a struct in order to avoid template specialization clash with std::uint64_t.
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.
std::default_delete< T > deleter
TVirtualCollectionProxy::Next_t fNext
TVirtualCollectionProxy::DeleteTwoIterators_t fDeleteTwoIterators
TVirtualCollectionProxy::CreateIterators_t fCreateIterators