File indexing completed on 2025-09-17 09:14:21
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef ROOT_RField_STLMisc
0015 #define ROOT_RField_STLMisc
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 <atomic>
0025 #include <bitset>
0026 #include <cstddef>
0027 #include <memory>
0028 #include <optional>
0029 #include <string>
0030 #include <string_view>
0031 #include <variant>
0032
0033 namespace ROOT {
0034 namespace Experimental {
0035
0036 namespace Detail {
0037 class RFieldVisitor;
0038 }
0039
0040 }
0041
0042
0043
0044
0045
0046 class RAtomicField : public RFieldBase {
0047 protected:
0048 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
0049
0050 void ConstructValue(void *where) const final { CallConstructValueOn(*fSubfields[0], where); }
0051 std::unique_ptr<RDeleter> GetDeleter() const final { return GetDeleterOf(*fSubfields[0]); }
0052
0053 std::size_t AppendImpl(const void *from) final { return CallAppendOn(*fSubfields[0], from); }
0054 void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final { CallReadOn(*fSubfields[0], globalIndex, to); }
0055 void ReadInClusterImpl(RNTupleLocalIndex localIndex, void *to) final { CallReadOn(*fSubfields[0], localIndex, to); }
0056
0057 public:
0058 RAtomicField(std::string_view fieldName, std::string_view typeName, std::unique_ptr<RFieldBase> itemField);
0059 RAtomicField(RAtomicField &&other) = default;
0060 RAtomicField &operator=(RAtomicField &&other) = default;
0061 ~RAtomicField() override = default;
0062
0063 std::vector<RValue> SplitValue(const RValue &value) const final;
0064
0065 size_t GetValueSize() const final { return fSubfields[0]->GetValueSize(); }
0066 size_t GetAlignment() const final { return fSubfields[0]->GetAlignment(); }
0067
0068 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
0069 };
0070
0071 template <typename ItemT>
0072 class RField<std::atomic<ItemT>> final : public RAtomicField {
0073 public:
0074 static std::string TypeName() { return "std::atomic<" + RField<ItemT>::TypeName() + ">"; }
0075 explicit RField(std::string_view name) : RAtomicField(name, TypeName(), std::make_unique<RField<ItemT>>("_0")) {}
0076 RField(RField &&other) = default;
0077 RField &operator=(RField &&other) = default;
0078 ~RField() final = default;
0079 };
0080
0081
0082
0083
0084
0085
0086
0087
0088 class RBitsetField : public RFieldBase {
0089 using Word_t = unsigned long;
0090 static constexpr std::size_t kWordSize = sizeof(Word_t);
0091 static constexpr std::size_t kBitsPerWord = kWordSize * 8;
0092
0093 protected:
0094 std::size_t fN;
0095
0096 protected:
0097 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
0098 {
0099 return std::make_unique<RBitsetField>(newName, fN);
0100 }
0101 const RColumnRepresentations &GetColumnRepresentations() const final;
0102 void GenerateColumns() final;
0103 void GenerateColumns(const ROOT::RNTupleDescriptor &desc) final;
0104 void ConstructValue(void *where) const final { memset(where, 0, GetValueSize()); }
0105 std::size_t AppendImpl(const void *from) final;
0106 void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
0107 void ReadInClusterImpl(RNTupleLocalIndex localIndex, void *to) final;
0108
0109 public:
0110 RBitsetField(std::string_view fieldName, std::size_t N);
0111 RBitsetField(RBitsetField &&other) = default;
0112 RBitsetField &operator=(RBitsetField &&other) = default;
0113 ~RBitsetField() override = default;
0114
0115 size_t GetValueSize() const final { return kWordSize * ((fN + kBitsPerWord - 1) / kBitsPerWord); }
0116 size_t GetAlignment() const final { return alignof(Word_t); }
0117 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
0118
0119
0120 std::size_t GetN() const { return fN; }
0121 };
0122
0123 template <std::size_t N>
0124 class RField<std::bitset<N>> final : public RBitsetField {
0125 public:
0126 static std::string TypeName() { return "std::bitset<" + std::to_string(N) + ">"; }
0127 explicit RField(std::string_view name) : RBitsetField(name, N) {}
0128 RField(RField &&other) = default;
0129 RField &operator=(RField &&other) = default;
0130 ~RField() final = default;
0131 };
0132
0133
0134
0135
0136
0137 extern template class RSimpleField<std::byte>;
0138
0139 template <>
0140 class RField<std::byte> final : public RSimpleField<std::byte> {
0141 protected:
0142 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
0143 {
0144 return std::make_unique<RField>(newName);
0145 }
0146
0147 const RColumnRepresentations &GetColumnRepresentations() const final;
0148
0149 public:
0150 static std::string TypeName() { return "std::byte"; }
0151 explicit RField(std::string_view name) : RSimpleField(name, TypeName()) {}
0152 RField(RField &&other) = default;
0153 RField &operator=(RField &&other) = default;
0154 ~RField() final = default;
0155
0156 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
0157 };
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167 class RNullableField : public RFieldBase {
0168
0169 ROOT::Internal::RColumnIndex fNWritten{0};
0170
0171 protected:
0172 const RFieldBase::RColumnRepresentations &GetColumnRepresentations() const final;
0173 void GenerateColumns() final;
0174 void GenerateColumns(const ROOT::RNTupleDescriptor &) final;
0175
0176 std::size_t AppendNull();
0177 std::size_t AppendValue(const void *from);
0178 void CommitClusterImpl() final { fNWritten = 0; }
0179
0180
0181
0182 RNTupleLocalIndex GetItemIndex(ROOT::NTupleSize_t globalIndex);
0183
0184 RNullableField(std::string_view fieldName, std::string_view typeName, std::unique_ptr<RFieldBase> itemField);
0185
0186 public:
0187 RNullableField(RNullableField &&other) = default;
0188 RNullableField &operator=(RNullableField &&other) = default;
0189 ~RNullableField() override = default;
0190
0191 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
0192 };
0193
0194 class ROptionalField : public RNullableField {
0195 class ROptionalDeleter : public RDeleter {
0196 private:
0197 std::unique_ptr<RDeleter> fItemDeleter;
0198 std::size_t fEngagementPtrOffset = 0;
0199
0200 public:
0201 ROptionalDeleter(std::unique_ptr<RDeleter> itemDeleter, std::size_t engagementPtrOffset)
0202 : fItemDeleter(std::move(itemDeleter)), fEngagementPtrOffset(engagementPtrOffset) {}
0203 void operator()(void *objPtr, bool dtorOnly) final;
0204 };
0205
0206 std::unique_ptr<RDeleter> fItemDeleter;
0207
0208
0209
0210 const bool *GetEngagementPtr(const void *optionalPtr) const;
0211 bool *GetEngagementPtr(void *optionalPtr) const;
0212 std::size_t GetEngagementPtrOffset() const;
0213
0214 protected:
0215 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
0216
0217 void ConstructValue(void *where) const final;
0218 std::unique_ptr<RDeleter> GetDeleter() const final;
0219
0220 std::size_t AppendImpl(const void *from) final;
0221 void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
0222
0223 public:
0224 ROptionalField(std::string_view fieldName, std::string_view typeName, std::unique_ptr<RFieldBase> itemField);
0225 ROptionalField(ROptionalField &&other) = default;
0226 ROptionalField &operator=(ROptionalField &&other) = default;
0227 ~ROptionalField() override = default;
0228
0229 std::vector<RValue> SplitValue(const RValue &value) const final;
0230 size_t GetValueSize() const final;
0231 size_t GetAlignment() const final;
0232 };
0233
0234 template <typename ItemT>
0235 class RField<std::optional<ItemT>> final : public ROptionalField {
0236 public:
0237 static std::string TypeName() { return "std::optional<" + RField<ItemT>::TypeName() + ">"; }
0238 explicit RField(std::string_view name) : ROptionalField(name, TypeName(), std::make_unique<RField<ItemT>>("_0")) {}
0239 RField(RField &&other) = default;
0240 RField &operator=(RField &&other) = default;
0241 ~RField() final = default;
0242 };
0243
0244 class RUniquePtrField : public RNullableField {
0245 class RUniquePtrDeleter : public RDeleter {
0246 private:
0247 std::unique_ptr<RDeleter> fItemDeleter;
0248
0249 public:
0250 explicit RUniquePtrDeleter(std::unique_ptr<RDeleter> itemDeleter) : fItemDeleter(std::move(itemDeleter)) {}
0251 void operator()(void *objPtr, bool dtorOnly) final;
0252 };
0253
0254 std::unique_ptr<RDeleter> fItemDeleter;
0255
0256 protected:
0257 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
0258
0259 void ConstructValue(void *where) const final { new (where) std::unique_ptr<char>(); }
0260 std::unique_ptr<RDeleter> GetDeleter() const final;
0261
0262 std::size_t AppendImpl(const void *from) final;
0263 void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
0264
0265 public:
0266 RUniquePtrField(std::string_view fieldName, std::string_view typeName, std::unique_ptr<RFieldBase> itemField);
0267 RUniquePtrField(RUniquePtrField &&other) = default;
0268 RUniquePtrField &operator=(RUniquePtrField &&other) = default;
0269 ~RUniquePtrField() override = default;
0270
0271 std::vector<RValue> SplitValue(const RValue &value) const final;
0272 size_t GetValueSize() const final { return sizeof(std::unique_ptr<char>); }
0273 size_t GetAlignment() const final { return alignof(std::unique_ptr<char>); }
0274 };
0275
0276 template <typename ItemT>
0277 class RField<std::unique_ptr<ItemT>> final : public RUniquePtrField {
0278 public:
0279 static std::string TypeName() { return "std::unique_ptr<" + RField<ItemT>::TypeName() + ">"; }
0280 explicit RField(std::string_view name) : RUniquePtrField(name, TypeName(), std::make_unique<RField<ItemT>>("_0")) {}
0281 RField(RField &&other) = default;
0282 RField &operator=(RField &&other) = default;
0283 ~RField() final = default;
0284 };
0285
0286
0287
0288
0289
0290 template <>
0291 class RField<std::string> final : public RFieldBase {
0292 private:
0293 ROOT::Internal::RColumnIndex fIndex;
0294
0295 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
0296 {
0297 return std::make_unique<RField>(newName);
0298 }
0299
0300 const RColumnRepresentations &GetColumnRepresentations() const final;
0301 void GenerateColumns() final;
0302 void GenerateColumns(const ROOT::RNTupleDescriptor &desc) final;
0303
0304 void ConstructValue(void *where) const final { new (where) std::string(); }
0305 std::unique_ptr<RDeleter> GetDeleter() const final { return std::make_unique<RTypedDeleter<std::string>>(); }
0306
0307 std::size_t AppendImpl(const void *from) final;
0308 void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
0309
0310 void CommitClusterImpl() final { fIndex = 0; }
0311
0312 public:
0313 static std::string TypeName() { return "std::string"; }
0314 explicit RField(std::string_view name)
0315 : RFieldBase(name, TypeName(), ROOT::ENTupleStructure::kLeaf, false ), fIndex(0)
0316 {
0317 }
0318 RField(RField &&other) = default;
0319 RField &operator=(RField &&other) = default;
0320 ~RField() final = default;
0321
0322 size_t GetValueSize() const final { return sizeof(std::string); }
0323 size_t GetAlignment() const final { return std::alignment_of<std::string>(); }
0324 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
0325 };
0326
0327
0328
0329
0330
0331
0332 class RVariantField : public RFieldBase {
0333 private:
0334
0335
0336
0337
0338 static constexpr std::size_t kMaxVariants = 125;
0339
0340 class RVariantDeleter : public RDeleter {
0341 private:
0342 std::size_t fTagOffset;
0343 std::size_t fVariantOffset;
0344 std::vector<std::unique_ptr<RDeleter>> fItemDeleters;
0345
0346 public:
0347 RVariantDeleter(std::size_t tagOffset, std::size_t variantOffset,
0348 std::vector<std::unique_ptr<RDeleter>> itemDeleters)
0349 : fTagOffset(tagOffset), fVariantOffset(variantOffset), fItemDeleters(std::move(itemDeleters))
0350 {
0351 }
0352 void operator()(void *objPtr, bool dtorOnly) final;
0353 };
0354
0355 size_t fMaxItemSize = 0;
0356 size_t fMaxAlignment = 1;
0357
0358 size_t fTagOffset = 0;
0359
0360 size_t fVariantOffset = 0;
0361 std::vector<ROOT::Internal::RColumnIndex::ValueType> fNWritten;
0362
0363 static std::string GetTypeList(const std::vector<std::unique_ptr<RFieldBase>> &itemFields);
0364
0365
0366
0367
0368 static std::uint8_t GetTag(const void *variantPtr, std::size_t tagOffset);
0369 static void SetTag(void *variantPtr, std::size_t tagOffset, std::uint8_t tag);
0370
0371 RVariantField(std::string_view name, const RVariantField &source);
0372
0373 protected:
0374 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
0375
0376 const RColumnRepresentations &GetColumnRepresentations() const final;
0377 void GenerateColumns() final;
0378 void GenerateColumns(const ROOT::RNTupleDescriptor &desc) final;
0379
0380 void ConstructValue(void *where) const final;
0381 std::unique_ptr<RDeleter> GetDeleter() const final;
0382
0383 std::size_t AppendImpl(const void *from) final;
0384 void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
0385
0386 void CommitClusterImpl() final;
0387
0388 public:
0389 RVariantField(std::string_view fieldName, std::vector<std::unique_ptr<RFieldBase>> itemFields);
0390 RVariantField(RVariantField &&other) = default;
0391 RVariantField &operator=(RVariantField &&other) = default;
0392 ~RVariantField() override = default;
0393
0394 size_t GetValueSize() const final;
0395 size_t GetAlignment() const final;
0396 };
0397
0398 template <typename... ItemTs>
0399 class RField<std::variant<ItemTs...>> final : public RVariantField {
0400 private:
0401 template <typename HeadT, typename... TailTs>
0402 static std::string BuildItemTypes()
0403 {
0404 std::string result = RField<HeadT>::TypeName();
0405 if constexpr (sizeof...(TailTs) > 0)
0406 result += "," + BuildItemTypes<TailTs...>();
0407 return result;
0408 }
0409
0410 template <typename HeadT, typename... TailTs>
0411 static void _BuildItemFields(std::vector<std::unique_ptr<RFieldBase>> &itemFields, unsigned int index = 0)
0412 {
0413 itemFields.emplace_back(new RField<HeadT>("_" + std::to_string(index)));
0414 if constexpr (sizeof...(TailTs) > 0)
0415 _BuildItemFields<TailTs...>(itemFields, index + 1);
0416 }
0417 static std::vector<std::unique_ptr<RFieldBase>> BuildItemFields()
0418 {
0419 std::vector<std::unique_ptr<RFieldBase>> result;
0420 _BuildItemFields<ItemTs...>(result);
0421 return result;
0422 }
0423
0424 public:
0425 static std::string TypeName() { return "std::variant<" + BuildItemTypes<ItemTs...>() + ">"; }
0426 explicit RField(std::string_view name) : RVariantField(name, BuildItemFields()) {}
0427 RField(RField &&other) = default;
0428 RField &operator=(RField &&other) = default;
0429 ~RField() final = default;
0430 };
0431
0432 }
0433
0434 #endif