Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 09:14:21

0001 /// \file ROOT/RField/SequenceContainer.hxx
0002 /// \ingroup NTuple
0003 /// \author Jakob Blomer <jblomer@cern.ch>
0004 /// \date 2018-10-09
0005 
0006 /*************************************************************************
0007  * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers.               *
0008  * All rights reserved.                                                  *
0009  *                                                                       *
0010  * For the licensing terms see $ROOTSYS/LICENSE.                         *
0011  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
0012  *************************************************************************/
0013 
0014 #ifndef ROOT_RField_SequenceContainer
0015 #define ROOT_RField_SequenceContainer
0016 
0017 #ifndef ROOT_RField
0018 #error "Please include RField.hxx!"
0019 #endif
0020 
0021 #include <ROOT/RFieldBase.hxx>
0022 #include <ROOT/RNTupleUtil.hxx>
0023 #include <ROOT/RVec.hxx>
0024 
0025 #include <array>
0026 #include <memory>
0027 #include <vector>
0028 
0029 namespace ROOT {
0030 
0031 namespace Detail {
0032 class RFieldVisitor;
0033 } // namespace Detail
0034 
0035 ////////////////////////////////////////////////////////////////////////////////
0036 /// Template specializations for C++ std::array and C-style arrays
0037 ////////////////////////////////////////////////////////////////////////////////
0038 
0039 /// The generic field for fixed size arrays, which do not need an offset column
0040 class RArrayField : public RFieldBase {
0041 private:
0042    class RArrayDeleter : public RDeleter {
0043    private:
0044       std::size_t fItemSize = 0;
0045       std::size_t fArrayLength = 0;
0046       std::unique_ptr<RDeleter> fItemDeleter;
0047 
0048    public:
0049       RArrayDeleter(std::size_t itemSize, std::size_t arrayLength, std::unique_ptr<RDeleter> itemDeleter)
0050          : fItemSize(itemSize), fArrayLength(arrayLength), fItemDeleter(std::move(itemDeleter))
0051       {
0052       }
0053       void operator()(void *objPtr, bool dtorOnly) final;
0054    };
0055 
0056    std::size_t fItemSize;
0057    std::size_t fArrayLength;
0058 
0059 protected:
0060    std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
0061 
0062    void ConstructValue(void *where) const final;
0063    std::unique_ptr<RDeleter> GetDeleter() const final;
0064 
0065    std::size_t AppendImpl(const void *from) final;
0066    void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
0067    void ReadInClusterImpl(RNTupleLocalIndex localIndex, void *to) final;
0068 
0069 public:
0070    RArrayField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField, std::size_t arrayLength);
0071    RArrayField(RArrayField &&other) = default;
0072    RArrayField &operator=(RArrayField &&other) = default;
0073    ~RArrayField() override = default;
0074 
0075    std::vector<RValue> SplitValue(const RValue &value) const final;
0076    size_t GetLength() const { return fArrayLength; }
0077    size_t GetValueSize() const final { return fItemSize * fArrayLength; }
0078    size_t GetAlignment() const final { return fSubfields[0]->GetAlignment(); }
0079    void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
0080 };
0081 
0082 template <typename ItemT, std::size_t N>
0083 class RField<std::array<ItemT, N>> : public RArrayField {
0084 public:
0085    static std::string TypeName() { return "std::array<" + RField<ItemT>::TypeName() + "," + std::to_string(N) + ">"; }
0086    explicit RField(std::string_view name) : RArrayField(name, std::make_unique<RField<ItemT>>("_0"), N) {}
0087    RField(RField &&other) = default;
0088    RField &operator=(RField &&other) = default;
0089    ~RField() override = default;
0090 };
0091 
0092 template <typename ItemT, std::size_t N>
0093 class RField<ItemT[N]> final : public RField<std::array<ItemT, N>> {
0094 public:
0095    explicit RField(std::string_view name) : RField<std::array<ItemT, N>>(name) {}
0096    RField(RField &&other) = default;
0097    RField &operator=(RField &&other) = default;
0098    ~RField() final = default;
0099 };
0100 
0101 ////////////////////////////////////////////////////////////////////////////////
0102 /// Template specializations for ROOT's RVec
0103 ////////////////////////////////////////////////////////////////////////////////
0104 
0105 /// The type-erased field for a RVec<Type>
0106 class RRVecField : public RFieldBase {
0107 public:
0108    /// the RRVecDeleter is also used by RArrayAsRVecField and therefore declared public
0109    class RRVecDeleter : public RDeleter {
0110    private:
0111       std::size_t fItemAlignment;
0112       std::size_t fItemSize = 0;
0113       std::unique_ptr<RDeleter> fItemDeleter;
0114 
0115    public:
0116       explicit RRVecDeleter(std::size_t itemAlignment) : fItemAlignment(itemAlignment) {}
0117       RRVecDeleter(std::size_t itemAlignment, std::size_t itemSize, std::unique_ptr<RDeleter> itemDeleter)
0118          : fItemAlignment(itemAlignment), fItemSize(itemSize), fItemDeleter(std::move(itemDeleter))
0119       {
0120       }
0121       void operator()(void *objPtr, bool dtorOnly) final;
0122    };
0123 
0124    std::unique_ptr<RDeleter> fItemDeleter;
0125 
0126 protected:
0127    std::size_t fItemSize;
0128    ROOT::Internal::RColumnIndex fNWritten;
0129    std::size_t fValueSize;
0130 
0131    std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
0132    const RColumnRepresentations &GetColumnRepresentations() const final;
0133    void GenerateColumns() final;
0134    void GenerateColumns(const ROOT::RNTupleDescriptor &desc) final;
0135 
0136    void ConstructValue(void *where) const final;
0137    std::unique_ptr<RDeleter> GetDeleter() const final;
0138 
0139    std::size_t AppendImpl(const void *from) final;
0140    void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
0141    std::size_t ReadBulkImpl(const RBulkSpec &bulkSpec) final;
0142 
0143    void CommitClusterImpl() final { fNWritten = 0; }
0144 
0145 public:
0146    RRVecField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField);
0147    RRVecField(RRVecField &&) = default;
0148    RRVecField &operator=(RRVecField &&) = default;
0149    RRVecField(const RRVecField &) = delete;
0150    RRVecField &operator=(RRVecField &) = delete;
0151    ~RRVecField() override = default;
0152 
0153    std::vector<RValue> SplitValue(const RValue &value) const final;
0154    size_t GetValueSize() const final;
0155    size_t GetAlignment() const final;
0156    void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
0157    void
0158    GetCollectionInfo(ROOT::NTupleSize_t globalIndex, RNTupleLocalIndex *collectionStart, ROOT::NTupleSize_t *size) const
0159    {
0160       fPrincipalColumn->GetCollectionInfo(globalIndex, collectionStart, size);
0161    }
0162    void
0163    GetCollectionInfo(RNTupleLocalIndex localIndex, RNTupleLocalIndex *collectionStart, ROOT::NTupleSize_t *size) const
0164    {
0165       fPrincipalColumn->GetCollectionInfo(localIndex, collectionStart, size);
0166    }
0167 };
0168 
0169 template <typename ItemT>
0170 class RField<ROOT::VecOps::RVec<ItemT>> final : public RRVecField {
0171 public:
0172    RField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField)
0173       : RRVecField(fieldName, std::move(itemField))
0174    {
0175    }
0176 
0177    explicit RField(std::string_view name) : RField(name, std::make_unique<RField<ItemT>>("_0")) {}
0178    RField(RField &&other) = default;
0179    RField &operator=(RField &&other) = default;
0180    ~RField() final = default;
0181 
0182    static std::string TypeName() { return "ROOT::VecOps::RVec<" + RField<ItemT>::TypeName() + ">"; }
0183 };
0184 
0185 ////////////////////////////////////////////////////////////////////////////////
0186 /// Template specializations for C++ std::vector
0187 ////////////////////////////////////////////////////////////////////////////////
0188 
0189 /// The generic field for a (nested) `std::vector<Type>` except for `std::vector<bool>`
0190 /// The field can be constructed as untyped collection through CreateUntyped().
0191 class RVectorField : public RFieldBase {
0192 private:
0193    class RVectorDeleter : public RDeleter {
0194    private:
0195       std::size_t fItemSize = 0;
0196       std::unique_ptr<RDeleter> fItemDeleter;
0197 
0198    public:
0199       RVectorDeleter() = default;
0200       RVectorDeleter(std::size_t itemSize, std::unique_ptr<RDeleter> itemDeleter)
0201          : fItemSize(itemSize), fItemDeleter(std::move(itemDeleter))
0202       {
0203       }
0204       void operator()(void *objPtr, bool dtorOnly) final;
0205    };
0206 
0207    std::size_t fItemSize;
0208    ROOT::Internal::RColumnIndex fNWritten;
0209    std::unique_ptr<RDeleter> fItemDeleter;
0210 
0211 protected:
0212    RVectorField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField, bool isUntyped);
0213 
0214    std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
0215 
0216    const RColumnRepresentations &GetColumnRepresentations() const final;
0217    void GenerateColumns() final;
0218    void GenerateColumns(const ROOT::RNTupleDescriptor &desc) final;
0219 
0220    void ConstructValue(void *where) const final { new (where) std::vector<char>(); }
0221    std::unique_ptr<RDeleter> GetDeleter() const final;
0222 
0223    std::size_t AppendImpl(const void *from) final;
0224    void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
0225 
0226    void CommitClusterImpl() final { fNWritten = 0; }
0227 
0228 public:
0229    RVectorField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField);
0230    RVectorField(RVectorField &&other) = default;
0231    RVectorField &operator=(RVectorField &&other) = default;
0232    ~RVectorField() override = default;
0233 
0234    static std::unique_ptr<RVectorField>
0235    CreateUntyped(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField);
0236 
0237    std::vector<RValue> SplitValue(const RValue &value) const final;
0238    size_t GetValueSize() const final { return sizeof(std::vector<char>); }
0239    size_t GetAlignment() const final { return std::alignment_of<std::vector<char>>(); }
0240    void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
0241    void
0242    GetCollectionInfo(ROOT::NTupleSize_t globalIndex, RNTupleLocalIndex *collectionStart, ROOT::NTupleSize_t *size) const
0243    {
0244       fPrincipalColumn->GetCollectionInfo(globalIndex, collectionStart, size);
0245    }
0246    void
0247    GetCollectionInfo(RNTupleLocalIndex localIndex, RNTupleLocalIndex *collectionStart, ROOT::NTupleSize_t *size) const
0248    {
0249       fPrincipalColumn->GetCollectionInfo(localIndex, collectionStart, size);
0250    }
0251 };
0252 
0253 template <typename ItemT>
0254 class RField<std::vector<ItemT>> final : public RVectorField {
0255 public:
0256    static std::string TypeName() { return "std::vector<" + RField<ItemT>::TypeName() + ">"; }
0257    explicit RField(std::string_view name) : RVectorField(name, std::make_unique<RField<ItemT>>("_0")) {}
0258    RField(RField &&other) = default;
0259    RField &operator=(RField &&other) = default;
0260    ~RField() final = default;
0261 };
0262 
0263 // `std::vector<bool>` is a template specialization and needs special treatment
0264 template <>
0265 class RField<std::vector<bool>> final : public RFieldBase {
0266 private:
0267    ROOT::Internal::RColumnIndex fNWritten{0};
0268 
0269 protected:
0270    std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final
0271    {
0272       return std::make_unique<RField>(newName);
0273    }
0274 
0275    const RColumnRepresentations &GetColumnRepresentations() const final;
0276    void GenerateColumns() final;
0277    void GenerateColumns(const ROOT::RNTupleDescriptor &desc) final;
0278 
0279    void ConstructValue(void *where) const final { new (where) std::vector<bool>(); }
0280    std::unique_ptr<RDeleter> GetDeleter() const final { return std::make_unique<RTypedDeleter<std::vector<bool>>>(); }
0281 
0282    std::size_t AppendImpl(const void *from) final;
0283    void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
0284 
0285    void CommitClusterImpl() final { fNWritten = 0; }
0286 
0287 public:
0288    static std::string TypeName() { return "std::vector<bool>"; }
0289    explicit RField(std::string_view name);
0290    RField(RField &&other) = default;
0291    RField &operator=(RField &&other) = default;
0292    ~RField() final = default;
0293 
0294    std::vector<RValue> SplitValue(const RValue &value) const final;
0295 
0296    size_t GetValueSize() const final { return sizeof(std::vector<bool>); }
0297    size_t GetAlignment() const final { return std::alignment_of<std::vector<bool>>(); }
0298    void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
0299    void
0300    GetCollectionInfo(ROOT::NTupleSize_t globalIndex, RNTupleLocalIndex *collectionStart, ROOT::NTupleSize_t *size) const
0301    {
0302       fPrincipalColumn->GetCollectionInfo(globalIndex, collectionStart, size);
0303    }
0304    void
0305    GetCollectionInfo(RNTupleLocalIndex localIndex, RNTupleLocalIndex *collectionStart, ROOT::NTupleSize_t *size) const
0306    {
0307       fPrincipalColumn->GetCollectionInfo(localIndex, collectionStart, size);
0308    }
0309 };
0310 
0311 ////////////////////////////////////////////////////////////////////////////////
0312 /// Additional classes related to sequence containers
0313 ////////////////////////////////////////////////////////////////////////////////
0314 
0315 /**
0316 \class ROOT::RArrayAsRVecField
0317 \brief A field for fixed-size arrays that are represented as RVecs in memory.
0318 \ingroup NTuple
0319 This class is used only for reading. In particular, it helps exposing
0320 arbitrarily-nested `std::array` on-disk fields as RVecs for usage in RDataFrame.
0321 */
0322 class RArrayAsRVecField final : public RFieldBase {
0323 private:
0324    std::unique_ptr<RDeleter> fItemDeleter; /// Sub field deleter or nullptr for simple fields
0325    std::size_t fItemSize;                  /// The size of a child field's item
0326    std::size_t fArrayLength;               /// The length of the arrays in this field
0327    std::size_t fValueSize;                 /// The size of a value of this field, i.e. an RVec
0328 
0329 protected:
0330    std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
0331 
0332    void GenerateColumns() final { R__ASSERT(false && "RArrayAsRVec fields must only be used for reading"); }
0333    using RFieldBase::GenerateColumns;
0334 
0335    void ConstructValue(void *where) const final;
0336    /// Returns an RRVecField::RRVecDeleter
0337    std::unique_ptr<RDeleter> GetDeleter() const final;
0338 
0339    void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
0340    void ReadInClusterImpl(RNTupleLocalIndex localIndex, void *to) final;
0341 
0342 public:
0343    /**
0344       Constructor of the field. The `itemField` argument represents the inner
0345       item of the on-disk array, i.e. for an `std::array<float>` it is the `float`
0346       field and not the `std::array` itself.
0347    */
0348    RArrayAsRVecField(std::string_view fieldName, std::unique_ptr<RFieldBase> itemField, std::size_t arrayLength);
0349    RArrayAsRVecField(const RArrayAsRVecField &other) = delete;
0350    RArrayAsRVecField &operator=(const RArrayAsRVecField &other) = delete;
0351    RArrayAsRVecField(RArrayAsRVecField &&other) = default;
0352    RArrayAsRVecField &operator=(RArrayAsRVecField &&other) = default;
0353    ~RArrayAsRVecField() final = default;
0354 
0355    std::size_t GetValueSize() const final { return fValueSize; }
0356    std::size_t GetAlignment() const final;
0357 
0358    std::vector<RFieldBase::RValue> SplitValue(const RFieldBase::RValue &value) const final;
0359    void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
0360 };
0361 
0362 } // namespace ROOT
0363 
0364 #endif