File indexing completed on 2025-09-17 09:14:20
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef ROOT_RField_Record
0015 #define ROOT_RField_Record
0016
0017 #ifndef ROOT_RField
0018 #error "Please include RField.hxx!"
0019 #endif
0020
0021 #include <ROOT/RFieldBase.hxx>
0022 #include <ROOT/RNTupleUtil.hxx>
0023
0024 #include <string>
0025 #include <string_view>
0026 #include <tuple>
0027 #include <utility>
0028 #include <vector>
0029
0030 namespace ROOT {
0031
0032 namespace Detail {
0033 class RFieldVisitor;
0034 }
0035
0036 namespace Internal {
0037 std::unique_ptr<RFieldBase> CreateEmulatedField(std::string_view fieldName,
0038 std::vector<std::unique_ptr<RFieldBase>> itemFields,
0039 std::string_view emulatedFromType);
0040 }
0041
0042
0043
0044 class RRecordField : public RFieldBase {
0045 friend std::unique_ptr<RFieldBase> Internal::CreateEmulatedField(std::string_view fieldName,
0046 std::vector<std::unique_ptr<RFieldBase>> itemFields,
0047 std::string_view emulatedFromType);
0048
0049 class RRecordDeleter : public RDeleter {
0050 private:
0051 std::vector<std::unique_ptr<RDeleter>> fItemDeleters;
0052 std::vector<std::size_t> fOffsets;
0053
0054 public:
0055 RRecordDeleter(std::vector<std::unique_ptr<RDeleter>> itemDeleters, const std::vector<std::size_t> &offsets)
0056 : fItemDeleters(std::move(itemDeleters)), fOffsets(offsets)
0057 {
0058 }
0059 void operator()(void *objPtr, bool dtorOnly) final;
0060 };
0061
0062 RRecordField(std::string_view name, const RRecordField &source);
0063
0064
0065
0066 RRecordField(std::string_view fieldName, std::vector<std::unique_ptr<RFieldBase>> itemFields,
0067 std::string_view emulatedFromType);
0068
0069 protected:
0070 std::size_t fMaxAlignment = 1;
0071 std::size_t fSize = 0;
0072 std::vector<std::size_t> fOffsets;
0073
0074 std::size_t GetItemPadding(std::size_t baseOffset, std::size_t itemAlignment) const;
0075
0076 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
0077
0078 void ConstructValue(void *where) const final;
0079 std::unique_ptr<RDeleter> GetDeleter() const final;
0080
0081 std::size_t AppendImpl(const void *from) final;
0082 void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
0083 void ReadInClusterImpl(RNTupleLocalIndex localIndex, void *to) final;
0084
0085 RRecordField(std::string_view fieldName, std::string_view typeName);
0086
0087 void AttachItemFields(std::vector<std::unique_ptr<RFieldBase>> itemFields);
0088
0089 template <std::size_t N>
0090 void AttachItemFields(std::array<std::unique_ptr<RFieldBase>, N> itemFields)
0091 {
0092 fTraits |= kTraitTrivialType;
0093 for (unsigned i = 0; i < N; ++i) {
0094 fMaxAlignment = std::max(fMaxAlignment, itemFields[i]->GetAlignment());
0095 fSize += GetItemPadding(fSize, itemFields[i]->GetAlignment()) + itemFields[i]->GetValueSize();
0096 fTraits &= itemFields[i]->GetTraits();
0097 Attach(std::move(itemFields[i]));
0098 }
0099
0100
0101 fSize += GetItemPadding(fSize, fMaxAlignment);
0102 }
0103
0104 public:
0105
0106
0107 RRecordField(std::string_view fieldName, std::vector<std::unique_ptr<RFieldBase>> itemFields);
0108 RRecordField(RRecordField &&other) = default;
0109 RRecordField &operator=(RRecordField &&other) = default;
0110 ~RRecordField() override = default;
0111
0112 std::vector<RValue> SplitValue(const RValue &value) const final;
0113 size_t GetValueSize() const final
0114 {
0115
0116 return std::max<size_t>(1ul, fSize);
0117 }
0118 size_t GetAlignment() const final { return fMaxAlignment; }
0119 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
0120
0121 const std::vector<std::size_t> &GetOffsets() const { return fOffsets; }
0122 };
0123
0124
0125
0126
0127
0128
0129 class RPairField : public RRecordField {
0130 private:
0131 static std::string GetTypeList(const std::array<std::unique_ptr<RFieldBase>, 2> &itemFields);
0132
0133 protected:
0134 RPairField(std::string_view fieldName, std::array<std::unique_ptr<RFieldBase>, 2> itemFields,
0135 const std::array<std::size_t, 2> &offsets);
0136
0137 public:
0138 RPairField(std::string_view fieldName, std::array<std::unique_ptr<RFieldBase>, 2> itemFields);
0139 RPairField(RPairField &&other) = default;
0140 RPairField &operator=(RPairField &&other) = default;
0141 ~RPairField() override = default;
0142 };
0143
0144 template <typename T1, typename T2>
0145 class RField<std::pair<T1, T2>> final : public RPairField {
0146 using ContainerT = typename std::pair<T1, T2>;
0147
0148 private:
0149 static std::array<std::unique_ptr<RFieldBase>, 2> BuildItemFields()
0150 {
0151 return {std::make_unique<RField<T1>>("_0"), std::make_unique<RField<T2>>("_1")};
0152 }
0153
0154 static std::array<std::size_t, 2> BuildItemOffsets()
0155 {
0156 auto pair = ContainerT();
0157 auto offsetFirst = reinterpret_cast<std::uintptr_t>(&(pair.first)) - reinterpret_cast<std::uintptr_t>(&pair);
0158 auto offsetSecond = reinterpret_cast<std::uintptr_t>(&(pair.second)) - reinterpret_cast<std::uintptr_t>(&pair);
0159 return {offsetFirst, offsetSecond};
0160 }
0161
0162 public:
0163 static std::string TypeName() { return "std::pair<" + RField<T1>::TypeName() + "," + RField<T2>::TypeName() + ">"; }
0164 explicit RField(std::string_view name) : RPairField(name, BuildItemFields(), BuildItemOffsets())
0165 {
0166 R__ASSERT(fMaxAlignment >= std::max(alignof(T1), alignof(T2)));
0167 R__ASSERT(fSize >= sizeof(ContainerT));
0168 }
0169 RField(RField &&other) = default;
0170 RField &operator=(RField &&other) = default;
0171 ~RField() final = default;
0172 };
0173
0174
0175
0176
0177
0178
0179 class RTupleField : public RRecordField {
0180 private:
0181 static std::string GetTypeList(const std::vector<std::unique_ptr<RFieldBase>> &itemFields);
0182
0183 protected:
0184 RTupleField(std::string_view fieldName, std::vector<std::unique_ptr<RFieldBase>> itemFields,
0185 const std::vector<std::size_t> &offsets);
0186
0187 public:
0188 RTupleField(std::string_view fieldName, std::vector<std::unique_ptr<RFieldBase>> itemFields);
0189 RTupleField(RTupleField &&other) = default;
0190 RTupleField &operator=(RTupleField &&other) = default;
0191 ~RTupleField() override = default;
0192 };
0193
0194 template <typename... ItemTs>
0195 class RField<std::tuple<ItemTs...>> final : public RTupleField {
0196 using ContainerT = typename std::tuple<ItemTs...>;
0197
0198 private:
0199 template <typename HeadT, typename... TailTs>
0200 static std::string BuildItemTypes()
0201 {
0202 std::string result = RField<HeadT>::TypeName();
0203 if constexpr (sizeof...(TailTs) > 0)
0204 result += "," + BuildItemTypes<TailTs...>();
0205 return result;
0206 }
0207
0208 template <typename HeadT, typename... TailTs>
0209 static void _BuildItemFields(std::vector<std::unique_ptr<RFieldBase>> &itemFields, unsigned int index = 0)
0210 {
0211 itemFields.emplace_back(new RField<HeadT>("_" + std::to_string(index)));
0212 if constexpr (sizeof...(TailTs) > 0)
0213 _BuildItemFields<TailTs...>(itemFields, index + 1);
0214 }
0215 static std::vector<std::unique_ptr<RFieldBase>> BuildItemFields()
0216 {
0217 std::vector<std::unique_ptr<RFieldBase>> result;
0218 _BuildItemFields<ItemTs...>(result);
0219 return result;
0220 }
0221
0222 template <unsigned Index, typename HeadT, typename... TailTs>
0223 static void _BuildItemOffsets(std::vector<std::size_t> &offsets, const ContainerT &tuple)
0224 {
0225 auto offset =
0226 reinterpret_cast<std::uintptr_t>(&std::get<Index>(tuple)) - reinterpret_cast<std::uintptr_t>(&tuple);
0227 offsets.emplace_back(offset);
0228 if constexpr (sizeof...(TailTs) > 0)
0229 _BuildItemOffsets<Index + 1, TailTs...>(offsets, tuple);
0230 }
0231 static std::vector<std::size_t> BuildItemOffsets()
0232 {
0233 std::vector<std::size_t> result;
0234 _BuildItemOffsets<0, ItemTs...>(result, ContainerT());
0235 return result;
0236 }
0237
0238 public:
0239 static std::string TypeName() { return "std::tuple<" + BuildItemTypes<ItemTs...>() + ">"; }
0240 explicit RField(std::string_view name) : RTupleField(name, BuildItemFields(), BuildItemOffsets())
0241 {
0242 R__ASSERT(fMaxAlignment >= std::max({alignof(ItemTs)...}));
0243 R__ASSERT(fSize >= sizeof(ContainerT));
0244 }
0245 RField(RField &&other) = default;
0246 RField &operator=(RField &&other) = default;
0247 ~RField() final = default;
0248 };
0249
0250 }
0251
0252 #endif