File indexing completed on 2025-01-30 10:22:27
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef ROOT7_REntry
0017 #define ROOT7_REntry
0018
0019 #include <ROOT/RError.hxx>
0020 #include <ROOT/RField.hxx>
0021 #include <string_view>
0022
0023 #include <TError.h>
0024
0025 #include <algorithm>
0026 #include <iterator>
0027 #include <memory>
0028 #include <type_traits>
0029 #include <utility>
0030 #include <vector>
0031
0032 namespace ROOT {
0033 namespace Experimental {
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045 class REntry {
0046 friend class RNTupleCollectionWriter;
0047 friend class RNTupleModel;
0048 friend class RNTupleReader;
0049 friend class RNTupleFillContext;
0050
0051 public:
0052
0053
0054 class RFieldToken {
0055 friend class REntry;
0056 friend class RNTupleModel;
0057
0058 std::size_t fIndex;
0059 std::uint64_t fModelId;
0060 RFieldToken(std::size_t index, std::uint64_t modelId) : fIndex(index), fModelId(modelId) {}
0061 };
0062
0063 private:
0064
0065 std::uint64_t fModelId = 0;
0066
0067 std::vector<RFieldBase::RValue> fValues;
0068
0069
0070
0071 REntry() = default;
0072 explicit REntry(std::uint64_t modelId) : fModelId(modelId) {}
0073
0074 void AddValue(RFieldBase::RValue &&value) { fValues.emplace_back(std::move(value)); }
0075
0076
0077 template <typename T, typename... ArgsT>
0078 std::shared_ptr<T> AddValue(RField<T> &field, ArgsT &&...args)
0079 {
0080 auto ptr = std::make_shared<T>(std::forward<ArgsT>(args)...);
0081 fValues.emplace_back(field.BindValue(ptr));
0082 return ptr;
0083 }
0084
0085 void Read(NTupleSize_t index)
0086 {
0087 for (auto &v : fValues) {
0088 v.Read(index);
0089 }
0090 }
0091
0092 std::size_t Append()
0093 {
0094 std::size_t bytesWritten = 0;
0095 for (auto &v : fValues) {
0096 bytesWritten += v.Append();
0097 }
0098 return bytesWritten;
0099 }
0100
0101 void EnsureMatchingModel(RFieldToken token) const
0102 {
0103 if (fModelId != token.fModelId) {
0104 throw RException(R__FAIL("invalid token for this entry, "
0105 "make sure to use a token from the same model as this entry."));
0106 }
0107 }
0108
0109 template <typename T>
0110 void EnsureMatchingType(RFieldToken token [[maybe_unused]]) const
0111 {
0112 if constexpr (!std::is_void_v<T>) {
0113 const auto &v = fValues[token.fIndex];
0114 if (v.GetField().GetTypeName() != RField<T>::TypeName()) {
0115 throw RException(R__FAIL("type mismatch for field " + v.GetField().GetFieldName() + ": " +
0116 v.GetField().GetTypeName() + " vs. " + RField<T>::TypeName()));
0117 }
0118 }
0119 }
0120
0121 public:
0122 using ConstIterator_t = decltype(fValues)::const_iterator;
0123
0124 REntry(const REntry &other) = delete;
0125 REntry &operator=(const REntry &other) = delete;
0126 REntry(REntry &&other) = default;
0127 REntry &operator=(REntry &&other) = default;
0128 ~REntry() = default;
0129
0130
0131 RFieldToken GetToken(std::string_view fieldName) const
0132 {
0133 auto it = std::find_if(fValues.begin(), fValues.end(),
0134 [&fieldName] (const RFieldBase::RValue &value) { return value.GetField().GetFieldName() == fieldName; });
0135
0136 if ( it == fValues.end() ) {
0137 throw RException(R__FAIL("invalid field name: " + std::string(fieldName)));
0138 }
0139 return RFieldToken(std::distance(fValues.begin(), it), fModelId);
0140 }
0141
0142 void EmplaceNewValue(RFieldToken token)
0143 {
0144 EnsureMatchingModel(token);
0145 fValues[token.fIndex].EmplaceNew();
0146 }
0147
0148 void EmplaceNewValue(std::string_view fieldName) { EmplaceNewValue(GetToken(fieldName)); }
0149
0150 template <typename T>
0151 void BindValue(RFieldToken token, std::shared_ptr<T> objPtr)
0152 {
0153 EnsureMatchingModel(token);
0154 EnsureMatchingType<T>(token);
0155 fValues[token.fIndex].Bind(objPtr);
0156 }
0157
0158 template <typename T>
0159 void BindValue(std::string_view fieldName, std::shared_ptr<T> objPtr)
0160 {
0161 BindValue<T>(GetToken(fieldName), objPtr);
0162 }
0163
0164 template <typename T>
0165 void BindRawPtr(RFieldToken token, T *rawPtr)
0166 {
0167 EnsureMatchingModel(token);
0168 EnsureMatchingType<T>(token);
0169 fValues[token.fIndex].BindRawPtr(rawPtr);
0170 }
0171
0172 template <typename T>
0173 void BindRawPtr(std::string_view fieldName, T *rawPtr)
0174 {
0175 BindRawPtr<void>(GetToken(fieldName), rawPtr);
0176 }
0177
0178 template <typename T>
0179 std::shared_ptr<T> GetPtr(RFieldToken token) const
0180 {
0181 EnsureMatchingModel(token);
0182 EnsureMatchingType<T>(token);
0183 return std::static_pointer_cast<T>(fValues[token.fIndex].GetPtr<void>());
0184 }
0185
0186 template <typename T>
0187 std::shared_ptr<T> GetPtr(std::string_view fieldName) const
0188 {
0189 return GetPtr<T>(GetToken(fieldName));
0190 }
0191
0192 std::uint64_t GetModelId() const { return fModelId; }
0193
0194 ConstIterator_t begin() const { return fValues.cbegin(); }
0195 ConstIterator_t end() const { return fValues.cend(); }
0196 };
0197
0198 }
0199 }
0200
0201 #endif