File indexing completed on 2024-04-06 12:03:53
0001 #ifndef DataFormats_Common_Ref_h
0002 #define DataFormats_Common_Ref_h
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104 #include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
0105 #include "DataFormats/Common/interface/EDProductfwd.h"
0106 #include "DataFormats/Common/interface/EDProductGetter.h"
0107 #include "DataFormats/Common/interface/Handle.h"
0108 #include "DataFormats/Common/interface/OrphanHandle.h"
0109 #include "DataFormats/Common/interface/RefCore.h"
0110 #include "DataFormats/Common/interface/RefCoreWithIndex.h"
0111 #include "DataFormats/Common/interface/TestHandle.h"
0112 #include "DataFormats/Common/interface/traits.h"
0113 #include "DataFormats/Provenance/interface/ProductID.h"
0114
0115 #include "boost/functional.hpp"
0116
0117 #include <vector>
0118 #include <type_traits>
0119
0120 #include "DataFormats/Common/interface/RefTraits.h"
0121
0122 namespace edm {
0123
0124 template <typename, typename = void>
0125 struct has_key_compare : std::false_type {};
0126 template <typename T>
0127 struct has_key_compare<T, std::void_t<typename T::key_compare>> : std::true_type {};
0128
0129 template <typename C, typename K>
0130 bool compare_key(K const& lhs, K const& rhs) {
0131 if constexpr (has_key_compare<C>::value) {
0132 using comparison_functor = typename C::key_compare;
0133 return comparison_functor()(lhs, rhs);
0134 } else {
0135 return lhs < rhs;
0136 }
0137 }
0138
0139 template <typename C, typename T, typename F>
0140 class RefVector;
0141
0142 template <typename T>
0143 class RefToBaseVector;
0144
0145 template <typename C,
0146 typename T = typename refhelper::ValueTrait<C>::value,
0147 typename F = typename refhelper::FindTrait<C, T>::value>
0148 class Ref {
0149 private:
0150 typedef refhelper::FindRefVectorUsingAdvance<RefVector<C, T, F>> VF;
0151 typedef refhelper::FindRefVectorUsingAdvance<RefToBaseVector<T>> VBF;
0152 friend class RefVectorIterator<C, T, F>;
0153 friend class RefVector<C, T, F>;
0154 friend class RefVector<RefVector<C, T, F>, T, VF>;
0155 friend class RefVector<RefVector<C, T, F>, T, VBF>;
0156
0157 public:
0158
0159 typedef C product_type;
0160 typedef T value_type;
0161 typedef T const element_type;
0162 typedef F finder_type;
0163 typedef typename boost::binary_traits<F>::second_argument_type argument_type;
0164 typedef typename std::remove_cv<typename std::remove_reference<argument_type>::type>::type key_type;
0165
0166
0167
0168 static key_type invalidKey() { return key_traits<key_type>::value; }
0169
0170
0171 Ref() : product_(), index_(key_traits<key_type>::value) {}
0172
0173
0174 Ref(Handle<C> const& handle, key_type itemKey, bool setNow = true);
0175
0176
0177 Ref(OrphanHandle<C> const& handle, key_type itemKey, bool setNow = true);
0178
0179
0180
0181
0182
0183
0184 Ref(C const* product, key_type itemKey, bool setNow = true);
0185
0186
0187
0188
0189 Ref(TestHandle<C> const& handle, key_type itemKey, bool setNow = true);
0190
0191
0192
0193
0194 Ref(ProductID const& productID, key_type itemKey, EDProductGetter const* prodGetter)
0195 : product_(productID, nullptr, mustBeNonZero(prodGetter, "Ref", productID), false), index_(itemKey) {}
0196
0197
0198
0199
0200
0201
0202
0203
0204 Ref(ProductID const& iProductID, T const* item, key_type itemKey, C const* )
0205 : product_(iProductID, item, 0, false), index_(itemKey) {}
0206
0207 Ref(ProductID const& iProductID, T const* item, key_type itemKey)
0208 : product_(iProductID, item, nullptr, false), index_(itemKey) {}
0209
0210 Ref(ProductID const& iProductID, T const* item, key_type itemKey, bool transient)
0211 : product_(iProductID, item, nullptr, transient), index_(itemKey) {}
0212
0213
0214
0215
0216
0217 explicit Ref(ProductID const& iId) : product_(iId, nullptr, nullptr, false), index_(key_traits<key_type>::value) {}
0218
0219
0220 Ref(RefProd<C> const& refProd, key_type itemKey);
0221
0222
0223 ~Ref() {}
0224
0225
0226 T const& operator*() const;
0227
0228
0229 T const* operator->() const;
0230
0231
0232 T const* get() const { return isNull() ? nullptr : this->operator->(); }
0233
0234
0235 bool isNull() const { return !isNonnull(); }
0236
0237
0238 bool isNonnull() const { return index_ != edm::key_traits<key_type>::value; }
0239
0240
0241 bool operator!() const { return isNull(); }
0242
0243
0244 ProductID id() const { return product_.id(); }
0245
0246
0247 EDProductGetter const* productGetter() const { return product_.productGetter(); }
0248
0249
0250 key_type key() const { return index_; }
0251
0252
0253 key_type index() const { return index_; }
0254
0255
0256 bool hasProductCache() const { return product_.productPtr() != nullptr; }
0257
0258
0259
0260
0261
0262 bool isAvailable() const;
0263
0264
0265 bool isTransient() const { return product_.isTransient(); }
0266
0267 RefCore const& refCore() const { return product_; }
0268
0269
0270 CMS_CLASS_VERSION(10)
0271
0272
0273 Ref(RefCore const& iRefCore, key_type const& iKey) : product_(iRefCore), index_(iKey) {}
0274
0275 private:
0276
0277
0278 void checkTypeAtCompileTime(C const*) {}
0279
0280 RefCore product_;
0281 key_type index_;
0282 };
0283
0284
0285
0286
0287 #define REF_FOR_VECTOR_ARGS \
0288 std::vector<E>, typename refhelper::ValueTrait<std::vector<E>>::value, \
0289 typename refhelper::FindTrait<std::vector<E>, typename refhelper::ValueTrait<std::vector<E>>::value>::value
0290
0291 template <typename E>
0292 class Ref<REF_FOR_VECTOR_ARGS> {
0293 private:
0294 typedef typename refhelper::ValueTrait<std::vector<E>>::value T;
0295 typedef
0296 typename refhelper::FindTrait<std::vector<E>, typename refhelper::ValueTrait<std::vector<E>>::value>::value F;
0297
0298 typedef refhelper::FindRefVectorUsingAdvance<RefVector<std::vector<E>, T, F>> VF;
0299 typedef refhelper::FindRefVectorUsingAdvance<RefToBaseVector<T>> VBF;
0300 friend class RefVectorIterator<std::vector<E>, T, F>;
0301 friend class RefVector<std::vector<E>, T, F>;
0302 friend class RefVector<RefVector<std::vector<E>, T, F>, T, VF>;
0303 friend class RefVector<RefVector<std::vector<E>, T, F>, T, VBF>;
0304
0305 public:
0306
0307 typedef std::vector<E> product_type;
0308 typedef typename refhelper::ValueTrait<std::vector<E>>::value value_type;
0309 typedef value_type const element_type;
0310 typedef typename refhelper::FindTrait<std::vector<E>, typename refhelper::ValueTrait<std::vector<E>>::value>::value
0311 finder_type;
0312 typedef typename boost::binary_traits<F>::second_argument_type argument_type;
0313 typedef unsigned int key_type;
0314
0315
0316
0317 static key_type invalidKey() { return key_traits<key_type>::value; }
0318
0319
0320 Ref() : product_() {}
0321
0322
0323 Ref(Handle<product_type> const& handle, key_type itemKey, bool setNow = true);
0324
0325
0326 Ref(OrphanHandle<product_type> const& handle, key_type itemKey, bool setNow = true);
0327
0328
0329
0330
0331
0332
0333 Ref(product_type const* product, key_type itemKey, bool setNow = true);
0334
0335
0336
0337
0338 Ref(TestHandle<product_type> const& handle, key_type itemKey, bool setNow = true);
0339
0340
0341
0342
0343 Ref(ProductID const& productID, key_type itemKey, EDProductGetter const* prodGetter)
0344 : product_(productID, nullptr, mustBeNonZero(prodGetter, "Ref", productID), false, itemKey) {}
0345
0346
0347
0348
0349
0350
0351
0352
0353 Ref(ProductID const& iProductID, T const* item, key_type itemKey, product_type const* )
0354 : product_(iProductID, item, nullptr, false, itemKey) {}
0355
0356 Ref(ProductID const& iProductID, T const* item, key_type itemKey)
0357 : product_(iProductID, item, nullptr, false, itemKey) {}
0358
0359 Ref(ProductID const& iProductID, T const* item, key_type itemKey, bool transient)
0360 : product_(iProductID, item, nullptr, transient, itemKey) {}
0361
0362
0363
0364
0365
0366 explicit Ref(ProductID const& iId) : product_(iId, nullptr, nullptr, false, key_traits<key_type>::value) {}
0367
0368
0369 Ref(RefProd<product_type> const& refProd, key_type itemKey);
0370
0371
0372 ~Ref() {}
0373
0374
0375 T const& operator*() const;
0376
0377
0378 T const* operator->() const;
0379
0380
0381 T const* get() const { return isNull() ? nullptr : this->operator->(); }
0382
0383
0384 bool isNull() const { return !isNonnull(); }
0385
0386
0387 bool isNonnull() const { return key() != edm::key_traits<key_type>::value; }
0388
0389
0390 bool operator!() const { return isNull(); }
0391
0392
0393 ProductID id() const { return product_.id(); }
0394
0395
0396 EDProductGetter const* productGetter() const { return product_.productGetter(); }
0397
0398
0399 key_type key() const { return product_.index(); }
0400
0401
0402 key_type index() const { return product_.index(); }
0403
0404
0405 bool hasProductCache() const { return product_.productPtr() != nullptr; }
0406
0407
0408
0409
0410
0411 bool isAvailable() const;
0412
0413
0414 bool isTransient() const { return product_.isTransient(); }
0415
0416 RefCore const& refCore() const { return product_.toRefCore(); }
0417
0418
0419 CMS_CLASS_VERSION(11)
0420
0421
0422 Ref(RefCore const& iRefCore, key_type const& iKey) : product_(iRefCore, iKey) {}
0423
0424 private:
0425
0426
0427 void checkTypeAtCompileTime(product_type const*) {}
0428
0429 RefCoreWithIndex product_;
0430 };
0431 }
0432
0433 #include "DataFormats/Common/interface/RefProd.h"
0434 #include "DataFormats/Common/interface/RefCoreGet.h"
0435 #include "DataFormats/Common/interface/RefItemGet.h"
0436
0437 namespace edm {
0438
0439
0440 template <typename C, typename T, typename F>
0441 inline Ref<C, T, F>::Ref(Handle<C> const& handle, key_type itemKey, bool)
0442 : product_(handle.id(), nullptr, nullptr, false), index_(itemKey) {
0443 if (itemKey == key_traits<key_type>::value)
0444 return;
0445 refitem::findRefItem<C, T, F, key_type>(product_, handle.product(), itemKey);
0446 }
0447
0448
0449 template <typename E>
0450 inline Ref<REF_FOR_VECTOR_ARGS>::Ref(Handle<std::vector<E>> const& handle, key_type itemKey, bool)
0451 : product_(handle.id(), nullptr, nullptr, false, itemKey) {
0452 if (itemKey == key_traits<key_type>::value)
0453 return;
0454 refitem::findRefItem<product_type, value_type, finder_type, key_type>(
0455 product_.toRefCore(), handle.product(), itemKey);
0456 }
0457
0458
0459 template <typename C, typename T, typename F>
0460 inline Ref<C, T, F>::Ref(OrphanHandle<C> const& handle, key_type itemKey, bool)
0461 : product_(handle.id(), nullptr, nullptr, false), index_(itemKey) {
0462 if (itemKey == key_traits<key_type>::value)
0463 return;
0464 refitem::findRefItem<C, T, F, key_type>(product_, handle.product(), itemKey);
0465 }
0466
0467
0468 template <typename E>
0469 inline Ref<REF_FOR_VECTOR_ARGS>::Ref(OrphanHandle<std::vector<E>> const& handle, key_type itemKey, bool)
0470 : product_(handle.id(), nullptr, nullptr, false, itemKey) {
0471 if (itemKey == key_traits<key_type>::value)
0472 return;
0473 refitem::findRefItem<product_type, value_type, finder_type, key_type>(
0474 product_.toRefCore(), handle.product(), itemKey);
0475 }
0476
0477
0478
0479
0480
0481
0482
0483
0484 template <typename C, typename T, typename F>
0485 inline Ref<C, T, F>::Ref(C const* iProduct, key_type itemKey, bool)
0486 : product_(ProductID(), nullptr, nullptr, true),
0487 index_(iProduct != nullptr ? itemKey : key_traits<key_type>::value) {
0488 if (iProduct != nullptr) {
0489 refitem::findRefItem<C, T, F, key_type>(product_, iProduct, itemKey);
0490 }
0491 }
0492
0493 template <typename E>
0494 inline Ref<REF_FOR_VECTOR_ARGS>::Ref(std::vector<E> const* iProduct, key_type itemKey, bool)
0495 : product_(ProductID(), nullptr, nullptr, true, iProduct != nullptr ? itemKey : key_traits<key_type>::value) {
0496 if (iProduct != nullptr) {
0497 refitem::findRefItem<product_type, value_type, finder_type, key_type>(product_.toRefCore(), iProduct, itemKey);
0498 }
0499 }
0500
0501
0502
0503 template <typename C, typename T, typename F>
0504 inline Ref<C, T, F>::Ref(TestHandle<C> const& handle, key_type itemKey, bool)
0505 : product_(handle.id(), nullptr, nullptr, true), index_(itemKey) {
0506 if (itemKey == key_traits<key_type>::value)
0507 return;
0508 refitem::findRefItem<C, T, F, key_type>(product_, handle.product(), itemKey);
0509 }
0510
0511 template <typename E>
0512 inline Ref<REF_FOR_VECTOR_ARGS>::Ref(TestHandle<std::vector<E>> const& handle, key_type itemKey, bool)
0513 : product_(handle.id(), nullptr, nullptr, true, itemKey) {
0514 if (itemKey == key_traits<key_type>::value)
0515 return;
0516 refitem::findRefItem<product_type, value_type, finder_type, key_type>(
0517 product_.toRefCore(), handle.product(), itemKey);
0518 }
0519
0520
0521 template <typename C, typename T, typename F>
0522 inline Ref<C, T, F>::Ref(RefProd<C> const& refProd, key_type itemKey)
0523 : product_(refProd.id(), nullptr, refProd.refCore().productGetter(), refProd.refCore().isTransient()),
0524 index_(itemKey) {
0525 if (refProd.refCore().productPtr() != nullptr && itemKey != key_traits<key_type>::value) {
0526 refitem::findRefItem<C, T, F, key_type>(
0527 product_, static_cast<product_type const*>(refProd.refCore().productPtr()), itemKey);
0528 }
0529 }
0530
0531 template <typename E>
0532 inline Ref<REF_FOR_VECTOR_ARGS>::Ref(RefProd<std::vector<E>> const& refProd, key_type itemKey)
0533 : product_(refProd.id(), nullptr, refProd.refCore().productGetter(), refProd.refCore().isTransient(), itemKey) {
0534 if (refProd.refCore().productPtr() != nullptr && itemKey != key_traits<key_type>::value) {
0535 refitem::findRefItem<product_type, value_type, finder_type, key_type>(
0536 product_.toRefCore(), static_cast<product_type const*>(refProd.refCore().productPtr()), itemKey);
0537 }
0538 }
0539
0540 template <typename C, typename T, typename F>
0541 inline bool Ref<C, T, F>::isAvailable() const {
0542 if (product_.isAvailable()) {
0543 return true;
0544 }
0545 return isThinnedAvailable<C>(product_, index_);
0546 }
0547
0548 template <typename E>
0549 inline bool Ref<REF_FOR_VECTOR_ARGS>::isAvailable() const {
0550 if (product_.isAvailable()) {
0551 return true;
0552 }
0553 return isThinnedAvailable<std::vector<E>>(product_.toRefCore(), key());
0554 }
0555
0556
0557 template <typename C, typename T, typename F>
0558 inline T const& Ref<C, T, F>::operator*() const {
0559 return *getRefPtr<C, T, F>(product_, index_);
0560 }
0561 template <typename E>
0562 inline typename refhelper::ValueTrait<std::vector<E>>::value const& Ref<REF_FOR_VECTOR_ARGS>::operator*() const {
0563 return *getRefPtr<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), key());
0564 }
0565
0566
0567 template <typename C, typename T, typename F>
0568 inline T const* Ref<C, T, F>::operator->() const {
0569 return getRefPtr<C, T, F>(product_, index_);
0570 }
0571 template <typename E>
0572 inline typename refhelper::ValueTrait<std::vector<E>>::value const* Ref<REF_FOR_VECTOR_ARGS>::operator->() const {
0573 return getRefPtr<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), key());
0574 }
0575
0576 template <typename C, typename T, typename F>
0577 inline bool operator==(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
0578 return lhs.key() == rhs.key() && lhs.refCore() == rhs.refCore();
0579 }
0580
0581 template <typename C, typename T, typename F>
0582 inline bool operator!=(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
0583 return !(lhs == rhs);
0584 }
0585
0586 template <typename C, typename T, typename F>
0587 inline bool operator<(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
0588
0589
0590 return (lhs.refCore() == rhs.refCore() ? compare_key<C>(lhs.key(), rhs.key()) : lhs.refCore() < rhs.refCore());
0591 }
0592
0593 }
0594
0595
0596 #include "DataFormats/Common/interface/HolderToVectorTrait_Ref_specialization.h"
0597 #endif