CMS 3D CMS Logo

RefItemGet.h
Go to the documentation of this file.
1 #ifndef DataFormats_Common_RefItemGet_h
2 #define DataFormats_Common_RefItemGet_h
3 
4 /*----------------------------------------------------------------------
5 
6 RefItemGet: Free function to get pointer to a referenced item.
7 
8 
9 ----------------------------------------------------------------------*/
13 
14 namespace edm {
15 
16  namespace refitem {
17 
18  template <typename C, typename T, typename F, typename K>
19  inline void findRefItem(RefCore const& refCore, C const* container, K const& key) {
20  F finder;
21  T const* item = finder(*container, key);
22  refCore.setProductPtr(item);
23  }
24 
25  template <typename C, typename T, typename F, typename KEY>
26  struct GetRefPtrImpl {
27  static T const* getRefPtr_(RefCore const& product, KEY const& key) {
28  T const* item = static_cast<T const*>(product.productPtr());
29  if (item != nullptr) {
30  return item;
31  }
32  auto prodGetter = product.productGetter();
33  if (nullptr == prodGetter) {
34  item = static_cast<T const*>(product.productPtr());
35  if (item != nullptr) {
36  //Another thread updated the value since we checked
37  return item;
38  }
39  }
40  C const* prod = edm::template getProductWithCoreFromRef<C>(product, prodGetter);
41  /*
42  typename C::const_iterator it = prod->begin();
43  std::advance(it, item.key());
44  T const* p = it.operator->();
45  */
46  F func;
47  item = func(*prod, key);
48  product.setProductPtr(item);
49  return item;
50  }
51  };
52 
53  template <typename C, typename T, typename F>
54  struct GetRefPtrImpl<C, T, F, unsigned int> {
55  static T const* getRefPtr_(RefCore const& product, unsigned int key) {
56  T const* item = static_cast<T const*>(product.productPtr());
57  if (item != nullptr) {
58  return item;
59  }
60  auto getter = product.productGetter();
61  if (getter == nullptr) {
62  auto prod = product.productPtr();
63  if (prod != nullptr) {
64  //another thread updated the value since we last checked.
65  return static_cast<T const*>(prod);
66  }
67  }
68  C const* prod = edm::template tryToGetProductWithCoreFromRef<C>(product, getter);
69  if (prod != nullptr) {
70  F func;
71  item = func(*prod, key);
72  product.setProductPtr(item);
73  return item;
74  }
75  unsigned int thinnedKey;
76  std::tie(prod, thinnedKey) = edm::template getThinnedProduct<C>(product, key, getter);
77  F func;
78  item = func(*prod, thinnedKey);
79  product.setProductPtr(item);
80  return item;
81  }
82  };
83  } // namespace refitem
84 
85  template <typename C, typename T, typename F, typename KEY>
86  inline T const* getRefPtr(RefCore const& product, KEY const& iKey) {
88  }
89 
90  namespace refitem {
91  template <typename C, typename KEY>
93  static bool isThinnedAvailable_(RefCore const& product, KEY const& key) { return false; }
94  };
95 
96  template <typename C>
97  struct IsThinnedAvailableImpl<C, unsigned int> {
98  static bool isThinnedAvailable_(RefCore const& ref, unsigned int key) {
99  if (ref.productPtr() != nullptr) {
100  return true;
101  }
102  if (ref.isTransient()) {
103  return false;
104  }
105  auto getter = ref.productGetter();
106  if (getter != nullptr) {
107  return ref.isThinnedAvailable(key, getter);
108  }
109  //another thread may have updated the cache
110  return nullptr != ref.productPtr();
111  }
112  };
113  } // namespace refitem
114 
115  template <typename C, typename KEY>
116  inline bool isThinnedAvailable(RefCore const& product, KEY const& iKey) {
118  }
119 
121  //
122  // The thinned may point to parent collection, in which case the Ref-to-parent is returned
123  //
124  // If thinned does not contain the element of the Ref-to-parent, a Null Ref is returned.
125  //
126  // If parent collection is not thinned, or there is no thinning relation between parent and thinned,
127  // an exception is thrown
128  template <typename C, typename T, typename F>
130  RefProd<C> const& thinned,
131  edm::EDProductGetter const& prodGetter) {
132  if (parent.id() == thinned.id()) {
133  return parent;
134  }
135 
136  auto thinnedKey = prodGetter.getThinnedKeyFrom(parent.id(), parent.key(), thinned.id());
137  if (std::holds_alternative<unsigned int>(thinnedKey)) {
138  return Ref<C, T, F>(thinned, std::get<unsigned int>(thinnedKey));
139  } else if (std::holds_alternative<detail::GetThinnedKeyFromExceptionFactory>(thinnedKey)) {
140  auto ex = std::get<detail::GetThinnedKeyFromExceptionFactory>(thinnedKey)();
141  ex.addContext("Calling edm::thinnedRefFrom()");
142  throw ex;
143  }
144 
145  return Ref<C, T, F>();
146  }
147 
149  //
150  // The thinned may point to parent collection, in which case the Ref-to-parent is returned
151  //
152  // If thinned does not contain the element of the Ref-to-parent, a Null Ref is returned.
153  //
154  // If parent collection is not thinned, or there is no thinning relation between parent and thinned,
155  // a Null Ref is returned
156  template <typename C, typename T, typename F>
158  RefProd<C> const& thinned,
159  edm::EDProductGetter const& prodGetter) {
160  if (parent.id() == thinned.id()) {
161  return parent;
162  }
163 
164  auto thinnedKey = prodGetter.getThinnedKeyFrom(parent.id(), parent.key(), thinned.id());
165  if (std::holds_alternative<unsigned int>(thinnedKey)) {
166  return Ref<C, T, F>(thinned, std::get<unsigned int>(thinnedKey));
167  }
168 
169  return Ref<C, T, F>();
170  }
171 } // namespace edm
172 
173 #endif
bool isThinnedAvailable(RefCore const &product, KEY const &iKey)
Definition: RefItemGet.h:116
T const * getRefPtr(RefCore const &product, KEY const &iKey)
Definition: RefItemGet.h:86
static bool isThinnedAvailable_(RefCore const &product, KEY const &key)
Definition: RefItemGet.h:93
void const * productPtr() const
Definition: RefCore.h:51
static T const * getRefPtr_(RefCore const &product, unsigned int key)
Definition: RefItemGet.h:55
void findRefItem(RefCore const &refCore, C const *container, K const &key)
Definition: RefItemGet.h:19
bool isThinnedAvailable(unsigned int key, EDProductGetter const *prodGetter) const
Definition: RefCore.cc:115
void setProductPtr(void const *prodPtr) const
Definition: RefCore.h:57
bool isTransient() const
Definition: RefCore.h:105
key
prepare the HTCondor submission files and eventually submit them
def template(fileName, svg, replaceme="REPLACEME")
Definition: svgfig.py:521
Ref< C, T, F > thinnedRefFrom(Ref< C, T, F > const &parent, RefProd< C > const &thinned, edm::EDProductGetter const &prodGetter)
Return a Ref to thinned collection corresponding to an element of the Ref to parent collection...
Definition: RefItemGet.h:129
ProductID id() const
Accessor for product ID.
Definition: RefProd.h:124
static T const * getRefPtr_(RefCore const &product, KEY const &key)
Definition: RefItemGet.h:27
Ref< C, T, F > tryThinnedRefFrom(Ref< C, T, F > const &parent, RefProd< C > const &thinned, edm::EDProductGetter const &prodGetter)
Return a Ref to thinned collection corresponding to an element of the Ref to parent collection...
Definition: RefItemGet.h:157
HLT enums.
virtual OptionalThinnedKey getThinnedKeyFrom(ProductID const &parent, unsigned int key, ProductID const &thinned) const =0
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:163
EDProductGetter const * productGetter() const
Definition: RefCore.h:81
static bool isThinnedAvailable_(RefCore const &ref, unsigned int key)
Definition: RefItemGet.h:98
long double T