File indexing completed on 2021-06-11 04:36:58
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 bool isAvailable() const;
0261
0262
0263 bool isTransient() const { return product_.isTransient(); }
0264
0265 RefCore const& refCore() const { return product_; }
0266
0267
0268 CMS_CLASS_VERSION(10)
0269
0270
0271 Ref(RefCore const& iRefCore, key_type const& iKey) : product_(iRefCore), index_(iKey) {}
0272
0273 private:
0274
0275
0276 void checkTypeAtCompileTime(C const*) {}
0277
0278 RefCore product_;
0279 key_type index_;
0280 };
0281
0282
0283
0284
0285 #define REF_FOR_VECTOR_ARGS \
0286 std::vector<E>, typename refhelper::ValueTrait<std::vector<E>>::value, \
0287 typename refhelper::FindTrait<std::vector<E>, typename refhelper::ValueTrait<std::vector<E>>::value>::value
0288
0289 template <typename E>
0290 class Ref<REF_FOR_VECTOR_ARGS> {
0291 private:
0292 typedef typename refhelper::ValueTrait<std::vector<E>>::value T;
0293 typedef
0294 typename refhelper::FindTrait<std::vector<E>, typename refhelper::ValueTrait<std::vector<E>>::value>::value F;
0295
0296 typedef refhelper::FindRefVectorUsingAdvance<RefVector<std::vector<E>, T, F>> VF;
0297 typedef refhelper::FindRefVectorUsingAdvance<RefToBaseVector<T>> VBF;
0298 friend class RefVectorIterator<std::vector<E>, T, F>;
0299 friend class RefVector<std::vector<E>, T, F>;
0300 friend class RefVector<RefVector<std::vector<E>, T, F>, T, VF>;
0301 friend class RefVector<RefVector<std::vector<E>, T, F>, T, VBF>;
0302
0303 public:
0304
0305 typedef std::vector<E> product_type;
0306 typedef typename refhelper::ValueTrait<std::vector<E>>::value value_type;
0307 typedef value_type const element_type;
0308 typedef typename refhelper::FindTrait<std::vector<E>, typename refhelper::ValueTrait<std::vector<E>>::value>::value
0309 finder_type;
0310 typedef typename boost::binary_traits<F>::second_argument_type argument_type;
0311 typedef unsigned int key_type;
0312
0313
0314
0315 static key_type invalidKey() { return key_traits<key_type>::value; }
0316
0317
0318 Ref() : product_() {}
0319
0320
0321 Ref(Handle<product_type> const& handle, key_type itemKey, bool setNow = true);
0322
0323
0324 Ref(OrphanHandle<product_type> const& handle, key_type itemKey, bool setNow = true);
0325
0326
0327
0328
0329
0330
0331 Ref(product_type const* product, key_type itemKey, bool setNow = true);
0332
0333
0334
0335
0336 Ref(TestHandle<product_type> const& handle, key_type itemKey, bool setNow = true);
0337
0338
0339
0340
0341 Ref(ProductID const& productID, key_type itemKey, EDProductGetter const* prodGetter)
0342 : product_(productID, nullptr, mustBeNonZero(prodGetter, "Ref", productID), false, itemKey) {}
0343
0344
0345
0346
0347
0348
0349
0350
0351 Ref(ProductID const& iProductID, T const* item, key_type itemKey, product_type const* )
0352 : product_(iProductID, item, nullptr, false, itemKey) {}
0353
0354 Ref(ProductID const& iProductID, T const* item, key_type itemKey)
0355 : product_(iProductID, item, nullptr, false, itemKey) {}
0356
0357 Ref(ProductID const& iProductID, T const* item, key_type itemKey, bool transient)
0358 : product_(iProductID, item, nullptr, transient, itemKey) {}
0359
0360
0361
0362
0363
0364 explicit Ref(ProductID const& iId) : product_(iId, nullptr, nullptr, false, key_traits<key_type>::value) {}
0365
0366
0367 Ref(RefProd<product_type> const& refProd, key_type itemKey);
0368
0369
0370 ~Ref() {}
0371
0372
0373 T const& operator*() const;
0374
0375
0376 T const* operator->() const;
0377
0378
0379 T const* get() const { return isNull() ? nullptr : this->operator->(); }
0380
0381
0382 bool isNull() const { return !isNonnull(); }
0383
0384
0385 bool isNonnull() const { return key() != edm::key_traits<key_type>::value; }
0386
0387
0388 bool operator!() const { return isNull(); }
0389
0390
0391 ProductID id() const { return product_.id(); }
0392
0393
0394 EDProductGetter const* productGetter() const { return product_.productGetter(); }
0395
0396
0397 key_type key() const { return product_.index(); }
0398
0399
0400 key_type index() const { return product_.index(); }
0401
0402
0403 bool hasProductCache() const { return product_.productPtr() != nullptr; }
0404
0405
0406
0407 bool isAvailable() const;
0408
0409
0410 bool isTransient() const { return product_.isTransient(); }
0411
0412 RefCore const& refCore() const { return product_.toRefCore(); }
0413
0414
0415 CMS_CLASS_VERSION(11)
0416
0417
0418 Ref(RefCore const& iRefCore, key_type const& iKey) : product_(iRefCore, iKey) {}
0419
0420 private:
0421
0422
0423 void checkTypeAtCompileTime(product_type const*) {}
0424
0425 RefCoreWithIndex product_;
0426 };
0427 }
0428
0429 #include "DataFormats/Common/interface/RefProd.h"
0430 #include "DataFormats/Common/interface/RefCoreGet.h"
0431 #include "DataFormats/Common/interface/RefItemGet.h"
0432
0433 namespace edm {
0434
0435
0436 template <typename C, typename T, typename F>
0437 inline Ref<C, T, F>::Ref(Handle<C> const& handle, key_type itemKey, bool)
0438 : product_(handle.id(), nullptr, nullptr, false), index_(itemKey) {
0439 if (itemKey == key_traits<key_type>::value)
0440 return;
0441 refitem::findRefItem<C, T, F, key_type>(product_, handle.product(), itemKey);
0442 }
0443
0444
0445 template <typename E>
0446 inline Ref<REF_FOR_VECTOR_ARGS>::Ref(Handle<std::vector<E>> const& handle, key_type itemKey, bool)
0447 : product_(handle.id(), nullptr, nullptr, false, itemKey) {
0448 if (itemKey == key_traits<key_type>::value)
0449 return;
0450 refitem::findRefItem<product_type, value_type, finder_type, key_type>(
0451 product_.toRefCore(), handle.product(), itemKey);
0452 }
0453
0454
0455 template <typename C, typename T, typename F>
0456 inline Ref<C, T, F>::Ref(OrphanHandle<C> const& handle, key_type itemKey, bool)
0457 : product_(handle.id(), nullptr, nullptr, false), index_(itemKey) {
0458 if (itemKey == key_traits<key_type>::value)
0459 return;
0460 refitem::findRefItem<C, T, F, key_type>(product_, handle.product(), itemKey);
0461 }
0462
0463
0464 template <typename E>
0465 inline Ref<REF_FOR_VECTOR_ARGS>::Ref(OrphanHandle<std::vector<E>> const& handle, key_type itemKey, bool)
0466 : product_(handle.id(), nullptr, nullptr, false, itemKey) {
0467 if (itemKey == key_traits<key_type>::value)
0468 return;
0469 refitem::findRefItem<product_type, value_type, finder_type, key_type>(
0470 product_.toRefCore(), handle.product(), itemKey);
0471 }
0472
0473
0474
0475
0476
0477
0478
0479
0480 template <typename C, typename T, typename F>
0481 inline Ref<C, T, F>::Ref(C const* iProduct, key_type itemKey, bool)
0482 : product_(ProductID(), nullptr, nullptr, true),
0483 index_(iProduct != nullptr ? itemKey : key_traits<key_type>::value) {
0484 if (iProduct != nullptr) {
0485 refitem::findRefItem<C, T, F, key_type>(product_, iProduct, itemKey);
0486 }
0487 }
0488
0489 template <typename E>
0490 inline Ref<REF_FOR_VECTOR_ARGS>::Ref(std::vector<E> const* iProduct, key_type itemKey, bool)
0491 : product_(ProductID(), nullptr, nullptr, true, iProduct != nullptr ? itemKey : key_traits<key_type>::value) {
0492 if (iProduct != nullptr) {
0493 refitem::findRefItem<product_type, value_type, finder_type, key_type>(product_.toRefCore(), iProduct, itemKey);
0494 }
0495 }
0496
0497
0498
0499 template <typename C, typename T, typename F>
0500 inline Ref<C, T, F>::Ref(TestHandle<C> const& handle, key_type itemKey, bool)
0501 : product_(handle.id(), nullptr, nullptr, true), index_(itemKey) {
0502 if (itemKey == key_traits<key_type>::value)
0503 return;
0504 refitem::findRefItem<C, T, F, key_type>(product_, handle.product(), itemKey);
0505 }
0506
0507 template <typename E>
0508 inline Ref<REF_FOR_VECTOR_ARGS>::Ref(TestHandle<std::vector<E>> const& handle, key_type itemKey, bool)
0509 : product_(handle.id(), nullptr, nullptr, true, itemKey) {
0510 if (itemKey == key_traits<key_type>::value)
0511 return;
0512 refitem::findRefItem<product_type, value_type, finder_type, key_type>(
0513 product_.toRefCore(), handle.product(), itemKey);
0514 }
0515
0516
0517 template <typename C, typename T, typename F>
0518 inline Ref<C, T, F>::Ref(RefProd<C> const& refProd, key_type itemKey)
0519 : product_(refProd.id(), nullptr, refProd.refCore().productGetter(), refProd.refCore().isTransient()),
0520 index_(itemKey) {
0521 if (refProd.refCore().productPtr() != nullptr && itemKey != key_traits<key_type>::value) {
0522 refitem::findRefItem<C, T, F, key_type>(
0523 product_, static_cast<product_type const*>(refProd.refCore().productPtr()), itemKey);
0524 }
0525 }
0526
0527 template <typename E>
0528 inline Ref<REF_FOR_VECTOR_ARGS>::Ref(RefProd<std::vector<E>> const& refProd, key_type itemKey)
0529 : product_(refProd.id(), nullptr, refProd.refCore().productGetter(), refProd.refCore().isTransient(), itemKey) {
0530 if (refProd.refCore().productPtr() != nullptr && itemKey != key_traits<key_type>::value) {
0531 refitem::findRefItem<product_type, value_type, finder_type, key_type>(
0532 product_.toRefCore(), static_cast<product_type const*>(refProd.refCore().productPtr()), itemKey);
0533 }
0534 }
0535
0536 template <typename C, typename T, typename F>
0537 inline bool Ref<C, T, F>::isAvailable() const {
0538 if (product_.isAvailable()) {
0539 return true;
0540 }
0541 return isThinnedAvailable<C>(product_, index_);
0542 }
0543
0544 template <typename E>
0545 inline bool Ref<REF_FOR_VECTOR_ARGS>::isAvailable() const {
0546 if (product_.isAvailable()) {
0547 return true;
0548 }
0549 return isThinnedAvailable<std::vector<E>>(product_.toRefCore(), key());
0550 }
0551
0552
0553 template <typename C, typename T, typename F>
0554 inline T const& Ref<C, T, F>::operator*() const {
0555 return *getRefPtr<C, T, F>(product_, index_);
0556 }
0557 template <typename E>
0558 inline typename refhelper::ValueTrait<std::vector<E>>::value const& Ref<REF_FOR_VECTOR_ARGS>::operator*() const {
0559 return *getRefPtr<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), key());
0560 }
0561
0562
0563 template <typename C, typename T, typename F>
0564 inline T const* Ref<C, T, F>::operator->() const {
0565 return getRefPtr<C, T, F>(product_, index_);
0566 }
0567 template <typename E>
0568 inline typename refhelper::ValueTrait<std::vector<E>>::value const* Ref<REF_FOR_VECTOR_ARGS>::operator->() const {
0569 return getRefPtr<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), key());
0570 }
0571
0572 template <typename C, typename T, typename F>
0573 inline bool operator==(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
0574 return lhs.key() == rhs.key() && lhs.refCore() == rhs.refCore();
0575 }
0576
0577 template <typename C, typename T, typename F>
0578 inline bool operator!=(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
0579 return !(lhs == rhs);
0580 }
0581
0582 template <typename C, typename T, typename F>
0583 inline bool operator<(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
0584
0585
0586 return (lhs.refCore() == rhs.refCore() ? compare_key<C>(lhs.key(), rhs.key()) : lhs.refCore() < rhs.refCore());
0587 }
0588
0589 }
0590
0591
0592 #include "DataFormats/Common/interface/HolderToVectorTrait_Ref_specialization.h"
0593 #endif