File indexing completed on 2025-09-17 09:14:20
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef ROOT_RField_ProxiedCollection
0015 #define ROOT_RField_ProxiedCollection
0016
0017 #ifndef ROOT_RField
0018 #error "Please include RField.hxx!"
0019 #endif
0020
0021 #include <ROOT/RFieldBase.hxx>
0022 #include <ROOT/RNTupleUtil.hxx>
0023
0024 #include <TVirtualCollectionProxy.h>
0025
0026 #include <iterator>
0027 #include <map>
0028 #include <set>
0029 #include <string>
0030 #include <string_view>
0031 #include <type_traits>
0032 #include <unordered_map>
0033 #include <unordered_set>
0034 #include <vector>
0035
0036 namespace ROOT {
0037
0038 namespace Detail {
0039 class RFieldVisitor;
0040 }
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051 class RProxiedCollectionField : public RFieldBase {
0052 protected:
0053
0054
0055 class RCollectionIterableOnce {
0056 public:
0057 struct RIteratorFuncs {
0058 TVirtualCollectionProxy::CreateIterators_t fCreateIterators;
0059 TVirtualCollectionProxy::DeleteTwoIterators_t fDeleteTwoIterators;
0060 TVirtualCollectionProxy::Next_t fNext;
0061 };
0062 static RIteratorFuncs GetIteratorFuncs(TVirtualCollectionProxy *proxy, bool readFromDisk);
0063
0064 private:
0065 class RIterator {
0066 const RCollectionIterableOnce &fOwner;
0067 void *fIterator = nullptr;
0068 void *fElementPtr = nullptr;
0069
0070 void Advance()
0071 {
0072 auto fnNext_Contig = [&]() {
0073
0074
0075 auto &iter = reinterpret_cast<unsigned char *&>(fIterator), p = iter;
0076 iter += fOwner.fStride;
0077 return p;
0078 };
0079 fElementPtr = fOwner.fStride ? fnNext_Contig() : fOwner.fIFuncs.fNext(fIterator, fOwner.fEnd);
0080 }
0081
0082 public:
0083 using iterator_category = std::forward_iterator_tag;
0084 using iterator = RIterator;
0085 using difference_type = std::ptrdiff_t;
0086 using pointer = void *;
0087
0088 RIterator(const RCollectionIterableOnce &owner) : fOwner(owner) {}
0089 RIterator(const RCollectionIterableOnce &owner, void *iter) : fOwner(owner), fIterator(iter) { Advance(); }
0090 iterator operator++()
0091 {
0092 Advance();
0093 return *this;
0094 }
0095 pointer operator*() const { return fElementPtr; }
0096 bool operator!=(const iterator &rh) const { return fElementPtr != rh.fElementPtr; }
0097 bool operator==(const iterator &rh) const { return fElementPtr == rh.fElementPtr; }
0098 };
0099
0100 const RIteratorFuncs &fIFuncs;
0101 const std::size_t fStride;
0102 unsigned char fBeginSmallBuf[TVirtualCollectionProxy::fgIteratorArenaSize];
0103 unsigned char fEndSmallBuf[TVirtualCollectionProxy::fgIteratorArenaSize];
0104 void *fBegin = &fBeginSmallBuf;
0105 void *fEnd = &fEndSmallBuf;
0106
0107 public:
0108
0109
0110
0111 RCollectionIterableOnce(void *collection, const RIteratorFuncs &ifuncs, TVirtualCollectionProxy *proxy,
0112 std::size_t stride = 0U)
0113 : fIFuncs(ifuncs), fStride(stride)
0114 {
0115 fIFuncs.fCreateIterators(collection, &fBegin, &fEnd, proxy);
0116 }
0117 ~RCollectionIterableOnce() { fIFuncs.fDeleteTwoIterators(fBegin, fEnd); }
0118
0119 RIterator begin() { return RIterator(*this, fBegin); }
0120 RIterator end() { return fStride ? RIterator(*this, fEnd) : RIterator(*this); }
0121 };
0122
0123 class RProxiedCollectionDeleter : public RDeleter {
0124 private:
0125 std::shared_ptr<TVirtualCollectionProxy> fProxy;
0126 std::unique_ptr<RDeleter> fItemDeleter;
0127 std::size_t fItemSize = 0;
0128 RCollectionIterableOnce::RIteratorFuncs fIFuncsWrite;
0129
0130 public:
0131 explicit RProxiedCollectionDeleter(std::shared_ptr<TVirtualCollectionProxy> proxy) : fProxy(proxy) {}
0132 RProxiedCollectionDeleter(std::shared_ptr<TVirtualCollectionProxy> proxy, std::unique_ptr<RDeleter> itemDeleter,
0133 size_t itemSize)
0134 : fProxy(proxy), fItemDeleter(std::move(itemDeleter)), fItemSize(itemSize)
0135 {
0136 fIFuncsWrite = RCollectionIterableOnce::GetIteratorFuncs(fProxy.get(), false );
0137 }
0138 void operator()(void *objPtr, bool dtorOnly) final;
0139 };
0140
0141
0142 std::shared_ptr<TVirtualCollectionProxy> fProxy;
0143 Int_t fProperties;
0144 Int_t fCollectionType;
0145
0146
0147 RCollectionIterableOnce::RIteratorFuncs fIFuncsRead;
0148 RCollectionIterableOnce::RIteratorFuncs fIFuncsWrite;
0149 std::size_t fItemSize;
0150 ROOT::Internal::RColumnIndex fNWritten;
0151
0152
0153
0154 RProxiedCollectionField(std::string_view fieldName, TClass *classp);
0155
0156 RProxiedCollectionField(std::string_view fieldName, std::string_view typeName,
0157 std::unique_ptr<RFieldBase> itemField);
0158
0159 protected:
0160 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
0161 const RColumnRepresentations &GetColumnRepresentations() const final;
0162 void GenerateColumns() final;
0163 void GenerateColumns(const ROOT::RNTupleDescriptor &desc) final;
0164
0165 void ConstructValue(void *where) const final;
0166 std::unique_ptr<RDeleter> GetDeleter() const final;
0167
0168 std::size_t AppendImpl(const void *from) final;
0169 void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
0170
0171 void CommitClusterImpl() final { fNWritten = 0; }
0172
0173 public:
0174 RProxiedCollectionField(std::string_view fieldName, std::string_view typeName);
0175 RProxiedCollectionField(RProxiedCollectionField &&other) = default;
0176 RProxiedCollectionField &operator=(RProxiedCollectionField &&other) = default;
0177 ~RProxiedCollectionField() override = default;
0178
0179 std::vector<RValue> SplitValue(const RValue &value) const final;
0180 size_t GetValueSize() const final { return fProxy->Sizeof(); }
0181 size_t GetAlignment() const final { return alignof(std::max_align_t); }
0182 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
0183 void
0184 GetCollectionInfo(ROOT::NTupleSize_t globalIndex, RNTupleLocalIndex *collectionStart, ROOT::NTupleSize_t *size) const
0185 {
0186 fPrincipalColumn->GetCollectionInfo(globalIndex, collectionStart, size);
0187 }
0188 void
0189 GetCollectionInfo(RNTupleLocalIndex localIndex, RNTupleLocalIndex *collectionStart, ROOT::NTupleSize_t *size) const
0190 {
0191 fPrincipalColumn->GetCollectionInfo(localIndex, collectionStart, size);
0192 }
0193 };
0194
0195
0196
0197
0198
0199 template <typename T, typename = void>
0200 struct HasCollectionProxyMemberType : std::false_type {
0201 };
0202 template <typename T>
0203 struct HasCollectionProxyMemberType<
0204 T, typename std::enable_if<std::is_same<typename T::IsCollectionProxy, std::true_type>::value>::type>
0205 : std::true_type {
0206 };
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247 template <typename T, typename = void>
0248 struct IsCollectionProxy : HasCollectionProxyMemberType<T> {
0249 };
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265 template <typename T>
0266 class RField<T, typename std::enable_if<IsCollectionProxy<T>::value>::type> final : public RProxiedCollectionField {
0267 public:
0268 static std::string TypeName() { return ROOT::Internal::GetRenormalizedDemangledTypeName(typeid(T)); }
0269 RField(std::string_view name) : RProxiedCollectionField(name, TypeName())
0270 {
0271 static_assert(std::is_class<T>::value, "collection proxy unsupported for fundamental types");
0272 }
0273 RField(RField &&other) = default;
0274 RField &operator=(RField &&other) = default;
0275 ~RField() final = default;
0276 };
0277
0278
0279
0280
0281
0282
0283 class RMapField : public RProxiedCollectionField {
0284 public:
0285 RMapField(std::string_view fieldName, std::string_view typeName, std::unique_ptr<RFieldBase> itemField);
0286 RMapField(RMapField &&other) = default;
0287 RMapField &operator=(RMapField &&other) = default;
0288 ~RMapField() override = default;
0289 };
0290
0291 template <typename KeyT, typename ValueT>
0292 class RField<std::map<KeyT, ValueT>> final : public RMapField {
0293 public:
0294 static std::string TypeName()
0295 {
0296 return "std::map<" + RField<KeyT>::TypeName() + "," + RField<ValueT>::TypeName() + ">";
0297 }
0298
0299 explicit RField(std::string_view name)
0300 : RMapField(name, TypeName(), std::make_unique<RField<std::pair<KeyT, ValueT>>>("_0"))
0301 {
0302 }
0303 RField(RField &&other) = default;
0304 RField &operator=(RField &&other) = default;
0305 ~RField() final = default;
0306 };
0307
0308 template <typename KeyT, typename ValueT>
0309 class RField<std::unordered_map<KeyT, ValueT>> final : public RMapField {
0310 public:
0311 static std::string TypeName()
0312 {
0313 return "std::unordered_map<" + RField<KeyT>::TypeName() + "," + RField<ValueT>::TypeName() + ">";
0314 }
0315
0316 explicit RField(std::string_view name)
0317 : RMapField(name, TypeName(), std::make_unique<RField<std::pair<KeyT, ValueT>>>("_0"))
0318 {
0319 }
0320 RField(RField &&other) = default;
0321 RField &operator=(RField &&other) = default;
0322 ~RField() final = default;
0323 };
0324
0325 template <typename KeyT, typename ValueT>
0326 class RField<std::multimap<KeyT, ValueT>> final : public RMapField {
0327 public:
0328 static std::string TypeName()
0329 {
0330 return "std::multimap<" + RField<KeyT>::TypeName() + "," + RField<ValueT>::TypeName() + ">";
0331 }
0332
0333 explicit RField(std::string_view name)
0334 : RMapField(name, TypeName(), std::make_unique<RField<std::pair<KeyT, ValueT>>>("_0"))
0335 {
0336 }
0337 RField(RField &&other) = default;
0338 RField &operator=(RField &&other) = default;
0339 ~RField() final = default;
0340 };
0341
0342 template <typename KeyT, typename ValueT>
0343 class RField<std::unordered_multimap<KeyT, ValueT>> final : public RMapField {
0344 public:
0345 static std::string TypeName()
0346 {
0347 return "std::unordered_multimap<" + RField<KeyT>::TypeName() + "," + RField<ValueT>::TypeName() + ">";
0348 }
0349
0350 explicit RField(std::string_view name)
0351 : RMapField(name, TypeName(), std::make_unique<RField<std::pair<KeyT, ValueT>>>("_0"))
0352 {
0353 }
0354 RField(RField &&other) = default;
0355 RField &operator=(RField &&other) = default;
0356 ~RField() final = default;
0357 };
0358
0359
0360
0361
0362
0363
0364 class RSetField : public RProxiedCollectionField {
0365 public:
0366 RSetField(std::string_view fieldName, std::string_view typeName, std::unique_ptr<RFieldBase> itemField);
0367 RSetField(RSetField &&other) = default;
0368 RSetField &operator=(RSetField &&other) = default;
0369 ~RSetField() override = default;
0370 };
0371
0372 template <typename ItemT>
0373 class RField<std::set<ItemT>> final : public RSetField {
0374 public:
0375 static std::string TypeName() { return "std::set<" + RField<ItemT>::TypeName() + ">"; }
0376
0377 explicit RField(std::string_view name) : RSetField(name, TypeName(), std::make_unique<RField<ItemT>>("_0")) {}
0378 RField(RField &&other) = default;
0379 RField &operator=(RField &&other) = default;
0380 ~RField() final = default;
0381 };
0382
0383 template <typename ItemT>
0384 class RField<std::unordered_set<ItemT>> final : public RSetField {
0385 public:
0386 static std::string TypeName() { return "std::unordered_set<" + RField<ItemT>::TypeName() + ">"; }
0387
0388 explicit RField(std::string_view name) : RSetField(name, TypeName(), std::make_unique<RField<ItemT>>("_0")) {}
0389 RField(RField &&other) = default;
0390 RField &operator=(RField &&other) = default;
0391 ~RField() final = default;
0392 };
0393
0394 template <typename ItemT>
0395 class RField<std::multiset<ItemT>> final : public RSetField {
0396 public:
0397 static std::string TypeName() { return "std::multiset<" + RField<ItemT>::TypeName() + ">"; }
0398
0399 explicit RField(std::string_view name) : RSetField(name, TypeName(), std::make_unique<RField<ItemT>>("_0")) {}
0400 RField(RField &&other) = default;
0401 RField &operator=(RField &&other) = default;
0402 ~RField() final = default;
0403 };
0404
0405 template <typename ItemT>
0406 class RField<std::unordered_multiset<ItemT>> final : public RSetField {
0407 public:
0408 static std::string TypeName() { return "std::unordered_multiset<" + RField<ItemT>::TypeName() + ">"; }
0409
0410 explicit RField(std::string_view name) : RSetField(name, TypeName(), std::make_unique<RField<ItemT>>("_0")) {}
0411 RField(RField &&other) = default;
0412 RField &operator=(RField &&other) = default;
0413 ~RField() final = default;
0414 };
0415
0416 }
0417
0418 #endif