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