52#include <unordered_map>
56const std::unordered_map<std::string_view, std::string_view> typeTranslationMap{
59 {
"Double_t",
"double"},
60 {
"string",
"std::string"},
62 {
"byte",
"std::byte"},
64 {
"int8_t",
"std::int8_t"},
65 {
"signed char",
"char"},
66 {
"UChar_t",
"std::uint8_t"},
67 {
"unsigned char",
"std::uint8_t"},
68 {
"uint8_t",
"std::uint8_t"},
70 {
"Short_t",
"std::int16_t"},
71 {
"int16_t",
"std::int16_t"},
72 {
"short",
"std::int16_t"},
73 {
"UShort_t",
"std::uint16_t"},
74 {
"unsigned short",
"std::uint16_t"},
75 {
"uint16_t",
"std::uint16_t"},
77 {
"Int_t",
"std::int32_t"},
78 {
"int32_t",
"std::int32_t"},
79 {
"int",
"std::int32_t"},
80 {
"UInt_t",
"std::uint32_t"},
81 {
"unsigned",
"std::uint32_t"},
82 {
"unsigned int",
"std::uint32_t"},
83 {
"uint32_t",
"std::uint32_t"},
86 {
"Long_t",
"std::int64_t"},
87 {
"Long64_t",
"std::int64_t"},
88 {
"int64_t",
"std::int64_t"},
89 {
"long",
"std::int64_t"},
90 {
"ULong_t",
"std::uint64_t"},
91 {
"ULong64_t",
"std::uint64_t"},
92 {
"unsigned long",
"std::uint64_t"},
93 {
"uint64_t",
"std::uint64_t"}
98std::vector<std::string> TokenizeTypeList(std::string templateType) {
99 std::vector<std::string>
result;
100 if (templateType.empty())
103 const char *eol = templateType.data() + templateType.length();
104 const char *typeBegin = templateType.data();
105 const char *typeCursor = templateType.data();
106 unsigned int nestingLevel = 0;
107 while (typeCursor != eol) {
108 switch (*typeCursor) {
116 if (nestingLevel == 0) {
117 result.push_back(std::string(typeBegin, typeCursor - typeBegin));
118 typeBegin = typeCursor + 1;
124 result.push_back(std::string(typeBegin, typeCursor - typeBegin));
133std::tuple<std::string, std::vector<size_t>> ParseArrayType(std::string_view typeName)
135 std::vector<size_t> sizeVec;
138 while (typeName.back() ==
']') {
139 auto posRBrace = typeName.size() - 1;
140 auto posLBrace = typeName.find_last_of(
'[', posRBrace);
141 if (posLBrace == std::string_view::npos)
145 if (std::from_chars(typeName.data() + posLBrace + 1, typeName.data() + posRBrace,
size).ec != std::errc{})
147 sizeVec.insert(sizeVec.begin(),
size);
148 typeName.remove_suffix(typeName.size() - posLBrace);
150 return std::make_tuple(std::string{typeName}, sizeVec);
155std::string GetCanonicalTypeName(
const std::string &typeName)
158 if (typeName ==
"ROOT::Experimental::ClusterSize_t" || typeName.substr(0, 5) ==
"std::" ||
159 typeName.substr(0, 39) ==
"ROOT::Experimental::RNTupleCardinality<")
170std::string GetNormalizedTypeName(
const std::string &typeName)
174 if (
auto it = typeTranslationMap.find(normalizedType); it != typeTranslationMap.end())
175 normalizedType = it->second;
177 if (normalizedType.substr(0, 7) ==
"vector<")
178 normalizedType =
"std::" + normalizedType;
179 if (normalizedType.substr(0, 6) ==
"array<")
180 normalizedType =
"std::" + normalizedType;
181 if (normalizedType.substr(0, 8) ==
"variant<")
182 normalizedType =
"std::" + normalizedType;
183 if (normalizedType.substr(0, 5) ==
"pair<")
184 normalizedType =
"std::" + normalizedType;
185 if (normalizedType.substr(0, 6) ==
"tuple<")
186 normalizedType =
"std::" + normalizedType;
187 if (normalizedType.substr(0, 7) ==
"bitset<")
188 normalizedType =
"std::" + normalizedType;
189 if (normalizedType.substr(0, 11) ==
"unique_ptr<")
190 normalizedType =
"std::" + normalizedType;
191 if (normalizedType.substr(0, 4) ==
"set<")
192 normalizedType =
"std::" + normalizedType;
193 if (normalizedType.substr(0, 14) ==
"unordered_set<")
194 normalizedType =
"std::" + normalizedType;
195 if (normalizedType.substr(0, 4) ==
"map<")
196 normalizedType =
"std::" + normalizedType;
197 if (normalizedType.substr(0, 14) ==
"unordered_map<")
198 normalizedType =
"std::" + normalizedType;
199 if (normalizedType.substr(0, 7) ==
"atomic<")
200 normalizedType =
"std::" + normalizedType;
202 if (normalizedType.substr(0, 11) ==
"ROOT::RVec<")
203 normalizedType =
"ROOT::VecOps::RVec<" + normalizedType.substr(11);
205 return normalizedType;
209class CreateContextGuard;
211 friend class CreateContextGuard;
213 std::vector<std::string> fClassesOnStack;
216 CreateContext() =
default;
220class CreateContextGuard {
221 CreateContext &fCreateContext;
222 std::size_t fNOriginalClassesOnStack;
225 CreateContextGuard(CreateContext &ctx) : fCreateContext(ctx), fNOriginalClassesOnStack(ctx.fClassesOnStack.
size()) {}
226 ~CreateContextGuard() { fCreateContext.fClassesOnStack.resize(fNOriginalClassesOnStack); }
228 void AddClassToStack(
const std::string &cl)
230 if (std::find(fCreateContext.fClassesOnStack.begin(), fCreateContext.fClassesOnStack.end(), cl) !=
231 fCreateContext.fClassesOnStack.end()) {
234 fCreateContext.fClassesOnStack.emplace_back(cl);
240std::tuple<void **, std::int32_t *, std::int32_t *> GetRVecDataMembers(
void *rvecPtr)
242 void **begin =
reinterpret_cast<void **
>(rvecPtr);
244 std::int32_t *
size =
reinterpret_cast<std::int32_t *
>(begin + 1);
247 std::int32_t *capacity =
size + 1;
249 return {begin,
size, capacity};
252std::tuple<const void *const *, const std::int32_t *, const std::int32_t *> GetRVecDataMembers(
const void *rvecPtr)
254 return {GetRVecDataMembers(
const_cast<void *
>(rvecPtr))};
262 auto iFrom = from.
cbegin();
263 auto iTo = to.
begin();
264 for (; iFrom != from.
cend(); ++iFrom, ++iTo) {
265 iTo->SetOnDiskId(iFrom->GetOnDiskId());
269std::size_t EvalRVecValueSize(std::size_t alignOfT, std::size_t sizeOfT, std::size_t alignOfRVecT)
283 constexpr auto dataMemberSz =
sizeof(
void *) + 2 *
sizeof(std::int32_t);
286 const auto inlineStorageSz = [&] {
287#ifdef R__HAS_HARDWARE_INTERFERENCE_SIZE
289 constexpr unsigned cacheLineSize = std::hardware_destructive_interference_size;
291 constexpr unsigned cacheLineSize = 64u;
293 const unsigned elementsPerCacheLine = (cacheLineSize - dataMemberSz) / sizeOfT;
294 constexpr unsigned maxInlineByteSize = 1024;
295 const unsigned nElements =
296 elementsPerCacheLine >= 8 ? elementsPerCacheLine : (sizeOfT * 8 > maxInlineByteSize ? 0 : 8);
297 return nElements * sizeOfT;
302 auto paddingMiddle = dataMemberSz % alignOfT;
303 if (paddingMiddle != 0)
304 paddingMiddle = alignOfT - paddingMiddle;
307 auto paddingEnd = (dataMemberSz + paddingMiddle + inlineStorageSz) % alignOfRVecT;
309 paddingEnd = alignOfRVecT - paddingEnd;
311 return dataMemberSz + inlineStorageSz + paddingMiddle + paddingEnd;
314std::size_t EvalRVecAlignment(std::size_t alignOfSubField)
318 return std::max({
alignof(
void *),
alignof(std::int32_t), alignOfSubField});
321void DestroyRVecWithChecks(std::size_t alignOfT,
void **beginPtr,
char *begin, std::int32_t *capacityPtr)
325 constexpr auto dataMemberSz =
sizeof(
void *) + 2 *
sizeof(std::int32_t);
326 auto paddingMiddle = dataMemberSz % alignOfT;
327 if (paddingMiddle != 0)
328 paddingMiddle = alignOfT - paddingMiddle;
329 const bool isSmall = (
reinterpret_cast<void *
>(begin) == (beginPtr + dataMemberSz + paddingMiddle));
331 const bool owns = (*capacityPtr != -1);
332 if (!isSmall && owns)
363 : fSerializationTypes(serializationTypes), fDeserializationTypes(serializationTypes)
366 deserializationExtraTypes.begin(), deserializationExtraTypes.end());
381 : fField(other.fField),
383 fCapacity(other.fCapacity),
385 fIsAdopted(other.fIsAdopted),
386 fNValidValues(other.fNValidValues),
387 fFirstIndex(other.fFirstIndex)
389 std::swap(
fDeleter, other.fDeleter);
390 std::swap(
fValues, other.fValues);
396 std::swap(fField, other.fField);
397 std::swap(fDeleter, other.fDeleter);
398 std::swap(fValues, other.fValues);
400 std::swap(fCapacity, other.fCapacity);
401 std::swap(
fSize, other.fSize);
402 std::swap(fIsAdopted, other.fIsAdopted);
403 std::swap(fMaskAvail, other.fMaskAvail);
404 std::swap(fNValidValues, other.fNValidValues);
405 std::swap(fFirstIndex, other.fFirstIndex);
425 for (std::size_t i = 0; i < fCapacity; ++i) {
426 fDeleter->operator()(GetValuePtrAt(i),
true );
433 if (fCapacity <
size) {
435 throw RException(
R__FAIL(
"invalid attempt to bulk read beyond the adopted buffer"));
441 for (std::size_t i = 0; i <
size; ++i) {
442 fField->ConstructValue(GetValuePtrAt(i));
446 fMaskAvail = std::make_unique<bool[]>(
size);
450 std::fill(fMaskAvail.get(), fMaskAvail.get() +
size,
false);
453 fFirstIndex = firstIndex;
460 for (std::size_t i = 0; i <
fSize; ++i)
461 fNValidValues +=
static_cast<std::size_t
>(fMaskAvail[i]);
468 fCapacity = capacity;
471 fMaskAvail = std::make_unique<bool[]>(capacity);
486std::unique_ptr<void, typename ROOT::Experimental::RFieldBase::RCreateObjectDeleter<void>::deleter>
487ROOT::Experimental::RFieldBase::CreateObject<void>()
const
490 return std::unique_ptr<void, RCreateObjectDeleter<void>::deleter>(
CreateObjectRawPtr(), gDeleter);
496 bool isSimple, std::size_t nRepetitions)
510 std::string
result = GetFieldName();
511 auto parent = GetParent();
512 while (parent && !parent->GetFieldName().empty()) {
514 parent = parent->GetParent();
522 auto typeAlias = GetNormalizedTypeName(typeName);
523 auto canonicalType = GetNormalizedTypeName(GetCanonicalTypeName(typeAlias));
529 const std::string &typeAlias)
531 thread_local CreateContext createContext;
532 CreateContextGuard createContextGuard(createContext);
534 if (canonicalType.empty())
535 return R__FAIL(
"no type name specified for Field " + fieldName);
537 if (
auto [arrayBaseType, arraySizes] = ParseArrayType(canonicalType); !arraySizes.empty()) {
538 std::unique_ptr<RFieldBase> arrayField = Create(
"_0", arrayBaseType).Unwrap();
539 for (
int i = arraySizes.size() - 1; i >= 0; --i) {
540 arrayField = std::make_unique<RArrayField>((i == 0) ? fieldName :
"_0", std::move(arrayField), arraySizes[i]);
545 std::unique_ptr<ROOT::Experimental::RFieldBase>
result;
547 if (canonicalType ==
"ROOT::Experimental::ClusterSize_t") {
548 result = std::make_unique<RField<ClusterSize_t>>(fieldName);
549 }
else if (canonicalType ==
"bool") {
550 result = std::make_unique<RField<bool>>(fieldName);
551 }
else if (canonicalType ==
"char") {
552 result = std::make_unique<RField<char>>(fieldName);
553 }
else if (canonicalType ==
"std::byte") {
554 result = std::make_unique<RField<std::byte>>(fieldName);
555 }
else if (canonicalType ==
"std::int8_t") {
556 result = std::make_unique<RField<std::int8_t>>(fieldName);
557 }
else if (canonicalType ==
"std::uint8_t") {
558 result = std::make_unique<RField<std::uint8_t>>(fieldName);
559 }
else if (canonicalType ==
"std::int16_t") {
560 result = std::make_unique<RField<std::int16_t>>(fieldName);
561 }
else if (canonicalType ==
"std::uint16_t") {
562 result = std::make_unique<RField<std::uint16_t>>(fieldName);
563 }
else if (canonicalType ==
"std::int32_t") {
564 result = std::make_unique<RField<std::int32_t>>(fieldName);
565 }
else if (canonicalType ==
"std::uint32_t") {
566 result = std::make_unique<RField<std::uint32_t>>(fieldName);
567 }
else if (canonicalType ==
"std::int64_t") {
568 result = std::make_unique<RField<std::int64_t>>(fieldName);
569 }
else if (canonicalType ==
"std::uint64_t") {
570 result = std::make_unique<RField<std::uint64_t>>(fieldName);
571 }
else if (canonicalType ==
"float") {
572 result = std::make_unique<RField<float>>(fieldName);
573 }
else if (canonicalType ==
"double") {
574 result = std::make_unique<RField<double>>(fieldName);
575 }
else if (canonicalType ==
"Double32_t") {
576 result = std::make_unique<RField<double>>(fieldName);
580 }
else if (canonicalType ==
"std::string") {
581 result = std::make_unique<RField<std::string>>(fieldName);
582 }
else if (canonicalType ==
"std::vector<bool>") {
583 result = std::make_unique<RField<std::vector<bool>>>(fieldName);
584 }
else if (canonicalType.substr(0, 12) ==
"std::vector<") {
585 std::string itemTypeName = canonicalType.substr(12, canonicalType.length() - 13);
586 auto itemField = Create(
"_0", itemTypeName);
587 result = std::make_unique<RVectorField>(fieldName, itemField.Unwrap());
588 }
else if (canonicalType.substr(0, 19) ==
"ROOT::VecOps::RVec<") {
589 std::string itemTypeName = canonicalType.substr(19, canonicalType.length() - 20);
590 auto itemField = Create(
"_0", itemTypeName);
591 result = std::make_unique<RRVecField>(fieldName, itemField.Unwrap());
592 }
else if (canonicalType.substr(0, 11) ==
"std::array<") {
593 auto arrayDef = TokenizeTypeList(canonicalType.substr(11, canonicalType.length() - 12));
595 auto arrayLength = std::stoi(arrayDef[1]);
596 auto itemField = Create(
"_0", arrayDef[0]);
597 result = std::make_unique<RArrayField>(fieldName, itemField.Unwrap(), arrayLength);
598 }
else if (canonicalType.substr(0, 13) ==
"std::variant<") {
599 auto innerTypes = TokenizeTypeList(canonicalType.substr(13, canonicalType.length() - 14));
600 std::vector<RFieldBase *> items;
601 for (
unsigned int i = 0; i < innerTypes.size(); ++i) {
602 items.emplace_back(Create(
"_" + std::to_string(i), innerTypes[i]).Unwrap().release());
604 result = std::make_unique<RVariantField>(fieldName, items);
605 }
else if (canonicalType.substr(0, 10) ==
"std::pair<") {
606 auto innerTypes = TokenizeTypeList(canonicalType.substr(10, canonicalType.length() - 11));
607 if (innerTypes.size() != 2)
608 return R__FAIL(
"the type list for std::pair must have exactly two elements");
609 std::array<std::unique_ptr<RFieldBase>, 2> items{Create(
"_0", innerTypes[0]).Unwrap(),
610 Create(
"_1", innerTypes[1]).Unwrap()};
611 result = std::make_unique<RPairField>(fieldName, items);
612 }
else if (canonicalType.substr(0, 11) ==
"std::tuple<") {
613 auto innerTypes = TokenizeTypeList(canonicalType.substr(11, canonicalType.length() - 12));
614 std::vector<std::unique_ptr<RFieldBase>> items;
615 for (
unsigned int i = 0; i < innerTypes.size(); ++i) {
616 items.emplace_back(Create(
"_" + std::to_string(i), innerTypes[i]).Unwrap());
618 result = std::make_unique<RTupleField>(fieldName, items);
619 }
else if (canonicalType.substr(0, 12) ==
"std::bitset<") {
620 auto size = std::stoull(canonicalType.substr(12, canonicalType.length() - 13));
621 result = std::make_unique<RBitsetField>(fieldName,
size);
622 }
else if (canonicalType.substr(0, 16) ==
"std::unique_ptr<") {
623 std::string itemTypeName = canonicalType.substr(16, canonicalType.length() - 17);
624 auto itemField = Create(
"_0", itemTypeName).Unwrap();
625 auto normalizedInnerTypeName = itemField->GetTypeName();
626 result = std::make_unique<RUniquePtrField>(fieldName,
"std::unique_ptr<" + normalizedInnerTypeName +
">",
627 std::move(itemField));
628 }
else if (canonicalType.substr(0, 9) ==
"std::set<") {
629 std::string itemTypeName = canonicalType.substr(9, canonicalType.length() - 10);
630 auto itemField = Create(
"_0", itemTypeName).Unwrap();
631 auto normalizedInnerTypeName = itemField->GetTypeName();
633 std::make_unique<RSetField>(fieldName,
"std::set<" + normalizedInnerTypeName +
">", std::move(itemField));
634 }
else if (canonicalType.substr(0, 19) ==
"std::unordered_set<") {
635 std::string itemTypeName = canonicalType.substr(19, canonicalType.length() - 20);
636 auto itemField = Create(
"_0", itemTypeName).Unwrap();
637 auto normalizedInnerTypeName = itemField->GetTypeName();
638 result = std::make_unique<RSetField>(fieldName,
"std::unordered_set<" + normalizedInnerTypeName +
">",
639 std::move(itemField));
640 }
else if (canonicalType.substr(0, 9) ==
"std::map<") {
641 auto innerTypes = TokenizeTypeList(canonicalType.substr(9, canonicalType.length() - 10));
642 if (innerTypes.size() != 2)
643 return R__FAIL(
"the type list for std::map must have exactly two elements");
645 auto normalizedKeyTypeName = GetNormalizedTypeName(innerTypes[0]);
646 auto normalizedValueTypeName = GetNormalizedTypeName(innerTypes[1]);
649 Create(
"_0",
"std::pair<" + normalizedKeyTypeName +
"," + normalizedValueTypeName +
">").Unwrap();
650 result = std::make_unique<RMapField>(
651 fieldName,
"std::map<" + normalizedKeyTypeName +
"," + normalizedValueTypeName +
">", std::move(itemField));
652 }
else if (canonicalType.substr(0, 19) ==
"std::unordered_map<") {
653 auto innerTypes = TokenizeTypeList(canonicalType.substr(19, canonicalType.length() - 20));
654 if (innerTypes.size() != 2)
655 return R__FAIL(
"the type list for std::unordered_map must have exactly two elements");
657 auto normalizedKeyTypeName = GetNormalizedTypeName(innerTypes[0]);
658 auto normalizedValueTypeName = GetNormalizedTypeName(innerTypes[1]);
661 Create(
"_0",
"std::pair<" + normalizedKeyTypeName +
"," + normalizedValueTypeName +
">").Unwrap();
662 result = std::make_unique<RMapField>(
663 fieldName,
"std::unordered_map<" + normalizedKeyTypeName +
"," + normalizedValueTypeName +
">",
664 std::move(itemField));
665 }
else if (canonicalType.substr(0, 12) ==
"std::atomic<") {
666 std::string itemTypeName = canonicalType.substr(12, canonicalType.length() - 13);
667 auto itemField = Create(
"_0", itemTypeName).Unwrap();
668 auto normalizedInnerTypeName = itemField->GetTypeName();
669 result = std::make_unique<RAtomicField>(fieldName,
"std::atomic<" + normalizedInnerTypeName +
">",
670 std::move(itemField));
671 }
else if (canonicalType.substr(0, 39) ==
"ROOT::Experimental::RNTupleCardinality<") {
672 auto innerTypes = TokenizeTypeList(canonicalType.substr(39, canonicalType.length() - 40));
673 if (innerTypes.size() != 1)
674 return R__FAIL(std::string(
"Field ") + fieldName +
" has invalid cardinality template: " + canonicalType);
675 if (innerTypes[0] ==
"std::uint32_t") {
676 result = std::make_unique<RField<RNTupleCardinality<std::uint32_t>>>(fieldName);
677 }
else if (innerTypes[0] ==
"std::uint64_t") {
678 result = std::make_unique<RField<RNTupleCardinality<std::uint64_t>>>(fieldName);
680 return R__FAIL(std::string(
"Field ") + fieldName +
" has invalid cardinality template: " + canonicalType);
687 result = std::make_unique<REnumField>(fieldName, canonicalType);
694 if (cl->GetCollectionProxy()) {
695 result = std::make_unique<RProxiedCollectionField>(fieldName, canonicalType);
697 createContextGuard.AddClassToStack(canonicalType);
698 result = std::make_unique<RClassField>(fieldName, canonicalType);
704 if (typeAlias != canonicalType)
705 result->fTypeAlias = typeAlias;
708 return R__FAIL(std::string(
"Field ") + fieldName +
" has unknown type " + canonicalType);
713 if (fieldName.empty()) {
714 return R__FAIL(
"name cannot be empty string \"\"");
715 }
else if (fieldName.find(
'.') != std::string::npos) {
716 return R__FAIL(
"name '" + std::string(fieldName) +
"' cannot contain dot characters '.'");
725 return representations;
730 auto clone = CloneImpl(newName);
731 clone->fTypeAlias = fTypeAlias;
732 clone->fOnDiskId = fOnDiskId;
733 clone->fDescription = fDescription;
735 clone->fColumnRepresentative = fColumnRepresentative;
741 R__ASSERT(
false &&
"A non-simple RField must implement its own AppendImpl");
752 const auto valueSize = GetValueSize();
753 std::size_t nRead = 0;
754 for (std::size_t i = 0; i < bulkSpec.
fCount; ++i) {
763 Read(bulkSpec.
fFirstIndex + i,
reinterpret_cast<unsigned char *
>(bulkSpec.
fValues) + i * valueSize);
772 void *where =
operator new(GetValueSize());
774 ConstructValue(where);
780 void *obj = CreateObjectRawPtr();
784std::vector<ROOT::Experimental::RFieldBase::RValue>
787 return std::vector<RValue>();
794 if (fState != EState::kUnconnected)
795 throw RException(
R__FAIL(
"invalid attempt to attach subfield to already connected field"));
796 child->fParent =
this;
797 fSubFields.emplace_back(std::move(
child));
803 std::size_t
result = globalIndex;
804 for (
auto f =
this;
f !=
nullptr;
f =
f->GetParent()) {
805 auto parent =
f->GetParent();
806 if (parent && (parent->GetStructure() ==
kCollection || parent->GetStructure() ==
kVariant))
808 result *= std::max(
f->GetNRepetitions(), std::size_t{1U});
815 std::vector<RFieldBase *>
result;
816 result.reserve(fSubFields.size());
817 for (
const auto &
f : fSubFields) {
825 std::vector<const RFieldBase *>
result;
826 result.reserve(fSubFields.size());
827 for (
const auto &
f : fSubFields) {
835 for (
auto& column : fColumns) {
843 if (fState != EState::kUnconnected)
844 throw RException(
R__FAIL(
"cannot set field description once field is connected"));
845 fDescription = std::string(description);
850 if (fState != EState::kUnconnected)
858 if (fColumnRepresentative)
859 return *fColumnRepresentative;
860 return GetColumnRepresentations().GetSerializationDefault();
865 if (fState != EState::kUnconnected)
866 throw RException(
R__FAIL(
"cannot set column representative once field is connected"));
867 const auto &validTypes = GetColumnRepresentations().GetSerializationTypes();
868 auto itRepresentative = std::find(validTypes.begin(), validTypes.end(), representative);
869 if (itRepresentative == std::end(validTypes))
871 fColumnRepresentative = &(*itRepresentative);
878 throw RException(
R__FAIL(
"No on-disk column information for field `" + GetQualifiedFieldName() +
"`"));
882 onDiskTypes.emplace_back(
c.GetModel().GetType());
884 for (
const auto &t : GetColumnRepresentations().GetDeserializationTypes()) {
885 if (t == onDiskTypes)
889 std::string columnTypeNames;
890 for (
const auto &t : onDiskTypes) {
891 if (!columnTypeNames.empty())
892 columnTypeNames +=
", ";
895 throw RException(
R__FAIL(
"On-disk column types `" + columnTypeNames +
"` for field `" + GetQualifiedFieldName() +
896 "` cannot be matched."));
901 fReadCallbacks.push_back(func);
903 return fReadCallbacks.size() - 1;
908 fReadCallbacks.erase(fReadCallbacks.begin() + idx);
909 fIsSimple = (fTraits & kTraitMappable) && fReadCallbacks.empty();
914 if ((options.
GetCompression() == 0) && HasDefaultColumnRepresentative()) {
916 for (
auto &colType : rep) {
928 SetColumnRepresentative(rep);
933 for (
auto &colType : rep) {
940 SetColumnRepresentative(rep);
943 if (fTypeAlias ==
"Double32_t")
951 if (fState != EState::kUnconnected)
952 throw RException(
R__FAIL(
"invalid attempt to connect an already connected field to a page sink"));
956 GenerateColumnsImpl();
957 if (!fColumns.empty())
958 fPrincipalColumn = fColumns[0].get();
959 for (
auto &column : fColumns) {
960 auto firstElementIndex = (column.get() == fPrincipalColumn) ? EntryToColumnElementIndex(firstEntry) : 0;
961 column->ConnectPageSink(fOnDiskId, pageSink, firstElementIndex);
964 fState = EState::kConnectedToSink;
970 throw RException(
R__FAIL(
"invalid attempt to connect zero field to page source"));
971 if (fState != EState::kUnconnected)
972 throw RException(
R__FAIL(
"invalid attempt to connect an already connected field to a page source"));
974 if (fColumnRepresentative)
975 throw RException(
R__FAIL(
"fixed column representative only valid when connecting to a page sink"));
976 if (!fDescription.empty())
977 throw RException(
R__FAIL(
"setting description only valid when connecting to a page sink"));
979 for (
auto &
f : fSubFields) {
983 f->ConnectPageSource(pageSource);
989 GenerateColumnsImpl(desc);
991 for (
const auto &
c : fColumns) {
992 onDiskColumnTypes.emplace_back(
c->GetModel().GetType());
994 for (
const auto &t : GetColumnRepresentations().GetDeserializationTypes()) {
995 if (t == onDiskColumnTypes)
996 fColumnRepresentative = &t;
1002 if (!fColumns.empty())
1003 fPrincipalColumn = fColumns[0].get();
1004 for (
auto& column : fColumns)
1005 column->ConnectPageSource(fOnDiskId, pageSource);
1006 OnConnectPageSource();
1008 fState = EState::kConnectedToSource;
1018std::unique_ptr<ROOT::Experimental::RFieldBase>
1021 auto result = std::make_unique<RFieldZero>();
1022 for (
auto &
f : fSubFields)
1023 result->Attach(
f->Clone(
f->GetFieldName()));
1039 static RColumnRepresentations representations(
1042 return representations;
1047 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
1052 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1053 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(RColumnModel(onDiskTypes[0]), 0));
1058 visitor.VisitClusterSizeField(*
this);
1069 return representations;
1074 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1075 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(
RColumnModel(onDiskTypes[0]), 0));
1101 return representations;
1106 fColumns.emplace_back(Internal::RColumn::Create<char>(
RColumnModel(GetColumnRepresentative()[0]), 0));
1111 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1112 fColumns.emplace_back(Internal::RColumn::Create<char>(
RColumnModel(onDiskTypes[0]), 0));
1126 return representations;
1131 fColumns.emplace_back(Internal::RColumn::Create<char>(RColumnModel(GetColumnRepresentative()[0]), 0));
1136 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1137 fColumns.emplace_back(Internal::RColumn::Create<char>(RColumnModel(onDiskTypes[0]), 0));
1142 visitor.VisitByteField(*
this);
1151 return representations;
1156 fColumns.emplace_back(Internal::RColumn::Create<std::int8_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
1161 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1162 fColumns.emplace_back(Internal::RColumn::Create<std::int8_t>(RColumnModel(onDiskTypes[0]), 0));
1167 visitor.VisitInt8Field(*
this);
1176 return representations;
1181 fColumns.emplace_back(Internal::RColumn::Create<std::uint8_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
1186 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1187 fColumns.emplace_back(Internal::RColumn::Create<std::uint8_t>(RColumnModel(onDiskTypes[0]), 0));
1192 visitor.VisitUInt8Field(*
this);
1201 return representations;
1206 fColumns.emplace_back(Internal::RColumn::Create<bool>(
RColumnModel(GetColumnRepresentative()[0]), 0));
1211 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1212 fColumns.emplace_back(Internal::RColumn::Create<bool>(
RColumnModel(onDiskTypes[0]), 0));
1227 return representations;
1232 fColumns.emplace_back(Internal::RColumn::Create<float>(
RColumnModel(GetColumnRepresentative()[0]), 0));
1237 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1238 fColumns.emplace_back(Internal::RColumn::Create<float>(
RColumnModel(onDiskTypes[0]), 0));
1258 return representations;
1263 fColumns.emplace_back(Internal::RColumn::Create<double>(
RColumnModel(GetColumnRepresentative()[0]), 0));
1268 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1269 fColumns.emplace_back(Internal::RColumn::Create<double>(
RColumnModel(onDiskTypes[0]), 0));
1279 fTypeAlias =
"Double32_t";
1289 return representations;
1294 fColumns.emplace_back(Internal::RColumn::Create<std::int16_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
1299 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1300 fColumns.emplace_back(Internal::RColumn::Create<std::int16_t>(RColumnModel(onDiskTypes[0]), 0));
1305 visitor.VisitInt16Field(*
this);
1315 return representations;
1320 fColumns.emplace_back(Internal::RColumn::Create<std::uint16_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
1325 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1326 fColumns.emplace_back(Internal::RColumn::Create<std::uint16_t>(RColumnModel(onDiskTypes[0]), 0));
1331 visitor.VisitUInt16Field(*
this);
1341 return representations;
1346 fColumns.emplace_back(Internal::RColumn::Create<std::int32_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
1351 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1352 fColumns.emplace_back(Internal::RColumn::Create<std::int32_t>(RColumnModel(onDiskTypes[0]), 0));
1357 visitor.VisitIntField(*
this);
1367 return representations;
1372 fColumns.emplace_back(Internal::RColumn::Create<std::uint32_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
1377 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1378 fColumns.emplace_back(Internal::RColumn::Create<std::uint32_t>(RColumnModel(onDiskTypes[0]), 0));
1383 visitor.VisitUInt32Field(*
this);
1393 return representations;
1398 fColumns.emplace_back(Internal::RColumn::Create<std::uint64_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
1403 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1404 fColumns.emplace_back(Internal::RColumn::Create<std::uint64_t>(RColumnModel(onDiskTypes[0]), 0));
1409 visitor.VisitUInt64Field(*
this);
1424 return representations;
1429 fColumns.emplace_back(Internal::RColumn::Create<std::int64_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
1434 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1435 fColumns.emplace_back(Internal::RColumn::Create<std::int64_t>(RColumnModel(onDiskTypes[0]), 0));
1440 visitor.VisitInt64Field(*
this);
1453 return representations;
1458 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
1459 fColumns.emplace_back(Internal::RColumn::Create<char>(RColumnModel(GetColumnRepresentative()[1]), 1));
1464 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1465 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(RColumnModel(onDiskTypes[0]), 0));
1466 fColumns.emplace_back(Internal::RColumn::Create<char>(RColumnModel(onDiskTypes[1]), 1));
1471 auto typedValue =
static_cast<const std::string *
>(from);
1472 auto length = typedValue->length();
1473 fColumns[1]->AppendV(typedValue->data(),
length);
1475 fColumns[0]->Append(&fIndex);
1476 return length + fColumns[0]->GetElement()->GetPackedSize();
1481 auto typedValue =
static_cast<std::string *
>(to);
1482 RClusterIndex collectionStart;
1484 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nChars);
1486 typedValue->clear();
1488 typedValue->resize(nChars);
1489 fColumns[1]->ReadV(collectionStart, nChars,
const_cast<char *
>(typedValue->data()));
1495 visitor.VisitStringField(*
this);
1510 throw RException(
R__FAIL(
"RField: no I/O support for type " + std::string(className)));
1518 R__FAIL(std::string(className) +
" has an associated collection proxy; use RProxiedCollectionField instead"));
1532 TClass *
c = baseClass->GetClassPointer();
1535 fTraits &= subField->GetTraits();
1536 Attach(std::move(subField),
1545 if (!dataMember->IsPersistent()) {
1551 std::string typeName{GetNormalizedTypeName(dataMember->GetTrueTypeName())};
1552 std::string typeAlias{GetNormalizedTypeName(dataMember->GetFullTypeName())};
1554 if (dataMember->Property() &
kIsArray) {
1555 for (
int dim = 0,
n = dataMember->GetArrayDim(); dim <
n; ++dim)
1556 typeName +=
"[" + std::to_string(dataMember->GetMaxIndex(dim)) +
"]";
1558 auto subField =
RFieldBase::Create(dataMember->GetName(), typeName, typeAlias).Unwrap();
1559 fTraits &= subField->GetTraits();
1560 Attach(std::move(subField),
1567 fMaxAlignment = std::max(fMaxAlignment,
child->GetAlignment());
1568 fSubFieldsInfo.push_back(info);
1575 for (
const auto rule : rules) {
1580 auto func = rule->GetReadFunctionPointer();
1582 fReadCallbacks.emplace_back([func, classp](
void *
target) {
1586 func(
static_cast<char *
>(
target), &oldObj);
1587 oldObj.fClass =
nullptr;
1592std::unique_ptr<ROOT::Experimental::RFieldBase>
1596 SyncFieldIDs(*
this, *
result);
1602 std::size_t nbytes = 0;
1603 for (
unsigned i = 0; i < fSubFields.size(); i++) {
1604 nbytes += CallAppendOn(*fSubFields[i],
static_cast<const unsigned char *
>(from) + fSubFieldsInfo[i].fOffset);
1611 for (
unsigned i = 0; i < fSubFields.size(); i++) {
1612 CallReadOn(*fSubFields[i], globalIndex,
static_cast<unsigned char *
>(to) + fSubFieldsInfo[i].fOffset);
1618 for (
unsigned i = 0; i < fSubFields.size(); i++) {
1619 CallReadOn(*fSubFields[i], clusterIndex,
static_cast<unsigned char *
>(to) + fSubFieldsInfo[i].fOffset);
1627 const auto ruleset =
fClass->GetSchemaRules();
1631 if (rule->GetTarget() ==
nullptr)
1634 const auto dataMember = klass->GetDataMember(
target->GetString());
1635 if (!dataMember || dataMember->IsPersistent()) {
1637 << dataMember->GetName();
1644 auto rules = ruleset->FindRules(
fClass->GetName(),
static_cast<Int_t>(GetOnDiskTypeVersion()));
1645 rules.erase(std::remove_if(rules.begin(), rules.end(), referencesNonTransientMembers), rules.end());
1646 AddReadCallbacksFromIORules(rules,
fClass);
1656 fClass->Destructor(objPtr,
true );
1657 RDeleter::operator()(objPtr, dtorOnly);
1660std::vector<ROOT::Experimental::RFieldBase::RValue>
1663 std::vector<RValue>
result;
1664 auto basePtr =
value.GetPtr<
unsigned char>().get();
1665 for (
unsigned i = 0; i < fSubFields.size(); i++) {
1667 fSubFields[i]->BindValue(std::shared_ptr<void>(
value.GetPtr<
void>(), basePtr + fSubFieldsInfo[i].fOffset)));
1675 return fClass->GetClassSize();
1680 return fClass->GetClassVersion();
1691 :
REnumField(fieldName, enumName,
TEnum::GetEnum(std::string(enumName).c_str()))
1698 if (enump ==
nullptr) {
1699 throw RException(
R__FAIL(
"RField: no I/O support for enum type " + std::string(enumName)));
1717 default:
throw RException(
R__FAIL(
"Unsupported underlying integral type for enum type " + std::string(enumName)));
1724 std::unique_ptr<RFieldBase> intField)
1727 Attach(std::move(intField));
1731std::unique_ptr<ROOT::Experimental::RFieldBase>
1734 auto newIntField = fSubFields[0]->Clone(fSubFields[0]->GetFieldName());
1735 return std::unique_ptr<REnumField>(
new REnumField(newName, GetTypeName(), std::move(newIntField)));
1738std::vector<ROOT::Experimental::RFieldBase::RValue>
1741 std::vector<RValue>
result;
1742 result.emplace_back(fSubFields[0]->BindValue(
value.GetPtr<
void>()));
1762 (ifuncs.
fNext !=
nullptr));
1767 std::string_view typeName,
TClass *classp)
1770 if (classp ==
nullptr)
1771 throw RException(
R__FAIL(
"RField: no I/O support for collection proxy type " + std::string(typeName)));
1773 throw RException(
R__FAIL(std::string(typeName) +
" has no associated collection proxy"));
1778 if (
fProxy->HasPointers())
1779 throw RException(
R__FAIL(
"collection proxies whose value type is a pointer are not supported"));
1780 if (!
fProxy->GetCollectionClass()->HasDictionary()) {
1782 GetNormalizedTypeName(
fProxy->GetCollectionClass()->GetName())));
1790 std::string_view typeName,
1791 std::unique_ptr<RFieldBase> itemField)
1795 Attach(std::move(itemField));
1799 std::string_view typeName)
1804 throw RException(
R__FAIL(
"custom associative collection proxies not supported"));
1806 std::unique_ptr<ROOT::Experimental::RFieldBase> itemField;
1808 if (
auto valueClass =
fProxy->GetValueClass()) {
1812 switch (
fProxy->GetType()) {
1814 case EDataType::kUChar_t: itemField = std::make_unique<RField<std::uint8_t>>(
"_0");
break;
1815 case EDataType::kShort_t: itemField = std::make_unique<RField<std::int16_t>>(
"_0");
break;
1817 case EDataType::kInt_t: itemField = std::make_unique<RField<std::int32_t>>(
"_0");
break;
1818 case EDataType::kUInt_t: itemField = std::make_unique<RField<std::uint32_t>>(
"_0");
break;
1821 itemField = std::make_unique<RField<std::int64_t>>(
"_0");
1825 itemField = std::make_unique<RField<std::uint64_t>>(
"_0");
1836 Attach(std::move(itemField));
1839std::unique_ptr<ROOT::Experimental::RFieldBase>
1842 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetFieldName());
1843 return std::unique_ptr<RProxiedCollectionField>(
1849 std::size_t nbytes = 0;
1853 (fCollectionType ==
kSTLvector ? fItemSize : 0U)}) {
1854 nbytes += CallAppendOn(*fSubFields[0], ptr);
1859 fColumns[0]->Append(&fNWritten);
1860 return nbytes + fColumns[0]->GetElement()->GetPackedSize();
1867 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
1875 (fCollectionType ==
kSTLvector || obj != to ? fItemSize : 0U)}) {
1876 CallReadOn(*fSubFields[0], collectionStart + (i++), elementPtr);
1879 fProxy->Commit(obj);
1888 return representations;
1893 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(
RColumnModel(GetColumnRepresentative()[0]), 0));
1898 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
1899 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(
RColumnModel(onDiskTypes[0]), 0));
1907std::unique_ptr<ROOT::Experimental::RFieldBase::RDeleter>
1911 std::size_t itemSize = fCollectionType ==
kSTLvector ? fItemSize : 0U;
1912 return std::make_unique<RProxiedCollectionDeleter>(fProxy, GetDeleterOf(*fSubFields[0]), itemSize);
1914 return std::make_unique<RProxiedCollectionDeleter>(fProxy);
1922 fItemDeleter->operator()(ptr,
true );
1925 fProxy->Destructor(objPtr,
true );
1926 RDeleter::operator()(objPtr, dtorOnly);
1929std::vector<ROOT::Experimental::RFieldBase::RValue>
1932 std::vector<RValue>
result;
1933 auto valueRawPtr =
value.GetPtr<
void>().get();
1936 (fCollectionType ==
kSTLvector ? fItemSize : 0U)}) {
1937 result.emplace_back(fSubFields[0]->BindValue(std::shared_ptr<void>(
value.GetPtr<
void>(), ptr)));
1950 std::vector<std::unique_ptr<RFieldBase>> &&itemFields,
1951 const std::vector<std::size_t> &offsets, std::string_view typeName)
1956 for (
auto &item : itemFields) {
1965 std::vector<std::unique_ptr<RFieldBase>> &&itemFields)
1969 for (
auto &item : itemFields) {
1973 fSize += item->GetValueSize();
1983 std::vector<std::unique_ptr<RFieldBase>> &itemFields)
1990 if (itemAlignment > 1) {
1991 auto remainder = baseOffset % itemAlignment;
1993 return itemAlignment - remainder;
1998std::unique_ptr<ROOT::Experimental::RFieldBase>
2001 std::vector<std::unique_ptr<RFieldBase>> cloneItems;
2002 cloneItems.reserve(fSubFields.size());
2003 for (
auto &item : fSubFields)
2004 cloneItems.emplace_back(item->Clone(item->GetFieldName()));
2005 return std::unique_ptr<RRecordField>(
new RRecordField(newName, std::move(cloneItems), fOffsets, GetTypeName()));
2010 std::size_t nbytes = 0;
2011 for (
unsigned i = 0; i < fSubFields.size(); ++i) {
2012 nbytes += CallAppendOn(*fSubFields[i],
static_cast<const unsigned char *
>(from) + fOffsets[i]);
2019 for (
unsigned i = 0; i < fSubFields.size(); ++i) {
2020 CallReadOn(*fSubFields[i], globalIndex,
static_cast<unsigned char *
>(to) + fOffsets[i]);
2026 for (
unsigned i = 0; i < fSubFields.size(); ++i) {
2027 CallReadOn(*fSubFields[i], clusterIndex,
static_cast<unsigned char *
>(to) + fOffsets[i]);
2033 for (
unsigned i = 0; i < fSubFields.size(); ++i) {
2034 CallConstructValueOn(*fSubFields[i],
static_cast<unsigned char *
>(where) + fOffsets[i]);
2040 for (
unsigned i = 0; i < fItemDeleters.size(); ++i) {
2041 fItemDeleters[i]->operator()(
reinterpret_cast<unsigned char *
>(objPtr) + fOffsets[i],
true );
2043 RDeleter::operator()(objPtr, dtorOnly);
2048 std::vector<std::unique_ptr<RDeleter>> itemDeleters;
2049 itemDeleters.reserve(fOffsets.size());
2050 for (
const auto &
f : fSubFields) {
2051 itemDeleters.emplace_back(GetDeleterOf(*
f));
2053 return std::make_unique<RRecordDeleter>(itemDeleters, fOffsets);
2056std::vector<ROOT::Experimental::RFieldBase::RValue>
2059 auto basePtr =
value.GetPtr<
unsigned char>().get();
2060 std::vector<RValue>
result;
2061 for (
unsigned i = 0; i < fSubFields.size(); ++i) {
2062 result.emplace_back(fSubFields[i]->BindValue(std::shared_ptr<void>(
value.GetPtr<
void>(), basePtr + fOffsets[i])));
2076 :
ROOT::Experimental::
RFieldBase(fieldName,
"std::vector<" + itemField->GetTypeName() +
">",
2078 fItemSize(itemField->GetValueSize()),
2083 Attach(std::move(itemField));
2086std::unique_ptr<ROOT::Experimental::RFieldBase>
2089 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetFieldName());
2090 return std::make_unique<RVectorField>(newName, std::move(newItemField));
2095 auto typedValue =
static_cast<const std::vector<char> *
>(from);
2096 R__ASSERT((typedValue->size() % fItemSize) == 0);
2097 std::size_t nbytes = 0;
2098 auto count = typedValue->size() / fItemSize;
2100 if (fSubFields[0]->IsSimple() && count) {
2101 GetPrincipalColumnOf(*fSubFields[0])->AppendV(typedValue->data(), count);
2102 nbytes += count * GetPrincipalColumnOf(*fSubFields[0])->GetElement()->GetPackedSize();
2104 for (
unsigned i = 0; i < count; ++i) {
2105 nbytes += CallAppendOn(*fSubFields[0], typedValue->data() + (i * fItemSize));
2110 fColumns[0]->Append(&fNWritten);
2111 return nbytes + fColumns[0]->GetElement()->GetPackedSize();
2116 auto typedValue =
static_cast<std::vector<char> *
>(to);
2120 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
2122 if (fSubFields[0]->IsSimple()) {
2123 typedValue->resize(nItems * fItemSize);
2125 GetPrincipalColumnOf(*fSubFields[0])->ReadV(collectionStart, nItems, typedValue->data());
2130 const auto oldNItems = typedValue->size() / fItemSize;
2131 const bool canRealloc = oldNItems < nItems;
2132 bool allDeallocated =
false;
2134 allDeallocated = canRealloc;
2135 for (std::size_t i = allDeallocated ? 0 : nItems; i < oldNItems; ++i) {
2136 fItemDeleter->operator()(typedValue->data() + (i * fItemSize),
true );
2139 typedValue->resize(nItems * fItemSize);
2140 if (!(fSubFields[0]->GetTraits() & kTraitTriviallyConstructible)) {
2141 for (std::size_t i = allDeallocated ? 0 : oldNItems; i < nItems; ++i) {
2142 CallConstructValueOn(*fSubFields[0], typedValue->data() + (i * fItemSize));
2146 for (std::size_t i = 0; i < nItems; ++i) {
2147 CallReadOn(*fSubFields[0], collectionStart + i, typedValue->data() + (i * fItemSize));
2157 return representations;
2162 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(
RColumnModel(GetColumnRepresentative()[0]), 0));
2167 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
2168 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(
RColumnModel(onDiskTypes[0]), 0));
2173 auto vecPtr =
static_cast<std::vector<char> *
>(objPtr);
2175 R__ASSERT((vecPtr->size() % fItemSize) == 0);
2176 auto nItems = vecPtr->size() / fItemSize;
2177 for (std::size_t i = 0; i < nItems; ++i) {
2178 fItemDeleter->operator()(vecPtr->data() + (i * fItemSize),
true );
2181 std::destroy_at(vecPtr);
2182 RDeleter::operator()(objPtr, dtorOnly);
2188 return std::make_unique<RVectorDeleter>(fItemSize, GetDeleterOf(*fSubFields[0]));
2189 return std::make_unique<RVectorDeleter>();
2192std::vector<ROOT::Experimental::RFieldBase::RValue>
2195 auto vec =
value.GetPtr<std::vector<char>>();
2197 auto nItems =
vec->size() / fItemSize;
2198 std::vector<RValue>
result;
2199 for (
unsigned i = 0; i < nItems; ++i) {
2201 fSubFields[0]->BindValue(std::shared_ptr<void>(
value.GetPtr<
void>(),
vec->data() + (i * fItemSize))));
2215 :
ROOT::Experimental::
RFieldBase(fieldName,
"ROOT::VecOps::RVec<" + itemField->GetTypeName() +
">",
2217 fItemSize(itemField->GetValueSize()),
2222 Attach(std::move(itemField));
2226std::unique_ptr<ROOT::Experimental::RFieldBase>
2229 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetFieldName());
2230 return std::make_unique<RRVecField>(newName, std::move(newItemField));
2235 auto [beginPtr, sizePtr,
_] = GetRVecDataMembers(from);
2237 std::size_t nbytes = 0;
2238 if (fSubFields[0]->IsSimple() && *sizePtr) {
2239 GetPrincipalColumnOf(*fSubFields[0])->AppendV(*beginPtr, *sizePtr);
2240 nbytes += *sizePtr * GetPrincipalColumnOf(*fSubFields[0])->GetElement()->GetPackedSize();
2242 auto begin =
reinterpret_cast<const char *
>(*beginPtr);
2243 for (std::int32_t i = 0; i < *sizePtr; ++i) {
2244 nbytes += CallAppendOn(*fSubFields[0], begin + i * fItemSize);
2248 fNWritten += *sizePtr;
2249 fColumns[0]->Append(&fNWritten);
2250 return nbytes + fColumns[0]->GetElement()->GetPackedSize();
2258 auto [beginPtr, sizePtr, capacityPtr] = GetRVecDataMembers(to);
2263 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
2264 char *begin =
reinterpret_cast<char *
>(*beginPtr);
2265 const std::size_t oldSize = *sizePtr;
2269 const bool owns = (*capacityPtr != -1);
2270 const bool needsConstruct = !(fSubFields[0]->GetTraits() & kTraitTriviallyConstructible);
2271 const bool needsDestruct = owns && fItemDeleter;
2274 if (needsDestruct) {
2275 for (std::size_t i = nItems; i < oldSize; ++i) {
2276 fItemDeleter->operator()(begin + (i * fItemSize),
true );
2281 if (std::int32_t(nItems) > *capacityPtr) {
2284 if (needsDestruct) {
2285 for (std::size_t i = 0u; i < oldSize; ++i) {
2286 fItemDeleter->operator()(begin + (i * fItemSize),
true );
2297 *beginPtr =
malloc(nItems * fItemSize);
2299 begin =
reinterpret_cast<char *
>(*beginPtr);
2300 *capacityPtr = nItems;
2303 if (needsConstruct) {
2304 for (std::size_t i = 0u; i < oldSize; ++i)
2305 CallConstructValueOn(*fSubFields[0], begin + (i * fItemSize));
2311 if (needsConstruct) {
2312 for (std::size_t i = oldSize; i < nItems; ++i)
2313 CallConstructValueOn(*fSubFields[0], begin + (i * fItemSize));
2316 if (fSubFields[0]->IsSimple() && nItems) {
2317 GetPrincipalColumnOf(*fSubFields[0])->ReadV(collectionStart, nItems, begin);
2322 for (std::size_t i = 0; i < nItems; ++i) {
2323 CallReadOn(*fSubFields[0], collectionStart + i, begin + (i * fItemSize));
2329 if (!fSubFields[0]->IsSimple())
2335 bulkSpec.
fAuxData->resize(
sizeof(std::size_t));
2336 *
reinterpret_cast<std::size_t *
>(bulkSpec.
fAuxData->data()) = fSubFields[0]->GetValueSize();
2338 const auto itemValueSize = *
reinterpret_cast<std::size_t *
>(bulkSpec.
fAuxData->data());
2339 unsigned char *itemValueArray = bulkSpec.
fAuxData->data() +
sizeof(std::size_t);
2340 auto [beginPtr, sizePtr, capacityPtr] = GetRVecDataMembers(bulkSpec.
fValues);
2346 this->GetCollectionInfo(bulkSpec.
fFirstIndex, &firstItemIndex, &collectionSize);
2347 *beginPtr = itemValueArray;
2348 *sizePtr = collectionSize;
2354 auto lastOffset = firstItemIndex.
GetIndex() + collectionSize;
2356 std::size_t nValues = 1;
2357 std::size_t nItems = collectionSize;
2358 while (nRemainingValues > 0) {
2361 const std::size_t nBatch = std::min(nRemainingValues, nElementsUntilPageEnd);
2362 for (std::size_t i = 0; i < nBatch; ++i) {
2363 const auto size = offsets[i] - lastOffset;
2364 std::tie(beginPtr, sizePtr, capacityPtr) =
2365 GetRVecDataMembers(
reinterpret_cast<unsigned char *
>(bulkSpec.
fValues) + (nValues + i) *
fValueSize);
2366 *beginPtr = itemValueArray + nItems * itemValueSize;
2371 lastOffset = offsets[i];
2373 nRemainingValues -= nBatch;
2377 bulkSpec.
fAuxData->resize(
sizeof(std::size_t) + nItems * itemValueSize);
2379 const auto delta = itemValueArray - (bulkSpec.
fAuxData->data() +
sizeof(std::size_t));
2381 auto beginPtrAsUChar =
reinterpret_cast<unsigned char *
>(bulkSpec.
fValues);
2382 for (std::size_t i = 0; i < bulkSpec.
fCount; ++i) {
2383 *
reinterpret_cast<unsigned char **
>(beginPtrAsUChar) -= delta;
2388 GetPrincipalColumnOf(*fSubFields[0])->ReadV(firstItemIndex, nItems, itemValueArray - delta);
2389 return RBulkSpec::kAllSet;
2398 return representations;
2403 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(
RColumnModel(GetColumnRepresentative()[0]), 0));
2408 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
2409 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(
RColumnModel(onDiskTypes[0]), 0));
2416 void **beginPtr =
new (where)(
void *)(
nullptr);
2417 std::int32_t *sizePtr =
new (
reinterpret_cast<void *
>(beginPtr + 1)) std::int32_t(0);
2418 new (sizePtr + 1) std::int32_t(-1);
2423 auto [beginPtr, sizePtr, capacityPtr] = GetRVecDataMembers(objPtr);
2425 char *begin =
reinterpret_cast<char *
>(*beginPtr);
2427 for (std::int32_t i = 0; i < *sizePtr; ++i) {
2428 fItemDeleter->operator()(begin + i * fItemSize,
true );
2432 DestroyRVecWithChecks(fItemAlignment, beginPtr, begin, capacityPtr);
2433 RDeleter::operator()(objPtr, dtorOnly);
2439 return std::make_unique<RRVecDeleter>(fSubFields[0]->GetAlignment(), fItemSize, GetDeleterOf(*fSubFields[0]));
2440 return std::make_unique<RRVecDeleter>(fSubFields[0]->GetAlignment());
2443std::vector<ROOT::Experimental::RFieldBase::RValue>
2446 auto [beginPtr, sizePtr,
_] = GetRVecDataMembers(
value.GetPtr<
void>().get());
2448 std::vector<RValue>
result;
2449 char *begin =
reinterpret_cast<char *
>(*beginPtr);
2450 result.reserve(*sizePtr);
2451 for (std::int32_t i = 0; i < *sizePtr; ++i) {
2452 result.emplace_back(fSubFields[0]->BindValue(std::shared_ptr<void>(
value.GetPtr<
void>(), begin + i * fItemSize)));
2464 return EvalRVecAlignment(fSubFields[0]->GetAlignment());
2482 auto typedValue =
static_cast<const std::vector<bool> *
>(from);
2483 auto count = typedValue->size();
2484 for (
unsigned i = 0; i < count; ++i) {
2485 bool bval = (*typedValue)[i];
2486 CallAppendOn(*fSubFields[0], &bval);
2489 fColumns[0]->Append(&fNWritten);
2490 return count + fColumns[0]->GetElement()->GetPackedSize();
2495 auto typedValue =
static_cast<std::vector<bool> *
>(to);
2498 RClusterIndex collectionStart;
2499 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
2501 typedValue->resize(nItems);
2502 for (
unsigned i = 0; i < nItems; ++i) {
2504 CallReadOn(*fSubFields[0], collectionStart + i, &bval);
2505 (*typedValue)[i] = bval;
2512 static RColumnRepresentations representations(
2515 return representations;
2520 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(RColumnModel(GetColumnRepresentative()[0]), 0));
2525 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
2526 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(RColumnModel(onDiskTypes[0]), 0));
2529std::vector<ROOT::Experimental::RFieldBase::RValue>
2532 const auto &typedValue =
value.GetRef<std::vector<bool>>();
2533 auto count = typedValue.size();
2534 std::vector<RValue>
result;
2535 for (
unsigned i = 0; i < count; ++i) {
2537 result.emplace_back(fSubFields[0]->BindValue(std::shared_ptr<bool>(
new bool(
true))));
2539 result.emplace_back(fSubFields[0]->BindValue(std::shared_ptr<bool>(
new bool(
false))));
2546 visitor.VisitVectorBoolField(*
this);
2553 std::size_t arrayLength)
2555 "std::array<" + itemField->GetTypeName() +
"," + std::to_string(arrayLength) +
">",
2557 fItemSize(itemField->GetValueSize()),
2558 fArrayLength(arrayLength)
2560 fTraits |= itemField->GetTraits() & ~kTraitMappable;
2561 Attach(std::move(itemField));
2564std::unique_ptr<ROOT::Experimental::RFieldBase>
2567 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetFieldName());
2568 return std::make_unique<RArrayField>(newName, std::move(newItemField), fArrayLength);
2573 std::size_t nbytes = 0;
2574 auto arrayPtr =
static_cast<const unsigned char *
>(from);
2575 for (
unsigned i = 0; i < fArrayLength; ++i) {
2576 nbytes += CallAppendOn(*fSubFields[0], arrayPtr + (i * fItemSize));
2583 auto arrayPtr =
static_cast<unsigned char *
>(to);
2584 for (
unsigned i = 0; i < fArrayLength; ++i) {
2585 CallReadOn(*fSubFields[0], globalIndex * fArrayLength + i, arrayPtr + (i * fItemSize));
2591 auto arrayPtr =
static_cast<unsigned char *
>(to);
2592 for (
unsigned i = 0; i < fArrayLength; ++i) {
2594 arrayPtr + (i * fItemSize));
2600 if (fSubFields[0]->GetTraits() & kTraitTriviallyConstructible)
2603 auto arrayPtr =
reinterpret_cast<unsigned char *
>(where);
2604 for (
unsigned i = 0; i < fArrayLength; ++i) {
2605 CallConstructValueOn(*fSubFields[0], arrayPtr + (i * fItemSize));
2612 for (
unsigned i = 0; i < fArrayLength; ++i) {
2613 fItemDeleter->operator()(
reinterpret_cast<unsigned char *
>(objPtr) + i * fItemSize,
true );
2616 RDeleter::operator()(objPtr, dtorOnly);
2621 if (!(fSubFields[0]->GetTraits() & kTraitTriviallyDestructible))
2622 return std::make_unique<RArrayDeleter>(fItemSize, fArrayLength, GetDeleterOf(*fSubFields[0]));
2623 return std::make_unique<RDeleter>();
2626std::vector<ROOT::Experimental::RFieldBase::RValue>
2629 auto arrayPtr =
value.GetPtr<
unsigned char>().get();
2630 std::vector<RValue>
result;
2631 for (
unsigned i = 0; i < fArrayLength; ++i) {
2633 fSubFields[0]->BindValue(std::shared_ptr<void>(
value.GetPtr<
void>(), arrayPtr + (i * fItemSize))));
2647 std::unique_ptr<ROOT::Experimental::RFieldBase> itemField,
2648 std::size_t arrayLength)
2649 :
ROOT::Experimental::
RFieldBase(fieldName,
"ROOT::VecOps::RVec<" + itemField->GetTypeName() +
">",
2651 fItemSize(itemField->GetValueSize()),
2652 fArrayLength(arrayLength)
2654 Attach(std::move(itemField));
2660std::unique_ptr<ROOT::Experimental::RFieldBase>
2663 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetFieldName());
2664 return std::make_unique<RArrayAsRVecField>(newName, std::move(newItemField), fArrayLength);
2670 void **beginPtr =
new (where)(
void *)(
nullptr);
2671 std::int32_t *sizePtr =
new (
reinterpret_cast<void *
>(beginPtr + 1)) std::int32_t(0);
2672 std::int32_t *capacityPtr =
new (sizePtr + 1) std::int32_t(0);
2676 char *begin =
reinterpret_cast<char *
>(*beginPtr);
2679 if (*sizePtr == std::int32_t(fArrayLength))
2685 const bool owns = (*capacityPtr != -1);
2686 const bool needsConstruct = !(fSubFields[0]->GetTraits() & kTraitTriviallyConstructible);
2687 const bool needsDestruct = owns && fItemDeleter;
2691 if (needsDestruct) {
2692 for (std::int32_t i = 0; i < *sizePtr; ++i) {
2693 fItemDeleter->operator()(begin + (i * fItemSize),
true );
2703 *beginPtr =
malloc(fArrayLength * fItemSize);
2706 begin =
reinterpret_cast<char *
>(*beginPtr);
2708 *sizePtr = fArrayLength;
2709 *capacityPtr = fArrayLength;
2712 if (needsConstruct) {
2713 for (std::size_t i = 0; i < fArrayLength; ++i)
2714 CallConstructValueOn(*fSubFields[0], begin + (i * fItemSize));
2721 return std::make_unique<RRVecField::RRVecDeleter>(fSubFields[0]->GetAlignment(), fItemSize,
2722 GetDeleterOf(*fSubFields[0]));
2724 return std::make_unique<RRVecField::RRVecDeleter>(fSubFields[0]->GetAlignment());
2730 auto [beginPtr,
_, __] = GetRVecDataMembers(to);
2731 auto rvecBeginPtr =
reinterpret_cast<char *
>(*beginPtr);
2733 if (fSubFields[0]->IsSimple()) {
2734 GetPrincipalColumnOf(*fSubFields[0])->ReadV(globalIndex*fArrayLength, fArrayLength, rvecBeginPtr);
2739 for (std::size_t i = 0; i < fArrayLength; ++i) {
2740 CallReadOn(*fSubFields[0], globalIndex * fArrayLength + i, rvecBeginPtr + (i * fItemSize));
2746 auto [beginPtr,
_, __] = GetRVecDataMembers(to);
2747 auto rvecBeginPtr =
reinterpret_cast<char *
>(*beginPtr);
2750 const auto &clusterIndexIndex = clusterIndex.
GetIndex();
2752 if (fSubFields[0]->IsSimple()) {
2753 GetPrincipalColumnOf(*fSubFields[0])
2754 ->ReadV(
RClusterIndex(clusterId, clusterIndexIndex * fArrayLength), fArrayLength, rvecBeginPtr);
2759 for (std::size_t i = 0; i < fArrayLength; ++i) {
2760 CallReadOn(*fSubFields[0],
RClusterIndex(clusterId, clusterIndexIndex * fArrayLength + i),
2761 rvecBeginPtr + (i * fItemSize));
2767 return EvalRVecAlignment(fSubFields[0]->GetAlignment());
2770std::vector<ROOT::Experimental::RFieldBase::RValue>
2773 auto arrayPtr =
value.GetPtr<
unsigned char>().get();
2774 std::vector<ROOT::Experimental::RFieldBase::RValue>
result;
2775 for (
unsigned i = 0; i < fArrayLength; ++i) {
2777 fSubFields[0]->BindValue(std::shared_ptr<void>(
value.GetPtr<
void>(), arrayPtr + (i * fItemSize))));
2804 return representations;
2809 fColumns.emplace_back(Internal::RColumn::Create<bool>(
RColumnModel(GetColumnRepresentative()[0]), 0));
2814 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
2815 fColumns.emplace_back(Internal::RColumn::Create<bool>(
RColumnModel(onDiskTypes[0]), 0));
2820 const auto *asULongArray =
static_cast<const Word_t *
>(from);
2823 for (std::size_t word = 0; word < (fN + kBitsPerWord - 1) / kBitsPerWord; ++word) {
2824 for (std::size_t
mask = 0; (
mask < kBitsPerWord) && (i < fN); ++
mask, ++i) {
2825 elementValue = (asULongArray[word] & (
static_cast<Word_t>(1) <<
mask)) != 0;
2826 fColumns[0]->Append(&elementValue);
2834 auto *asULongArray =
static_cast<Word_t *
>(to);
2836 for (std::size_t i = 0; i < fN; ++i) {
2837 fColumns[0]->Read(globalIndex * fN + i, &elementValue);
2839 Word_t bit =
static_cast<Word_t>(elementValue) << (i % kBitsPerWord);
2840 asULongArray[i / kBitsPerWord] = (asULongArray[i / kBitsPerWord] & ~mask) | bit;
2854 for (
size_t i = 0; i < itemFields.size(); ++i) {
2855 result += itemFields[i]->GetTypeName() +
",";
2863 const std::vector<RFieldBase *> &itemFields)
2864 :
ROOT::Experimental::
RFieldBase(fieldName,
"std::variant<" + GetTypeList(itemFields) +
">",
2870 auto nFields = itemFields.size();
2873 for (
unsigned int i = 0; i < nFields; ++i) {
2876 fTraits &= itemFields[i]->GetTraits();
2877 Attach(std::unique_ptr<RFieldBase>(itemFields[i]));
2882std::unique_ptr<ROOT::Experimental::RFieldBase>
2885 auto nFields = fSubFields.size();
2886 std::vector<RFieldBase *> itemFields;
2887 for (
unsigned i = 0; i < nFields; ++i) {
2889 itemFields.emplace_back(fSubFields[i]->Clone(fSubFields[i]->GetFieldName()).release());
2891 return std::make_unique<RVariantField>(newName, itemFields);
2896 auto index = *(
reinterpret_cast<const char *
>(variantPtr) + tagOffset);
2902 auto index =
reinterpret_cast<char *
>(variantPtr) + tagOffset;
2903 *
index =
static_cast<char>(tag - 1);
2908 auto tag = GetTag(from, fTagOffset);
2909 std::size_t nbytes = 0;
2912 nbytes += CallAppendOn(*fSubFields[tag - 1], from);
2913 index = fNWritten[tag - 1]++;
2916 fColumns[0]->Append(&varSwitch);
2924 fPrincipalColumn->GetSwitchInfo(globalIndex, &variantIndex, &tag);
2930 CallConstructValueOn(*fSubFields[tag - 1], to);
2931 CallReadOn(*fSubFields[tag - 1], variantIndex, to);
2933 SetTag(to, fTagOffset, tag);
2940 return representations;
2945 fColumns.emplace_back(Internal::RColumn::Create<RColumnSwitch>(
RColumnModel(GetColumnRepresentative()[0]), 0));
2950 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
2951 fColumns.emplace_back(Internal::RColumn::Create<RColumnSwitch>(
RColumnModel(onDiskTypes[0]), 0));
2956 memset(where, 0, GetValueSize());
2957 CallConstructValueOn(*fSubFields[0], where);
2958 SetTag(where, fTagOffset, 1);
2963 auto tag = GetTag(objPtr, fTagOffset);
2965 fItemDeleters[tag - 1]->operator()(objPtr,
true );
2967 RDeleter::operator()(objPtr, dtorOnly);
2972 std::vector<std::unique_ptr<RDeleter>> itemDeleters;
2973 itemDeleters.reserve(fSubFields.size());
2974 for (
const auto &
f : fSubFields) {
2975 itemDeleters.emplace_back(GetDeleterOf(*
f));
2977 return std::make_unique<RVariantDeleter>(fTagOffset, itemDeleters);
2982 return fMaxItemSize + fMaxAlignment;
2987 std::fill(fNWritten.begin(), fNWritten.end(), 0);
2993 std::unique_ptr<RFieldBase> itemField)
3000 auto newItemField = fSubFields[0]->
Clone(fSubFields[0]->GetFieldName());
3001 return std::make_unique<RSetField>(newName, GetTypeName(), std::move(newItemField));
3007 std::unique_ptr<RFieldBase> itemField)
3010 if (!
dynamic_cast<RPairField *
>(itemField.get()))
3016 Attach(std::move(itemField));
3021 std::size_t nbytes = 0;
3025 nbytes += CallAppendOn(*fSubFields[0], ptr);
3029 fColumns[0]->Append(&fNWritten);
3030 return nbytes + fColumns[0]->GetElement()->GetPackedSize();
3037 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
3045 CallReadOn(*fSubFields[0], collectionStart + i, ptr);
3050 fProxy->Commit(obj);
3055 std::vector<RValue>
result;
3056 auto valueRawPtr =
value.GetPtr<
void>().get();
3059 result.emplace_back(fSubFields[0]->BindValue(std::shared_ptr<void>(
value.GetPtr<
void>(), ptr)));
3066 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetFieldName());
3067 return std::unique_ptr<RMapField>(
new RMapField(newName, GetTypeName(), std::move(newItemField)));
3073 std::unique_ptr<RFieldBase> itemField)
3076 Attach(std::move(itemField));
3085 return representations;
3090 if (HasDefaultColumnRepresentative()) {
3091 if (fSubFields[0]->GetValueSize() < 4) {
3096 fDefaultItemValue = std::make_unique<RValue>(fSubFields[0]->CreateValue());
3099 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(
RColumnModel(GetColumnRepresentative()[0]), 0));
3105 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
3109 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(
RColumnModel(onDiskTypes[0]), 0));
3117 fPrincipalColumn->Append(&
mask);
3118 return 1 + CallAppendOn(*fSubFields[0], fDefaultItemValue->GetPtr<
void>().get());
3120 fPrincipalColumn->Append(&fNWritten);
3127 auto nbytesItem = CallAppendOn(*fSubFields[0], from);
3130 fPrincipalColumn->Append(&
mask);
3131 return 1 + nbytesItem;
3134 fPrincipalColumn->Append(&fNWritten);
3143 const bool isValidItem = *fPrincipalColumn->Map<
bool>(globalIndex);
3144 return isValidItem ? fPrincipalColumn->GetClusterIndex(globalIndex) : nullIndex;
3148 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &collectionSize);
3149 return (collectionSize == 0) ? nullIndex : collectionStart;
3161 std::unique_ptr<RFieldBase> itemField)
3162 :
RNullableField(fieldName, typeName, std::move(itemField)), fItemDeleter(GetDeleterOf(*fSubFields[0]))
3166std::unique_ptr<ROOT::Experimental::RFieldBase>
3169 auto newItemField = fSubFields[0]->
Clone(fSubFields[0]->GetFieldName());
3170 return std::make_unique<RUniquePtrField>(newName, GetTypeName(), std::move(newItemField));
3175 auto typedValue =
static_cast<const std::unique_ptr<char> *
>(from);
3177 return AppendValue(typedValue->get());
3179 return AppendNull();
3185 auto ptr =
static_cast<std::unique_ptr<char> *
>(to);
3186 bool isValidValue =
static_cast<bool>(*ptr);
3188 auto itemIndex = GetItemIndex(globalIndex);
3191 void *valuePtr =
nullptr;
3193 valuePtr = ptr->get();
3195 if (isValidValue && !isValidItem) {
3197 fItemDeleter->operator()(valuePtr,
false );
3204 if (!isValidValue) {
3205 valuePtr =
malloc(fSubFields[0]->GetValueSize());
3206 CallConstructValueOn(*fSubFields[0], valuePtr);
3207 ptr->reset(
reinterpret_cast<char *
>(valuePtr));
3210 CallReadOn(*fSubFields[0], itemIndex, valuePtr);
3215 auto typedPtr =
static_cast<std::unique_ptr<char> *
>(objPtr);
3217 fItemDeleter->operator()(typedPtr->get(),
false );
3218 typedPtr->release();
3220 RDeleter::operator()(objPtr, dtorOnly);
3225 return std::make_unique<RUniquePtrDeleter>(GetDeleterOf(*fSubFields[0]));
3228std::vector<ROOT::Experimental::RFieldBase::RValue>
3231 std::vector<RValue>
result;
3232 const auto &ptr =
value.GetRef<std::unique_ptr<char>>();
3234 result.emplace_back(fSubFields[0]->BindValue(std::shared_ptr<void>(
value.GetPtr<
void>(), ptr.get())));
3242ROOT::Experimental::RPairField::RPairField::GetTypeList(
const std::array<std::unique_ptr<RFieldBase>, 2> &itemFields)
3244 return itemFields[0]->GetTypeName() +
"," + itemFields[1]->GetTypeName();
3248 std::array<std::unique_ptr<RFieldBase>, 2> &&itemFields,
3249 const std::array<std::size_t, 2> &offsets)
3250 :
ROOT::Experimental::
RRecordField(fieldName, std::move(itemFields), offsets,
3251 "std::pair<" + GetTypeList(itemFields) +
">")
3256 std::array<std::unique_ptr<RFieldBase>, 2> &itemFields)
3258 "std::pair<" + GetTypeList(itemFields) +
">")
3266 auto firstElem =
fClass->GetRealData(
"first");
3269 fOffsets[0] = firstElem->GetThisOffset();
3271 auto secondElem =
fClass->GetRealData(
"second");
3274 fOffsets[1] = secondElem->GetThisOffset();
3277std::unique_ptr<ROOT::Experimental::RFieldBase>
3280 std::array<std::unique_ptr<RFieldBase>, 2> items{fSubFields[0]->Clone(fSubFields[0]->GetFieldName()),
3281 fSubFields[1]->Clone(fSubFields[1]->GetFieldName())};
3283 std::unique_ptr<RPairField>
result(
new RPairField(newName, std::move(items), {fOffsets[0], fOffsets[1]}));
3295 fClass->Destructor(objPtr,
true );
3296 RDeleter::operator()(objPtr, dtorOnly);
3302ROOT::Experimental::RTupleField::RTupleField::GetTypeList(
const std::vector<std::unique_ptr<RFieldBase>> &itemFields)
3305 if (itemFields.empty())
3306 throw RException(
R__FAIL(
"the type list for std::tuple must have at least one element"));
3307 for (
size_t i = 0; i < itemFields.size(); ++i) {
3308 result += itemFields[i]->GetTypeName() +
",";
3315 std::vector<std::unique_ptr<RFieldBase>> &&itemFields,
3316 const std::vector<std::size_t> &offsets)
3317 :
ROOT::Experimental::
RRecordField(fieldName, std::move(itemFields), offsets,
3318 "std::tuple<" + GetTypeList(itemFields) +
">")
3323 std::vector<std::unique_ptr<RFieldBase>> &itemFields)
3325 "std::tuple<" + GetTypeList(itemFields) +
">")
3337 for (
unsigned i = 0; i < fSubFields.size(); ++i) {
3338 std::string memberName(
"_" + std::to_string(i));
3339 auto member =
fClass->GetRealData(memberName.c_str());
3342 fOffsets.push_back(member->GetThisOffset());
3346std::unique_ptr<ROOT::Experimental::RFieldBase>
3349 std::vector<std::unique_ptr<RFieldBase>> items;
3350 items.reserve(fSubFields.size());
3351 for (
const auto &item : fSubFields)
3352 items.push_back(item->Clone(item->GetFieldName()));
3354 std::unique_ptr<RTupleField>
result(
new RTupleField(newName, std::move(items), fOffsets));
3366 fClass->Destructor(objPtr,
true );
3367 RDeleter::operator()(objPtr, dtorOnly);
3373 std::shared_ptr<RNTupleCollectionWriter> collectionWriter,
3374 std::unique_ptr<RFieldZero> collectionParent)
3377 const std::size_t
N = collectionParent->
fSubFields.size();
3378 for (std::size_t i = 0; i <
N; ++i) {
3379 Attach(std::move(collectionParent->fSubFields[i]));
3389 return representations;
3394 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(
RColumnModel(GetColumnRepresentative()[0]), 0));
3399 auto onDiskTypes = EnsureCompatibleColumnTypes(desc);
3400 fColumns.emplace_back(Internal::RColumn::Create<ClusterSize_t>(
RColumnModel(onDiskTypes[0]), 0));
3403std::unique_ptr<ROOT::Experimental::RFieldBase>
3406 auto parent = std::make_unique<RFieldZero>();
3407 for (
auto&
f : fSubFields) {
3408 parent->Attach(
f->Clone(
f->GetFieldName()));
3410 return std::make_unique<RCollectionField>(newName, fCollectionWriter, std::move(parent));
3417 std::size_t bytesWritten = fCollectionWriter->fBytesWritten;
3418 fCollectionWriter->fBytesWritten = 0;
3420 fColumns[0]->Append(from);
3421 return bytesWritten + fColumns[0]->GetElement()->GetPackedSize();
3426 R__ASSERT(
false &&
"should never read an RCollectionField");
3431 *fCollectionWriter->GetOffsetPtr() = 0;
3437 std::unique_ptr<RFieldBase> itemField)
3444 Attach(std::move(itemField));
3447std::unique_ptr<ROOT::Experimental::RFieldBase>
3450 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetFieldName());
3451 return std::make_unique<RAtomicField>(newName, GetTypeName(), std::move(newItemField));
3454std::vector<ROOT::Experimental::RFieldBase::RValue>
3457 std::vector<RValue>
result;
3458 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
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t mask
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t target
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h length
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t child
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
Abstract base class for classes implementing the visitor design pattern.
virtual void VisitProxiedCollectionField(const RProxiedCollectionField &field)
virtual void VisitBoolField(const RField< bool > &field)
virtual void VisitBitsetField(const RBitsetField &field)
virtual void VisitNullableField(const RNullableField &field)
virtual void VisitFieldZero(const RFieldZero &field)
virtual void VisitRVecField(const RRVecField &field)
virtual void VisitCardinalityField(const RCardinalityField &field)
virtual void VisitEnumField(const REnumField &field)
virtual void VisitArrayAsRVecField(const RArrayAsRVecField &field)
virtual void VisitDoubleField(const RField< double > &field)
virtual void VisitField(const RFieldBase &field)=0
virtual void VisitCharField(const RField< char > &field)
virtual void VisitArrayField(const RArrayField &field)
virtual void VisitClassField(const RClassField &field)
virtual void VisitRecordField(const RRecordField &field)
virtual void VisitVectorField(const RVectorField &field)
virtual void VisitFloatField(const RField< float > &field)
virtual void VisitAtomicField(const RAtomicField &field)
static std::string GetTypeName(EColumnType type)
Abstract interface to write data into an ntuple.
const RNTupleWriteOptions & GetWriteOptions() const
Returns the sink's write options.
Abstract interface to read data from an ntuple.
const RSharedDescriptorGuard GetSharedDescriptorGuard() const
Takes the read lock for the descriptor.
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
The size of a value of this field, i.e. an RVec.
std::size_t GetAlignment() const final
As a rule of thumb, the alignment is equal to the size of the type.
std::size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
std::size_t 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
Creates the backing columns corresponsing to the field type for writing.
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
RBitsetField(std::string_view fieldName, std::size_t N)
const RColumnRepresentations & GetColumnRepresentations() const final
Implementations in derived classes should return a static RColumnRepresentations object.
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
const RColumnRepresentations & GetColumnRepresentations() const final
Implementations in derived classes should return a static RColumnRepresentations object.
const RField< RNTupleCardinality< std::uint32_t > > * As32Bit() const
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type for writing.
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
const RField< RNTupleCardinality< std::uint64_t > > * As64Bit() const
void operator()(void *objPtr, bool dtorOnly) final
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() only once connected; derived classes may override this as appropriate.
size_t GetValueSize() const override
The number of bytes taken by a value of the appropriate type.
void ConstructValue(void *where) const override
Constructs value in a given location of size at least GetValueSize(). Called by the base class' Creat...
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
void AddReadCallbacksFromIORules(const std::span< const TSchemaRule * > rules, TClass *classp=nullptr)
Register post-read callbacks corresponding to a list of ROOT I/O customization rules.
void AcceptVisitor(Detail::RFieldVisitor &visitor) const override
std::uint32_t GetTypeVersion() const final
Indicates an evolution of the C++ type itself.
RClassField(std::string_view fieldName, std::string_view className, TClass *classp)
std::vector< RValue > SplitValue(const RValue &value) const final
Creates the list of direct child values given a value for this field.
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
Creates the backing columns corresponsing to the field type for writing.
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
void CommitClusterImpl() final
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
const RColumnRepresentations & GetColumnRepresentations() const final
Implementations in derived classes should return a static RColumnRepresentations object.
Holds the static meta-data of an RNTuple column.
Holds the index and the tag of a kSwitch column.
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.
virtual void GenerateColumnsImpl()=0
Creates the backing columns corresponsing to the field type for writing.
static constexpr int kTraitTriviallyDestructible
The type is cleaned up just by freeing its memory. I.e. the destructor performs a no-op.
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 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.
RConstSchemaIterator cbegin() 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....
std::vector< EColumnType > ColumnRepresentation_t
virtual std::size_t ReadBulkImpl(const RBulkSpec &bulkSpec)
General implementation of bulk read.
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.
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.
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.
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)
static RResult< std::unique_ptr< RFieldBase > > Create(const std::string &fieldName, const std::string &canonicalType, const std::string &typeAlias)
Factory method to resurrect a field from the stored on-disk type information.
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 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.
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
Creates the backing columns corresponsing to the field type for writing.
void AcceptVisitor(Detail::RFieldVisitor &visitor) const final
RClusterIndex GetItemIndex(NTupleSize_t globalIndex)
Given the index of the nullable field, returns the corresponding global index of the subfield or,...
RNullableField(std::string_view fieldName, std::string_view typeName, std::unique_ptr< RFieldBase > itemField)
std::size_t AppendValue(const void *from)
void operator()(void *objPtr, bool dtorOnly) final
The generic field for std::pair<T1, T2> types.
void ConstructValue(void *where) const override
Constructs value in a given location of size at least GetValueSize(). Called by the base class' Creat...
RPairField(std::string_view fieldName, std::array< std::unique_ptr< RFieldBase >, 2 > &&itemFields, const std::array< std::size_t, 2 > &offsets)
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const override
Called by Clone(), which additionally copies the on-disk ID.
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
Creates the backing columns corresponsing to the field type for writing.
std::vector< RValue > SplitValue(const RValue &value) const override
Creates the list of direct child values given a value for this field.
RCollectionIterableOnce::RIteratorFuncs fIFuncsWrite
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) override
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
Creates the backing columns corresponsing to the field type for writing.
std::size_t AppendImpl(const void *from) override
Operations on values of complex types, e.g.
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) override
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
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
size_t GetValueSize() const final
The number of bytes taken by a value of the appropriate type.
static void SetTag(void *variantPtr, std::size_t tagOffset, std::uint32_t tag)
const RColumnRepresentations & GetColumnRepresentations() const final
Implementations in derived classes should return a static RColumnRepresentations object.
void ConstructValue(void *where) const override
Constructs value in a given location of size at least GetValueSize(). Called by the base class' Creat...
static std::string GetTypeList(const std::vector< RFieldBase * > &itemFields)
std::vector< ClusterSize_t::ValueType > fNWritten
size_t fTagOffset
In the std::variant memory layout, at which byte number is the index stored.
std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const final
Called by Clone(), which additionally copies the on-disk ID.
void GenerateColumnsImpl() final
Creates the backing columns corresponsing to the field type for writing.
void CommitClusterImpl() final
std::unique_ptr< RDeleter > GetDeleter() const final
static std::uint32_t GetTag(const void *variantPtr, std::size_t tagOffset)
Extracts the index from an std::variant and transforms it into the 1-based index used for the switch ...
std::size_t AppendImpl(const void *from) final
Operations on values of complex types, e.g.
size_t GetAlignment() const final
As a rule of thumb, the alignment is equal to the size of the type.
RVariantField(std::string_view fieldName, const std::vector< RFieldBase * > &itemFields)
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
Creates the backing columns corresponsing to the field type for writing.
void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
TClass instances represent classes, structs and namespaces in the ROOT type system.
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.
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
The TEnum class implements the enum type.
EDataType GetUnderlyingType() const
Get the underlying integer type of the enum: enum E { kOne }; // ==> int enum F: long; // ==> long Re...
Long_t Property() const override
Get property description word. For meaning of bits see EProperty.
static TEnum * GetEnum(const std::type_info &ti, ESearchAction sa=kALoadAndInterpLookup)
RAII helper class that ensures that PushProxy() / PopProxy() are called when entering / leaving a C++...
Defines a common interface to inspect/change the contents of an object that represents a collection.
@ kNeedDelete
The collection contains directly or indirectly (via other collection) some pointers that need explici...
virtual Next_t GetFunctionNext(Bool_t read=kTRUE)=0
Return a pointer to a function that can advance an iterator (see Next_t).
virtual DeleteTwoIterators_t GetFunctionDeleteTwoIterators(Bool_t read=kTRUE)=0
virtual TVirtualCollectionProxy * Generate() const =0
Returns a clean object of the actual class that derives from TVirtualCollectionProxy.
virtual CreateIterators_t GetFunctionCreateIterators(Bool_t read=kTRUE)=0
Return a pointer to a function that can create an iterator pair, where each iterator points to the be...
Wrapper around an object and giving indirect access to its content even if the object is not of a cla...
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
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
std::string ResolveTypedef(const char *tname, bool resolveAll=false)
std::string CleanType(const char *typeDesc, int mode=0, const char **tail=nullptr)
Cleanup type description, redundant blanks removed and redundant tail ignored return *tail = pointer ...
Wrap the integer in a struct in order to avoid template specialization clash with std::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.
std::default_delete< T > deleter
TVirtualCollectionProxy::Next_t fNext
TVirtualCollectionProxy::DeleteTwoIterators_t fDeleteTwoIterators
TVirtualCollectionProxy::CreateIterators_t fCreateIterators