File indexing completed on 2025-01-18 10:10:42
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef ROOT7_RField
0017 #define ROOT7_RField
0018
0019 #include <ROOT/RColumn.hxx>
0020 #include <ROOT/RError.hxx>
0021 #include <ROOT/RColumnElement.hxx>
0022 #include <ROOT/RNTupleUtil.hxx>
0023 #include <ROOT/RSpan.hxx>
0024 #include <string_view>
0025 #include <ROOT/RVec.hxx>
0026 #include <ROOT/TypeTraits.hxx>
0027
0028 #include <TGenericClassInfo.h>
0029 #include <TVirtualCollectionProxy.h>
0030
0031 #include <algorithm>
0032 #include <array>
0033 #include <atomic>
0034 #include <bitset>
0035 #include <cstddef>
0036 #include <functional>
0037 #include <iostream>
0038 #include <iterator>
0039 #include <map>
0040 #include <memory>
0041 #include <new>
0042 #include <set>
0043 #include <string>
0044 #include <tuple>
0045 #include <type_traits>
0046 #include <typeinfo>
0047 #include <variant>
0048 #include <vector>
0049 #include <utility>
0050
0051 class TClass;
0052 class TEnum;
0053
0054 namespace ROOT {
0055
0056 class TSchemaRule;
0057 class RFieldBase;
0058
0059 namespace Experimental {
0060
0061 class RCollectionField;
0062 class RNTupleCollectionWriter;
0063 class REntry;
0064
0065 namespace Internal {
0066 struct RFieldCallbackInjector;
0067 class RPageSink;
0068 class RPageSource;
0069
0070 void CallCommitClusterOnField(RFieldBase &);
0071 void CallConnectPageSinkOnField(RFieldBase &, RPageSink &, NTupleSize_t firstEntry = 0);
0072 void CallConnectPageSourceOnField(RFieldBase &, RPageSource &);
0073 }
0074
0075 namespace Detail {
0076 class RFieldVisitor;
0077 }
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094 class RFieldBase {
0095 friend class ROOT::Experimental::RCollectionField;
0096 friend struct ROOT::Experimental::Internal::RFieldCallbackInjector;
0097 friend void Internal::CallCommitClusterOnField(RFieldBase &);
0098 friend void Internal::CallConnectPageSinkOnField(RFieldBase &, Internal::RPageSink &, NTupleSize_t);
0099 friend void Internal::CallConnectPageSourceOnField(RFieldBase &, Internal::RPageSource &);
0100 using ReadCallback_t = std::function<void(void *)>;
0101
0102 protected:
0103
0104
0105
0106
0107 class RDeleter {
0108 public:
0109 virtual ~RDeleter() = default;
0110 virtual void operator()(void *objPtr, bool dtorOnly)
0111 {
0112 if (!dtorOnly)
0113 operator delete(objPtr);
0114 }
0115 };
0116
0117
0118 template <typename T>
0119 class RTypedDeleter : public RDeleter {
0120 public:
0121 void operator()(void *objPtr, bool dtorOnly) final
0122 {
0123 std::destroy_at(static_cast<T *>(objPtr));
0124 RDeleter::operator()(objPtr, dtorOnly);
0125 }
0126 };
0127
0128
0129
0130 struct RSharedPtrDeleter {
0131 std::unique_ptr<RFieldBase::RDeleter> fDeleter;
0132 void operator()(void *objPtr) { fDeleter->operator()(objPtr, false ); }
0133 explicit RSharedPtrDeleter(std::unique_ptr<RFieldBase::RDeleter> deleter) : fDeleter(std::move(deleter)) {}
0134 };
0135
0136 public:
0137 static constexpr std::uint32_t kInvalidTypeVersion = -1U;
0138
0139
0140 static constexpr int kTraitTriviallyConstructible = 0x01;
0141
0142 static constexpr int kTraitTriviallyDestructible = 0x02;
0143
0144
0145 static constexpr int kTraitMappable = 0x04;
0146
0147 static constexpr int kTraitTrivialType = kTraitTriviallyConstructible | kTraitTriviallyDestructible;
0148
0149 using ColumnRepresentation_t = std::vector<EColumnType>;
0150
0151
0152
0153
0154
0155
0156
0157
0158 enum class EState { kUnconnected, kConnectedToSink, kConnectedToSource };
0159
0160
0161
0162
0163
0164
0165
0166 class RColumnRepresentations {
0167 public:
0168 using TypesList_t = std::vector<ColumnRepresentation_t>;
0169 RColumnRepresentations();
0170 RColumnRepresentations(const TypesList_t &serializationTypes, const TypesList_t &deserializationExtraTypes);
0171
0172
0173 const ColumnRepresentation_t &GetSerializationDefault() const { return fSerializationTypes[0]; }
0174 const TypesList_t &GetSerializationTypes() const { return fSerializationTypes; }
0175 const TypesList_t &GetDeserializationTypes() const { return fDeserializationTypes; }
0176
0177 private:
0178 TypesList_t fSerializationTypes;
0179
0180
0181 TypesList_t fDeserializationTypes;
0182 };
0183
0184
0185
0186 class RValue {
0187 friend class RFieldBase;
0188
0189 private:
0190 RFieldBase *fField = nullptr;
0191 std::shared_ptr<void> fObjPtr;
0192
0193 RValue(RFieldBase *field, std::shared_ptr<void> objPtr) : fField(field), fObjPtr(objPtr) {}
0194
0195 public:
0196 RValue(const RValue &) = default;
0197 RValue &operator=(const RValue &) = default;
0198 RValue(RValue &&other) = default;
0199 RValue &operator=(RValue &&other) = default;
0200 ~RValue() = default;
0201
0202 std::size_t Append() { return fField->Append(fObjPtr.get()); }
0203 void Read(NTupleSize_t globalIndex) { fField->Read(globalIndex, fObjPtr.get()); }
0204 void Read(RClusterIndex clusterIndex) { fField->Read(clusterIndex, fObjPtr.get()); }
0205 void Bind(std::shared_ptr<void> objPtr) { fObjPtr = objPtr; }
0206 void BindRawPtr(void *rawPtr);
0207
0208 void EmplaceNew() { fObjPtr = fField->CreateValue().GetPtr<void>(); }
0209
0210 template <typename T>
0211 std::shared_ptr<T> GetPtr() const
0212 {
0213 return std::static_pointer_cast<T>(fObjPtr);
0214 }
0215
0216 template <typename T>
0217 const T &GetRef() const
0218 {
0219 return *static_cast<T *>(fObjPtr.get());
0220 }
0221
0222 const RFieldBase &GetField() const { return *fField; }
0223 };
0224
0225
0226
0227
0228
0229
0230 class RBulk {
0231 private:
0232 friend class RFieldBase;
0233
0234 RFieldBase *fField = nullptr;
0235 std::unique_ptr<RFieldBase::RDeleter> fDeleter;
0236 void *fValues = nullptr;
0237 std::size_t fValueSize = 0;
0238 std::size_t fCapacity = 0;
0239 std::size_t fSize = 0;
0240 bool fIsAdopted = false;
0241 std::unique_ptr<bool[]> fMaskAvail;
0242 std::size_t fNValidValues = 0;
0243 RClusterIndex fFirstIndex;
0244
0245
0246
0247 std::vector<unsigned char> fAuxData;
0248
0249 void ReleaseValues();
0250
0251
0252 void Reset(RClusterIndex firstIndex, std::size_t size);
0253 void CountValidValues();
0254
0255 bool ContainsRange(RClusterIndex firstIndex, std::size_t size) const
0256 {
0257 if (firstIndex.GetClusterId() != fFirstIndex.GetClusterId())
0258 return false;
0259 return (firstIndex.GetIndex() >= fFirstIndex.GetIndex()) &&
0260 ((firstIndex.GetIndex() + size) <= (fFirstIndex.GetIndex() + fSize));
0261 }
0262
0263 void *GetValuePtrAt(std::size_t idx) const
0264 {
0265 return reinterpret_cast<unsigned char *>(fValues) + idx * fValueSize;
0266 }
0267
0268 explicit RBulk(RFieldBase *field)
0269 : fField(field), fDeleter(field->GetDeleter()), fValueSize(field->GetValueSize())
0270 {
0271 }
0272
0273 public:
0274 ~RBulk();
0275 RBulk(const RBulk &) = delete;
0276 RBulk &operator=(const RBulk &) = delete;
0277 RBulk(RBulk &&other);
0278 RBulk &operator=(RBulk &&other);
0279
0280
0281
0282 void AdoptBuffer(void *buf, std::size_t capacity);
0283
0284
0285
0286
0287
0288 void *ReadBulk(RClusterIndex firstIndex, const bool *maskReq, std::size_t size)
0289 {
0290 if (!ContainsRange(firstIndex, size))
0291 Reset(firstIndex, size);
0292
0293
0294 auto offset = firstIndex.GetIndex() - fFirstIndex.GetIndex();
0295
0296 if (fNValidValues == fSize)
0297 return GetValuePtrAt(offset);
0298
0299 RBulkSpec bulkSpec;
0300 bulkSpec.fFirstIndex = firstIndex;
0301 bulkSpec.fCount = size;
0302 bulkSpec.fMaskReq = maskReq;
0303 bulkSpec.fMaskAvail = &fMaskAvail[offset];
0304 bulkSpec.fValues = GetValuePtrAt(offset);
0305 bulkSpec.fAuxData = &fAuxData;
0306 auto nRead = fField->ReadBulk(bulkSpec);
0307 if (nRead == RBulkSpec::kAllSet) {
0308 if ((offset == 0) && (size == fSize)) {
0309 fNValidValues = fSize;
0310 } else {
0311 CountValidValues();
0312 }
0313 } else {
0314 fNValidValues += nRead;
0315 }
0316 return GetValuePtrAt(offset);
0317 }
0318 };
0319
0320 private:
0321
0322 std::string fName;
0323
0324 std::string fType;
0325
0326 ENTupleStructure fStructure;
0327
0328 std::size_t fNRepetitions;
0329
0330 bool fIsSimple;
0331
0332
0333
0334 DescriptorId_t fOnDiskId = kInvalidDescriptorId;
0335
0336 std::string fDescription;
0337
0338 EState fState = EState::kUnconnected;
0339
0340 void InvokeReadCallbacks(void *target)
0341 {
0342 for (const auto &func : fReadCallbacks)
0343 func(target);
0344 }
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354 NTupleSize_t EntryToColumnElementIndex(NTupleSize_t globalIndex) const;
0355
0356
0357 void CommitCluster();
0358
0359
0360
0361 void ConnectPageSink(Internal::RPageSink &pageSink, NTupleSize_t firstEntry = 0);
0362
0363
0364
0365
0366 void ConnectPageSource(Internal::RPageSource &pageSource);
0367
0368
0369 void *CreateObjectRawPtr() const;
0370
0371 protected:
0372
0373 struct RBulkSpec {
0374
0375
0376 static const std::size_t kAllSet = std::size_t(-1);
0377
0378 RClusterIndex fFirstIndex;
0379 std::size_t fCount = 0;
0380
0381 const bool *fMaskReq = nullptr;
0382 bool *fMaskAvail = nullptr;
0383
0384 void *fValues = nullptr;
0385
0386
0387 std::vector<unsigned char> *fAuxData = nullptr;
0388 };
0389
0390
0391 std::vector<std::unique_ptr<RFieldBase>> fSubFields;
0392
0393 RFieldBase* fParent;
0394
0395
0396
0397 Internal::RColumn *fPrincipalColumn;
0398
0399 std::vector<std::unique_ptr<Internal::RColumn>> fColumns;
0400
0401 int fTraits = 0;
0402
0403 std::string fTypeAlias;
0404
0405 std::vector<ReadCallback_t> fReadCallbacks;
0406
0407 std::uint32_t fOnDiskTypeVersion = kInvalidTypeVersion;
0408
0409
0410 const ColumnRepresentation_t *fColumnRepresentative = nullptr;
0411
0412
0413
0414 virtual const RColumnRepresentations &GetColumnRepresentations() const;
0415
0416 virtual void GenerateColumnsImpl() = 0;
0417
0418
0419
0420 virtual void GenerateColumnsImpl(const RNTupleDescriptor &desc) = 0;
0421
0422
0423 const ColumnRepresentation_t &EnsureCompatibleColumnTypes(const RNTupleDescriptor &desc) const;
0424
0425
0426
0427 void AutoAdjustColumnTypes(const RNTupleWriteOptions &options);
0428
0429
0430 virtual std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const = 0;
0431
0432
0433 virtual void ConstructValue(void *where) const = 0;
0434 virtual std::unique_ptr<RDeleter> GetDeleter() const { return std::make_unique<RDeleter>(); }
0435
0436 static void CallConstructValueOn(const RFieldBase &other, void *where) { other.ConstructValue(where); }
0437 static std::unique_ptr<RDeleter> GetDeleterOf(const RFieldBase &other) { return other.GetDeleter(); }
0438
0439
0440
0441 virtual std::size_t AppendImpl(const void *from);
0442 virtual void ReadGlobalImpl(NTupleSize_t globalIndex, void *to);
0443 virtual void ReadInClusterImpl(RClusterIndex clusterIndex, void *to)
0444 {
0445 ReadGlobalImpl(fPrincipalColumn->GetGlobalIndex(clusterIndex), to);
0446 }
0447
0448
0449
0450 std::size_t Append(const void *from)
0451 {
0452 if (~fTraits & kTraitMappable)
0453 return AppendImpl(from);
0454
0455 fPrincipalColumn->Append(from);
0456 return fPrincipalColumn->GetElement()->GetPackedSize();
0457 }
0458
0459
0460
0461
0462 void Read(NTupleSize_t globalIndex, void *to)
0463 {
0464 if (fIsSimple)
0465 return (void)fPrincipalColumn->Read(globalIndex, to);
0466
0467 if (fTraits & kTraitMappable)
0468 fPrincipalColumn->Read(globalIndex, to);
0469 else
0470 ReadGlobalImpl(globalIndex, to);
0471 if (R__unlikely(!fReadCallbacks.empty()))
0472 InvokeReadCallbacks(to);
0473 }
0474
0475 void Read(RClusterIndex clusterIndex, void *to)
0476 {
0477 if (fIsSimple)
0478 return (void)fPrincipalColumn->Read(clusterIndex, to);
0479
0480 if (fTraits & kTraitMappable)
0481 fPrincipalColumn->Read(clusterIndex, to);
0482 else
0483 ReadInClusterImpl(clusterIndex, to);
0484 if (R__unlikely(!fReadCallbacks.empty()))
0485 InvokeReadCallbacks(to);
0486 }
0487
0488
0489
0490
0491 virtual std::size_t ReadBulkImpl(const RBulkSpec &bulkSpec);
0492
0493
0494
0495
0496 std::size_t ReadBulk(const RBulkSpec &bulkSpec)
0497 {
0498 if (fIsSimple) {
0499
0500 fPrincipalColumn->ReadV(bulkSpec.fFirstIndex, bulkSpec.fCount, bulkSpec.fValues);
0501 std::fill(bulkSpec.fMaskAvail, bulkSpec.fMaskAvail + bulkSpec.fCount, true);
0502 return RBulkSpec::kAllSet;
0503 }
0504
0505 return ReadBulkImpl(bulkSpec);
0506 }
0507
0508
0509 static std::size_t CallAppendOn(RFieldBase &other, const void *from) { return other.Append(from); }
0510 static void CallReadOn(RFieldBase &other, RClusterIndex clusterIndex, void *to) { other.Read(clusterIndex, to); }
0511 static void CallReadOn(RFieldBase &other, NTupleSize_t globalIndex, void *to) { other.Read(globalIndex, to); }
0512
0513
0514 static Internal::RColumn *GetPrincipalColumnOf(const RFieldBase &other) { return other.fPrincipalColumn; }
0515
0516
0517
0518
0519 size_t AddReadCallback(ReadCallback_t func);
0520 void RemoveReadCallback(size_t idx);
0521
0522
0523 virtual void CommitClusterImpl() {}
0524
0525
0526 void Attach(std::unique_ptr<RFieldBase> child);
0527
0528
0529
0530 virtual void OnConnectPageSource() {}
0531
0532
0533
0534
0535
0536 static RResult<std::unique_ptr<RFieldBase>> Create(const std::string &fieldName, const std::string &canonicalType,
0537 const std::string &typeAlias, bool fContinueOnError = false);
0538
0539 public:
0540
0541 template <bool IsConstT>
0542 class RSchemaIteratorTemplate {
0543 private:
0544 struct Position {
0545 using FieldPtr_t = std::conditional_t<IsConstT, const RFieldBase *, RFieldBase *>;
0546 Position() : fFieldPtr(nullptr), fIdxInParent(-1) { }
0547 Position(FieldPtr_t fieldPtr, int idxInParent) : fFieldPtr(fieldPtr), fIdxInParent(idxInParent) {}
0548 FieldPtr_t fFieldPtr;
0549 int fIdxInParent;
0550 };
0551
0552 std::vector<Position> fStack;
0553 public:
0554 using iterator = RSchemaIteratorTemplate<IsConstT>;
0555 using iterator_category = std::forward_iterator_tag;
0556 using difference_type = std::ptrdiff_t;
0557 using value_type = std::conditional_t<IsConstT, const RFieldBase, RFieldBase>;
0558 using pointer = std::conditional_t<IsConstT, const RFieldBase *, RFieldBase *>;
0559 using reference = std::conditional_t<IsConstT, const RFieldBase &, RFieldBase &>;
0560
0561 RSchemaIteratorTemplate() { fStack.emplace_back(Position()); }
0562 RSchemaIteratorTemplate(pointer val, int idxInParent) { fStack.emplace_back(Position(val, idxInParent)); }
0563 ~RSchemaIteratorTemplate() {}
0564
0565
0566 void Advance()
0567 {
0568 auto itr = fStack.rbegin();
0569 if (!itr->fFieldPtr->fSubFields.empty()) {
0570 fStack.emplace_back(Position(itr->fFieldPtr->fSubFields[0].get(), 0));
0571 return;
0572 }
0573
0574 unsigned int nextIdxInParent = ++(itr->fIdxInParent);
0575 while (nextIdxInParent >= itr->fFieldPtr->fParent->fSubFields.size()) {
0576 if (fStack.size() == 1) {
0577 itr->fFieldPtr = itr->fFieldPtr->fParent;
0578 itr->fIdxInParent = -1;
0579 return;
0580 }
0581 fStack.pop_back();
0582 itr = fStack.rbegin();
0583 nextIdxInParent = ++(itr->fIdxInParent);
0584 }
0585 itr->fFieldPtr = itr->fFieldPtr->fParent->fSubFields[nextIdxInParent].get();
0586 }
0587
0588 iterator operator++(int) { auto r = *this; Advance(); return r; }
0589 iterator& operator++() { Advance(); return *this; }
0590 reference operator* () const { return *fStack.back().fFieldPtr; }
0591 pointer operator->() const { return fStack.back().fFieldPtr; }
0592 bool operator==(const iterator& rh) const { return fStack.back().fFieldPtr == rh.fStack.back().fFieldPtr; }
0593 bool operator!=(const iterator& rh) const { return fStack.back().fFieldPtr != rh.fStack.back().fFieldPtr; }
0594 };
0595 using RSchemaIterator = RSchemaIteratorTemplate<false>;
0596 using RConstSchemaIterator = RSchemaIteratorTemplate<true>;
0597
0598
0599 template <typename T>
0600 struct RCreateObjectDeleter {
0601 using deleter = std::default_delete<T>;
0602 };
0603
0604
0605 struct RCheckResult {
0606 std::string fFieldName;
0607 std::string fTypeName;
0608 std::string fErrMsg;
0609 };
0610
0611
0612
0613
0614 RFieldBase(std::string_view name, std::string_view type, ENTupleStructure structure, bool isSimple,
0615 std::size_t nRepetitions = 0);
0616 RFieldBase(const RFieldBase&) = delete;
0617 RFieldBase(RFieldBase&&) = default;
0618 RFieldBase& operator =(const RFieldBase&) = delete;
0619 RFieldBase& operator =(RFieldBase&&) = default;
0620 virtual ~RFieldBase() = default;
0621
0622
0623 std::unique_ptr<RFieldBase> Clone(std::string_view newName) const;
0624
0625
0626 static RResult<std::unique_ptr<RFieldBase>>
0627 Create(const std::string &fieldName, const std::string &typeName);
0628
0629
0630 static std::vector<RCheckResult> Check(const std::string &fieldName, const std::string &typeName);
0631
0632 static RResult<void> EnsureValidFieldName(std::string_view fieldName);
0633
0634
0635
0636
0637
0638
0639
0640
0641
0642
0643 template <typename T>
0644 std::unique_ptr<T, typename RCreateObjectDeleter<T>::deleter> CreateObject() const;
0645
0646
0647 RValue CreateValue();
0648
0649 RBulk CreateBulk() { return RBulk(this); }
0650
0651 RValue BindValue(std::shared_ptr<void> objPtr) { return RValue(this, objPtr); }
0652
0653
0654
0655 virtual std::vector<RValue> SplitValue(const RValue &value) const;
0656
0657 virtual size_t GetValueSize() const = 0;
0658
0659
0660 virtual size_t GetAlignment() const = 0;
0661 int GetTraits() const { return fTraits; }
0662 bool HasReadCallbacks() const { return !fReadCallbacks.empty(); }
0663
0664 std::string GetFieldName() const { return fName; }
0665
0666 std::string GetQualifiedFieldName() const;
0667 std::string GetTypeName() const { return fType; }
0668 std::string GetTypeAlias() const { return fTypeAlias; }
0669 ENTupleStructure GetStructure() const { return fStructure; }
0670 std::size_t GetNRepetitions() const { return fNRepetitions; }
0671 NTupleSize_t GetNElements() const { return fPrincipalColumn->GetNElements(); }
0672 const RFieldBase *GetParent() const { return fParent; }
0673 std::vector<RFieldBase *> GetSubFields();
0674 std::vector<const RFieldBase *> GetSubFields() const;
0675 bool IsSimple() const { return fIsSimple; }
0676
0677 std::string GetDescription() const { return fDescription; }
0678 void SetDescription(std::string_view description);
0679 EState GetState() const { return fState; }
0680
0681 DescriptorId_t GetOnDiskId() const { return fOnDiskId; }
0682 void SetOnDiskId(DescriptorId_t id);
0683
0684
0685 const ColumnRepresentation_t &GetColumnRepresentative() const;
0686
0687
0688
0689 void SetColumnRepresentative(const ColumnRepresentation_t &representative);
0690
0691 bool HasDefaultColumnRepresentative() const { return fColumnRepresentative == nullptr; }
0692
0693
0694 virtual std::uint32_t GetFieldVersion() const { return 0; }
0695
0696 virtual std::uint32_t GetTypeVersion() const { return 0; }
0697
0698 std::uint32_t GetOnDiskTypeVersion() const { return fOnDiskTypeVersion; }
0699
0700 RSchemaIterator begin()
0701 {
0702 return fSubFields.empty() ? RSchemaIterator(this, -1) : RSchemaIterator(fSubFields[0].get(), 0);
0703 }
0704 RSchemaIterator end() { return RSchemaIterator(this, -1); }
0705 RConstSchemaIterator cbegin() const
0706 {
0707 return fSubFields.empty() ? RConstSchemaIterator(this, -1) : RConstSchemaIterator(fSubFields[0].get(), 0);
0708 }
0709 RConstSchemaIterator cend() const { return RConstSchemaIterator(this, -1); }
0710
0711 virtual void AcceptVisitor(Detail::RFieldVisitor &visitor) const;
0712 };
0713
0714
0715
0716 class RFieldZero final : public RFieldBase {
0717 protected:
0718 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const override;
0719 void GenerateColumnsImpl() final {}
0720 void GenerateColumnsImpl(const RNTupleDescriptor &) final {}
0721 void ConstructValue(void *) const final {}
0722
0723 public:
0724 RFieldZero() : RFieldBase("", "", ENTupleStructure::kRecord, false ) {}
0725
0726 using RFieldBase::Attach;
0727 size_t GetValueSize() const final { return 0; }
0728 size_t GetAlignment() const final { return 0; }
0729
0730 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
0731 };
0732
0733
0734 class RInvalidField final : public RFieldBase {
0735 std::string fError;
0736
0737 protected:
0738 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
0739 {
0740 return std::make_unique<RInvalidField>(newName, GetTypeName(), fError);
0741 }
0742 void GenerateColumnsImpl() final {}
0743 void GenerateColumnsImpl(const RNTupleDescriptor &) final {}
0744 void ConstructValue(void *) const final {}
0745
0746 public:
0747 RInvalidField(std::string_view name, std::string_view type, std::string_view error)
0748 : RFieldBase(name, type, ENTupleStructure::kLeaf, false ), fError(error)
0749 {
0750 }
0751
0752 std::string GetError() const { return fError; }
0753
0754 size_t GetValueSize() const final { return 0; }
0755 size_t GetAlignment() const final { return 0; }
0756 };
0757
0758
0759 class RClassField : public RFieldBase {
0760 private:
0761 enum ESubFieldRole {
0762 kBaseClass,
0763 kDataMember,
0764 };
0765 struct RSubFieldInfo {
0766 ESubFieldRole fRole;
0767 std::size_t fOffset;
0768 };
0769
0770 static constexpr const char *kPrefixInherited{":"};
0771
0772 class RClassDeleter : public RDeleter {
0773 private:
0774 TClass *fClass;
0775
0776 public:
0777 explicit RClassDeleter(TClass *cl) : fClass(cl) {}
0778 void operator()(void *objPtr, bool dtorOnly) final;
0779 };
0780
0781 TClass* fClass;
0782
0783 std::vector<RSubFieldInfo> fSubFieldsInfo;
0784 std::size_t fMaxAlignment = 1;
0785
0786 private:
0787 RClassField(std::string_view fieldName, std::string_view className, TClass *classp);
0788 void Attach(std::unique_ptr<RFieldBase> child, RSubFieldInfo info);
0789
0790
0791 void AddReadCallbacksFromIORules(const std::span<const TSchemaRule *> rules, TClass *classp = nullptr);
0792
0793 protected:
0794 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
0795 void GenerateColumnsImpl() final {}
0796 void GenerateColumnsImpl(const RNTupleDescriptor &) final {}
0797
0798 void ConstructValue(void *where) const override;
0799 std::unique_ptr<RDeleter> GetDeleter() const final { return std::make_unique<RClassDeleter>(fClass); }
0800
0801 std::size_t AppendImpl(const void *from) final;
0802 void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final;
0803 void ReadInClusterImpl(RClusterIndex clusterIndex, void *to) final;
0804 void OnConnectPageSource() final;
0805
0806 public:
0807 RClassField(std::string_view fieldName, std::string_view className);
0808 RClassField(RClassField&& other) = default;
0809 RClassField& operator =(RClassField&& other) = default;
0810 ~RClassField() override = default;
0811
0812 std::vector<RValue> SplitValue(const RValue &value) const final;
0813 size_t GetValueSize() const override;
0814 size_t GetAlignment() const final { return fMaxAlignment; }
0815 std::uint32_t GetTypeVersion() const final;
0816 void AcceptVisitor(Detail::RFieldVisitor &visitor) const override;
0817 };
0818
0819
0820 class REnumField : public RFieldBase {
0821 private:
0822 REnumField(std::string_view fieldName, std::string_view enumName, TEnum *enump);
0823 REnumField(std::string_view fieldName, std::string_view enumName, std::unique_ptr<RFieldBase> intField);
0824
0825 protected:
0826 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
0827 void GenerateColumnsImpl() final {}
0828 void GenerateColumnsImpl(const RNTupleDescriptor & ) final {}
0829
0830 void ConstructValue(void *where) const final { CallConstructValueOn(*fSubFields[0], where); }
0831
0832 std::size_t AppendImpl(const void *from) final { return CallAppendOn(*fSubFields[0], from); }
0833 void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final { CallReadOn(*fSubFields[0], globalIndex, to); }
0834 void ReadInClusterImpl(RClusterIndex clusterIndex, void *to) final { CallReadOn(*fSubFields[0], clusterIndex, to); }
0835
0836 public:
0837 REnumField(std::string_view fieldName, std::string_view enumName);
0838 REnumField(REnumField &&other) = default;
0839 REnumField &operator=(REnumField &&other) = default;
0840 ~REnumField() override = default;
0841
0842 std::vector<RValue> SplitValue(const RValue &value) const final;
0843 size_t GetValueSize() const final { return fSubFields[0]->GetValueSize(); }
0844 size_t GetAlignment() const final { return fSubFields[0]->GetAlignment(); }
0845 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
0846 };
0847
0848
0849
0850
0851
0852
0853
0854
0855
0856
0857 class RProxiedCollectionField : public RFieldBase {
0858 protected:
0859
0860
0861 class RCollectionIterableOnce {
0862 public:
0863 struct RIteratorFuncs {
0864 TVirtualCollectionProxy::CreateIterators_t fCreateIterators;
0865 TVirtualCollectionProxy::DeleteTwoIterators_t fDeleteTwoIterators;
0866 TVirtualCollectionProxy::Next_t fNext;
0867 };
0868 static RIteratorFuncs GetIteratorFuncs(TVirtualCollectionProxy *proxy, bool readFromDisk);
0869
0870 private:
0871 class RIterator {
0872 const RCollectionIterableOnce &fOwner;
0873 void *fIterator = nullptr;
0874 void *fElementPtr = nullptr;
0875
0876 void Advance()
0877 {
0878 auto fnNext_Contig = [&]() {
0879
0880
0881 auto &iter = reinterpret_cast<unsigned char *&>(fIterator), p = iter;
0882 iter += fOwner.fStride;
0883 return p;
0884 };
0885 fElementPtr = fOwner.fStride ? fnNext_Contig() : fOwner.fIFuncs.fNext(fIterator, fOwner.fEnd);
0886 }
0887
0888 public:
0889 using iterator_category = std::forward_iterator_tag;
0890 using iterator = RIterator;
0891 using difference_type = std::ptrdiff_t;
0892 using pointer = void *;
0893
0894 RIterator(const RCollectionIterableOnce &owner) : fOwner(owner) {}
0895 RIterator(const RCollectionIterableOnce &owner, void *iter) : fOwner(owner), fIterator(iter) { Advance(); }
0896 iterator operator++()
0897 {
0898 Advance();
0899 return *this;
0900 }
0901 pointer operator*() const { return fElementPtr; }
0902 bool operator!=(const iterator &rh) const { return fElementPtr != rh.fElementPtr; }
0903 bool operator==(const iterator &rh) const { return fElementPtr == rh.fElementPtr; }
0904 };
0905
0906 const RIteratorFuncs &fIFuncs;
0907 const std::size_t fStride;
0908 unsigned char fBeginSmallBuf[TVirtualCollectionProxy::fgIteratorArenaSize];
0909 unsigned char fEndSmallBuf[TVirtualCollectionProxy::fgIteratorArenaSize];
0910 void *fBegin = &fBeginSmallBuf;
0911 void *fEnd = &fEndSmallBuf;
0912 public:
0913
0914
0915
0916 RCollectionIterableOnce(void *collection, const RIteratorFuncs &ifuncs, TVirtualCollectionProxy *proxy,
0917 std::size_t stride = 0U)
0918 : fIFuncs(ifuncs), fStride(stride)
0919 {
0920 fIFuncs.fCreateIterators(collection, &fBegin, &fEnd, proxy);
0921 }
0922 ~RCollectionIterableOnce() { fIFuncs.fDeleteTwoIterators(fBegin, fEnd); }
0923
0924 RIterator begin() { return RIterator(*this, fBegin); }
0925 RIterator end() { return fStride ? RIterator(*this, fEnd) : RIterator(*this); }
0926 };
0927
0928 class RProxiedCollectionDeleter : public RDeleter {
0929 private:
0930 std::shared_ptr<TVirtualCollectionProxy> fProxy;
0931 std::unique_ptr<RDeleter> fItemDeleter;
0932 std::size_t fItemSize = 0;
0933 RCollectionIterableOnce::RIteratorFuncs fIFuncsWrite;
0934
0935 public:
0936 explicit RProxiedCollectionDeleter(std::shared_ptr<TVirtualCollectionProxy> proxy) : fProxy(proxy) {}
0937 RProxiedCollectionDeleter(std::shared_ptr<TVirtualCollectionProxy> proxy, std::unique_ptr<RDeleter> itemDeleter,
0938 size_t itemSize)
0939 : fProxy(proxy), fItemDeleter(std::move(itemDeleter)), fItemSize(itemSize)
0940 {
0941 fIFuncsWrite = RCollectionIterableOnce::GetIteratorFuncs(fProxy.get(), false );
0942 }
0943 void operator()(void *objPtr, bool dtorOnly) final;
0944 };
0945
0946
0947 std::shared_ptr<TVirtualCollectionProxy> fProxy;
0948 Int_t fProperties;
0949 Int_t fCollectionType;
0950
0951
0952 RCollectionIterableOnce::RIteratorFuncs fIFuncsRead;
0953 RCollectionIterableOnce::RIteratorFuncs fIFuncsWrite;
0954 std::size_t fItemSize;
0955 ClusterSize_t fNWritten;
0956
0957
0958
0959 RProxiedCollectionField(std::string_view fieldName, std::string_view typeName, TClass *classp);
0960
0961 RProxiedCollectionField(std::string_view fieldName, std::string_view typeName,
0962 std::unique_ptr<RFieldBase> itemField);
0963
0964 protected:
0965 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const override;
0966 const RColumnRepresentations &GetColumnRepresentations() const final;
0967 void GenerateColumnsImpl() final;
0968 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
0969
0970 void ConstructValue(void *where) const override;
0971 std::unique_ptr<RDeleter> GetDeleter() const override;
0972
0973 std::size_t AppendImpl(const void *from) override;
0974 void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) override;
0975
0976 void CommitClusterImpl() final { fNWritten = 0; }
0977
0978 public:
0979 RProxiedCollectionField(std::string_view fieldName, std::string_view typeName);
0980 RProxiedCollectionField(RProxiedCollectionField &&other) = default;
0981 RProxiedCollectionField &operator=(RProxiedCollectionField &&other) = default;
0982 ~RProxiedCollectionField() override = default;
0983
0984 std::vector<RValue> SplitValue(const RValue &value) const override;
0985 size_t GetValueSize() const override { return fProxy->Sizeof(); }
0986 size_t GetAlignment() const override { return alignof(std::max_align_t); }
0987 void AcceptVisitor(Detail::RFieldVisitor &visitor) const override;
0988 void GetCollectionInfo(NTupleSize_t globalIndex, RClusterIndex *collectionStart, ClusterSize_t *size) const
0989 {
0990 fPrincipalColumn->GetCollectionInfo(globalIndex, collectionStart, size);
0991 }
0992 void GetCollectionInfo(RClusterIndex clusterIndex, RClusterIndex *collectionStart, ClusterSize_t *size) const
0993 {
0994 fPrincipalColumn->GetCollectionInfo(clusterIndex, collectionStart, size);
0995 }
0996 };
0997
0998
0999
1000 class RRecordField : public RFieldBase {
1001 private:
1002 class RRecordDeleter : public RDeleter {
1003 private:
1004 std::vector<std::unique_ptr<RDeleter>> fItemDeleters;
1005 std::vector<std::size_t> fOffsets;
1006
1007 public:
1008 RRecordDeleter(std::vector<std::unique_ptr<RDeleter>> &itemDeleters, const std::vector<std::size_t> &offsets)
1009 : fItemDeleters(std::move(itemDeleters)), fOffsets(offsets)
1010 {
1011 }
1012 void operator()(void *objPtr, bool dtorOnly) final;
1013 };
1014
1015 protected:
1016 std::size_t fMaxAlignment = 1;
1017 std::size_t fSize = 0;
1018 std::vector<std::size_t> fOffsets;
1019
1020 std::size_t GetItemPadding(std::size_t baseOffset, std::size_t itemAlignment) const;
1021
1022 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const override;
1023
1024 void GenerateColumnsImpl() final {}
1025 void GenerateColumnsImpl(const RNTupleDescriptor &) final {}
1026
1027 void ConstructValue(void *where) const override;
1028 std::unique_ptr<RDeleter> GetDeleter() const override;
1029
1030 std::size_t AppendImpl(const void *from) final;
1031 void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final;
1032 void ReadInClusterImpl(RClusterIndex clusterIndex, void *to) final;
1033
1034 RRecordField(std::string_view fieldName, std::vector<std::unique_ptr<RFieldBase>> &&itemFields,
1035 const std::vector<std::size_t> &offsets, std::string_view typeName = "");
1036
1037 template <std::size_t N>
1038 RRecordField(std::string_view fieldName, std::array<std::unique_ptr<RFieldBase>, N> &&itemFields,
1039 const std::array<std::size_t, N> &offsets, std::string_view typeName = "")
1040 : ROOT::Experimental::RFieldBase(fieldName, typeName, ENTupleStructure::kRecord, false )
1041 {
1042 fTraits |= kTraitTrivialType;
1043 for (unsigned i = 0; i < N; ++i) {
1044 fOffsets.push_back(offsets[i]);
1045 fMaxAlignment = std::max(fMaxAlignment, itemFields[i]->GetAlignment());
1046 fSize += GetItemPadding(fSize, itemFields[i]->GetAlignment()) + itemFields[i]->GetValueSize();
1047 fTraits &= itemFields[i]->GetTraits();
1048 Attach(std::move(itemFields[i]));
1049 }
1050 }
1051 public:
1052
1053
1054 RRecordField(std::string_view fieldName, std::vector<std::unique_ptr<RFieldBase>> &&itemFields);
1055 RRecordField(std::string_view fieldName, std::vector<std::unique_ptr<RFieldBase>> &itemFields);
1056 RRecordField(RRecordField&& other) = default;
1057 RRecordField& operator =(RRecordField&& other) = default;
1058 ~RRecordField() override = default;
1059
1060 std::vector<RValue> SplitValue(const RValue &value) const final;
1061 size_t GetValueSize() const final { return fSize; }
1062 size_t GetAlignment() const final { return fMaxAlignment; }
1063 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
1064 };
1065
1066
1067 class RVectorField : public RFieldBase {
1068 private:
1069 class RVectorDeleter : public RDeleter {
1070 private:
1071 std::size_t fItemSize = 0;
1072 std::unique_ptr<RDeleter> fItemDeleter;
1073
1074 public:
1075 RVectorDeleter() = default;
1076 RVectorDeleter(std::size_t itemSize, std::unique_ptr<RDeleter> itemDeleter)
1077 : fItemSize(itemSize), fItemDeleter(std::move(itemDeleter))
1078 {
1079 }
1080 void operator()(void *objPtr, bool dtorOnly) final;
1081 };
1082
1083 std::size_t fItemSize;
1084 ClusterSize_t fNWritten;
1085 std::unique_ptr<RDeleter> fItemDeleter;
1086
1087 protected:
1088 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
1089
1090 const RColumnRepresentations &GetColumnRepresentations() const final;
1091 void GenerateColumnsImpl() final;
1092 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
1093
1094 void ConstructValue(void *where) const override { new (where) std::vector<char>(); }
1095 std::unique_ptr<RDeleter> GetDeleter() const final;
1096
1097 std::size_t AppendImpl(const void *from) final;
1098 void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final;
1099
1100 void CommitClusterImpl() final { fNWritten = 0; }
1101
1102 public:
1103 RVectorField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField);
1104 RVectorField(RVectorField&& other) = default;
1105 RVectorField& operator =(RVectorField&& other) = default;
1106 ~RVectorField() override = default;
1107
1108 std::vector<RValue> SplitValue(const RValue &value) const final;
1109 size_t GetValueSize() const override { return sizeof(std::vector<char>); }
1110 size_t GetAlignment() const final { return std::alignment_of<std::vector<char>>(); }
1111 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
1112 void GetCollectionInfo(NTupleSize_t globalIndex, RClusterIndex *collectionStart, ClusterSize_t *size) const {
1113 fPrincipalColumn->GetCollectionInfo(globalIndex, collectionStart, size);
1114 }
1115 void GetCollectionInfo(RClusterIndex clusterIndex, RClusterIndex *collectionStart, ClusterSize_t *size) const
1116 {
1117 fPrincipalColumn->GetCollectionInfo(clusterIndex, collectionStart, size);
1118 }
1119 };
1120
1121
1122 class RRVecField : public RFieldBase {
1123 public:
1124
1125 class RRVecDeleter : public RDeleter {
1126 private:
1127 std::size_t fItemAlignment;
1128 std::size_t fItemSize = 0;
1129 std::unique_ptr<RDeleter> fItemDeleter;
1130
1131 public:
1132 explicit RRVecDeleter(std::size_t itemAlignment) : fItemAlignment(itemAlignment) {}
1133 RRVecDeleter(std::size_t itemAlignment, std::size_t itemSize, std::unique_ptr<RDeleter> itemDeleter)
1134 : fItemAlignment(itemAlignment), fItemSize(itemSize), fItemDeleter(std::move(itemDeleter))
1135 {
1136 }
1137 void operator()(void *objPtr, bool dtorOnly) final;
1138 };
1139
1140 std::unique_ptr<RDeleter> fItemDeleter;
1141
1142 protected:
1143 std::size_t fItemSize;
1144 ClusterSize_t fNWritten;
1145 std::size_t fValueSize;
1146
1147 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const override;
1148 const RColumnRepresentations &GetColumnRepresentations() const final;
1149 void GenerateColumnsImpl() final;
1150 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
1151
1152 void ConstructValue(void *where) const override;
1153 std::unique_ptr<RDeleter> GetDeleter() const override;
1154
1155 std::size_t AppendImpl(const void *from) override;
1156 void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) override;
1157 std::size_t ReadBulkImpl(const RBulkSpec &bulkSpec) final;
1158
1159 void CommitClusterImpl() final { fNWritten = 0; }
1160
1161 public:
1162 RRVecField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField);
1163 RRVecField(RRVecField &&) = default;
1164 RRVecField &operator=(RRVecField &&) = default;
1165 RRVecField(const RRVecField &) = delete;
1166 RRVecField &operator=(RRVecField &) = delete;
1167 ~RRVecField() override = default;
1168
1169 std::vector<RValue> SplitValue(const RValue &value) const final;
1170 size_t GetValueSize() const override;
1171 size_t GetAlignment() const override;
1172 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
1173 void GetCollectionInfo(NTupleSize_t globalIndex, RClusterIndex *collectionStart, ClusterSize_t *size) const
1174 {
1175 fPrincipalColumn->GetCollectionInfo(globalIndex, collectionStart, size);
1176 }
1177 void GetCollectionInfo(RClusterIndex clusterIndex, RClusterIndex *collectionStart, ClusterSize_t *size) const
1178 {
1179 fPrincipalColumn->GetCollectionInfo(clusterIndex, collectionStart, size);
1180 }
1181 };
1182
1183
1184 class RArrayField : public RFieldBase {
1185 private:
1186 class RArrayDeleter : public RDeleter {
1187 private:
1188 std::size_t fItemSize = 0;
1189 std::size_t fArrayLength = 0;
1190 std::unique_ptr<RDeleter> fItemDeleter;
1191
1192 public:
1193 RArrayDeleter(std::size_t itemSize, std::size_t arrayLength, std::unique_ptr<RDeleter> itemDeleter)
1194 : fItemSize(itemSize), fArrayLength(arrayLength), fItemDeleter(std::move(itemDeleter))
1195 {
1196 }
1197 void operator()(void *objPtr, bool dtorOnly) final;
1198 };
1199
1200 std::size_t fItemSize;
1201 std::size_t fArrayLength;
1202
1203 protected:
1204 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
1205
1206 void GenerateColumnsImpl() final {}
1207 void GenerateColumnsImpl(const RNTupleDescriptor &) final {}
1208
1209 void ConstructValue(void *where) const override;
1210 std::unique_ptr<RDeleter> GetDeleter() const final;
1211
1212 std::size_t AppendImpl(const void *from) final;
1213 void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final;
1214 void ReadInClusterImpl(RClusterIndex clusterIndex, void *to) final;
1215
1216 public:
1217 RArrayField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField, std::size_t arrayLength);
1218 RArrayField(RArrayField &&other) = default;
1219 RArrayField& operator =(RArrayField &&other) = default;
1220 ~RArrayField() override = default;
1221
1222 std::vector<RValue> SplitValue(const RValue &value) const final;
1223 size_t GetLength() const { return fArrayLength; }
1224 size_t GetValueSize() const final { return fItemSize * fArrayLength; }
1225 size_t GetAlignment() const final { return fSubFields[0]->GetAlignment(); }
1226 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
1227 };
1228
1229
1230
1231
1232
1233
1234
1235
1236 class RArrayAsRVecField final : public RFieldBase {
1237 private:
1238 std::unique_ptr<RDeleter> fItemDeleter;
1239 std::size_t fItemSize;
1240 std::size_t fArrayLength;
1241 std::size_t fValueSize;
1242
1243 protected:
1244 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
1245
1246 void GenerateColumnsImpl() final { R__ASSERT(false && "RArrayAsRVec fields must only be used for reading"); }
1247 void GenerateColumnsImpl(const RNTupleDescriptor &) final {}
1248
1249 void ConstructValue(void *where) const final;
1250
1251 std::unique_ptr<RDeleter> GetDeleter() const final;
1252
1253 void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final;
1254 void ReadInClusterImpl(RClusterIndex clusterIndex, void *to) final;
1255
1256 public:
1257
1258
1259
1260
1261
1262 RArrayAsRVecField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField, std::size_t arrayLength);
1263 RArrayAsRVecField(const RArrayAsRVecField &other) = delete;
1264 RArrayAsRVecField &operator=(const RArrayAsRVecField &other) = delete;
1265 RArrayAsRVecField(RArrayAsRVecField &&other) = default;
1266 RArrayAsRVecField &operator=(RArrayAsRVecField &&other) = default;
1267 ~RArrayAsRVecField() final = default;
1268
1269 std::size_t GetValueSize() const final { return fValueSize; }
1270 std::size_t GetAlignment() const final;
1271
1272 std::vector<RFieldBase::RValue> SplitValue(const RFieldBase::RValue &value) const final;
1273 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
1274 };
1275
1276
1277
1278
1279 class RBitsetField : public RFieldBase {
1280 using Word_t = unsigned long;
1281 static constexpr std::size_t kWordSize = sizeof(Word_t);
1282 static constexpr std::size_t kBitsPerWord = kWordSize * 8;
1283
1284 protected:
1285 std::size_t fN;
1286
1287 protected:
1288 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
1289 {
1290 return std::make_unique<RBitsetField>(newName, fN);
1291 }
1292 const RColumnRepresentations &GetColumnRepresentations() const final;
1293 void GenerateColumnsImpl() final;
1294 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
1295 void ConstructValue(void *where) const final { memset(where, 0, GetValueSize()); }
1296 std::size_t AppendImpl(const void *from) final;
1297 void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final;
1298
1299 public:
1300 RBitsetField(std::string_view fieldName, std::size_t N);
1301 RBitsetField(RBitsetField &&other) = default;
1302 RBitsetField &operator=(RBitsetField &&other) = default;
1303 ~RBitsetField() override = default;
1304
1305 size_t GetValueSize() const final { return kWordSize * ((fN + kBitsPerWord - 1) / kBitsPerWord); }
1306 size_t GetAlignment() const final { return alignof(Word_t); }
1307 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
1308
1309
1310 std::size_t GetN() const { return fN; }
1311 };
1312
1313
1314 class RVariantField : public RFieldBase {
1315 private:
1316 class RVariantDeleter : public RDeleter {
1317 private:
1318 std::size_t fTagOffset;
1319 std::vector<std::unique_ptr<RDeleter>> fItemDeleters;
1320
1321 public:
1322 RVariantDeleter(std::size_t tagOffset, std::vector<std::unique_ptr<RDeleter>> &itemDeleters)
1323 : fTagOffset(tagOffset), fItemDeleters(std::move(itemDeleters))
1324 {
1325 }
1326 void operator()(void *objPtr, bool dtorOnly) final;
1327 };
1328
1329 size_t fMaxItemSize = 0;
1330 size_t fMaxAlignment = 1;
1331
1332 size_t fTagOffset = 0;
1333 std::vector<ClusterSize_t::ValueType> fNWritten;
1334
1335 static std::string GetTypeList(const std::vector<RFieldBase *> &itemFields);
1336
1337 static std::uint32_t GetTag(const void *variantPtr, std::size_t tagOffset);
1338 static void SetTag(void *variantPtr, std::size_t tagOffset, std::uint32_t tag);
1339
1340 protected:
1341 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
1342
1343 const RColumnRepresentations &GetColumnRepresentations() const final;
1344 void GenerateColumnsImpl() final;
1345 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
1346
1347 void ConstructValue(void *where) const override;
1348 std::unique_ptr<RDeleter> GetDeleter() const final;
1349
1350 std::size_t AppendImpl(const void *from) final;
1351 void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final;
1352
1353 void CommitClusterImpl() final;
1354
1355 public:
1356
1357 RVariantField(std::string_view fieldName, const std::vector<RFieldBase *> &itemFields);
1358 RVariantField(RVariantField &&other) = default;
1359 RVariantField& operator =(RVariantField &&other) = default;
1360 ~RVariantField() override = default;
1361
1362 size_t GetValueSize() const final;
1363 size_t GetAlignment() const final { return fMaxAlignment; }
1364 };
1365
1366
1367 class RSetField : public RProxiedCollectionField {
1368 protected:
1369 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
1370
1371 public:
1372 RSetField(std::string_view fieldName, std::string_view typeName, std::unique_ptr<RFieldBase> itemField);
1373 RSetField(RSetField &&other) = default;
1374 RSetField &operator=(RSetField &&other) = default;
1375 ~RSetField() override = default;
1376
1377 size_t GetAlignment() const override { return std::alignment_of<std::set<std::max_align_t>>(); }
1378 };
1379
1380
1381 class RMapField : public RProxiedCollectionField {
1382 private:
1383 TClass *fItemClass;
1384
1385 protected:
1386 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
1387
1388 std::size_t AppendImpl(const void *from) final;
1389 void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final;
1390
1391 public:
1392 RMapField(std::string_view fieldName, std::string_view typeName, std::unique_ptr<RFieldBase> itemField);
1393 RMapField(RMapField &&other) = default;
1394 RMapField &operator=(RMapField &&other) = default;
1395 ~RMapField() override = default;
1396
1397 std::vector<RValue> SplitValue(const RValue &value) const final;
1398
1399 size_t GetAlignment() const override { return std::alignment_of<std::map<std::max_align_t, std::max_align_t>>(); }
1400 };
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410 class RNullableField : public RFieldBase {
1411
1412 std::unique_ptr<RValue> fDefaultItemValue;
1413
1414 ClusterSize_t fNWritten{0};
1415
1416 protected:
1417 const RFieldBase::RColumnRepresentations &GetColumnRepresentations() const final;
1418 void GenerateColumnsImpl() final;
1419 void GenerateColumnsImpl(const RNTupleDescriptor &) final;
1420
1421 std::size_t AppendNull();
1422 std::size_t AppendValue(const void *from);
1423 void CommitClusterImpl() final { fNWritten = 0; }
1424
1425
1426
1427 RClusterIndex GetItemIndex(NTupleSize_t globalIndex);
1428
1429 RNullableField(std::string_view fieldName, std::string_view typeName, std::unique_ptr<RFieldBase> itemField);
1430
1431 public:
1432 RNullableField(RNullableField &&other) = default;
1433 RNullableField &operator=(RNullableField &&other) = default;
1434 ~RNullableField() override = default;
1435
1436 bool IsDense() const { return GetColumnRepresentative()[0] == EColumnType::kBit; }
1437 bool IsSparse() const { return !IsDense(); }
1438 void SetDense() { SetColumnRepresentative({EColumnType::kBit}); }
1439 void SetSparse() { SetColumnRepresentative({EColumnType::kSplitIndex32}); }
1440
1441 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
1442 };
1443
1444 class RUniquePtrField : public RNullableField {
1445 class RUniquePtrDeleter : public RDeleter {
1446 private:
1447 std::unique_ptr<RDeleter> fItemDeleter;
1448
1449 public:
1450 explicit RUniquePtrDeleter(std::unique_ptr<RDeleter> itemDeleter) : fItemDeleter(std::move(itemDeleter)) {}
1451 void operator()(void *objPtr, bool dtorOnly) final;
1452 };
1453
1454 std::unique_ptr<RDeleter> fItemDeleter;
1455
1456 protected:
1457 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
1458
1459 void ConstructValue(void *where) const final { new (where) std::unique_ptr<char>(); }
1460 std::unique_ptr<RDeleter> GetDeleter() const final;
1461
1462 std::size_t AppendImpl(const void *from) final;
1463 void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final;
1464
1465 public:
1466 RUniquePtrField(std::string_view fieldName, std::string_view typeName, std::unique_ptr<RFieldBase> itemField);
1467 RUniquePtrField(RUniquePtrField &&other) = default;
1468 RUniquePtrField &operator=(RUniquePtrField &&other) = default;
1469 ~RUniquePtrField() override = default;
1470
1471 std::vector<RValue> SplitValue(const RValue &value) const final;
1472 size_t GetValueSize() const final { return sizeof(std::unique_ptr<char>); }
1473 size_t GetAlignment() const final { return alignof(std::unique_ptr<char>); }
1474 };
1475
1476 class RAtomicField : public RFieldBase {
1477 protected:
1478 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
1479 void GenerateColumnsImpl() final {}
1480 void GenerateColumnsImpl(const RNTupleDescriptor &) final {}
1481
1482 void ConstructValue(void *where) const final { CallConstructValueOn(*fSubFields[0], where); }
1483 std::unique_ptr<RDeleter> GetDeleter() const final { return GetDeleterOf(*fSubFields[0]); }
1484
1485 std::size_t AppendImpl(const void *from) final { return CallAppendOn(*fSubFields[0], from); }
1486 void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final { CallReadOn(*fSubFields[0], globalIndex, to); }
1487 void ReadInClusterImpl(RClusterIndex clusterIndex, void *to) final { CallReadOn(*fSubFields[0], clusterIndex, to); }
1488
1489 public:
1490 RAtomicField(std::string_view fieldName, std::string_view typeName, std::unique_ptr<RFieldBase> itemField);
1491 RAtomicField(RAtomicField &&other) = default;
1492 RAtomicField &operator=(RAtomicField &&other) = default;
1493 ~RAtomicField() override = default;
1494
1495 std::vector<RValue> SplitValue(const RValue &value) const final;
1496
1497 size_t GetValueSize() const final { return fSubFields[0]->GetValueSize(); }
1498 size_t GetAlignment() const final { return fSubFields[0]->GetAlignment(); }
1499
1500 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
1501 };
1502
1503
1504 template <typename T, typename = void>
1505 class RField final : public RClassField {
1506 protected:
1507 void ConstructValue(void *where) const final
1508 {
1509 if constexpr (std::is_default_constructible_v<T>) {
1510 new (where) T();
1511 } else {
1512
1513 new (where) T(static_cast<TRootIOCtor *>(nullptr));
1514 }
1515 }
1516
1517 public:
1518 static std::string TypeName() { return ROOT::Internal::GetDemangledTypeName(typeid(T)); }
1519 RField(std::string_view name) : RClassField(name, TypeName()) {
1520 static_assert(std::is_class_v<T>, "no I/O support for this basic C++ type");
1521 }
1522 RField(RField &&other) = default;
1523 RField &operator=(RField &&other) = default;
1524 ~RField() override = default;
1525 };
1526
1527 template <typename T>
1528 class RField<T, typename std::enable_if<std::is_enum_v<T>>::type> : public REnumField {
1529 public:
1530 static std::string TypeName() { return ROOT::Internal::GetDemangledTypeName(typeid(T)); }
1531 RField(std::string_view name) : REnumField(name, TypeName()) {}
1532 RField(RField &&other) = default;
1533 RField &operator=(RField &&other) = default;
1534 ~RField() override = default;
1535 };
1536
1537 template <typename T, typename = void>
1538 struct HasCollectionProxyMemberType : std::false_type {
1539 };
1540 template <typename T>
1541 struct HasCollectionProxyMemberType<
1542 T, typename std::enable_if<std::is_same<typename T::IsCollectionProxy, std::true_type>::value>::type>
1543 : std::true_type {
1544 };
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583 template <typename T, typename = void>
1584 struct IsCollectionProxy : HasCollectionProxyMemberType<T> {
1585 };
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601 template <typename T>
1602 class RField<T, typename std::enable_if<IsCollectionProxy<T>::value>::type> final : public RProxiedCollectionField {
1603 protected:
1604 void ConstructValue(void *where) const final { new (where) T(); }
1605
1606 public:
1607 static std::string TypeName() { return ROOT::Internal::GetDemangledTypeName(typeid(T)); }
1608 RField(std::string_view name) : RProxiedCollectionField(name, TypeName())
1609 {
1610 static_assert(std::is_class<T>::value, "collection proxy unsupported for fundamental types");
1611 }
1612 RField(RField&& other) = default;
1613 RField& operator =(RField&& other) = default;
1614 ~RField() override = default;
1615 };
1616
1617
1618 class RCollectionField final : public ROOT::Experimental::RFieldBase {
1619 private:
1620
1621 std::shared_ptr<RNTupleCollectionWriter> fCollectionWriter;
1622
1623 protected:
1624 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
1625 const RColumnRepresentations &GetColumnRepresentations() const final;
1626 void GenerateColumnsImpl() final;
1627 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
1628 void ConstructValue(void *) const final {}
1629
1630 std::size_t AppendImpl(const void *from) final;
1631 void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final;
1632
1633 void CommitClusterImpl() final;
1634
1635 public:
1636 static std::string TypeName() { return ""; }
1637 RCollectionField(std::string_view name, std::shared_ptr<RNTupleCollectionWriter> collectionWriter,
1638 std::unique_ptr<RFieldZero> collectionParent);
1639 RCollectionField(RCollectionField&& other) = default;
1640 RCollectionField& operator =(RCollectionField&& other) = default;
1641 ~RCollectionField() override = default;
1642
1643 size_t GetValueSize() const final { return sizeof(ClusterSize_t); }
1644 size_t GetAlignment() const final { return alignof(ClusterSize_t); }
1645 };
1646
1647
1648 class RPairField : public RRecordField {
1649 private:
1650 class RPairDeleter : public RDeleter {
1651 private:
1652 TClass *fClass;
1653
1654 public:
1655 explicit RPairDeleter(TClass *cl) : fClass(cl) {}
1656 void operator()(void *objPtr, bool dtorOnly) final;
1657 };
1658
1659 TClass *fClass = nullptr;
1660 static std::string GetTypeList(const std::array<std::unique_ptr<RFieldBase>, 2> &itemFields);
1661
1662 protected:
1663 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const override;
1664
1665 void ConstructValue(void *where) const override;
1666 std::unique_ptr<RDeleter> GetDeleter() const override { return std::make_unique<RPairDeleter>(fClass); }
1667
1668 RPairField(std::string_view fieldName, std::array<std::unique_ptr<RFieldBase>, 2> &&itemFields,
1669 const std::array<std::size_t, 2> &offsets);
1670
1671 public:
1672 RPairField(std::string_view fieldName, std::array<std::unique_ptr<RFieldBase>, 2> &itemFields);
1673 RPairField(RPairField &&other) = default;
1674 RPairField &operator=(RPairField &&other) = default;
1675 ~RPairField() override = default;
1676 };
1677
1678
1679 class RTupleField : public RRecordField {
1680 private:
1681 class RTupleDeleter : public RDeleter {
1682 private:
1683 TClass *fClass;
1684
1685 public:
1686 explicit RTupleDeleter(TClass *cl) : fClass(cl) {}
1687 void operator()(void *objPtr, bool dtorOnly) final;
1688 };
1689
1690 TClass *fClass = nullptr;
1691 static std::string GetTypeList(const std::vector<std::unique_ptr<RFieldBase>> &itemFields);
1692
1693 protected:
1694 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const override;
1695
1696 void ConstructValue(void *where) const override;
1697 std::unique_ptr<RDeleter> GetDeleter() const override { return std::make_unique<RTupleDeleter>(fClass); }
1698
1699 RTupleField(std::string_view fieldName, std::vector<std::unique_ptr<RFieldBase>> &&itemFields,
1700 const std::vector<std::size_t> &offsets);
1701
1702 public:
1703 RTupleField(std::string_view fieldName, std::vector<std::unique_ptr<RFieldBase>> &itemFields);
1704 RTupleField(RTupleField &&other) = default;
1705 RTupleField &operator=(RTupleField &&other) = default;
1706 ~RTupleField() override = default;
1707 };
1708
1709
1710
1711
1712
1713
1714 class RCardinalityField : public RFieldBase {
1715 protected:
1716 RCardinalityField(std::string_view fieldName, std::string_view typeName)
1717 : RFieldBase(fieldName, typeName, ENTupleStructure::kLeaf, false )
1718 {
1719 }
1720
1721 const RColumnRepresentations &GetColumnRepresentations() const final;
1722
1723 void GenerateColumnsImpl() final { throw RException(R__FAIL("Cardinality fields must only be used for reading")); }
1724 void GenerateColumnsImpl(const RNTupleDescriptor &) final;
1725
1726 public:
1727 RCardinalityField(RCardinalityField &&other) = default;
1728 RCardinalityField &operator=(RCardinalityField &&other) = default;
1729 ~RCardinalityField() override = default;
1730
1731 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
1732
1733 const RField<RNTupleCardinality<std::uint32_t>> *As32Bit() const;
1734 const RField<RNTupleCardinality<std::uint64_t>> *As64Bit() const;
1735 };
1736
1737
1738
1739
1740
1741 template <>
1742 class RField<void> : public RFieldBase {
1743 public:
1744 static std::string TypeName() { return "void"; }
1745
1746 RField() = delete;
1747 RField(const RField &) = delete;
1748 RField &operator=(const RField &) = delete;
1749 };
1750
1751 template <>
1752 class RField<ClusterSize_t> final : public RFieldBase {
1753 protected:
1754 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
1755 {
1756 return std::make_unique<RField>(newName);
1757 }
1758
1759 const RColumnRepresentations &GetColumnRepresentations() const final;
1760 void GenerateColumnsImpl() final;
1761 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
1762 void ConstructValue(void *where) const final { new (where) ClusterSize_t(0); }
1763
1764 public:
1765 static std::string TypeName() { return "ROOT::Experimental::ClusterSize_t"; }
1766 explicit RField(std::string_view name) : RFieldBase(name, TypeName(), ENTupleStructure::kLeaf, true )
1767 {
1768 fTraits |= kTraitTrivialType;
1769 }
1770 RField(RField&& other) = default;
1771 RField& operator =(RField&& other) = default;
1772 ~RField() override = default;
1773
1774 ClusterSize_t *Map(NTupleSize_t globalIndex) {
1775 return fPrincipalColumn->Map<ClusterSize_t>(globalIndex);
1776 }
1777 ClusterSize_t *Map(RClusterIndex clusterIndex) { return fPrincipalColumn->Map<ClusterSize_t>(clusterIndex); }
1778 ClusterSize_t *MapV(NTupleSize_t globalIndex, NTupleSize_t &nItems) {
1779 return fPrincipalColumn->MapV<ClusterSize_t>(globalIndex, nItems);
1780 }
1781 ClusterSize_t *MapV(RClusterIndex clusterIndex, NTupleSize_t &nItems)
1782 {
1783 return fPrincipalColumn->MapV<ClusterSize_t>(clusterIndex, nItems);
1784 }
1785
1786 size_t GetValueSize() const final { return sizeof(ClusterSize_t); }
1787 size_t GetAlignment() const final { return alignof(ClusterSize_t); }
1788
1789
1790 void GetCollectionInfo(NTupleSize_t globalIndex, RClusterIndex *collectionStart, ClusterSize_t *size) {
1791 fPrincipalColumn->GetCollectionInfo(globalIndex, collectionStart, size);
1792 }
1793 void GetCollectionInfo(RClusterIndex clusterIndex, RClusterIndex *collectionStart, ClusterSize_t *size)
1794 {
1795 fPrincipalColumn->GetCollectionInfo(clusterIndex, collectionStart, size);
1796 }
1797 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
1798 };
1799
1800 template <typename SizeT>
1801 class RField<RNTupleCardinality<SizeT>> final : public RCardinalityField {
1802 protected:
1803 std::unique_ptr<ROOT::Experimental::RFieldBase> CloneImpl(std::string_view newName) const final
1804 {
1805 return std::make_unique<RField<RNTupleCardinality<SizeT>>>(newName);
1806 }
1807 void ConstructValue(void *where) const final { new (where) RNTupleCardinality<SizeT>(0); }
1808
1809 public:
1810 static std::string TypeName() { return "ROOT::Experimental::RNTupleCardinality<" + RField<SizeT>::TypeName() + ">"; }
1811 explicit RField(std::string_view name) : RCardinalityField(name, TypeName()) {}
1812 RField(RField &&other) = default;
1813 RField &operator=(RField &&other) = default;
1814 ~RField() override = default;
1815
1816 size_t GetValueSize() const final { return sizeof(RNTupleCardinality<SizeT>); }
1817 size_t GetAlignment() const final { return alignof(RNTupleCardinality<SizeT>); }
1818
1819
1820 void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
1821 {
1822 RClusterIndex collectionStart;
1823 ClusterSize_t size;
1824 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &size);
1825 *static_cast<RNTupleCardinality<SizeT> *>(to) = size;
1826 }
1827
1828
1829 void ReadInClusterImpl(RClusterIndex clusterIndex, void *to) final
1830 {
1831 RClusterIndex collectionStart;
1832 ClusterSize_t size;
1833 fPrincipalColumn->GetCollectionInfo(clusterIndex, &collectionStart, &size);
1834 *static_cast<RNTupleCardinality<SizeT> *>(to) = size;
1835 }
1836
1837 std::size_t ReadBulkImpl(const RBulkSpec &bulkSpec) final
1838 {
1839 RClusterIndex collectionStart;
1840 ClusterSize_t collectionSize;
1841 fPrincipalColumn->GetCollectionInfo(bulkSpec.fFirstIndex, &collectionStart, &collectionSize);
1842
1843 auto typedValues = static_cast<RNTupleCardinality<SizeT> *>(bulkSpec.fValues);
1844 typedValues[0] = collectionSize;
1845
1846 auto lastOffset = collectionStart.GetIndex() + collectionSize;
1847 ClusterSize_t::ValueType nRemainingEntries = bulkSpec.fCount - 1;
1848 std::size_t nEntries = 1;
1849 while (nRemainingEntries > 0) {
1850 NTupleSize_t nItemsUntilPageEnd;
1851 auto offsets = fPrincipalColumn->MapV<ClusterSize_t>(bulkSpec.fFirstIndex + nEntries, nItemsUntilPageEnd);
1852 std::size_t nBatch = std::min(nRemainingEntries, nItemsUntilPageEnd);
1853 for (std::size_t i = 0; i < nBatch; ++i) {
1854 typedValues[nEntries + i] = offsets[i] - lastOffset;
1855 lastOffset = offsets[i];
1856 }
1857 nRemainingEntries -= nBatch;
1858 nEntries += nBatch;
1859 }
1860 return RBulkSpec::kAllSet;
1861 }
1862 };
1863
1864 template <>
1865 class RField<bool> final : public RFieldBase {
1866 protected:
1867 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
1868 {
1869 return std::make_unique<RField>(newName);
1870 }
1871
1872 const RColumnRepresentations &GetColumnRepresentations() const final;
1873 void GenerateColumnsImpl() final;
1874 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
1875 void ConstructValue(void *where) const final { new (where) bool(false); }
1876
1877 public:
1878 static std::string TypeName() { return "bool"; }
1879 explicit RField(std::string_view name) : RFieldBase(name, TypeName(), ENTupleStructure::kLeaf, true )
1880 {
1881 fTraits |= kTraitTrivialType;
1882 }
1883 RField(RField&& other) = default;
1884 RField& operator =(RField&& other) = default;
1885 ~RField() override = default;
1886
1887 bool *Map(NTupleSize_t globalIndex) {
1888 return fPrincipalColumn->Map<bool>(globalIndex);
1889 }
1890 bool *Map(RClusterIndex clusterIndex) { return fPrincipalColumn->Map<bool>(clusterIndex); }
1891 bool *MapV(NTupleSize_t globalIndex, NTupleSize_t &nItems) {
1892 return fPrincipalColumn->MapV<bool>(globalIndex, nItems);
1893 }
1894 bool *MapV(RClusterIndex clusterIndex, NTupleSize_t &nItems)
1895 {
1896 return fPrincipalColumn->MapV<bool>(clusterIndex, nItems);
1897 }
1898
1899 size_t GetValueSize() const final { return sizeof(bool); }
1900 size_t GetAlignment() const final { return alignof(bool); }
1901 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
1902 };
1903
1904 template <>
1905 class RField<float> final : public RFieldBase {
1906 protected:
1907 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
1908 {
1909 return std::make_unique<RField>(newName);
1910 }
1911
1912 const RColumnRepresentations &GetColumnRepresentations() const final;
1913 void GenerateColumnsImpl() final;
1914 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
1915 void ConstructValue(void *where) const final { new (where) float(0.0); }
1916
1917 public:
1918 static std::string TypeName() { return "float"; }
1919 explicit RField(std::string_view name) : RFieldBase(name, TypeName(), ENTupleStructure::kLeaf, true )
1920 {
1921 fTraits |= kTraitTrivialType;
1922 }
1923 RField(RField&& other) = default;
1924 RField& operator =(RField&& other) = default;
1925 ~RField() override = default;
1926
1927 float *Map(NTupleSize_t globalIndex) {
1928 return fPrincipalColumn->Map<float>(globalIndex);
1929 }
1930 float *Map(RClusterIndex clusterIndex) { return fPrincipalColumn->Map<float>(clusterIndex); }
1931 float *MapV(NTupleSize_t globalIndex, NTupleSize_t &nItems) {
1932 return fPrincipalColumn->MapV<float>(globalIndex, nItems);
1933 }
1934 float *MapV(RClusterIndex clusterIndex, NTupleSize_t &nItems)
1935 {
1936 return fPrincipalColumn->MapV<float>(clusterIndex, nItems);
1937 }
1938
1939 size_t GetValueSize() const final { return sizeof(float); }
1940 size_t GetAlignment() const final { return alignof(float); }
1941 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
1942
1943 void SetHalfPrecision();
1944 };
1945
1946 template <>
1947 class RField<double> final : public RFieldBase {
1948 protected:
1949 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
1950 {
1951 return std::make_unique<RField>(newName);
1952 }
1953
1954 const RColumnRepresentations &GetColumnRepresentations() const final;
1955 void GenerateColumnsImpl() final;
1956 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
1957 void ConstructValue(void *where) const final { new (where) double(0.0); }
1958
1959 public:
1960 static std::string TypeName() { return "double"; }
1961 explicit RField(std::string_view name) : RFieldBase(name, TypeName(), ENTupleStructure::kLeaf, true )
1962 {
1963 fTraits |= kTraitTrivialType;
1964 }
1965 RField(RField&& other) = default;
1966 RField& operator =(RField&& other) = default;
1967 ~RField() override = default;
1968
1969 double *Map(NTupleSize_t globalIndex) {
1970 return fPrincipalColumn->Map<double>(globalIndex);
1971 }
1972 double *Map(RClusterIndex clusterIndex) { return fPrincipalColumn->Map<double>(clusterIndex); }
1973 double *MapV(NTupleSize_t globalIndex, NTupleSize_t &nItems) {
1974 return fPrincipalColumn->MapV<double>(globalIndex, nItems);
1975 }
1976 double *MapV(RClusterIndex clusterIndex, NTupleSize_t &nItems)
1977 {
1978 return fPrincipalColumn->MapV<double>(clusterIndex, nItems);
1979 }
1980
1981 size_t GetValueSize() const final { return sizeof(double); }
1982 size_t GetAlignment() const final { return alignof(double); }
1983 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
1984
1985
1986 void SetDouble32();
1987 };
1988
1989 template <>
1990 class RField<std::byte> final : public RFieldBase {
1991 protected:
1992 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
1993 {
1994 return std::make_unique<RField>(newName);
1995 }
1996
1997 const RColumnRepresentations &GetColumnRepresentations() const final;
1998 void GenerateColumnsImpl() final;
1999 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
2000 void ConstructValue(void *where) const final { new (where) std::byte{0}; }
2001
2002 public:
2003 static std::string TypeName() { return "std::byte"; }
2004 explicit RField(std::string_view name) : RFieldBase(name, TypeName(), ENTupleStructure::kLeaf, true )
2005 {
2006 fTraits |= kTraitTrivialType;
2007 }
2008 RField(RField &&other) = default;
2009 RField &operator=(RField &&other) = default;
2010 ~RField() override = default;
2011
2012 std::byte *Map(NTupleSize_t globalIndex) { return fPrincipalColumn->Map<std::byte>(globalIndex); }
2013 std::byte *Map(RClusterIndex clusterIndex) { return fPrincipalColumn->Map<std::byte>(clusterIndex); }
2014 std::byte *MapV(NTupleSize_t globalIndex, NTupleSize_t &nItems)
2015 {
2016 return fPrincipalColumn->MapV<std::byte>(globalIndex, nItems);
2017 }
2018 std::byte *MapV(RClusterIndex clusterIndex, NTupleSize_t &nItems)
2019 {
2020 return fPrincipalColumn->MapV<std::byte>(clusterIndex, nItems);
2021 }
2022
2023 size_t GetValueSize() const final { return sizeof(std::byte); }
2024 size_t GetAlignment() const final { return alignof(std::byte); }
2025 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
2026 };
2027
2028 template <>
2029 class RField<char> final : public RFieldBase {
2030 protected:
2031 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
2032 {
2033 return std::make_unique<RField>(newName);
2034 }
2035
2036 const RColumnRepresentations &GetColumnRepresentations() const final;
2037 void GenerateColumnsImpl() final;
2038 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
2039 void ConstructValue(void *where) const final { new (where) char(0); }
2040
2041 public:
2042 static std::string TypeName() { return "char"; }
2043 explicit RField(std::string_view name) : RFieldBase(name, TypeName(), ENTupleStructure::kLeaf, true )
2044 {
2045 fTraits |= kTraitTrivialType;
2046 }
2047 RField(RField&& other) = default;
2048 RField& operator =(RField&& other) = default;
2049 ~RField() override = default;
2050
2051 char *Map(NTupleSize_t globalIndex) {
2052 return fPrincipalColumn->Map<char>(globalIndex);
2053 }
2054 char *Map(RClusterIndex clusterIndex) { return fPrincipalColumn->Map<char>(clusterIndex); }
2055 char *MapV(NTupleSize_t globalIndex, NTupleSize_t &nItems) {
2056 return fPrincipalColumn->MapV<char>(globalIndex, nItems);
2057 }
2058 char *MapV(RClusterIndex clusterIndex, NTupleSize_t &nItems)
2059 {
2060 return fPrincipalColumn->MapV<char>(clusterIndex, nItems);
2061 }
2062
2063 size_t GetValueSize() const final { return sizeof(char); }
2064 size_t GetAlignment() const final { return alignof(char); }
2065 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
2066 };
2067
2068 template <>
2069 class RField<std::int8_t> final : public RFieldBase {
2070 protected:
2071 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
2072 {
2073 return std::make_unique<RField>(newName);
2074 }
2075
2076 const RColumnRepresentations &GetColumnRepresentations() const final;
2077 void GenerateColumnsImpl() final;
2078 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
2079 void ConstructValue(void *where) const final { new (where) int8_t(0); }
2080
2081 public:
2082 static std::string TypeName() { return "std::int8_t"; }
2083 explicit RField(std::string_view name) : RFieldBase(name, TypeName(), ENTupleStructure::kLeaf, true )
2084 {
2085 fTraits |= kTraitTrivialType;
2086 }
2087 RField(RField&& other) = default;
2088 RField& operator =(RField&& other) = default;
2089 ~RField() override = default;
2090
2091 std::int8_t *Map(NTupleSize_t globalIndex) {
2092 return fPrincipalColumn->Map<std::int8_t>(globalIndex);
2093 }
2094 std::int8_t *Map(RClusterIndex clusterIndex) { return fPrincipalColumn->Map<std::int8_t>(clusterIndex); }
2095 std::int8_t *MapV(NTupleSize_t globalIndex, NTupleSize_t &nItems) {
2096 return fPrincipalColumn->MapV<std::int8_t>(globalIndex, nItems);
2097 }
2098 std::int8_t *MapV(RClusterIndex clusterIndex, NTupleSize_t &nItems)
2099 {
2100 return fPrincipalColumn->MapV<std::int8_t>(clusterIndex, nItems);
2101 }
2102
2103 size_t GetValueSize() const final { return sizeof(std::int8_t); }
2104 size_t GetAlignment() const final { return alignof(std::int8_t); }
2105 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
2106 };
2107
2108 template <>
2109 class RField<std::uint8_t> final : public RFieldBase {
2110 protected:
2111 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
2112 {
2113 return std::make_unique<RField>(newName);
2114 }
2115
2116 const RColumnRepresentations &GetColumnRepresentations() const final;
2117 void GenerateColumnsImpl() final;
2118 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
2119 void ConstructValue(void *where) const final { new (where) uint8_t(0); }
2120
2121 public:
2122 static std::string TypeName() { return "std::uint8_t"; }
2123 explicit RField(std::string_view name) : RFieldBase(name, TypeName(), ENTupleStructure::kLeaf, true )
2124 {
2125 fTraits |= kTraitTrivialType;
2126 }
2127 RField(RField&& other) = default;
2128 RField& operator =(RField&& other) = default;
2129 ~RField() override = default;
2130
2131 std::uint8_t *Map(NTupleSize_t globalIndex) {
2132 return fPrincipalColumn->Map<std::uint8_t>(globalIndex);
2133 }
2134 std::uint8_t *Map(RClusterIndex clusterIndex) { return fPrincipalColumn->Map<std::uint8_t>(clusterIndex); }
2135 std::uint8_t *MapV(NTupleSize_t globalIndex, NTupleSize_t &nItems) {
2136 return fPrincipalColumn->MapV<std::uint8_t>(globalIndex, nItems);
2137 }
2138 std::uint8_t *MapV(RClusterIndex clusterIndex, NTupleSize_t &nItems)
2139 {
2140 return fPrincipalColumn->MapV<std::uint8_t>(clusterIndex, nItems);
2141 }
2142
2143 size_t GetValueSize() const final { return sizeof(std::uint8_t); }
2144 size_t GetAlignment() const final { return alignof(std::uint8_t); }
2145 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
2146 };
2147
2148 template <>
2149 class RField<std::int16_t> final : public RFieldBase {
2150 protected:
2151 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
2152 {
2153 return std::make_unique<RField>(newName);
2154 }
2155
2156 const RColumnRepresentations &GetColumnRepresentations() const final;
2157 void GenerateColumnsImpl() final;
2158 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
2159 void ConstructValue(void *where) const final { new (where) int16_t(0); }
2160
2161 public:
2162 static std::string TypeName() { return "std::int16_t"; }
2163 explicit RField(std::string_view name) : RFieldBase(name, TypeName(), ENTupleStructure::kLeaf, true )
2164 {
2165 fTraits |= kTraitTrivialType;
2166 }
2167 RField(RField&& other) = default;
2168 RField& operator =(RField&& other) = default;
2169 ~RField() override = default;
2170
2171 std::int16_t *Map(NTupleSize_t globalIndex) {
2172 return fPrincipalColumn->Map<std::int16_t>(globalIndex);
2173 }
2174 std::int16_t *Map(RClusterIndex clusterIndex) { return fPrincipalColumn->Map<std::int16_t>(clusterIndex); }
2175 std::int16_t *MapV(NTupleSize_t globalIndex, NTupleSize_t &nItems) {
2176 return fPrincipalColumn->MapV<std::int16_t>(globalIndex, nItems);
2177 }
2178 std::int16_t *MapV(RClusterIndex clusterIndex, NTupleSize_t &nItems)
2179 {
2180 return fPrincipalColumn->MapV<std::int16_t>(clusterIndex, nItems);
2181 }
2182
2183 size_t GetValueSize() const final { return sizeof(std::int16_t); }
2184 size_t GetAlignment() const final { return alignof(std::int16_t); }
2185 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
2186 };
2187
2188 template <>
2189 class RField<std::uint16_t> final : public RFieldBase {
2190 protected:
2191 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
2192 {
2193 return std::make_unique<RField>(newName);
2194 }
2195
2196 const RColumnRepresentations &GetColumnRepresentations() const final;
2197 void GenerateColumnsImpl() final;
2198 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
2199 void ConstructValue(void *where) const final { new (where) int16_t(0); }
2200
2201 public:
2202 static std::string TypeName() { return "std::uint16_t"; }
2203 explicit RField(std::string_view name) : RFieldBase(name, TypeName(), ENTupleStructure::kLeaf, true )
2204 {
2205 fTraits |= kTraitTrivialType;
2206 }
2207 RField(RField&& other) = default;
2208 RField& operator =(RField&& other) = default;
2209 ~RField() override = default;
2210
2211 std::uint16_t *Map(NTupleSize_t globalIndex) {
2212 return fPrincipalColumn->Map<std::uint16_t>(globalIndex);
2213 }
2214 std::uint16_t *Map(RClusterIndex clusterIndex) { return fPrincipalColumn->Map<std::uint16_t>(clusterIndex); }
2215 std::uint16_t *MapV(NTupleSize_t globalIndex, NTupleSize_t &nItems) {
2216 return fPrincipalColumn->MapV<std::uint16_t>(globalIndex, nItems);
2217 }
2218 std::uint16_t *MapV(RClusterIndex clusterIndex, NTupleSize_t &nItems)
2219 {
2220 return fPrincipalColumn->MapV<std::uint16_t>(clusterIndex, nItems);
2221 }
2222
2223 size_t GetValueSize() const final { return sizeof(std::uint16_t); }
2224 size_t GetAlignment() const final { return alignof(std::uint16_t); }
2225 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
2226 };
2227
2228 template <>
2229 class RField<std::int32_t> final : public RFieldBase {
2230 protected:
2231 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
2232 {
2233 return std::make_unique<RField>(newName);
2234 }
2235
2236 const RColumnRepresentations &GetColumnRepresentations() const final;
2237 void GenerateColumnsImpl() final;
2238 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
2239 void ConstructValue(void *where) const final { new (where) int32_t(0); }
2240
2241 public:
2242 static std::string TypeName() { return "std::int32_t"; }
2243 explicit RField(std::string_view name) : RFieldBase(name, TypeName(), ENTupleStructure::kLeaf, true )
2244 {
2245 fTraits |= kTraitTrivialType;
2246 }
2247 RField(RField&& other) = default;
2248 RField& operator =(RField&& other) = default;
2249 ~RField() override = default;
2250
2251 std::int32_t *Map(NTupleSize_t globalIndex) {
2252 return fPrincipalColumn->Map<std::int32_t>(globalIndex);
2253 }
2254 std::int32_t *Map(RClusterIndex clusterIndex) { return fPrincipalColumn->Map<std::int32_t>(clusterIndex); }
2255 std::int32_t *MapV(NTupleSize_t globalIndex, NTupleSize_t &nItems) {
2256 return fPrincipalColumn->MapV<std::int32_t>(globalIndex, nItems);
2257 }
2258 std::int32_t *MapV(RClusterIndex clusterIndex, NTupleSize_t &nItems)
2259 {
2260 return fPrincipalColumn->MapV<std::int32_t>(clusterIndex, nItems);
2261 }
2262
2263 size_t GetValueSize() const final { return sizeof(std::int32_t); }
2264 size_t GetAlignment() const final { return alignof(std::int32_t); }
2265 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
2266 };
2267
2268 template <>
2269 class RField<std::uint32_t> final : public RFieldBase {
2270 protected:
2271 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
2272 {
2273 return std::make_unique<RField>(newName);
2274 }
2275
2276 const RColumnRepresentations &GetColumnRepresentations() const final;
2277 void GenerateColumnsImpl() final;
2278 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
2279 void ConstructValue(void *where) const final { new (where) uint32_t(0); }
2280
2281 public:
2282 static std::string TypeName() { return "std::uint32_t"; }
2283 explicit RField(std::string_view name) : RFieldBase(name, TypeName(), ENTupleStructure::kLeaf, true )
2284 {
2285 fTraits |= kTraitTrivialType;
2286 }
2287 RField(RField&& other) = default;
2288 RField& operator =(RField&& other) = default;
2289 ~RField() override = default;
2290
2291 std::uint32_t *Map(NTupleSize_t globalIndex) {
2292 return fPrincipalColumn->Map<std::uint32_t>(globalIndex);
2293 }
2294 std::uint32_t *Map(const RClusterIndex clusterIndex) {
2295 return fPrincipalColumn->Map<std::uint32_t>(clusterIndex);
2296 }
2297 std::uint32_t *MapV(NTupleSize_t globalIndex, NTupleSize_t &nItems) {
2298 return fPrincipalColumn->MapV<std::uint32_t>(globalIndex, nItems);
2299 }
2300 std::uint32_t *MapV(RClusterIndex clusterIndex, NTupleSize_t &nItems)
2301 {
2302 return fPrincipalColumn->MapV<std::uint32_t>(clusterIndex, nItems);
2303 }
2304
2305 size_t GetValueSize() const final { return sizeof(std::uint32_t); }
2306 size_t GetAlignment() const final { return alignof(std::uint32_t); }
2307 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
2308 };
2309
2310 template <>
2311 class RField<std::uint64_t> final : public RFieldBase {
2312 protected:
2313 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
2314 {
2315 return std::make_unique<RField>(newName);
2316 }
2317
2318 const RColumnRepresentations &GetColumnRepresentations() const final;
2319 void GenerateColumnsImpl() final;
2320 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
2321 void ConstructValue(void *where) const final { new (where) uint64_t(0); }
2322
2323 public:
2324 static std::string TypeName() { return "std::uint64_t"; }
2325 explicit RField(std::string_view name) : RFieldBase(name, TypeName(), ENTupleStructure::kLeaf, true )
2326 {
2327 fTraits |= kTraitTrivialType;
2328 }
2329 RField(RField&& other) = default;
2330 RField& operator =(RField&& other) = default;
2331 ~RField() override = default;
2332
2333 std::uint64_t *Map(NTupleSize_t globalIndex) {
2334 return fPrincipalColumn->Map<std::uint64_t>(globalIndex);
2335 }
2336 std::uint64_t *Map(RClusterIndex clusterIndex) { return fPrincipalColumn->Map<std::uint64_t>(clusterIndex); }
2337 std::uint64_t *MapV(NTupleSize_t globalIndex, NTupleSize_t &nItems) {
2338 return fPrincipalColumn->MapV<std::uint64_t>(globalIndex, nItems);
2339 }
2340 std::uint64_t *MapV(RClusterIndex clusterIndex, NTupleSize_t &nItems)
2341 {
2342 return fPrincipalColumn->MapV<std::uint64_t>(clusterIndex, nItems);
2343 }
2344
2345 size_t GetValueSize() const final { return sizeof(std::uint64_t); }
2346 size_t GetAlignment() const final { return alignof(std::uint64_t); }
2347 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
2348 };
2349
2350 template <>
2351 class RField<std::int64_t> final : public RFieldBase {
2352 protected:
2353 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
2354 {
2355 return std::make_unique<RField>(newName);
2356 }
2357
2358 const RColumnRepresentations &GetColumnRepresentations() const final;
2359 void GenerateColumnsImpl() final;
2360 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
2361 void ConstructValue(void *where) const final { new (where) int64_t(0); }
2362
2363 public:
2364 static std::string TypeName() { return "std::int64_t"; }
2365 explicit RField(std::string_view name) : RFieldBase(name, TypeName(), ENTupleStructure::kLeaf, true )
2366 {
2367 fTraits |= kTraitTrivialType;
2368 }
2369 RField(RField&& other) = default;
2370 RField& operator =(RField&& other) = default;
2371 ~RField() override = default;
2372
2373 std::int64_t *Map(NTupleSize_t globalIndex) {
2374 return fPrincipalColumn->Map<std::int64_t>(globalIndex);
2375 }
2376 std::int64_t *Map(RClusterIndex clusterIndex) { return fPrincipalColumn->Map<std::int64_t>(clusterIndex); }
2377 std::int64_t *MapV(NTupleSize_t globalIndex, NTupleSize_t &nItems) {
2378 return fPrincipalColumn->MapV<std::int64_t>(globalIndex, nItems);
2379 }
2380 std::int64_t *MapV(RClusterIndex clusterIndex, NTupleSize_t &nItems)
2381 {
2382 return fPrincipalColumn->MapV<std::int64_t>(clusterIndex, nItems);
2383 }
2384
2385 size_t GetValueSize() const final { return sizeof(std::int64_t); }
2386 size_t GetAlignment() const final { return alignof(std::int64_t); }
2387 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
2388 };
2389
2390 template <>
2391 class RField<std::string> final : public RFieldBase {
2392 private:
2393 ClusterSize_t fIndex;
2394
2395 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
2396 {
2397 return std::make_unique<RField>(newName);
2398 }
2399
2400 const RColumnRepresentations &GetColumnRepresentations() const final;
2401 void GenerateColumnsImpl() final;
2402 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
2403
2404 void ConstructValue(void *where) const final { new (where) std::string(); }
2405 std::unique_ptr<RDeleter> GetDeleter() const final { return std::make_unique<RTypedDeleter<std::string>>(); }
2406
2407 std::size_t AppendImpl(const void *from) final;
2408 void ReadGlobalImpl(ROOT::Experimental::NTupleSize_t globalIndex, void *to) final;
2409
2410 void CommitClusterImpl() final { fIndex = 0; }
2411
2412 public:
2413 static std::string TypeName() { return "std::string"; }
2414 explicit RField(std::string_view name)
2415 : RFieldBase(name, TypeName(), ENTupleStructure::kLeaf, false ), fIndex(0)
2416 {
2417 }
2418 RField(RField&& other) = default;
2419 RField& operator =(RField&& other) = default;
2420 ~RField() override = default;
2421
2422 size_t GetValueSize() const final { return sizeof(std::string); }
2423 size_t GetAlignment() const final { return std::alignment_of<std::string>(); }
2424 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
2425 };
2426
2427 template <typename ItemT, std::size_t N>
2428 class RField<std::array<ItemT, N>> : public RArrayField {
2429 using ContainerT = typename std::array<ItemT, N>;
2430
2431 protected:
2432 void ConstructValue(void *where) const final { new (where) ContainerT(); }
2433
2434 public:
2435 static std::string TypeName() {
2436 return "std::array<" + RField<ItemT>::TypeName() + "," + std::to_string(N) + ">";
2437 }
2438 explicit RField(std::string_view name) : RArrayField(name, std::make_unique<RField<ItemT>>("_0"), N)
2439 {}
2440 RField(RField&& other) = default;
2441 RField& operator =(RField&& other) = default;
2442 ~RField() override = default;
2443 };
2444
2445 template <typename ItemT, std::size_t N>
2446 class RField<ItemT[N]> final : public RField<std::array<ItemT, N>> {
2447 public:
2448 explicit RField(std::string_view name) : RField<std::array<ItemT, N>>(name) {}
2449 RField(RField &&other) = default;
2450 RField &operator=(RField &&other) = default;
2451 ~RField() override = default;
2452 };
2453
2454 template <typename ItemT>
2455 class RField<std::set<ItemT>> : public RSetField {
2456 using ContainerT = typename std::set<ItemT>;
2457
2458 protected:
2459 void ConstructValue(void *where) const final { new (where) ContainerT(); }
2460 std::unique_ptr<RDeleter> GetDeleter() const final { return std::make_unique<RTypedDeleter<ContainerT>>(); }
2461
2462 public:
2463 static std::string TypeName() { return "std::set<" + RField<ItemT>::TypeName() + ">"; }
2464
2465 explicit RField(std::string_view name) : RSetField(name, TypeName(), std::make_unique<RField<ItemT>>("_0")) {}
2466 RField(RField &&other) = default;
2467 RField &operator=(RField &&other) = default;
2468 ~RField() override = default;
2469
2470 size_t GetValueSize() const final { return sizeof(ContainerT); }
2471 size_t GetAlignment() const final { return std::alignment_of<ContainerT>(); }
2472 };
2473
2474 template <typename ItemT>
2475 class RField<std::unordered_set<ItemT>> final : public RSetField {
2476 using ContainerT = typename std::unordered_set<ItemT>;
2477
2478 protected:
2479 void ConstructValue(void *where) const final { new (where) ContainerT(); }
2480 std::unique_ptr<RDeleter> GetDeleter() const final { return std::make_unique<RTypedDeleter<ContainerT>>(); }
2481
2482 public:
2483 static std::string TypeName() { return "std::unordered_set<" + RField<ItemT>::TypeName() + ">"; }
2484
2485 explicit RField(std::string_view name) : RSetField(name, TypeName(), std::make_unique<RField<ItemT>>("_0")) {}
2486 RField(RField &&other) = default;
2487 RField &operator=(RField &&other) = default;
2488 ~RField() override = default;
2489
2490 size_t GetValueSize() const final { return sizeof(ContainerT); }
2491 size_t GetAlignment() const final { return std::alignment_of<ContainerT>(); }
2492 };
2493
2494 template <typename KeyT, typename ValueT>
2495 class RField<std::map<KeyT, ValueT>> final : public RMapField {
2496 using ContainerT = typename std::map<KeyT, ValueT>;
2497
2498 protected:
2499 void ConstructValue(void *where) const final { new (where) ContainerT(); }
2500 std::unique_ptr<RDeleter> GetDeleter() const final { return std::make_unique<RTypedDeleter<ContainerT>>(); }
2501
2502 public:
2503 static std::string TypeName()
2504 {
2505 return "std::map<" + RField<KeyT>::TypeName() + "," + RField<ValueT>::TypeName() + ">";
2506 }
2507
2508 explicit RField(std::string_view name)
2509 : RMapField(name, TypeName(), std::make_unique<RField<std::pair<KeyT, ValueT>>>("_0"))
2510 {
2511 }
2512 RField(RField &&other) = default;
2513 RField &operator=(RField &&other) = default;
2514 ~RField() override = default;
2515
2516 size_t GetValueSize() const final { return sizeof(ContainerT); }
2517 size_t GetAlignment() const final { return std::alignment_of<ContainerT>(); }
2518 };
2519
2520 template <typename KeyT, typename ValueT>
2521 class RField<std::unordered_map<KeyT, ValueT>> final : public RMapField {
2522 using ContainerT = typename std::unordered_map<KeyT, ValueT>;
2523
2524 protected:
2525 void ConstructValue(void *where) const final { new (where) ContainerT(); }
2526 std::unique_ptr<RDeleter> GetDeleter() const final { return std::make_unique<RTypedDeleter<ContainerT>>(); }
2527
2528 public:
2529 static std::string TypeName()
2530 {
2531 return "std::unordered_map<" + RField<KeyT>::TypeName() + "," + RField<ValueT>::TypeName() + ">";
2532 }
2533
2534 explicit RField(std::string_view name)
2535 : RMapField(name, TypeName(), std::make_unique<RField<std::pair<KeyT, ValueT>>>("_0"))
2536 {
2537 }
2538 RField(RField &&other) = default;
2539 RField &operator=(RField &&other) = default;
2540 ~RField() override = default;
2541
2542 size_t GetValueSize() const final { return sizeof(ContainerT); }
2543 size_t GetAlignment() const final { return std::alignment_of<ContainerT>(); }
2544 };
2545
2546 template <typename... ItemTs>
2547 class RField<std::variant<ItemTs...>> final : public RVariantField {
2548 using ContainerT = typename std::variant<ItemTs...>;
2549 private:
2550 template <typename HeadT, typename... TailTs>
2551 static std::string BuildItemTypes()
2552 {
2553 std::string result = RField<HeadT>::TypeName();
2554 if constexpr(sizeof...(TailTs) > 0)
2555 result += "," + BuildItemTypes<TailTs...>();
2556 return result;
2557 }
2558
2559 template <typename HeadT, typename... TailTs>
2560 static std::vector<RFieldBase *> BuildItemFields(unsigned int index = 0)
2561 {
2562 std::vector<RFieldBase *> result;
2563 result.emplace_back(new RField<HeadT>("_" + std::to_string(index)));
2564 if constexpr(sizeof...(TailTs) > 0) {
2565 auto tailFields = BuildItemFields<TailTs...>(index + 1);
2566 result.insert(result.end(), tailFields.begin(), tailFields.end());
2567 }
2568 return result;
2569 }
2570
2571 protected:
2572 void ConstructValue(void *where) const final { new (where) ContainerT(); }
2573
2574 public:
2575 static std::string TypeName() { return "std::variant<" + BuildItemTypes<ItemTs...>() + ">"; }
2576 explicit RField(std::string_view name) : RVariantField(name, BuildItemFields<ItemTs...>()) {}
2577 RField(RField&& other) = default;
2578 RField& operator =(RField&& other) = default;
2579 ~RField() override = default;
2580 };
2581
2582 template <typename ItemT>
2583 class RField<std::vector<ItemT>> final : public RVectorField {
2584 using ContainerT = typename std::vector<ItemT>;
2585
2586 protected:
2587 void ConstructValue(void *where) const final { new (where) ContainerT(); }
2588
2589 public:
2590 static std::string TypeName() { return "std::vector<" + RField<ItemT>::TypeName() + ">"; }
2591 explicit RField(std::string_view name)
2592 : RVectorField(name, std::make_unique<RField<ItemT>>("_0"))
2593 {}
2594 RField(RField&& other) = default;
2595 RField& operator =(RField&& other) = default;
2596 ~RField() override = default;
2597
2598 size_t GetValueSize() const final { return sizeof(ContainerT); }
2599 };
2600
2601
2602 template <>
2603 class RField<std::vector<bool>> final : public RFieldBase {
2604 private:
2605 ClusterSize_t fNWritten{0};
2606
2607 protected:
2608 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
2609 {
2610 return std::make_unique<RField>(newName);
2611 }
2612
2613 const RColumnRepresentations &GetColumnRepresentations() const final;
2614 void GenerateColumnsImpl() final;
2615 void GenerateColumnsImpl(const RNTupleDescriptor &desc) final;
2616
2617 void ConstructValue(void *where) const final { new (where) std::vector<bool>(); }
2618 std::unique_ptr<RDeleter> GetDeleter() const final { return std::make_unique<RTypedDeleter<std::vector<bool>>>(); }
2619
2620 std::size_t AppendImpl(const void *from) final;
2621 void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final;
2622
2623 void CommitClusterImpl() final { fNWritten = 0; }
2624
2625 public:
2626 static std::string TypeName() { return "std::vector<bool>"; }
2627 explicit RField(std::string_view name);
2628 RField(RField&& other) = default;
2629 RField& operator =(RField&& other) = default;
2630 ~RField() override = default;
2631
2632 std::vector<RValue> SplitValue(const RValue &value) const final;
2633
2634 size_t GetValueSize() const final { return sizeof(std::vector<bool>); }
2635 size_t GetAlignment() const final { return std::alignment_of<std::vector<bool>>(); }
2636 void AcceptVisitor(Detail::RFieldVisitor &visitor) const final;
2637 void GetCollectionInfo(NTupleSize_t globalIndex, RClusterIndex *collectionStart, ClusterSize_t *size) const {
2638 fPrincipalColumn->GetCollectionInfo(globalIndex, collectionStart, size);
2639 }
2640 void GetCollectionInfo(RClusterIndex clusterIndex, RClusterIndex *collectionStart, ClusterSize_t *size) const
2641 {
2642 fPrincipalColumn->GetCollectionInfo(clusterIndex, collectionStart, size);
2643 }
2644 };
2645
2646 template <typename ItemT>
2647 class RField<ROOT::VecOps::RVec<ItemT>> final : public RRVecField {
2648 using ContainerT = typename ROOT::VecOps::RVec<ItemT>;
2649 protected:
2650 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
2651 {
2652 auto newItemField = fSubFields[0]->Clone(fSubFields[0]->GetFieldName());
2653 return std::make_unique<RField<ROOT::VecOps::RVec<ItemT>>>(newName, std::move(newItemField));
2654 }
2655
2656 void ConstructValue(void *where) const final { new (where) ContainerT(); }
2657 std::unique_ptr<RDeleter> GetDeleter() const final { return std::make_unique<RTypedDeleter<ContainerT>>(); }
2658
2659 std::size_t AppendImpl(const void *from) final
2660 {
2661 auto typedValue = static_cast<const ContainerT *>(from);
2662 auto nbytes = 0;
2663 auto count = typedValue->size();
2664 for (unsigned i = 0; i < count; ++i) {
2665 nbytes += CallAppendOn(*fSubFields[0], &typedValue->data()[i]);
2666 }
2667 this->fNWritten += count;
2668 fColumns[0]->Append(&this->fNWritten);
2669 return nbytes + fColumns[0]->GetElement()->GetPackedSize();
2670 }
2671 void ReadGlobalImpl(NTupleSize_t globalIndex, void *to) final
2672 {
2673 auto typedValue = static_cast<ContainerT *>(to);
2674 ClusterSize_t nItems;
2675 RClusterIndex collectionStart;
2676 fPrincipalColumn->GetCollectionInfo(globalIndex, &collectionStart, &nItems);
2677 typedValue->resize(nItems);
2678 for (unsigned i = 0; i < nItems; ++i) {
2679 CallReadOn(*fSubFields[0], collectionStart + i, &typedValue->data()[i]);
2680 }
2681 }
2682
2683 public:
2684 RField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField)
2685 : RRVecField(fieldName, std::move(itemField))
2686 {
2687 }
2688
2689 explicit RField(std::string_view name)
2690 : RField(name, std::make_unique<RField<ItemT>>("_0"))
2691 {
2692 }
2693 RField(RField&& other) = default;
2694 RField& operator =(RField&& other) = default;
2695 ~RField() override = default;
2696
2697 static std::string TypeName() { return "ROOT::VecOps::RVec<" + RField<ItemT>::TypeName() + ">"; }
2698
2699 size_t GetValueSize() const final { return sizeof(ContainerT); }
2700 size_t GetAlignment() const final { return std::alignment_of<ContainerT>(); }
2701 };
2702
2703 template <typename T1, typename T2>
2704 class RField<std::pair<T1, T2>> final : public RPairField {
2705 using ContainerT = typename std::pair<T1,T2>;
2706 private:
2707 template <typename Ty1, typename Ty2>
2708 static std::array<std::unique_ptr<RFieldBase>, 2> BuildItemFields()
2709 {
2710 return {std::make_unique<RField<Ty1>>("_0"), std::make_unique<RField<Ty2>>("_1")};
2711 }
2712
2713 static std::array<std::size_t, 2> BuildItemOffsets()
2714 {
2715 auto pair = ContainerT();
2716 auto offsetFirst = reinterpret_cast<std::uintptr_t>(&(pair.first)) - reinterpret_cast<std::uintptr_t>(&pair);
2717 auto offsetSecond = reinterpret_cast<std::uintptr_t>(&(pair.second)) - reinterpret_cast<std::uintptr_t>(&pair);
2718 return {offsetFirst, offsetSecond};
2719 }
2720
2721 protected:
2722 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
2723 {
2724 std::array<std::unique_ptr<RFieldBase>, 2> items{fSubFields[0]->Clone(fSubFields[0]->GetFieldName()),
2725 fSubFields[1]->Clone(fSubFields[1]->GetFieldName())};
2726 return std::make_unique<RField<std::pair<T1, T2>>>(newName, std::move(items));
2727 }
2728
2729 void ConstructValue(void *where) const final { new (where) ContainerT(); }
2730 std::unique_ptr<RDeleter> GetDeleter() const final { return std::make_unique<RTypedDeleter<ContainerT>>(); }
2731
2732 public:
2733 static std::string TypeName() {
2734 return "std::pair<" + RField<T1>::TypeName() + "," + RField<T2>::TypeName() + ">";
2735 }
2736 explicit RField(std::string_view name, std::array<std::unique_ptr<RFieldBase>, 2> &&itemFields)
2737 : RPairField(name, std::move(itemFields), BuildItemOffsets())
2738 {
2739 fMaxAlignment = std::max(alignof(T1), alignof(T2));
2740 fSize = sizeof(ContainerT);
2741 }
2742 explicit RField(std::string_view name) : RField(name, BuildItemFields<T1, T2>()) {}
2743 RField(RField&& other) = default;
2744 RField& operator =(RField&& other) = default;
2745 ~RField() override = default;
2746 };
2747
2748 template <typename... ItemTs>
2749 class RField<std::tuple<ItemTs...>> final : public RTupleField {
2750 using ContainerT = typename std::tuple<ItemTs...>;
2751 private:
2752 template <typename HeadT, typename... TailTs>
2753 static std::string BuildItemTypes()
2754 {
2755 std::string result = RField<HeadT>::TypeName();
2756 if constexpr (sizeof...(TailTs) > 0)
2757 result += "," + BuildItemTypes<TailTs...>();
2758 return result;
2759 }
2760
2761 template <typename HeadT, typename... TailTs>
2762 static void _BuildItemFields(std::vector<std::unique_ptr<RFieldBase>> &itemFields, unsigned int index = 0)
2763 {
2764 itemFields.emplace_back(new RField<HeadT>("_" + std::to_string(index)));
2765 if constexpr (sizeof...(TailTs) > 0)
2766 _BuildItemFields<TailTs...>(itemFields, index + 1);
2767 }
2768 template <typename... Ts>
2769 static std::vector<std::unique_ptr<RFieldBase>> BuildItemFields()
2770 {
2771 std::vector<std::unique_ptr<RFieldBase>> result;
2772 _BuildItemFields<Ts...>(result);
2773 return result;
2774 }
2775
2776 template <unsigned Index, typename HeadT, typename... TailTs>
2777 static void _BuildItemOffsets(std::vector<std::size_t> &offsets, const ContainerT &tuple)
2778 {
2779 auto offset =
2780 reinterpret_cast<std::uintptr_t>(&std::get<Index>(tuple)) - reinterpret_cast<std::uintptr_t>(&tuple);
2781 offsets.emplace_back(offset);
2782 if constexpr (sizeof...(TailTs) > 0)
2783 _BuildItemOffsets<Index + 1, TailTs...>(offsets, tuple);
2784 }
2785 template <typename... Ts>
2786 static std::vector<std::size_t> BuildItemOffsets()
2787 {
2788 std::vector<std::size_t> result;
2789 _BuildItemOffsets<0, Ts...>(result, ContainerT());
2790 return result;
2791 }
2792
2793 protected:
2794 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
2795 {
2796 std::vector<std::unique_ptr<RFieldBase>> items;
2797 for (auto &item : fSubFields)
2798 items.push_back(item->Clone(item->GetFieldName()));
2799 return std::make_unique<RField<std::tuple<ItemTs...>>>(newName, std::move(items));
2800 }
2801
2802 void ConstructValue(void *where) const final { new (where) ContainerT(); }
2803 std::unique_ptr<RDeleter> GetDeleter() const final { return std::make_unique<RTypedDeleter<ContainerT>>(); }
2804
2805 public:
2806 static std::string TypeName() { return "std::tuple<" + BuildItemTypes<ItemTs...>() + ">"; }
2807 explicit RField(std::string_view name, std::vector<std::unique_ptr<RFieldBase>> &&itemFields)
2808 : RTupleField(name, std::move(itemFields), BuildItemOffsets<ItemTs...>())
2809 {
2810 fMaxAlignment = std::max({alignof(ItemTs)...});
2811 fSize = sizeof(ContainerT);
2812 }
2813 explicit RField(std::string_view name) : RField(name, BuildItemFields<ItemTs...>()) {}
2814 RField(RField &&other) = default;
2815 RField &operator=(RField &&other) = default;
2816 ~RField() override = default;
2817 };
2818
2819 template <std::size_t N>
2820 class RField<std::bitset<N>> final : public RBitsetField {
2821 public:
2822 static std::string TypeName() { return "std::bitset<" + std::to_string(N) + ">"; }
2823 explicit RField(std::string_view name) : RBitsetField(name, N) {}
2824 RField(RField &&other) = default;
2825 RField &operator=(RField &&other) = default;
2826 ~RField() override = default;
2827 };
2828
2829 template <typename ItemT>
2830 class RField<std::unique_ptr<ItemT>> final : public RUniquePtrField {
2831 public:
2832 static std::string TypeName() { return "std::unique_ptr<" + RField<ItemT>::TypeName() + ">"; }
2833 explicit RField(std::string_view name) : RUniquePtrField(name, TypeName(), std::make_unique<RField<ItemT>>("_0")) {}
2834 RField(RField &&other) = default;
2835 RField &operator=(RField &&other) = default;
2836 ~RField() override = default;
2837 };
2838
2839 template <typename ItemT>
2840 class RField<std::atomic<ItemT>> final : public RAtomicField {
2841 public:
2842 static std::string TypeName() { return "std::atomic<" + RField<ItemT>::TypeName() + ">"; }
2843 explicit RField(std::string_view name) : RAtomicField(name, TypeName(), std::make_unique<RField<ItemT>>("_0")) {}
2844 RField(RField &&other) = default;
2845 RField &operator=(RField &&other) = default;
2846 ~RField() override = default;
2847 };
2848
2849
2850
2851
2852 template <typename T>
2853 std::unique_ptr<T, typename RFieldBase::RCreateObjectDeleter<T>::deleter> RFieldBase::CreateObject() const
2854 {
2855 if (GetTypeName() != RField<T>::TypeName()) {
2856 throw RException(
2857 R__FAIL("type mismatch for field " + GetFieldName() + ": " + GetTypeName() + " vs. " + RField<T>::TypeName()));
2858 }
2859 return std::unique_ptr<T>(static_cast<T *>(CreateObjectRawPtr()));
2860 }
2861
2862 template <>
2863 struct RFieldBase::RCreateObjectDeleter<void> {
2864 using deleter = RCreateObjectDeleter<void>;
2865 void operator()(void *);
2866 };
2867
2868 template <>
2869 std::unique_ptr<void, typename RFieldBase::RCreateObjectDeleter<void>::deleter>
2870 ROOT::Experimental::RFieldBase::CreateObject<void>() const;
2871
2872 }
2873 }
2874
2875 #endif