File indexing completed on 2024-08-29 02:16:40
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 template <typename C, typename K>
0124 bool compare_key(K const& lhs, K const& rhs) {
0125 if constexpr (requires { typename C::key_compare; }) {
0126 using comparison_functor = typename C::key_compare;
0127 return comparison_functor()(lhs, rhs);
0128 } else {
0129 return lhs < rhs;
0130 }
0131 }
0132
0133 template <typename C, typename T, typename F>
0134 class RefVector;
0135
0136 template <typename T>
0137 class RefToBaseVector;
0138
0139 template <typename C,
0140 typename T = typename refhelper::ValueTrait<C>::value,
0141 typename F = typename refhelper::FindTrait<C, T>::value>
0142 class Ref {
0143 private:
0144 typedef refhelper::FindRefVectorUsingAdvance<RefVector<C, T, F>> VF;
0145 typedef refhelper::FindRefVectorUsingAdvance<RefToBaseVector<T>> VBF;
0146 friend class RefVectorIterator<C, T, F>;
0147 friend class RefVector<C, T, F>;
0148 friend class RefVector<RefVector<C, T, F>, T, VF>;
0149 friend class RefVector<RefVector<C, T, F>, T, VBF>;
0150
0151 public:
0152
0153 typedef C product_type;
0154 typedef T value_type;
0155 typedef T const element_type;
0156 typedef F finder_type;
0157 typedef typename boost::binary_traits<F>::second_argument_type argument_type;
0158 typedef typename std::remove_cv<typename std::remove_reference<argument_type>::type>::type key_type;
0159
0160
0161
0162 static key_type invalidKey() { return key_traits<key_type>::value; }
0163
0164
0165 Ref() : product_(), index_(key_traits<key_type>::value) {}
0166
0167
0168 Ref(Handle<C> const& handle, key_type itemKey, bool setNow = true);
0169
0170
0171 Ref(OrphanHandle<C> const& handle, key_type itemKey, bool setNow = true);
0172
0173
0174
0175
0176
0177
0178 Ref(C const* product, key_type itemKey, bool setNow = true);
0179
0180
0181
0182
0183 Ref(TestHandle<C> const& handle, key_type itemKey, bool setNow = true);
0184
0185
0186
0187
0188 Ref(ProductID const& productID, key_type itemKey, EDProductGetter const* prodGetter)
0189 : product_(productID, nullptr, mustBeNonZero(prodGetter, "Ref", productID), false), index_(itemKey) {}
0190
0191
0192
0193
0194
0195
0196
0197
0198 Ref(ProductID const& iProductID, T const* item, key_type itemKey, C const* )
0199 : product_(iProductID, item, 0, false), index_(itemKey) {}
0200
0201 Ref(ProductID const& iProductID, T const* item, key_type itemKey)
0202 : product_(iProductID, item, nullptr, false), index_(itemKey) {}
0203
0204 Ref(ProductID const& iProductID, T const* item, key_type itemKey, bool transient)
0205 : product_(iProductID, item, nullptr, transient), index_(itemKey) {}
0206
0207
0208
0209
0210
0211 explicit Ref(ProductID const& iId) : product_(iId, nullptr, nullptr, false), index_(key_traits<key_type>::value) {}
0212
0213
0214 Ref(RefProd<C> const& refProd, key_type itemKey);
0215
0216
0217 ~Ref() {}
0218
0219
0220 T const& operator*() const;
0221
0222
0223 T const* operator->() const;
0224
0225
0226 T const* get() const { return isNull() ? nullptr : this->operator->(); }
0227
0228
0229 bool isNull() const { return !isNonnull(); }
0230
0231
0232 bool isNonnull() const { return index_ != edm::key_traits<key_type>::value; }
0233
0234
0235 bool operator!() const { return isNull(); }
0236
0237
0238 ProductID id() const { return product_.id(); }
0239
0240
0241 EDProductGetter const* productGetter() const { return product_.productGetter(); }
0242
0243
0244 key_type key() const { return index_; }
0245
0246
0247 key_type index() const { return index_; }
0248
0249
0250 bool hasProductCache() const { return product_.productPtr() != nullptr; }
0251
0252
0253
0254
0255
0256 bool isAvailable() const;
0257
0258
0259 bool isTransient() const { return product_.isTransient(); }
0260
0261 RefCore const& refCore() const { return product_; }
0262
0263
0264 CMS_CLASS_VERSION(10)
0265
0266
0267 Ref(RefCore const& iRefCore, key_type const& iKey) : product_(iRefCore), index_(iKey) {}
0268
0269 private:
0270
0271
0272 void checkTypeAtCompileTime(C const*) {}
0273
0274 RefCore product_;
0275 key_type index_;
0276 };
0277
0278
0279
0280
0281 #define REF_FOR_VECTOR_ARGS \
0282 std::vector<E>, typename refhelper::ValueTrait<std::vector<E>>::value, \
0283 typename refhelper::FindTrait<std::vector<E>, typename refhelper::ValueTrait<std::vector<E>>::value>::value
0284
0285 template <typename E>
0286 class Ref<REF_FOR_VECTOR_ARGS> {
0287 private:
0288 typedef typename refhelper::ValueTrait<std::vector<E>>::value T;
0289 typedef
0290 typename refhelper::FindTrait<std::vector<E>, typename refhelper::ValueTrait<std::vector<E>>::value>::value F;
0291
0292 typedef refhelper::FindRefVectorUsingAdvance<RefVector<std::vector<E>, T, F>> VF;
0293 typedef refhelper::FindRefVectorUsingAdvance<RefToBaseVector<T>> VBF;
0294 friend class RefVectorIterator<std::vector<E>, T, F>;
0295 friend class RefVector<std::vector<E>, T, F>;
0296 friend class RefVector<RefVector<std::vector<E>, T, F>, T, VF>;
0297 friend class RefVector<RefVector<std::vector<E>, T, F>, T, VBF>;
0298
0299 public:
0300
0301 typedef std::vector<E> product_type;
0302 typedef typename refhelper::ValueTrait<std::vector<E>>::value value_type;
0303 typedef value_type const element_type;
0304 typedef typename refhelper::FindTrait<std::vector<E>, typename refhelper::ValueTrait<std::vector<E>>::value>::value
0305 finder_type;
0306 typedef typename boost::binary_traits<F>::second_argument_type argument_type;
0307 typedef unsigned int key_type;
0308
0309
0310
0311 static key_type invalidKey() { return key_traits<key_type>::value; }
0312
0313
0314 Ref() : product_() {}
0315
0316
0317 Ref(Handle<product_type> const& handle, key_type itemKey, bool setNow = true);
0318
0319
0320 Ref(OrphanHandle<product_type> const& handle, key_type itemKey, bool setNow = true);
0321
0322
0323
0324
0325
0326
0327 Ref(product_type const* product, key_type itemKey, bool setNow = true);
0328
0329
0330
0331
0332 Ref(TestHandle<product_type> const& handle, key_type itemKey, bool setNow = true);
0333
0334
0335
0336
0337 Ref(ProductID const& productID, key_type itemKey, EDProductGetter const* prodGetter)
0338 : product_(productID, nullptr, mustBeNonZero(prodGetter, "Ref", productID), false, itemKey) {}
0339
0340
0341
0342
0343
0344
0345
0346
0347 Ref(ProductID const& iProductID, T const* item, key_type itemKey, product_type const* )
0348 : product_(iProductID, item, nullptr, false, itemKey) {}
0349
0350 Ref(ProductID const& iProductID, T const* item, key_type itemKey)
0351 : product_(iProductID, item, nullptr, false, itemKey) {}
0352
0353 Ref(ProductID const& iProductID, T const* item, key_type itemKey, bool transient)
0354 : product_(iProductID, item, nullptr, transient, itemKey) {}
0355
0356
0357
0358
0359
0360 explicit Ref(ProductID const& iId) : product_(iId, nullptr, nullptr, false, key_traits<key_type>::value) {}
0361
0362
0363 Ref(RefProd<product_type> const& refProd, key_type itemKey);
0364
0365
0366 ~Ref() {}
0367
0368
0369 T const& operator*() const;
0370
0371
0372 T const* operator->() const;
0373
0374
0375 T const* get() const { return isNull() ? nullptr : this->operator->(); }
0376
0377
0378 bool isNull() const { return !isNonnull(); }
0379
0380
0381 bool isNonnull() const { return key() != edm::key_traits<key_type>::value; }
0382
0383
0384 bool operator!() const { return isNull(); }
0385
0386
0387 ProductID id() const { return product_.id(); }
0388
0389
0390 EDProductGetter const* productGetter() const { return product_.productGetter(); }
0391
0392
0393 key_type key() const { return product_.index(); }
0394
0395
0396 key_type index() const { return product_.index(); }
0397
0398
0399 bool hasProductCache() const { return product_.productPtr() != nullptr; }
0400
0401
0402
0403
0404
0405 bool isAvailable() const;
0406
0407
0408 bool isTransient() const { return product_.isTransient(); }
0409
0410 RefCore const& refCore() const { return product_.toRefCore(); }
0411
0412
0413 CMS_CLASS_VERSION(11)
0414
0415
0416 Ref(RefCore const& iRefCore, key_type const& iKey) : product_(iRefCore, iKey) {}
0417
0418 private:
0419
0420
0421 void checkTypeAtCompileTime(product_type const*) {}
0422
0423 RefCoreWithIndex product_;
0424 };
0425 }
0426
0427 #include "DataFormats/Common/interface/RefProd.h"
0428 #include "DataFormats/Common/interface/RefCoreGet.h"
0429 #include "DataFormats/Common/interface/RefItemGet.h"
0430
0431 namespace edm {
0432
0433
0434 template <typename C, typename T, typename F>
0435 inline Ref<C, T, F>::Ref(Handle<C> const& handle, key_type itemKey, bool)
0436 : product_(handle.id(), nullptr, nullptr, false), index_(itemKey) {
0437 if (itemKey == key_traits<key_type>::value)
0438 return;
0439 refitem::findRefItem<C, T, F, key_type>(product_, handle.product(), itemKey);
0440 }
0441
0442
0443 template <typename E>
0444 inline Ref<REF_FOR_VECTOR_ARGS>::Ref(Handle<std::vector<E>> const& handle, key_type itemKey, bool)
0445 : product_(handle.id(), nullptr, nullptr, false, itemKey) {
0446 if (itemKey == key_traits<key_type>::value)
0447 return;
0448 refitem::findRefItem<product_type, value_type, finder_type, key_type>(
0449 product_.toRefCore(), handle.product(), itemKey);
0450 }
0451
0452
0453 template <typename C, typename T, typename F>
0454 inline Ref<C, T, F>::Ref(OrphanHandle<C> const& handle, key_type itemKey, bool)
0455 : product_(handle.id(), nullptr, nullptr, false), index_(itemKey) {
0456 if (itemKey == key_traits<key_type>::value)
0457 return;
0458 refitem::findRefItem<C, T, F, key_type>(product_, handle.product(), itemKey);
0459 }
0460
0461
0462 template <typename E>
0463 inline Ref<REF_FOR_VECTOR_ARGS>::Ref(OrphanHandle<std::vector<E>> const& handle, key_type itemKey, bool)
0464 : product_(handle.id(), nullptr, nullptr, false, itemKey) {
0465 if (itemKey == key_traits<key_type>::value)
0466 return;
0467 refitem::findRefItem<product_type, value_type, finder_type, key_type>(
0468 product_.toRefCore(), handle.product(), itemKey);
0469 }
0470
0471
0472
0473
0474
0475
0476
0477
0478 template <typename C, typename T, typename F>
0479 inline Ref<C, T, F>::Ref(C const* iProduct, key_type itemKey, bool)
0480 : product_(ProductID(), nullptr, nullptr, true),
0481 index_(iProduct != nullptr ? itemKey : key_traits<key_type>::value) {
0482 if (iProduct != nullptr) {
0483 refitem::findRefItem<C, T, F, key_type>(product_, iProduct, itemKey);
0484 }
0485 }
0486
0487 template <typename E>
0488 inline Ref<REF_FOR_VECTOR_ARGS>::Ref(std::vector<E> const* iProduct, key_type itemKey, bool)
0489 : product_(ProductID(), nullptr, nullptr, true, iProduct != nullptr ? itemKey : key_traits<key_type>::value) {
0490 if (iProduct != nullptr) {
0491 refitem::findRefItem<product_type, value_type, finder_type, key_type>(product_.toRefCore(), iProduct, itemKey);
0492 }
0493 }
0494
0495
0496
0497 template <typename C, typename T, typename F>
0498 inline Ref<C, T, F>::Ref(TestHandle<C> const& handle, key_type itemKey, bool)
0499 : product_(handle.id(), nullptr, nullptr, true), index_(itemKey) {
0500 if (itemKey == key_traits<key_type>::value)
0501 return;
0502 refitem::findRefItem<C, T, F, key_type>(product_, handle.product(), itemKey);
0503 }
0504
0505 template <typename E>
0506 inline Ref<REF_FOR_VECTOR_ARGS>::Ref(TestHandle<std::vector<E>> const& handle, key_type itemKey, bool)
0507 : product_(handle.id(), nullptr, nullptr, true, itemKey) {
0508 if (itemKey == key_traits<key_type>::value)
0509 return;
0510 refitem::findRefItem<product_type, value_type, finder_type, key_type>(
0511 product_.toRefCore(), handle.product(), itemKey);
0512 }
0513
0514
0515 template <typename C, typename T, typename F>
0516 inline Ref<C, T, F>::Ref(RefProd<C> const& refProd, key_type itemKey)
0517 : product_(refProd.id(), nullptr, refProd.refCore().productGetter(), refProd.refCore().isTransient()),
0518 index_(itemKey) {
0519 if (refProd.refCore().productPtr() != nullptr && itemKey != key_traits<key_type>::value) {
0520 refitem::findRefItem<C, T, F, key_type>(
0521 product_, static_cast<product_type const*>(refProd.refCore().productPtr()), itemKey);
0522 }
0523 }
0524
0525 template <typename E>
0526 inline Ref<REF_FOR_VECTOR_ARGS>::Ref(RefProd<std::vector<E>> const& refProd, key_type itemKey)
0527 : product_(refProd.id(), nullptr, refProd.refCore().productGetter(), refProd.refCore().isTransient(), itemKey) {
0528 if (refProd.refCore().productPtr() != nullptr && itemKey != key_traits<key_type>::value) {
0529 refitem::findRefItem<product_type, value_type, finder_type, key_type>(
0530 product_.toRefCore(), static_cast<product_type const*>(refProd.refCore().productPtr()), itemKey);
0531 }
0532 }
0533
0534 template <typename C, typename T, typename F>
0535 inline bool Ref<C, T, F>::isAvailable() const {
0536 if (product_.isAvailable()) {
0537 return true;
0538 }
0539 return isThinnedAvailable<C>(product_, index_);
0540 }
0541
0542 template <typename E>
0543 inline bool Ref<REF_FOR_VECTOR_ARGS>::isAvailable() const {
0544 if (product_.isAvailable()) {
0545 return true;
0546 }
0547 return isThinnedAvailable<std::vector<E>>(product_.toRefCore(), key());
0548 }
0549
0550
0551 template <typename C, typename T, typename F>
0552 inline T const& Ref<C, T, F>::operator*() const {
0553 return *getRefPtr<C, T, F>(product_, index_);
0554 }
0555 template <typename E>
0556 inline typename refhelper::ValueTrait<std::vector<E>>::value const& Ref<REF_FOR_VECTOR_ARGS>::operator*() const {
0557 return *getRefPtr<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), key());
0558 }
0559
0560
0561 template <typename C, typename T, typename F>
0562 inline T const* Ref<C, T, F>::operator->() const {
0563 return getRefPtr<C, T, F>(product_, index_);
0564 }
0565 template <typename E>
0566 inline typename refhelper::ValueTrait<std::vector<E>>::value const* Ref<REF_FOR_VECTOR_ARGS>::operator->() const {
0567 return getRefPtr<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), key());
0568 }
0569
0570 template <typename C, typename T, typename F>
0571 inline bool operator==(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
0572 return lhs.key() == rhs.key() && lhs.refCore() == rhs.refCore();
0573 }
0574
0575 template <typename C, typename T, typename F>
0576 inline bool operator!=(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
0577 return !(lhs == rhs);
0578 }
0579
0580 template <typename C, typename T, typename F>
0581 inline bool operator<(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
0582
0583
0584 return (lhs.refCore() == rhs.refCore() ? compare_key<C>(lhs.key(), rhs.key()) : lhs.refCore() < rhs.refCore());
0585 }
0586
0587 }
0588
0589
0590 #include "DataFormats/Common/interface/HolderToVectorTrait_Ref_specialization.h"
0591 #endif