34 auto fieldNameStr = std::string(fieldName);
35 if (
fFieldNames.insert(fieldNameStr).second ==
false) {
36 throw RException(
R__FAIL(
"field name '" + fieldNameStr +
"' already exists in NTuple model"));
58 auto model = CreateBare();
59 model->fDefaultEntry = std::unique_ptr<REntry>(
new REntry());
65 auto cloneModel = std::unique_ptr<RNTupleModel>(
new RNTupleModel());
66 auto cloneFieldZero = fFieldZero->Clone(
"");
67 cloneModel->fModelId = fModelId;
68 cloneModel->fFieldZero = std::unique_ptr<RFieldZero>(
static_cast<RFieldZero *
>(cloneFieldZero.release()));
69 cloneModel->fFieldNames = fFieldNames;
70 cloneModel->fDescription = fDescription;
72 cloneModel->fDefaultEntry = std::unique_ptr<REntry>(
new REntry(fModelId));
73 for (
const auto &
f : cloneModel->fFieldZero->GetSubFields()) {
74 cloneModel->fDefaultEntry->AddValue(
f->GenerateValue());
86 EnsureValidFieldName(field->GetName());
89 fDefaultEntry->AddValue(field->GenerateValue());
90 fFieldZero->Attach(std::move(field));
95 std::string_view fieldName, std::unique_ptr<RNTupleModel> collectionModel)
98 EnsureValidFieldName(fieldName);
99 if (!collectionModel) {
102 auto collectionNTuple = std::make_shared<RCollectionNTupleWriter>(std::move(collectionModel->fDefaultEntry));
103 auto field = std::make_unique<RCollectionField>(fieldName, collectionNTuple, std::move(collectionModel));
105 fDefaultEntry->CaptureValue(field->CaptureValue(collectionNTuple->GetOffsetPtr()));
106 fFieldZero->Attach(std::move(field));
107 return collectionNTuple;
113 if (fieldName.empty())
117 for (
auto subfieldName :
ROOT::Split(fieldName,
".")) {
120 std::find_if(subfields.begin(), subfields.end(), [&](
const auto *
f) { return f->GetName() == subfieldName; });
121 if (it != subfields.end()) {
135 throw RException(
R__FAIL(
"invalid attempt to get default entry of unfrozen model"));
137 return fDefaultEntry.get();
145 auto entry = std::unique_ptr<REntry>(
new REntry(fModelId));
146 for (
const auto &
f : fFieldZero->GetSubFields()) {
147 entry->AddValue(
f->GenerateValue());
157 auto entry = std::unique_ptr<REntry>(
new REntry(fModelId));
158 for (
const auto &
f : fFieldZero->GetSubFields()) {
159 entry->CaptureValue(
f->CaptureValue(
nullptr));
169 static std::atomic<std::uint64_t> gLastModelId = 0;
170 fModelId = ++gLastModelId;
172 fDefaultEntry->fModelId = fModelId;
178 fDescription = std::string(description);
#define R__FAIL(msg)
Short-hand to return an RResult<T> in an error state; the RError is implicitly converted into RResult...
static RResult< void > EnsureValidFieldName(std::string_view fieldName)
Check whether a given string is a valid field name.
std::vector< RFieldBase * > GetSubFields() const
void Throw()
Throws an RException with fError.
The REntry is a collection of values in an ntuple corresponding to a complete row in the data set.
Base class for all ROOT issued exceptions.
The container field for an ntuple model, which itself has no physical representation.
The RNTupleModel encapulates the schema of an ntuple.
std::unordered_set< std::string > fFieldNames
Keeps track of which field names are taken.
void EnsureValidFieldName(std::string_view fieldName)
Checks that user-provided field names are valid in the context of this NTuple model.
void EnsureNotBare() const
Throws an RException if fDefaultEntry is nullptr.
std::unique_ptr< RNTupleModel > Clone() const
void EnsureNotFrozen() const
Throws an RException if fFrozen is true.
REntry * GetDefaultEntry() const
std::unique_ptr< REntry > CreateBareEntry() const
In a bare entry, all values point to nullptr.
std::unique_ptr< REntry > CreateEntry() const
static std::unique_ptr< RNTupleModel > Create()
void SetDescription(std::string_view description)
std::shared_ptr< RCollectionNTupleWriter > MakeCollection(std::string_view fieldName, std::unique_ptr< RNTupleModel > collectionModel)
Ingests a model for a sub collection and attaches it to the current model.
const Detail::RFieldBase * GetField(std::string_view fieldName) const
void AddField(std::unique_ptr< Detail::RFieldBase > field)
Adds a field whose type is not known at compile time.
The class is used as a return type for operations that can fail; wraps a value of type T or an RError...
std::vector< std::string > Split(std::string_view str, std::string_view delims, bool skipEmpty=false)
Splits a string at each character in delims.