Warning, file /include/root/ROOT/REntry.hxx was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef ROOT_REntry
0015 #define ROOT_REntry
0016
0017 #include <ROOT/RError.hxx>
0018 #include <ROOT/RField.hxx>
0019 #include <ROOT/RFieldToken.hxx>
0020 #include <string_view>
0021
0022 #include <TError.h>
0023
0024 #include <algorithm>
0025 #include <iterator>
0026 #include <memory>
0027 #include <type_traits>
0028 #include <utility>
0029 #include <vector>
0030 #include <unordered_map>
0031
0032 namespace ROOT {
0033
0034 class RNTupleFillContext;
0035 class RNTupleReader;
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047 class REntry {
0048 friend class RNTupleFillContext;
0049 friend class RNTupleModel;
0050 friend class RNTupleReader;
0051
0052 private:
0053
0054 std::uint64_t fModelId = 0;
0055
0056 std::uint64_t fSchemaId = 0;
0057
0058 std::vector<ROOT::RFieldBase::RValue> fValues;
0059
0060 std::unordered_map<std::string, std::size_t> fFieldName2Token;
0061
0062 std::vector<std::string> fFieldTypes;
0063
0064
0065 REntry() = default;
0066 explicit REntry(std::uint64_t modelId, std::uint64_t schemaId) : fModelId(modelId), fSchemaId(schemaId) {}
0067
0068 void AddValue(ROOT::RFieldBase::RValue &&value)
0069 {
0070 fFieldName2Token[value.GetField().GetQualifiedFieldName()] = fValues.size();
0071 fFieldTypes.push_back(value.GetField().GetTypeName());
0072 fValues.emplace_back(std::move(value));
0073 }
0074
0075
0076 template <typename T>
0077 std::shared_ptr<T> AddValue(ROOT::RField<T> &field)
0078 {
0079 fFieldName2Token[field.GetQualifiedFieldName()] = fValues.size();
0080 fFieldTypes.push_back(field.GetTypeName());
0081 auto value = field.CreateValue();
0082 fValues.emplace_back(value);
0083
0084 return std::static_pointer_cast<T>(value.template GetPtr<void>());
0085 }
0086
0087 void Read(ROOT::NTupleSize_t index)
0088 {
0089 for (auto &v : fValues) {
0090 v.Read(index);
0091 }
0092 }
0093
0094 std::size_t Append()
0095 {
0096 std::size_t bytesWritten = 0;
0097 for (auto &v : fValues) {
0098 bytesWritten += v.Append();
0099 }
0100 return bytesWritten;
0101 }
0102
0103 void EnsureMatchingModel(ROOT::RFieldToken token) const
0104 {
0105 if (fSchemaId != token.fSchemaId) {
0106 throw RException(R__FAIL("invalid token for this entry, "
0107 "make sure to use a token from a model with the same schema as this entry."));
0108 }
0109 }
0110
0111
0112 const std::string &FindFieldName(ROOT::RFieldToken token) const
0113 {
0114 for (const auto &[fieldName, index] : fFieldName2Token) {
0115 if (index == token.fIndex) {
0116 return fieldName;
0117 }
0118 }
0119
0120 static const std::string empty = "";
0121 return empty;
0122 }
0123
0124 template <typename T>
0125 void EnsureMatchingType(ROOT::RFieldToken token [[maybe_unused]]) const
0126 {
0127 if constexpr (!std::is_void_v<T>) {
0128 if (!Internal::IsMatchingFieldType<T>(fFieldTypes[token.fIndex])) {
0129 throw RException(R__FAIL("type mismatch for field " + FindFieldName(token) + ": " +
0130 fFieldTypes[token.fIndex] + " vs. " + ROOT::RField<T>::TypeName()));
0131 }
0132 }
0133 }
0134
0135 public:
0136 using ConstIterator_t = decltype(fValues)::const_iterator;
0137
0138 REntry(const REntry &other) = delete;
0139 REntry &operator=(const REntry &other) = delete;
0140 REntry(REntry &&other) = default;
0141 REntry &operator=(REntry &&other) = default;
0142 ~REntry() = default;
0143
0144
0145 ROOT::RFieldToken GetToken(std::string_view fieldName) const
0146 {
0147 auto it = fFieldName2Token.find(std::string(fieldName));
0148 if (it == fFieldName2Token.end()) {
0149 throw RException(R__FAIL("invalid field name: " + std::string(fieldName)));
0150 }
0151 return ROOT::RFieldToken(it->second, fSchemaId);
0152 }
0153
0154
0155 void EmplaceNewValue(ROOT::RFieldToken token)
0156 {
0157 EnsureMatchingModel(token);
0158 fValues[token.fIndex].EmplaceNew();
0159 }
0160
0161
0162 void EmplaceNewValue(std::string_view fieldName) { EmplaceNewValue(GetToken(fieldName)); }
0163
0164
0165
0166
0167 template <typename T>
0168 void BindValue(ROOT::RFieldToken token, std::shared_ptr<T> objPtr)
0169 {
0170 EnsureMatchingModel(token);
0171 EnsureMatchingType<T>(token);
0172 fValues[token.fIndex].Bind(objPtr);
0173 }
0174
0175
0176
0177
0178
0179
0180
0181
0182 template <typename T>
0183 void BindValue(std::string_view fieldName, std::shared_ptr<T> objPtr)
0184 {
0185 BindValue<T>(GetToken(fieldName), objPtr);
0186 }
0187
0188
0189
0190
0191 template <typename T>
0192 void BindRawPtr(ROOT::RFieldToken token, T *rawPtr)
0193 {
0194 EnsureMatchingModel(token);
0195 EnsureMatchingType<T>(token);
0196 fValues[token.fIndex].BindRawPtr(rawPtr);
0197 }
0198
0199
0200
0201
0202
0203
0204
0205
0206 template <typename T>
0207 void BindRawPtr(std::string_view fieldName, T *rawPtr)
0208 {
0209 BindRawPtr<void>(GetToken(fieldName), rawPtr);
0210 }
0211
0212
0213
0214
0215 template <typename T>
0216 std::shared_ptr<T> GetPtr(ROOT::RFieldToken token) const
0217 {
0218 EnsureMatchingModel(token);
0219 EnsureMatchingType<T>(token);
0220 return std::static_pointer_cast<T>(fValues[token.fIndex].GetPtr<void>());
0221 }
0222
0223
0224
0225
0226
0227
0228
0229 template <typename T>
0230 std::shared_ptr<T> GetPtr(std::string_view fieldName) const
0231 {
0232 return GetPtr<T>(GetToken(fieldName));
0233 }
0234
0235 const std::string &GetTypeName(ROOT::RFieldToken token) const
0236 {
0237 EnsureMatchingModel(token);
0238 return fFieldTypes[token.fIndex];
0239 }
0240
0241 const std::string &GetTypeName(std::string_view fieldName) const { return GetTypeName(GetToken(fieldName)); }
0242
0243 std::uint64_t GetModelId() const { return fModelId; }
0244 std::uint64_t GetSchemaId() const { return fSchemaId; }
0245
0246 ConstIterator_t begin() const { return fValues.cbegin(); }
0247 ConstIterator_t end() const { return fValues.cend(); }
0248 };
0249
0250 }
0251
0252 #endif