File indexing completed on 2025-12-15 10:28:35
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef ROOT_RField_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/RNTupleTypes.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
0155 RProxiedCollectionField(std::string_view fieldName, TClass *classp);
0156
0157 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const override;
0158 const RColumnRepresentations &GetColumnRepresentations() const final;
0159 void GenerateColumns() final;
0160 void GenerateColumns(const ROOT::RNTupleDescriptor &desc) final;
0161
0162 void ConstructValue(void *where) const final;
0163 std::unique_ptr<RDeleter> GetDeleter() const final;
0164
0165 std::size_t AppendImpl(const void *from) final;
0166 void ReadGlobalImpl(ROOT::NTupleSize_t globalIndex, void *to) final;
0167
0168 void ReconcileOnDiskField(const RNTupleDescriptor &desc) override;
0169
0170 void CommitClusterImpl() final { fNWritten = 0; }
0171
0172 public:
0173 RProxiedCollectionField(std::string_view fieldName, std::string_view typeName);
0174 RProxiedCollectionField(RProxiedCollectionField &&other) = default;
0175 RProxiedCollectionField &operator=(RProxiedCollectionField &&other) = default;
0176 ~RProxiedCollectionField() override = default;
0177
0178 std::vector<RValue> SplitValue(const RValue &value) const final;
0179 size_t GetValueSize() const final { return fProxy->Sizeof(); }
0180 size_t GetAlignment() const final { return alignof(std::max_align_t); }
0181 void AcceptVisitor(ROOT::Detail::RFieldVisitor &visitor) const final;
0182 };
0183
0184
0185
0186
0187
0188 template <typename T, typename = void>
0189 struct HasCollectionProxyMemberType : std::false_type {
0190 };
0191 template <typename T>
0192 struct HasCollectionProxyMemberType<
0193 T, typename std::enable_if<std::is_same<typename T::IsCollectionProxy, std::true_type>::value>::type>
0194 : std::true_type {
0195 };
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
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 template <typename T, typename = void>
0237 struct IsCollectionProxy : HasCollectionProxyMemberType<T> {
0238 };
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254 template <typename T>
0255 class RField<T, typename std::enable_if<IsCollectionProxy<T>::value>::type> final : public RProxiedCollectionField {
0256 public:
0257 static std::string TypeName() { return ROOT::Internal::GetRenormalizedTypeName(typeid(T)); }
0258 RField(std::string_view name) : RProxiedCollectionField(name, TypeName())
0259 {
0260 static_assert(std::is_class<T>::value, "collection proxy unsupported for fundamental types");
0261 }
0262 RField(RField &&other) = default;
0263 RField &operator=(RField &&other) = default;
0264 ~RField() final = default;
0265 };
0266
0267
0268
0269
0270
0271
0272 class RMapField : public RProxiedCollectionField {
0273 public:
0274 enum class EMapType {
0275 kMap,
0276 kUnorderedMap,
0277 kMultiMap,
0278 kUnorderedMultiMap
0279 };
0280
0281 private:
0282 EMapType fMapType;
0283
0284 protected:
0285 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
0286 void ReconcileOnDiskField(const RNTupleDescriptor &desc) final;
0287
0288 public:
0289 RMapField(std::string_view fieldName, EMapType mapType, std::unique_ptr<RFieldBase> itemField);
0290 RMapField(RMapField &&other) = default;
0291 RMapField &operator=(RMapField &&other) = default;
0292 ~RMapField() override = default;
0293 };
0294
0295 template <typename KeyT, typename ValueT>
0296 class RField<std::map<KeyT, ValueT>> final : public RMapField {
0297 public:
0298 static std::string TypeName()
0299 {
0300 return "std::map<" + RField<KeyT>::TypeName() + "," + RField<ValueT>::TypeName() + ">";
0301 }
0302
0303 explicit RField(std::string_view name)
0304 : RMapField(name, EMapType::kMap, std::make_unique<RField<std::pair<KeyT, ValueT>>>("_0"))
0305 {
0306 }
0307 RField(RField &&other) = default;
0308 RField &operator=(RField &&other) = default;
0309 ~RField() final = default;
0310 };
0311
0312 template <typename KeyT, typename ValueT>
0313 class RField<std::unordered_map<KeyT, ValueT>> final : public RMapField {
0314 public:
0315 static std::string TypeName()
0316 {
0317 return "std::unordered_map<" + RField<KeyT>::TypeName() + "," + RField<ValueT>::TypeName() + ">";
0318 }
0319
0320 explicit RField(std::string_view name)
0321 : RMapField(name, EMapType::kUnorderedMap, std::make_unique<RField<std::pair<KeyT, ValueT>>>("_0"))
0322 {
0323 }
0324 RField(RField &&other) = default;
0325 RField &operator=(RField &&other) = default;
0326 ~RField() final = default;
0327 };
0328
0329 template <typename KeyT, typename ValueT>
0330 class RField<std::multimap<KeyT, ValueT>> final : public RMapField {
0331 public:
0332 static std::string TypeName()
0333 {
0334 return "std::multimap<" + RField<KeyT>::TypeName() + "," + RField<ValueT>::TypeName() + ">";
0335 }
0336
0337 explicit RField(std::string_view name)
0338 : RMapField(name, EMapType::kMultiMap, std::make_unique<RField<std::pair<KeyT, ValueT>>>("_0"))
0339 {
0340 }
0341 RField(RField &&other) = default;
0342 RField &operator=(RField &&other) = default;
0343 ~RField() final = default;
0344 };
0345
0346 template <typename KeyT, typename ValueT>
0347 class RField<std::unordered_multimap<KeyT, ValueT>> final : public RMapField {
0348 public:
0349 static std::string TypeName()
0350 {
0351 return "std::unordered_multimap<" + RField<KeyT>::TypeName() + "," + RField<ValueT>::TypeName() + ">";
0352 }
0353
0354 explicit RField(std::string_view name)
0355 : RMapField(name, EMapType::kUnorderedMultiMap, std::make_unique<RField<std::pair<KeyT, ValueT>>>("_0"))
0356 {
0357 }
0358 RField(RField &&other) = default;
0359 RField &operator=(RField &&other) = default;
0360 ~RField() final = default;
0361 };
0362
0363
0364
0365
0366
0367
0368 class RSetField : public RProxiedCollectionField {
0369 public:
0370 enum class ESetType {
0371 kSet,
0372 kUnorderedSet,
0373 kMultiSet,
0374 kUnorderedMultiSet
0375 };
0376
0377 private:
0378 ESetType fSetType;
0379
0380 protected:
0381 std::unique_ptr<RFieldBase> CloneImpl(std::string_view newName) const final;
0382 void ReconcileOnDiskField(const RNTupleDescriptor &desc) final;
0383
0384 public:
0385 RSetField(std::string_view fieldName, ESetType setType, std::unique_ptr<RFieldBase> itemField);
0386 RSetField(RSetField &&other) = default;
0387 RSetField &operator=(RSetField &&other) = default;
0388 ~RSetField() override = default;
0389 };
0390
0391 template <typename ItemT>
0392 class RField<std::set<ItemT>> final : public RSetField {
0393 public:
0394 static std::string TypeName() { return "std::set<" + RField<ItemT>::TypeName() + ">"; }
0395
0396 explicit RField(std::string_view name) : RSetField(name, ESetType::kSet, std::make_unique<RField<ItemT>>("_0")) {}
0397 RField(RField &&other) = default;
0398 RField &operator=(RField &&other) = default;
0399 ~RField() final = default;
0400 };
0401
0402 template <typename ItemT>
0403 class RField<std::unordered_set<ItemT>> final : public RSetField {
0404 public:
0405 static std::string TypeName() { return "std::unordered_set<" + RField<ItemT>::TypeName() + ">"; }
0406
0407 explicit RField(std::string_view name)
0408 : RSetField(name, ESetType::kUnorderedSet, std::make_unique<RField<ItemT>>("_0"))
0409 {
0410 }
0411 RField(RField &&other) = default;
0412 RField &operator=(RField &&other) = default;
0413 ~RField() final = default;
0414 };
0415
0416 template <typename ItemT>
0417 class RField<std::multiset<ItemT>> final : public RSetField {
0418 public:
0419 static std::string TypeName() { return "std::multiset<" + RField<ItemT>::TypeName() + ">"; }
0420
0421 explicit RField(std::string_view name) : RSetField(name, ESetType::kMultiSet, std::make_unique<RField<ItemT>>("_0"))
0422 {
0423 }
0424 RField(RField &&other) = default;
0425 RField &operator=(RField &&other) = default;
0426 ~RField() final = default;
0427 };
0428
0429 template <typename ItemT>
0430 class RField<std::unordered_multiset<ItemT>> final : public RSetField {
0431 public:
0432 static std::string TypeName() { return "std::unordered_multiset<" + RField<ItemT>::TypeName() + ">"; }
0433
0434 explicit RField(std::string_view name)
0435 : RSetField(name, ESetType::kUnorderedMultiSet, std::make_unique<RField<ItemT>>("_0"))
0436 {
0437 }
0438 RField(RField &&other) = default;
0439 RField &operator=(RField &&other) = default;
0440 ~RField() final = default;
0441 };
0442
0443 }
0444
0445 #endif