File indexing completed on 2023-03-17 10:49:25
0001 #ifndef DataFormats_Common_RefItemGet_h
0002 #define DataFormats_Common_RefItemGet_h
0003
0004
0005
0006
0007
0008
0009
0010 #include "DataFormats/Common/interface/EDProductGetter.h"
0011 #include "DataFormats/Common/interface/RefCore.h"
0012 #include "DataFormats/Common/interface/RefCoreGet.h"
0013
0014 namespace edm {
0015
0016 namespace refitem {
0017
0018 template <typename C, typename T, typename F, typename K>
0019 inline void findRefItem(RefCore const& refCore, C const* container, K const& key) {
0020 F finder;
0021 T const* item = finder(*container, key);
0022 refCore.setProductPtr(item);
0023 }
0024
0025 template <typename C, typename T, typename F, typename KEY>
0026 struct GetRefPtrImpl {
0027 static T const* getRefPtr_(RefCore const& product, KEY const& key) {
0028 T const* item = static_cast<T const*>(product.productPtr());
0029 if (item != nullptr) {
0030 return item;
0031 }
0032 auto prodGetter = product.productGetter();
0033 if (nullptr == prodGetter) {
0034 item = static_cast<T const*>(product.productPtr());
0035 if (item != nullptr) {
0036
0037 return item;
0038 }
0039 }
0040 C const* prod = edm::template getProductWithCoreFromRef<C>(product, prodGetter);
0041
0042
0043
0044
0045
0046 F func;
0047 item = func(*prod, key);
0048 product.setProductPtr(item);
0049 return item;
0050 }
0051 };
0052
0053 template <typename C, typename T, typename F>
0054 struct GetRefPtrImpl<C, T, F, unsigned int> {
0055 static T const* getRefPtr_(RefCore const& product, unsigned int key) {
0056 T const* item = static_cast<T const*>(product.productPtr());
0057 if (item != nullptr) {
0058 return item;
0059 }
0060 auto getter = product.productGetter();
0061 if (getter == nullptr) {
0062 auto prod = product.productPtr();
0063 if (prod != nullptr) {
0064
0065 return static_cast<T const*>(prod);
0066 }
0067 }
0068 C const* prod = edm::template tryToGetProductWithCoreFromRef<C>(product, getter);
0069 if (prod != nullptr) {
0070 F func;
0071 item = func(*prod, key);
0072 product.setProductPtr(item);
0073 return item;
0074 }
0075 unsigned int thinnedKey;
0076 std::tie(prod, thinnedKey) = edm::template getThinnedProduct<C>(product, key, getter);
0077 F func;
0078 item = func(*prod, thinnedKey);
0079 product.setProductPtr(item);
0080 return item;
0081 }
0082 };
0083 }
0084
0085 template <typename C, typename T, typename F, typename KEY>
0086 inline T const* getRefPtr(RefCore const& product, KEY const& iKey) {
0087 return refitem::GetRefPtrImpl<C, T, F, KEY>::getRefPtr_(product, iKey);
0088 }
0089
0090 namespace refitem {
0091 template <typename C, typename KEY>
0092 struct IsThinnedAvailableImpl {
0093 static bool isThinnedAvailable_(RefCore const& product, KEY const& key) { return false; }
0094 };
0095
0096 template <typename C>
0097 struct IsThinnedAvailableImpl<C, unsigned int> {
0098 static bool isThinnedAvailable_(RefCore const& ref, unsigned int key) {
0099 if (ref.productPtr() != nullptr) {
0100 return true;
0101 }
0102 if (ref.isTransient()) {
0103 return false;
0104 }
0105 auto getter = ref.productGetter();
0106 if (getter != nullptr) {
0107 return ref.isThinnedAvailable(key, getter);
0108 }
0109
0110 return nullptr != ref.productPtr();
0111 }
0112 };
0113 }
0114
0115 template <typename C, typename KEY>
0116 inline bool isThinnedAvailable(RefCore const& product, KEY const& iKey) {
0117 return refitem::IsThinnedAvailableImpl<C, KEY>::isThinnedAvailable_(product, iKey);
0118 }
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128 template <typename C, typename T, typename F>
0129 Ref<C, T, F> thinnedRefFrom(Ref<C, T, F> const& parent,
0130 RefProd<C> const& thinned,
0131 edm::EDProductGetter const& prodGetter) {
0132 if (parent.id() == thinned.id()) {
0133 return parent;
0134 }
0135
0136 auto thinnedKey = prodGetter.getThinnedKeyFrom(parent.id(), parent.key(), thinned.id());
0137 if (std::holds_alternative<unsigned int>(thinnedKey)) {
0138 return Ref<C, T, F>(thinned, std::get<unsigned int>(thinnedKey));
0139 } else if (std::holds_alternative<detail::GetThinnedKeyFromExceptionFactory>(thinnedKey)) {
0140 auto ex = std::get<detail::GetThinnedKeyFromExceptionFactory>(thinnedKey)();
0141 ex.addContext("Calling edm::thinnedRefFrom()");
0142 throw ex;
0143 }
0144
0145 return Ref<C, T, F>();
0146 }
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156 template <typename C, typename T, typename F>
0157 Ref<C, T, F> tryThinnedRefFrom(Ref<C, T, F> const& parent,
0158 RefProd<C> const& thinned,
0159 edm::EDProductGetter const& prodGetter) {
0160 if (parent.id() == thinned.id()) {
0161 return parent;
0162 }
0163
0164 auto thinnedKey = prodGetter.getThinnedKeyFrom(parent.id(), parent.key(), thinned.id());
0165 if (std::holds_alternative<unsigned int>(thinnedKey)) {
0166 return Ref<C, T, F>(thinned, std::get<unsigned int>(thinnedKey));
0167 }
0168
0169 return Ref<C, T, F>();
0170 }
0171 }
0172
0173 #endif