Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
REntry.hxx
Go to the documentation of this file.
1/// \file ROOT/REntry.hxx
2/// \ingroup NTuple ROOT7
3/// \author Jakob Blomer <jblomer@cern.ch>
4/// \date 2018-07-19
5/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
6/// is welcome!
7
8/*************************************************************************
9 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
10 * All rights reserved. *
11 * *
12 * For the licensing terms see $ROOTSYS/LICENSE. *
13 * For the list of contributors see $ROOTSYS/README/CREDITS. *
14 *************************************************************************/
15
16#ifndef ROOT7_REntry
17#define ROOT7_REntry
18
19#include <ROOT/RError.hxx>
20#include <ROOT/RField.hxx>
21#include <string_view>
22
23#include <TError.h>
24
25#include <algorithm>
26#include <iterator>
27#include <memory>
28#include <type_traits>
29#include <utility>
30#include <vector>
31
32namespace ROOT {
33namespace Experimental {
34
35// clang-format off
36/**
37\class ROOT::Experimental::REntry
38\ingroup NTuple
39\brief The REntry is a collection of values in an ntuple corresponding to a complete row in the data set
40
41The entry provides a memory-managed binder for a set of values. Through shared pointers, the memory locations
42that are associated to values are managed.
43*/
44// clang-format on
45class REntry {
47 friend class RNTupleModel;
48 friend class RNTupleReader;
49 friend class RNTupleFillContext;
50
51 /// The entry must be linked to a specific model (or one if its clones), identified by a model ID
52 std::uint64_t fModelId = 0;
53 /// Corresponds to the top-level fields of the linked model
54 std::vector<RFieldBase::RValue> fValues;
55
56 // Creation of entries is done by the RNTupleModel class
57
58 REntry() = default;
59 explicit REntry(std::uint64_t modelId) : fModelId(modelId) {}
60
61 void AddValue(RFieldBase::RValue &&value) { fValues.emplace_back(std::move(value)); }
62
63 /// While building the entry, adds a new value to the list and return the value's shared pointer
64 template <typename T, typename... ArgsT>
65 std::shared_ptr<T> AddValue(RField<T> &field, ArgsT &&...args)
66 {
67 auto ptr = std::make_shared<T>(std::forward<ArgsT>(args)...);
68 fValues.emplace_back(field.BindValue(ptr));
69 return ptr;
70 }
71
73 {
74 for (auto &v : fValues) {
75 v.Read(index);
76 }
77 }
78
79 std::size_t Append()
80 {
81 std::size_t bytesWritten = 0;
82 for (auto &v : fValues) {
83 bytesWritten += v.Append();
84 }
85 return bytesWritten;
86 }
87
88public:
89 using ConstIterator_t = decltype(fValues)::const_iterator;
90
91 /// The field token identifies a top-level field in this entry. It can be used for fast indexing in REntry's
92 /// methods, e.g. BindValue
94 friend class REntry;
95 std::size_t fIndex; ///< the index in fValues that belongs to the top-level field
96 std::uint64_t fModelId; ///< Safety check to prevent tokens from other models being used
97 RFieldToken(std::size_t index, std::uint64_t modelId) : fIndex(index), fModelId(modelId) {}
98 };
99
100 REntry(const REntry &other) = delete;
101 REntry &operator=(const REntry &other) = delete;
102 REntry(REntry &&other) = default;
103 REntry &operator=(REntry &&other) = default;
104 ~REntry() = default;
105
106 /// The ordinal of the top-level field fieldName; can be used in other methods to address the corresponding value
107 RFieldToken GetToken(std::string_view fieldName) const
108 {
109 auto it = std::find_if(fValues.begin(), fValues.end(),
110 [&fieldName] (const RFieldBase::RValue &value) { return value.GetField().GetFieldName() == fieldName; });
111
112 if ( it == fValues.end() ) {
113 throw RException(R__FAIL("invalid field name: " + std::string(fieldName)));
114 }
115 return RFieldToken(std::distance(fValues.begin(), it), fModelId);
116 }
117
118 template <typename T>
119 void BindValue(RFieldToken token, std::shared_ptr<T> objPtr)
120 {
121 if (fModelId != token.fModelId) {
122 throw RException(R__FAIL("invalid token for this entry, "
123 "make sure to use a token from the same model as this entry."));
124 }
125 auto &v = fValues[token.fIndex];
126 if constexpr (!std::is_void_v<T>) {
127 if (v.GetField().GetTypeName() != RField<T>::TypeName()) {
128 throw RException(R__FAIL("type mismatch for field " + v.GetField().GetFieldName() + ": " +
129 v.GetField().GetTypeName() + " vs. " + RField<T>::TypeName()));
130 }
131 }
132 v.Bind(objPtr);
133 }
134
135 template <typename T>
136 void BindValue(std::string_view fieldName, std::shared_ptr<T> objPtr)
137 {
138 BindValue<T>(GetToken(fieldName), objPtr);
139 }
140
141 template <typename T>
142 void BindRawPtr(RFieldToken token, T *rawPtr)
143 {
144 BindValue<void>(token, std::shared_ptr<T>(rawPtr, [](T *) {}));
145 }
146
147 template <typename T>
148 void BindRawPtr(std::string_view fieldName, T *rawPtr)
149 {
150 BindValue<void>(fieldName, std::shared_ptr<T>(rawPtr, [](T *) {}));
151 }
152
153 template <typename T>
154 std::shared_ptr<T> GetPtr(RFieldToken token) const
155 {
156 if (fModelId != token.fModelId) {
157 throw RException(R__FAIL("invalid token for this entry"));
158 }
159
160 auto &v = fValues[token.fIndex];
161 if constexpr (std::is_void_v<T>)
162 return v.GetPtr<void>();
163
164 if (v.GetField().GetTypeName() != RField<T>::TypeName()) {
165 throw RException(R__FAIL("type mismatch for field " + v.GetField().GetFieldName() + ": " +
166 v.GetField().GetTypeName() + " vs. " + RField<T>::TypeName()));
167 }
168 return std::static_pointer_cast<T>(v.GetPtr<void>());
169 }
170
171 template <typename T>
172 std::shared_ptr<T> GetPtr(std::string_view fieldName) const
173 {
174 return GetPtr<T>(GetToken(fieldName));
175 }
176
177 std::uint64_t GetModelId() const { return fModelId; }
178
179 ConstIterator_t begin() const { return fValues.cbegin(); }
180 ConstIterator_t end() const { return fValues.cend(); }
181};
182
183} // namespace Experimental
184} // namespace ROOT
185
186#endif
#define R__FAIL(msg)
Short-hand to return an RResult<T> in an error state; the RError is implicitly converted into RResult...
Definition RError.hxx:290
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 value
The field token identifies a top-level field in this entry.
Definition REntry.hxx:93
std::uint64_t fModelId
Safety check to prevent tokens from other models being used.
Definition REntry.hxx:96
std::size_t fIndex
the index in fValues that belongs to the top-level field
Definition REntry.hxx:95
RFieldToken(std::size_t index, std::uint64_t modelId)
Definition REntry.hxx:97
The REntry is a collection of values in an ntuple corresponding to a complete row in the data set.
Definition REntry.hxx:45
std::uint64_t fModelId
The entry must be linked to a specific model (or one if its clones), identified by a model ID.
Definition REntry.hxx:52
void BindValue(RFieldToken token, std::shared_ptr< T > objPtr)
Definition REntry.hxx:119
REntry & operator=(REntry &&other)=default
decltype(fValues)::const_iterator ConstIterator_t
Definition REntry.hxx:89
void Read(NTupleSize_t index)
Definition REntry.hxx:72
ConstIterator_t begin() const
Definition REntry.hxx:179
REntry & operator=(const REntry &other)=delete
REntry(std::uint64_t modelId)
Definition REntry.hxx:59
REntry(REntry &&other)=default
std::uint64_t GetModelId() const
Definition REntry.hxx:177
std::shared_ptr< T > AddValue(RField< T > &field, ArgsT &&...args)
While building the entry, adds a new value to the list and return the value's shared pointer.
Definition REntry.hxx:65
void BindRawPtr(RFieldToken token, T *rawPtr)
Definition REntry.hxx:142
void BindValue(std::string_view fieldName, std::shared_ptr< T > objPtr)
Definition REntry.hxx:136
RFieldToken GetToken(std::string_view fieldName) const
The ordinal of the top-level field fieldName; can be used in other methods to address the correspondi...
Definition REntry.hxx:107
void AddValue(RFieldBase::RValue &&value)
Definition REntry.hxx:61
std::vector< RFieldBase::RValue > fValues
Corresponds to the top-level fields of the linked model.
Definition REntry.hxx:54
void BindRawPtr(std::string_view fieldName, T *rawPtr)
Definition REntry.hxx:148
ConstIterator_t end() const
Definition REntry.hxx:180
REntry(const REntry &other)=delete
std::shared_ptr< T > GetPtr(std::string_view fieldName) const
Definition REntry.hxx:172
std::shared_ptr< T > GetPtr(RFieldToken token) const
Definition REntry.hxx:154
Base class for all ROOT issued exceptions.
Definition RError.hxx:78
Points to an object with RNTuple I/O support and keeps a pointer to the corresponding field.
Definition RField.hxx:182
RValue BindValue(std::shared_ptr< void > objPtr)
Creates a value from a memory location with an already constructed object.
Definition RField.hxx:615
Classes with dictionaries that can be inspected by TClass.
Definition RField.hxx:1458
static std::string TypeName()
Definition RField.hxx:1471
A context for filling entries (data) into clusters of an RNTuple.
Definition RNTuple.hxx:364
The RNTupleModel encapulates the schema of an ntuple.
An RNTuple that is used to read data from storage.
Definition RNTuple.hxx:98
std::uint64_t NTupleSize_t
Integer type long enough to hold the maximum number of entries in a column.
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.