24class CreateContextGuard;
26 friend class CreateContextGuard;
28 std::vector<std::string> fClassesOnStack;
31 bool fContinueOnError =
false;
34 CreateContext() =
default;
35 bool GetContinueOnError()
const {
return fContinueOnError; }
39class CreateContextGuard {
40 CreateContext &fCreateContext;
41 std::size_t fNOriginalClassesOnStack;
42 bool fOriginalContinueOnError;
45 CreateContextGuard(CreateContext &ctx)
46 : fCreateContext(ctx),
47 fNOriginalClassesOnStack(ctx.fClassesOnStack.
size()),
48 fOriginalContinueOnError(ctx.fContinueOnError)
53 fCreateContext.fClassesOnStack.resize(fNOriginalClassesOnStack);
54 fCreateContext.fContinueOnError = fOriginalContinueOnError;
57 void AddClassToStack(
const std::string &cl)
59 if (std::find(fCreateContext.fClassesOnStack.begin(), fCreateContext.fClassesOnStack.end(), cl) !=
60 fCreateContext.fClassesOnStack.end()) {
61 throw ROOT::RException(
R__FAIL(
"cyclic class definition: " + cl));
63 fCreateContext.fClassesOnStack.emplace_back(cl);
66 void SetContinueOnError(
bool value) { fCreateContext.fContinueOnError =
value; }
101 operator delete(objPtr, std::align_val_t(
fAlignment));
118 deserializationExtraTypes.end());
141 std::swap(
fDeleter, other.fDeleter);
142 std::swap(
fValues, other.fValues);
148 std::swap(
fField, other.fField);
149 std::swap(
fDeleter, other.fDeleter);
150 std::swap(
fValues, other.fValues);
153 std::swap(
fSize, other.fSize);
173 for (std::size_t i = 0; i <
fCapacity; ++i) {
178 operator delete(
fValues, std::align_val_t(
fField->GetAlignment()));
185 throw RException(
R__FAIL(
"invalid attempt to bulk read beyond the adopted buffer"));
191 for (std::size_t i = 0; i <
size; ++i) {
214 fMaskAvail = std::make_unique<bool[]>(capacity);
229std::unique_ptr<void, typename ROOT::RFieldBase::RCreateObjectDeleter<void>::deleter>
232 static RCreateObjectDeleter<void>::deleter gDeleter;
233 return std::unique_ptr<void, RCreateObjectDeleter<void>::deleter>(
CreateObjectRawPtr(), gDeleter);
239 bool isSimple, std::size_t nRepetitions)
256 while (parent && !parent->GetFieldName().empty()) {
258 parent = parent->GetParent();
270std::vector<ROOT::RFieldBase::RCheckResult>
276 cfOpts.SetEmulateUnknownTypes(
false);
279 std::vector<RCheckResult>
result;
280 for (
const auto &
f : fieldZero) {
287 RCheckResult{invalidField.GetQualifiedFieldName(), invalidField.GetTypeName(), invalidField.GetError()});
292ROOT::RResult<std::unique_ptr<ROOT::RFieldBase>>
302 thread_local CreateContext createContext;
303 CreateContextGuard createContextGuard(createContext);
305 createContextGuard.SetContinueOnError(
true);
307 auto fnFail = [&fieldName,
308 &resolvedType](
const std::string &errMsg,
311 if (createContext.GetContinueOnError()) {
312 return std::unique_ptr<RFieldBase>(std::make_unique<RInvalidField>(fieldName, resolvedType, errMsg, cat));
318 if (resolvedType.empty())
319 return R__FORWARD_RESULT(fnFail(
"no type name specified for field '" + fieldName +
"'"));
321 std::unique_ptr<ROOT::RFieldBase>
result;
323 const auto maybeGetChildId = [desc, fieldId](
int childId) {
335 if (resolvedType ==
"bool") {
336 result = std::make_unique<RField<bool>>(fieldName);
337 }
else if (resolvedType ==
"char") {
338 result = std::make_unique<RField<char>>(fieldName);
339 }
else if (resolvedType ==
"std::byte") {
340 result = std::make_unique<RField<std::byte>>(fieldName);
341 }
else if (resolvedType ==
"std::int8_t") {
342 result = std::make_unique<RField<std::int8_t>>(fieldName);
343 }
else if (resolvedType ==
"std::uint8_t") {
344 result = std::make_unique<RField<std::uint8_t>>(fieldName);
345 }
else if (resolvedType ==
"std::int16_t") {
346 result = std::make_unique<RField<std::int16_t>>(fieldName);
347 }
else if (resolvedType ==
"std::uint16_t") {
348 result = std::make_unique<RField<std::uint16_t>>(fieldName);
349 }
else if (resolvedType ==
"std::int32_t") {
350 result = std::make_unique<RField<std::int32_t>>(fieldName);
351 }
else if (resolvedType ==
"std::uint32_t") {
352 result = std::make_unique<RField<std::uint32_t>>(fieldName);
353 }
else if (resolvedType ==
"std::int64_t") {
354 result = std::make_unique<RField<std::int64_t>>(fieldName);
355 }
else if (resolvedType ==
"std::uint64_t") {
356 result = std::make_unique<RField<std::uint64_t>>(fieldName);
357 }
else if (resolvedType ==
"float") {
358 result = std::make_unique<RField<float>>(fieldName);
359 }
else if (resolvedType ==
"double") {
360 result = std::make_unique<RField<double>>(fieldName);
361 }
else if (resolvedType ==
"Double32_t") {
362 result = std::make_unique<RField<double>>(fieldName);
366 }
else if (resolvedType ==
"std::string") {
367 result = std::make_unique<RField<std::string>>(fieldName);
368 }
else if (resolvedType ==
"TObject") {
369 result = std::make_unique<RField<TObject>>(fieldName);
370 }
else if (resolvedType ==
"std::vector<bool>") {
371 result = std::make_unique<RField<std::vector<bool>>>(fieldName);
372 }
else if (resolvedType.substr(0, 12) ==
"std::vector<") {
373 std::string itemTypeName = resolvedType.substr(12, resolvedType.length() - 13);
374 auto itemField = Create(
"_0", itemTypeName, options, desc, maybeGetChildId(0));
375 result = std::make_unique<RVectorField>(fieldName, itemField.Unwrap());
376 }
else if (resolvedType.substr(0, 19) ==
"ROOT::VecOps::RVec<") {
377 std::string itemTypeName = resolvedType.substr(19, resolvedType.length() - 20);
378 auto itemField = Create(
"_0", itemTypeName, options, desc, maybeGetChildId(0));
379 result = std::make_unique<RRVecField>(fieldName, itemField.Unwrap());
380 }
else if (resolvedType.substr(0, 11) ==
"std::array<") {
381 auto arrayDef =
TokenizeTypeList(resolvedType.substr(11, resolvedType.length() - 12));
382 if (arrayDef.size() != 2) {
383 return R__FORWARD_RESULT(fnFail(
"the template list for std::array must have exactly two elements"));
386 auto itemField = Create(
"_0", arrayDef[0], options, desc, maybeGetChildId(0));
387 result = std::make_unique<RArrayField>(fieldName, itemField.Unwrap(), arrayLength);
388 }
else if (resolvedType.substr(0, 13) ==
"std::variant<") {
389 auto innerTypes =
TokenizeTypeList(resolvedType.substr(13, resolvedType.length() - 14));
390 std::vector<std::unique_ptr<RFieldBase>> items;
391 items.reserve(innerTypes.size());
392 for (
unsigned int i = 0; i < innerTypes.size(); ++i) {
394 Create(
"_" + std::to_string(i), innerTypes[i], options, desc, maybeGetChildId(i)).Unwrap());
396 result = std::make_unique<RVariantField>(fieldName, std::move(items));
397 }
else if (resolvedType.substr(0, 10) ==
"std::pair<") {
398 auto innerTypes =
TokenizeTypeList(resolvedType.substr(10, resolvedType.length() - 11));
399 if (innerTypes.size() != 2) {
400 return R__FORWARD_RESULT(fnFail(
"the type list for std::pair must have exactly two elements"));
402 std::array<std::unique_ptr<RFieldBase>, 2> items{
403 Create(
"_0", innerTypes[0], options, desc, maybeGetChildId(0)).Unwrap(),
404 Create(
"_1", innerTypes[1], options, desc, maybeGetChildId(1)).Unwrap()};
405 result = std::make_unique<RPairField>(fieldName, std::move(items));
406 }
else if (resolvedType.substr(0, 11) ==
"std::tuple<") {
407 auto innerTypes =
TokenizeTypeList(resolvedType.substr(11, resolvedType.length() - 12));
408 std::vector<std::unique_ptr<RFieldBase>> items;
409 items.reserve(innerTypes.size());
410 for (
unsigned int i = 0; i < innerTypes.size(); ++i) {
412 Create(
"_" + std::to_string(i), innerTypes[i], options, desc, maybeGetChildId(i)).Unwrap());
414 result = std::make_unique<RTupleField>(fieldName, std::move(items));
415 }
else if (resolvedType.substr(0, 12) ==
"std::bitset<") {
417 result = std::make_unique<RBitsetField>(fieldName,
size);
418 }
else if (resolvedType.substr(0, 16) ==
"std::unique_ptr<") {
419 std::string itemTypeName = resolvedType.substr(16, resolvedType.length() - 17);
420 auto itemField = Create(
"_0", itemTypeName, options, desc, maybeGetChildId(0)).Unwrap();
421 result = std::make_unique<RUniquePtrField>(fieldName, std::move(itemField));
422 }
else if (resolvedType.substr(0, 14) ==
"std::optional<") {
423 std::string itemTypeName = resolvedType.substr(14, resolvedType.length() - 15);
424 auto itemField = Create(
"_0", itemTypeName, options, desc, maybeGetChildId(0)).Unwrap();
425 result = std::make_unique<ROptionalField>(fieldName, std::move(itemField));
426 }
else if (resolvedType.substr(0, 9) ==
"std::set<") {
427 std::string itemTypeName = resolvedType.substr(9, resolvedType.length() - 10);
428 auto itemField =
Create(
"_0", itemTypeName, options, desc, maybeGetChildId(0)).Unwrap();
430 }
else if (resolvedType.substr(0, 19) ==
"std::unordered_set<") {
431 std::string itemTypeName = resolvedType.substr(19, resolvedType.length() - 20);
432 auto itemField =
Create(
"_0", itemTypeName, options, desc, maybeGetChildId(0)).Unwrap();
434 }
else if (resolvedType.substr(0, 14) ==
"std::multiset<") {
435 std::string itemTypeName = resolvedType.substr(14, resolvedType.length() - 15);
436 auto itemField = Create(
"_0", itemTypeName, options, desc, maybeGetChildId(0)).Unwrap();
438 }
else if (resolvedType.substr(0, 24) ==
"std::unordered_multiset<") {
439 std::string itemTypeName = resolvedType.substr(24, resolvedType.length() - 25);
440 auto itemField = Create(
"_0", itemTypeName, options, desc, maybeGetChildId(0)).Unwrap();
441 auto normalizedInnerTypeName = itemField->GetTypeName();
443 }
else if (resolvedType.substr(0, 9) ==
"std::map<") {
444 auto innerTypes =
TokenizeTypeList(resolvedType.substr(9, resolvedType.length() - 10));
445 if (innerTypes.size() != 2) {
446 return R__FORWARD_RESULT(fnFail(
"the type list for std::map must have exactly two elements"));
449 Create(
"_0",
"std::pair<" + innerTypes[0] +
"," + innerTypes[1] +
">", options, desc, maybeGetChildId(0))
452 }
else if (resolvedType.substr(0, 19) ==
"std::unordered_map<") {
453 auto innerTypes =
TokenizeTypeList(resolvedType.substr(19, resolvedType.length() - 20));
454 if (innerTypes.size() != 2)
455 return R__FORWARD_RESULT(fnFail(
"the type list for std::unordered_map must have exactly two elements"));
457 Create(
"_0",
"std::pair<" + innerTypes[0] +
"," + innerTypes[1] +
">", options, desc, maybeGetChildId(0))
460 }
else if (resolvedType.substr(0, 14) ==
"std::multimap<") {
461 auto innerTypes =
TokenizeTypeList(resolvedType.substr(14, resolvedType.length() - 15));
462 if (innerTypes.size() != 2)
463 return R__FORWARD_RESULT(fnFail(
"the type list for std::multimap must have exactly two elements"));
465 Create(
"_0",
"std::pair<" + innerTypes[0] +
"," + innerTypes[1] +
">", options, desc, maybeGetChildId(0))
468 }
else if (resolvedType.substr(0, 24) ==
"std::unordered_multimap<") {
469 auto innerTypes =
TokenizeTypeList(resolvedType.substr(24, resolvedType.length() - 25));
470 if (innerTypes.size() != 2)
472 fnFail(
"the type list for std::unordered_multimap must have exactly two elements"));
474 Create(
"_0",
"std::pair<" + innerTypes[0] +
"," + innerTypes[1] +
">", options, desc, maybeGetChildId(0))
477 }
else if (resolvedType.substr(0, 12) ==
"std::atomic<") {
478 std::string itemTypeName = resolvedType.substr(12, resolvedType.length() - 13);
479 auto itemField = Create(
"_0", itemTypeName, options, desc, maybeGetChildId(0)).Unwrap();
480 result = std::make_unique<RAtomicField>(fieldName, std::move(itemField));
481 }
else if (resolvedType.substr(0, 25) ==
"ROOT::RNTupleCardinality<") {
482 auto innerTypes =
TokenizeTypeList(resolvedType.substr(25, resolvedType.length() - 26));
483 if (innerTypes.size() != 1)
484 return R__FORWARD_RESULT(fnFail(
"invalid cardinality template: " + resolvedType));
486 if (canonicalInnerType ==
"std::uint32_t") {
487 result = std::make_unique<RField<RNTupleCardinality<std::uint32_t>>>(fieldName);
488 }
else if (canonicalInnerType ==
"std::uint64_t") {
489 result = std::make_unique<RField<RNTupleCardinality<std::uint64_t>>>(fieldName);
491 return R__FORWARD_RESULT(fnFail(
"invalid cardinality template: " + resolvedType));
499 createContextGuard.AddClassToStack(resolvedType);
500 if (cl->GetCollectionProxy()) {
501 result = std::make_unique<RProxiedCollectionField>(fieldName, typeName);
509 result = std::make_unique<ROOT::Experimental::RSoAField>(fieldName, typeName);
512 result = std::make_unique<RStreamerField>(fieldName, typeName);
514 result = std::make_unique<RClassField>(fieldName, typeName);
525 std::vector<std::unique_ptr<RFieldBase>> memberFields;
526 memberFields.reserve(fieldDesc.GetLinkIds().size());
527 for (
auto id : fieldDesc.GetLinkIds()) {
529 auto field = Create(memberDesc.GetFieldName(), memberDesc.GetTypeName(), options, desc,
id).Unwrap();
530 memberFields.emplace_back(std::move(field));
532 R__ASSERT(typeName == fieldDesc.GetTypeName());
535 recordField->fTypeAlias = fieldDesc.GetTypeAlias();
538 if (fieldDesc.GetLinkIds().size() != 1)
541 auto itemFieldId = fieldDesc.GetLinkIds()[0];
544 Create(itemFieldDesc.GetFieldName(), itemFieldDesc.GetTypeName(), options, desc, itemFieldId)
548 vecField->fTypeAlias = fieldDesc.GetTypeAlias();
557 result = std::make_unique<REnumField>(fieldName, typeName);
560 }
catch (
const RException &
e) {
561 auto error =
e.GetError();
562 if (createContext.GetContinueOnError()) {
563 return std::unique_ptr<RFieldBase>(std::make_unique<RInvalidField>(fieldName, typeName, error.GetReport(),
568 }
catch (
const std::logic_error &
e) {
570 if (createContext.GetContinueOnError()) {
571 return std::unique_ptr<RFieldBase>(
580 if (normOrigType !=
result->GetTypeName()) {
581 result->fTypeAlias = normOrigType;
591 return representations;
607 R__ASSERT(
false &&
"A non-simple RField must implement its own AppendImpl");
624 std::size_t nRead = 0;
625 for (std::size_t i = 0; i < bulkSpec.
fCount; ++i) {
645 if (align <=
sizeof(std::max_align_t)) {
665 return std::vector<RValue>();
673 throw RException(
R__FAIL(
"invalid attempt to attach subfield to already connected, non-extensible field"));
675 if (!expectedChildName.empty() &&
child->GetFieldName() != expectedChildName) {
677 " expected: " + std::string(expectedChildName)));
680 child->fParent =
this;
681 fSubfields.emplace_back(std::move(
child));
687 for (
auto f =
this;
f !=
nullptr;
f =
f->GetParent()) {
688 auto parent =
f->GetParent();
700 std::vector<RFieldBase *>
result;
710 std::vector<const RFieldBase *>
result;
721 const auto activeRepresentationIndex =
fPrincipalColumn->GetRepresentationIndex();
723 if (column->GetRepresentationIndex() == activeRepresentationIndex) {
733 const auto activeRepresentationIndex =
fPrincipalColumn->GetRepresentationIndex();
735 if (column->GetRepresentationIndex() == activeRepresentationIndex) {
738 column->CommitSuppressed();
748 throw RException(
R__FAIL(
"cannot set field description once field is connected"));
777 return RValue(
this, objPtr);
844 throw RException(
R__FAIL(
"cannot set column representative once field is connected"));
848 for (
const auto &
r : representatives) {
849 auto itRepresentative = std::find(validTypes.begin(), validTypes.end(),
r);
850 if (itRepresentative == std::end(validTypes))
859 std::uint16_t representationIndex)
const
868 if (
c.GetRepresentationIndex() == representationIndex)
869 onDiskTypes.emplace_back(
c.GetType());
871 if (onDiskTypes.empty()) {
872 if (representationIndex == 0) {
879 if (t == onDiskTypes)
883 std::string columnTypeNames;
884 for (
const auto &t : onDiskTypes) {
885 if (!columnTypeNames.empty())
886 columnTypeNames +=
", ";
890 "` cannot be matched to its in-memory type `" +
GetTypeName() +
"` " +
891 "(representation index: " + std::to_string(representationIndex) +
")"));
911 for (
auto &colType : rep) {
938 throw RException(
R__FAIL(
"invalid attempt to connect an already connected field to a page sink"));
948 column->ConnectPageSink(
fOnDiskId, pageSink, firstElementIndex);
963 f->ConnectPageSource(pageSource);
968 throw RException(
R__FAIL(
"invalid attempt to connect an already connected field to a page source"));
971 throw RException(
R__FAIL(
"fixed column representative only valid when connecting to a page sink"));
973 throw RException(
R__FAIL(
"setting description only valid when connecting to a page sink"));
994 if (
typeid(*itr) ==
typeid(
RFieldZero) &&
static_cast<const RFieldZero *
>(itr)->GetAllowFieldSubstitutions()) {
995 for (
auto &
f :
fParent->fSubfields) {
999 f = std::move(substitute);
1000 f->ConnectPageSource(pageSource);
1018 f->ConnectPageSource(pageSource);
1039 if (fieldDesc.GetTypeChecksum().has_value())
1044 column->ConnectPageSource(
fOnDiskId, pageSource);
1064 std::ostringstream errMsg;
1066 <<
"with on-disk field " << fieldDesc.GetFieldName() <<
":";
1068 errMsg <<
" field version " <<
GetFieldVersion() <<
" vs. " << fieldDesc.GetFieldVersion() <<
";";
1071 errMsg <<
" type version " <<
GetTypeVersion() <<
" vs. " << fieldDesc.GetTypeVersion() <<
";";
1074 errMsg <<
" structural role " <<
GetStructure() <<
" vs. " << fieldDesc.GetStructure() <<
";";
1077 errMsg <<
" incompatible on-disk type name " << fieldDesc.GetTypeName() <<
";";
1080 errMsg <<
" repetition count " <<
GetNRepetitions() <<
" vs. " << fieldDesc.GetNRepetitions() <<
";";
1094 const std::vector<std::string> &prefixes)
const
1097 for (
const auto &p : prefixes) {
1098 if (fieldDesc.GetTypeName().rfind(p, 0) == 0)
1107 std::uint32_t diffBits = 0;
#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(...)
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
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 r
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 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 VisitField(const ROOT::RFieldBase &field)=0
static const char * GetColumnTypeName(ROOT::ENTupleColumnType type)
Abstract interface to write data into an ntuple.
void RegisterOnCommitDatasetCallback(Callback_t callback)
The registered callback is executed at the beginning of CommitDataset();.
const ROOT::RNTupleWriteOptions & GetWriteOptions() const
Returns the sink's write options.
virtual void UpdateExtraTypeInfo(const ROOT::RExtraTypeInfoDescriptor &extraTypeInfo)=0
Adds an extra type information record to schema.
const ROOT::RNTupleDescriptor & GetRef() const
Abstract interface to read data from an ntuple.
const RSharedDescriptorGuard GetSharedDescriptorGuard() const
Takes the read lock for the descriptor. Multiple threads can take the lock concurrently....
Template specializations for C++ std::atomic.
void ConstructValue(void *where) const final
std::unique_ptr< RDeleter > GetDeleter() const final
Base class for all ROOT issued exceptions.
Points to an array of objects with RNTuple I/O support, used for bulk reading.
std::unique_ptr< bool[]> fMaskAvail
Masks invalid values in the array.
std::unique_ptr< RFieldBase::RDeleter > fDeleter
void * GetValuePtrAt(std::size_t idx) const
std::size_t fNValidValues
The sum of non-zero elements in the fMask.
bool fIsAdopted
True if the user provides the memory buffer for fValues.
void Reset(RNTupleLocalIndex firstIndex, std::size_t size)
Sets a new range for the bulk.
void * fValues
Cached deleter of fField.
std::size_t fCapacity
The size of the array memory block in number of values.
std::size_t fValueSize
Cached copy of RFieldBase::GetValueSize()
RFieldBase * fField
The field that created the array of values.
RBulkValues & operator=(const RBulkValues &)=delete
RBulkValues(RFieldBase *field)
std::size_t fSize
The number of available values in the array (provided their mask is set)
void AdoptBuffer(void *buf, std::size_t capacity)
RNTupleLocalIndex fFirstIndex
Index of the first value of the array.
The list of column representations a field can have.
Selection_t fSerializationTypes
std::vector< ColumnRepresentation_t > Selection_t
A list of column representations.
Selection_t fDeserializationTypes
The union of the serialization types and the deserialization extra types passed during construction.
void DeleteAligned(void *objPtr) const
Points to an object with RNTuple I/O support and keeps a pointer to the corresponding field.
std::shared_ptr< void > fObjPtr
Set by Bind() or by RFieldBase::CreateValue(), RFieldBase::SplitValue() or RFieldBase::BindValue()
void BindRawPtr(void *rawPtr)
A field translates read and write calls from/to underlying columns to/from tree values.
ROOT::DescriptorId_t fOnDiskId
When the columns are connected to a page source or page sink, the field represents a field id in the ...
ROOT::ENTupleStructure GetStructure() const
virtual size_t GetValueSize() const =0
What sizeof(T) for this type returns.
void Attach(std::unique_ptr< RFieldBase > child, std::string_view expectedChildName="")
Add a new subfield to the list of nested fields.
void SetColumnRepresentatives(const RColumnRepresentations::Selection_t &representatives)
Fixes a column representative.
ROOT::Internal::RColumn * fPrincipalColumn
All fields that have columns have a distinct main column.
virtual void ReconcileOnDiskField(const RNTupleDescriptor &desc)
For non-artificial fields, check compatibility of the in-memory field and the on-disk field.
ROOT::NTupleSize_t EntryToColumnElementIndex(ROOT::NTupleSize_t globalIndex) const
Translate an entry index to a column element index of the principal column.
virtual void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const
void FlushColumns()
Flushes data from active columns.
virtual void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to)
std::vector< std::unique_ptr< RFieldBase > > fSubfields
virtual const RColumnRepresentations & GetColumnRepresentations() const
Implementations in derived classes should return a static RColumnRepresentations object.
bool fIsSimple
A field qualifies as simple if it is mappable (which implies it has a single principal column),...
RConstSchemaIterator cbegin() const
std::unique_ptr< T, typename RCreateObjectDeleter< T >::deleter > CreateObject() const
Generates an object of the field type and allocates new initialized memory according to the type.
void AutoAdjustColumnTypes(const ROOT::RNTupleWriteOptions &options)
When connecting a field to a page sink, the field's default column representation is subject to adjus...
std::vector< const RFieldBase * > GetConstSubfields() const
void SetOnDiskId(ROOT::DescriptorId_t id)
void RemoveReadCallback(size_t idx)
@ kTraitTriviallyDestructible
The type is cleaned up just by freeing its memory. I.e. the destructor performs a no-op.
@ kTraitTriviallyConstructible
No constructor needs to be called, i.e.
@ kTraitMappable
A field of a fundamental type that can be directly mapped via RField<T>::Map(), i....
@ kTraitInvalidField
This field is an instance of RInvalidField and can be safely static_cast to it.
virtual void GenerateColumns()
Implementations in derived classes should create the backing columns corresponding to the field type ...
const RFieldBase * GetParent() const
std::vector< RFieldBase * > GetMutableSubfields()
std::string fDescription
Free text set by the user.
static std::vector< RCheckResult > Check(const std::string &fieldName, const std::string &typeName)
Checks if the given type is supported by RNTuple.
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...
RResult< void > EnsureMatchingOnDiskCollection(const RNTupleDescriptor &desc) const
Convenience wrapper for the common case of calling EnsureMatchinOnDiskField() for collections.
RConstSchemaIterator cend() const
std::size_t fNRepetitions
For fixed sized arrays, the array length.
std::function< void(void *)> ReadCallback_t
std::size_t Append(const void *from)
Write the given value into columns.
RValue CreateValue()
Generates an object of the field's type, wraps it in a shared pointer and returns it as an RValue con...
RSchemaIteratorTemplate< false > RSchemaIterator
const ColumnRepresentation_t & EnsureCompatibleColumnTypes(const ROOT::RNTupleDescriptor &desc, std::uint16_t representationIndex) const
Returns the on-disk column types found in the provided descriptor for fOnDiskId and the given represe...
virtual std::vector< RValue > SplitValue(const RValue &value) const
Creates the list of direct child values given an existing value for this field.
virtual std::unique_ptr< RFieldBase > CloneImpl(std::string_view newName) const =0
Called by Clone(), which additionally copies the on-disk ID.
std::string GetQualifiedFieldName() const
Returns the field name and parent field names separated by dots (grandparent.parent....
RBulkValues CreateBulk()
Creates a new, initially empty bulk.
const std::string & GetFieldName() const
void ConnectPageSink(ROOT::Internal::RPageSink &pageSink, ROOT::NTupleSize_t firstEntry=0)
Fields and their columns live in the void until connected to a physical page storage.
std::size_t ReadBulk(const RBulkSpec &bulkSpec)
Returns the number of newly available values, that is the number of bools in bulkSpec....
std::vector< ROOT::ENTupleColumnType > ColumnRepresentation_t
std::vector< ReadCallback_t > fReadCallbacks
List of functions to be called after reading a value.
RResult< void > EnsureMatchingOnDiskField(const RNTupleDescriptor &desc, std::uint32_t ignoreBits=0) const
Compares the field to the corresponding on-disk field information in the provided descriptor.
virtual void ReadInClusterImpl(RNTupleLocalIndex localIndex, void *to)
virtual void CommitClusterImpl()
std::vector< std::reference_wrapper< const ColumnRepresentation_t > > fColumnRepresentatives
Pointers into the static vector returned by RColumnRepresentations::GetSerializationTypes() when SetC...
std::uint32_t fTraits
Properties of the type that allow for optimizations of collections of that type.
virtual std::size_t AppendImpl(const void *from)
Operations on values of complex types, e.g.
RFieldBase * fParent
Subfields point to their mother field.
std::vector< std::unique_ptr< ROOT::Internal::RColumn > > fAvailableColumns
The columns are connected either to a sink or to a source (not to both); they are owned by the field.
RFieldBase(std::string_view name, std::string_view type, ROOT::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.
static RResult< std::unique_ptr< RFieldBase > > Create(const std::string &fieldName, const std::string &typeName, const ROOT::RCreateFieldOptions &options, const ROOT::RNTupleDescriptor *desc, ROOT::DescriptorId_t fieldId)
Factory method to resurrect a field from the stored on-disk type information.
std::string fTypeAlias
A typedef or using name that was used when creating the field.
virtual std::uint32_t GetFieldVersion() const
Indicates an evolution of the mapping scheme from C++ type to columns.
virtual std::unique_ptr< RFieldBase > BeforeConnectPageSource(ROOT::Internal::RPageSource &)
Called by ConnectPageSource() before connecting; derived classes may override this as appropriate,...
std::uint32_t CompareOnDiskField(const RFieldDescriptor &fieldDesc, std::uint32_t ignoreBits) const
Returns a combination of kDiff... flags, indicating peroperties that are different between the field ...
std::string fType
The C++ type captured by this field.
RColumnRepresentations::Selection_t GetColumnRepresentatives() const
Returns the fColumnRepresentative pointee or, if unset (always the case for artificial fields),...
RSchemaIteratorTemplate< true > RConstSchemaIterator
std::size_t GetNRepetitions() const
std::uint32_t fOnDiskTypeChecksum
TClass checksum cached from the descriptor after a call to ConnectPageSource().
const std::string & GetTypeName() const
ROOT::ENTupleStructure fStructure
The role of this field in the data model structure.
RValue BindValue(std::shared_ptr< void > objPtr)
Creates a value from a memory location with an already constructed object.
void SetDescription(std::string_view description)
ROOT::DescriptorId_t GetOnDiskId() const
std::uint32_t fOnDiskTypeVersion
C++ type version cached from the descriptor after a call to ConnectPageSource()
std::unique_ptr< RFieldBase > Clone(std::string_view newName) const
Copies the field and its subfields using a possibly new name and a new, unconnected set of columns.
std::string fName
The field name relative to its parent field.
void CommitCluster()
Flushes data from active columns to disk and calls CommitClusterImpl()
void ConnectPageSource(ROOT::Internal::RPageSource &pageSource)
Connects the field and its subfield tree to the given page source.
RResult< void > EnsureMatchingTypePrefix(const RNTupleDescriptor &desc, const std::vector< std::string > &prefixes) const
Many fields accept a range of type prefixes for schema evolution, e.g.
virtual ROOT::RExtraTypeInfoDescriptor GetExtraTypeInfo() const
virtual std::uint32_t GetTypeVersion() const
Indicates an evolution of the C++ type itself.
void * CreateObjectRawPtr() const
Factory method for the field's type. The caller owns the returned pointer.
void Read(ROOT::NTupleSize_t globalIndex, void *to)
virtual bool HasExtraTypeInfo() const
bool fIsArtificial
A field that is not backed on disk but computed, e.g.
virtual std::size_t ReadBulkImpl(const RBulkSpec &bulkSpec)
General implementation of bulk read.
bool HasDefaultColumnRepresentative() const
Whether or not an explicit column representative was set.
@ kDiffStructure
The in-memory field and the on-disk field differ in their structural roles.
@ kDiffTypeName
The in-memory field and the on-disk field have different type names.
@ kDiffTypeVersion
The in-memory field and the on-disk field differ in the type version.
@ kDiffFieldVersion
The in-memory field and the on-disk field differ in the field version.
@ kDiffNRepetitions
The in-memory field and the on-disk field have different repetition counts.
Metadata stored for every field of an RNTuple.
std::uint32_t GetFieldVersion() const
ROOT::ENTupleStructure GetStructure() const
const std::vector< ROOT::DescriptorId_t > & GetLinkIds() const
std::uint64_t GetNRepetitions() const
std::uint32_t GetTypeVersion() const
const std::string & GetTypeName() const
The container field for an ntuple model, which itself has no physical representation.
void Attach(std::unique_ptr< RFieldBase > child)
A public version of the Attach method that allows piece-wise construction of the zero field.
Classes with dictionaries that can be inspected by TClass.
Used in RFieldBase::Check() to record field creation failures.
@ kGeneric
Generic unrecoverable error.
@ kUnknownType
The type given to RFieldBase::Create was unknown.
@ kTypeError
The type given to RFieldBase::Create was invalid.
The on-storage metadata of an RNTuple.
const RFieldDescriptor & GetFieldDescriptor(ROOT::DescriptorId_t fieldId) const
RColumnDescriptorIterable GetColumnIterable() const
ROOT::DescriptorId_t FindFieldId(std::string_view fieldName, ROOT::DescriptorId_t parentId) const
Addresses a column element or field item relative to a particular cluster, instead of a global NTuple...
Common user-tunable settings for storing RNTuples.
std::uint32_t GetCompression() const
The class is used as a return type for operations that can fail; wraps a value of type T or an RError...
size_t GetAlignment() const final
size_t GetValueSize() const final
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.
static TEnum * GetEnum(const std::type_info &ti, ESearchAction sa=kALoadAndInterpLookup)
std::vector< std::string > TokenizeTypeList(std::string_view templateType, std::size_t maxArgs=0)
Used in RFieldBase::Create() in order to get the comma-separated list of template types E....
std::unique_ptr< RFieldBase > CreateEmulatedVectorField(std::string_view fieldName, std::unique_ptr< RFieldBase > itemField, std::string_view emulatedFromType)
RResult< void > EnsureValidNameForRNTuple(std::string_view name, std::string_view where)
Check whether a given string is a valid name according to the RNTuple specification.
ROOT::RLogChannel & NTupleLog()
Log channel for RNTuple diagnostics.
void CallCommitClusterOnField(RFieldBase &)
void CallConnectPageSourceOnField(RFieldBase &, ROOT::Internal::RPageSource &)
unsigned long long ParseUIntTypeToken(const std::string &uintToken)
std::unique_ptr< RFieldBase > CreateEmulatedRecordField(std::string_view fieldName, std::vector< std::unique_ptr< RFieldBase > > itemFields, std::string_view emulatedFromType)
std::string GetRNTupleSoARecord(const TClass *cl)
Checks if the "rntuple.SoARecord" class attribute is set in the dictionary.
ROOT::RResult< std::unique_ptr< ROOT::RFieldBase > > CallFieldBaseCreate(const std::string &fieldName, const std::string &typeName, const ROOT::RCreateFieldOptions &options, const ROOT::RNTupleDescriptor *desc, ROOT::DescriptorId_t fieldId)
std::string GetTypeTraceReport(const RFieldBase &field, const RNTupleDescriptor &desc)
Prints the hierarchy of types with their field names and field IDs for the given in-memory field and ...
auto MakeAliasedSharedPtr(T *rawPtr)
std::string GetCanonicalTypePrefix(const std::string &typeName)
Applies RNTuple specific type name normalization rules (see specs) that help the string parsing in RF...
void CallFlushColumnsOnField(RFieldBase &)
std::string GetNormalizedUnresolvedTypeName(const std::string &origName)
Applies all RNTuple type normalization rules except typedef resolution.
ERNTupleSerializationMode GetRNTupleSerializationMode(const TClass *cl)
bool IsStdAtomicFieldDesc(const RFieldDescriptor &fieldDesc)
Tells if the field describes a std::atomic<T> type.
void CallConnectPageSinkOnField(RFieldBase &, ROOT::Internal::RPageSink &, ROOT::NTupleSize_t firstEntry=0)
std::uint64_t DescriptorId_t
Distriniguishes elements of the same type within a descriptor, e.g. different fields.
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
constexpr DescriptorId_t kInvalidDescriptorId
ENTupleStructure
The fields in the RNTuple data model tree can carry different structural information about the type s...
std::string ResolveTypedef(const char *tname, bool resolveAll=false)
void SetReturnInvalidOnError(bool v)
bool GetReturnInvalidOnError() const
bool GetEmulateUnknownTypes() const
Input parameter to RFieldBase::ReadBulk() and RFieldBase::ReadBulkImpl().
static const std::size_t kAllSet
Possible return value of ReadBulk() and ReadBulkImpl(), which indicates that the full bulk range was ...
RNTupleLocalIndex fFirstIndex
Start of the bulk range.
void * fValues
The destination area, which has to be an array of valid objects of the correct type large enough to h...
std::size_t fCount
Size of the bulk range.
bool * fMaskAvail
A bool array of size fCount, indicating the valid values in fValues.
const bool * fMaskReq
A bool array of size fCount, indicating the required values in the requested range.
Used in the return value of the Check() method.