CMS 3D CMS Logo

Ref.h
Go to the documentation of this file.
1 #ifndef DataFormats_Common_Ref_h
2 #define DataFormats_Common_Ref_h
3 
4 /*----------------------------------------------------------------------
5 
6 Ref: A template for a interproduct reference to a member of a product_.
7 
8 ----------------------------------------------------------------------*/
72 /*----------------------------------------------------------------------
73 // This defines the public interface to the class Ref<C, T, F>.
74 // C is the collection type.
75 // T (default C::value_type) is the type of an element in the collection.
76 //
77 // ProductID productID is the product ID of the collection.
78 // key_type itemKey is the key of the element in the collection.
79 // C::value_type *itemPtr is a C++ pointer to the element
80 // Ref<C, T, F> const& ref is another Ref<C, T, F>
81 
82 // Constructors
83  Ref(); // Default constructor
84  Ref(Ref<C, T> const& ref); // Copy constructor (default, not explicitly specified)
85 
86  Ref(Handle<C> const& handle, key_type itemKey);
87  Ref(ProductID pid, key_type itemKey, EDProductGetter const* prodGetter);
88 
89 // Destructor
90  virtual ~Ref() {}
91 
92  // Operators and methods
93  Ref<C, T>& operator=(Ref<C, T> const&); // assignment (default, not explicitly specified)
94  T const& operator*() const; // dereference
95  T const* const operator->() const; // member dereference
96  bool operator==(Ref<C, T> const& ref) const; // equality
97  bool operator!=(Ref<C, T> const& ref) const; // inequality
98  bool operator<(Ref<C, T> const& ref) const; // ordering
99  bool isNonnull() const; // true if an object is referenced
100  bool isNull() const; // equivalent to !isNonnull()
101  bool operator!() const; // equivalent to !isNonnull()
102  ----------------------------------------------------------------------*/
103 
114 
115 #include "boost/functional.hpp"
116 
117 #include <vector>
118 #include <type_traits>
119 
121 
122 namespace edm {
123  template <typename C, typename K>
124  bool compare_key(K const& lhs, K const& rhs) {
125  if constexpr (requires { typename C::key_compare; }) {
126  using comparison_functor = typename C::key_compare;
127  return comparison_functor()(lhs, rhs);
128  } else {
129  return lhs < rhs;
130  }
131  }
132 
133  template <typename C, typename T, typename F>
134  class RefVector;
135 
136  template <typename T>
137  class RefToBaseVector;
138 
139  template <typename C,
140  typename T = typename refhelper::ValueTrait<C>::value,
141  typename F = typename refhelper::FindTrait<C, T>::value>
142  class Ref {
143  private:
146  friend class RefVectorIterator<C, T, F>;
147  friend class RefVector<C, T, F>;
148  friend class RefVector<RefVector<C, T, F>, T, VF>;
149  friend class RefVector<RefVector<C, T, F>, T, VBF>;
150 
151  public:
153  typedef C product_type;
154  typedef T value_type;
155  typedef T const element_type; //used for generic programming
156  typedef F finder_type;
157  typedef typename boost::binary_traits<F>::second_argument_type argument_type;
161 
163 
166 
168  Ref(Handle<C> const& handle, key_type itemKey, bool setNow = true);
169 
171  Ref(OrphanHandle<C> const& handle, key_type itemKey, bool setNow = true);
172 
174  // An exception will be thrown if an attempt is made to persistify
175  // any object containing this Ref. Also, in the future work will
176  // be done to throw an exception if an attempt is made to put any object
177  // containing this Ref into an event(or run or lumi).
178  Ref(C const* product, key_type itemKey, bool setNow = true);
179 
181  // An exception will be thrown if an attempt is made to persistify
182  // any object containing this Ref. Also, in the future work will
183  Ref(TestHandle<C> const& handle, key_type itemKey, bool setNow = true);
184 
188  Ref(ProductID const& productID, key_type itemKey, EDProductGetter const* prodGetter)
189  : product_(productID, nullptr, mustBeNonZero(prodGetter, "Ref", productID), false), index_(itemKey) {}
190 
192  // It is an error (not diagnosable at compile- or run-time) to call
193  // this constructor with a pointer to a T unless the pointed-to T
194  // object is already in a collection of type C stored in the
195  // Event. The given ProductID must be the id of the collection in
196  // the Event.
197 
198  Ref(ProductID const& iProductID, T const* item, key_type itemKey, C const* /* iProduct */)
199  : product_(iProductID, item, 0, false), index_(itemKey) {}
200 
201  Ref(ProductID const& iProductID, T const* item, key_type itemKey)
202  : product_(iProductID, item, nullptr, false), index_(itemKey) {}
203 
204  Ref(ProductID const& iProductID, T const* item, key_type itemKey, bool transient)
205  : product_(iProductID, item, nullptr, transient), index_(itemKey) {}
206 
210 
211  explicit Ref(ProductID const& iId) : product_(iId, nullptr, nullptr, false), index_(key_traits<key_type>::value) {}
212 
214  Ref(RefProd<C> const& refProd, key_type itemKey);
215 
217  ~Ref() {}
218 
220  T const& operator*() const;
221 
223  T const* operator->() const;
224 
226  T const* get() const { return isNull() ? nullptr : this->operator->(); }
227 
229  bool isNull() const { return !isNonnull(); }
230 
233 
235  bool operator!() const { return isNull(); }
236 
238  ProductID id() const { return product_.id(); }
239 
242 
244  key_type key() const { return index_; }
245 
246  // This one just for backward compatibility. Will be removed soon.
247  key_type index() const { return index_; }
248 
250  bool hasProductCache() const { return product_.productPtr() != nullptr; }
251 
256  bool isAvailable() const;
257 
259  bool isTransient() const { return product_.isTransient(); }
260 
261  RefCore const& refCore() const { return product_; }
262 
263  //Used by ROOT storage
265  // private:
266  // Constructor from member of RefVector
267  Ref(RefCore const& iRefCore, key_type const& iKey) : product_(iRefCore), index_(iKey) {}
268 
269  private:
270  // Compile time check that the argument is a C* or C const*
271  // or derived from it.
272  void checkTypeAtCompileTime(C const*) {}
273 
276  };
277 
278  //***************************
279  //Specialization for a vector
280  //***************************
281 #define REF_FOR_VECTOR_ARGS \
282  std::vector<E>, typename refhelper::ValueTrait<std::vector<E>>::value, \
283  typename refhelper::FindTrait<std::vector<E>, typename refhelper::ValueTrait<std::vector<E>>::value>::value
284 
285  template <typename E>
287  private:
289  typedef
291 
294  friend class RefVectorIterator<std::vector<E>, T, F>;
295  friend class RefVector<std::vector<E>, T, F>;
296  friend class RefVector<RefVector<std::vector<E>, T, F>, T, VF>;
297  friend class RefVector<RefVector<std::vector<E>, T, F>, T, VBF>;
298 
299  public:
302  typedef typename refhelper::ValueTrait<std::vector<E>>::value value_type;
303  typedef value_type const element_type; //used for generic programming
304  typedef typename refhelper::FindTrait<std::vector<E>, typename refhelper::ValueTrait<std::vector<E>>::value>::value
306  typedef typename boost::binary_traits<F>::second_argument_type argument_type;
307  typedef unsigned int key_type;
310 
312 
314  Ref() : product_() {}
315 
317  Ref(Handle<product_type> const& handle, key_type itemKey, bool setNow = true);
318 
320  Ref(OrphanHandle<product_type> const& handle, key_type itemKey, bool setNow = true);
321 
323  // An exception will be thrown if an attempt is made to persistify
324  // any object containing this Ref. Also, in the future work will
325  // be done to throw an exception if an attempt is made to put any object
326  // containing this Ref into an event(or run or lumi).
327  Ref(product_type const* product, key_type itemKey, bool setNow = true);
328 
330  // An exception will be thrown if an attempt is made to persistify
331  // any object containing this Ref. Also, in the future work will
332  Ref(TestHandle<product_type> const& handle, key_type itemKey, bool setNow = true);
333 
337  Ref(ProductID const& productID, key_type itemKey, EDProductGetter const* prodGetter)
338  : product_(productID, nullptr, mustBeNonZero(prodGetter, "Ref", productID), false, itemKey) {}
339 
341  // It is an error (not diagnosable at compile- or run-time) to call
342  // this constructor with a pointer to a T unless the pointed-to T
343  // object is already in a collection of type C stored in the
344  // Event. The given ProductID must be the id of the collection in
345  // the Event.
346 
347  Ref(ProductID const& iProductID, T const* item, key_type itemKey, product_type const* /* iProduct */)
348  : product_(iProductID, item, nullptr, false, itemKey) {}
349 
350  Ref(ProductID const& iProductID, T const* item, key_type itemKey)
351  : product_(iProductID, item, nullptr, false, itemKey) {}
352 
353  Ref(ProductID const& iProductID, T const* item, key_type itemKey, bool transient)
354  : product_(iProductID, item, nullptr, transient, itemKey) {}
355 
359 
360  explicit Ref(ProductID const& iId) : product_(iId, nullptr, nullptr, false, key_traits<key_type>::value) {}
361 
363  Ref(RefProd<product_type> const& refProd, key_type itemKey);
364 
366  ~Ref() {}
367 
369  T const& operator*() const;
370 
372  T const* operator->() const;
373 
375  T const* get() const { return isNull() ? nullptr : this->operator->(); }
376 
378  bool isNull() const { return !isNonnull(); }
379 
381  bool isNonnull() const { return key() != edm::key_traits<key_type>::value; }
382 
384  bool operator!() const { return isNull(); }
385 
387  ProductID id() const { return product_.id(); }
388 
391 
393  key_type key() const { return product_.index(); }
394 
395  // This one just for backward compatibility. Will be removed soon.
396  key_type index() const { return product_.index(); }
397 
399  bool hasProductCache() const { return product_.productPtr() != nullptr; }
400 
405  bool isAvailable() const;
406 
408  bool isTransient() const { return product_.isTransient(); }
409 
410  RefCore const& refCore() const { return product_.toRefCore(); }
411 
412  //Used by ROOT storage
414  // private:
415  // Constructor from member of RefVector
416  Ref(RefCore const& iRefCore, key_type const& iKey) : product_(iRefCore, iKey) {}
417 
418  private:
419  // Compile time check that the argument is a C* or C const*
420  // or derived from it.
422 
424  };
425 } // namespace edm
426 
430 
431 namespace edm {
432 
434  template <typename C, typename T, typename F>
435  inline Ref<C, T, F>::Ref(Handle<C> const& handle, key_type itemKey, bool)
436  : product_(handle.id(), nullptr, nullptr, false), index_(itemKey) {
437  if (itemKey == key_traits<key_type>::value)
438  return;
439  refitem::findRefItem<C, T, F, key_type>(product_, handle.product(), itemKey);
440  }
441 
443  template <typename E>
444  inline Ref<REF_FOR_VECTOR_ARGS>::Ref(Handle<std::vector<E>> const& handle, key_type itemKey, bool)
445  : product_(handle.id(), nullptr, nullptr, false, itemKey) {
446  if (itemKey == key_traits<key_type>::value)
447  return;
448  refitem::findRefItem<product_type, value_type, finder_type, key_type>(
449  product_.toRefCore(), handle.product(), itemKey);
450  }
451 
453  template <typename C, typename T, typename F>
454  inline Ref<C, T, F>::Ref(OrphanHandle<C> const& handle, key_type itemKey, bool)
455  : product_(handle.id(), nullptr, nullptr, false), index_(itemKey) {
456  if (itemKey == key_traits<key_type>::value)
457  return;
458  refitem::findRefItem<C, T, F, key_type>(product_, handle.product(), itemKey);
459  }
460 
462  template <typename E>
463  inline Ref<REF_FOR_VECTOR_ARGS>::Ref(OrphanHandle<std::vector<E>> const& handle, key_type itemKey, bool)
464  : product_(handle.id(), nullptr, nullptr, false, itemKey) {
465  if (itemKey == key_traits<key_type>::value)
466  return;
467  refitem::findRefItem<product_type, value_type, finder_type, key_type>(
468  product_.toRefCore(), handle.product(), itemKey);
469  }
470 
472  // An exception will be thrown if an attempt is made to persistify
473  // any object containing this Ref. Also, in the future work will
474  // be done to throw an exception if an attempt is made to put any object
475  // containing this Ref into an event(or run or lumi).
476  // Note: It is legal for the referenced object to be put into the event
477  // and persistified. It is this Ref itself that cannot be persistified.
478  template <typename C, typename T, typename F>
479  inline Ref<C, T, F>::Ref(C const* iProduct, key_type itemKey, bool)
480  : product_(ProductID(), nullptr, nullptr, true),
481  index_(iProduct != nullptr ? itemKey : key_traits<key_type>::value) {
482  if (iProduct != nullptr) {
483  refitem::findRefItem<C, T, F, key_type>(product_, iProduct, itemKey);
484  }
485  }
486 
487  template <typename E>
488  inline Ref<REF_FOR_VECTOR_ARGS>::Ref(std::vector<E> const* iProduct, key_type itemKey, bool)
489  : product_(ProductID(), nullptr, nullptr, true, iProduct != nullptr ? itemKey : key_traits<key_type>::value) {
490  if (iProduct != nullptr) {
491  refitem::findRefItem<product_type, value_type, finder_type, key_type>(product_.toRefCore(), iProduct, itemKey);
492  }
493  }
494 
496  // An exception will be thrown if an attempt is made to persistify any object containing this Ref.
497  template <typename C, typename T, typename F>
498  inline Ref<C, T, F>::Ref(TestHandle<C> const& handle, key_type itemKey, bool)
499  : product_(handle.id(), nullptr, nullptr, true), index_(itemKey) {
500  if (itemKey == key_traits<key_type>::value)
501  return;
502  refitem::findRefItem<C, T, F, key_type>(product_, handle.product(), itemKey);
503  }
504 
505  template <typename E>
506  inline Ref<REF_FOR_VECTOR_ARGS>::Ref(TestHandle<std::vector<E>> const& handle, key_type itemKey, bool)
507  : product_(handle.id(), nullptr, nullptr, true, itemKey) {
508  if (itemKey == key_traits<key_type>::value)
509  return;
510  refitem::findRefItem<product_type, value_type, finder_type, key_type>(
511  product_.toRefCore(), handle.product(), itemKey);
512  }
513 
515  template <typename C, typename T, typename F>
516  inline Ref<C, T, F>::Ref(RefProd<C> const& refProd, key_type itemKey)
517  : product_(refProd.id(), nullptr, refProd.refCore().productGetter(), refProd.refCore().isTransient()),
518  index_(itemKey) {
519  if (refProd.refCore().productPtr() != nullptr && itemKey != key_traits<key_type>::value) {
520  refitem::findRefItem<C, T, F, key_type>(
521  product_, static_cast<product_type const*>(refProd.refCore().productPtr()), itemKey);
522  }
523  }
524 
525  template <typename E>
526  inline Ref<REF_FOR_VECTOR_ARGS>::Ref(RefProd<std::vector<E>> const& refProd, key_type itemKey)
527  : product_(refProd.id(), nullptr, refProd.refCore().productGetter(), refProd.refCore().isTransient(), itemKey) {
528  if (refProd.refCore().productPtr() != nullptr && itemKey != key_traits<key_type>::value) {
529  refitem::findRefItem<product_type, value_type, finder_type, key_type>(
530  product_.toRefCore(), static_cast<product_type const*>(refProd.refCore().productPtr()), itemKey);
531  }
532  }
533 
534  template <typename C, typename T, typename F>
535  inline bool Ref<C, T, F>::isAvailable() const {
536  if (product_.isAvailable()) {
537  return true;
538  }
539  return isThinnedAvailable<C>(product_, index_);
540  }
541 
542  template <typename E>
544  if (product_.isAvailable()) {
545  return true;
546  }
547  return isThinnedAvailable<std::vector<E>>(product_.toRefCore(), key());
548  }
549 
551  template <typename C, typename T, typename F>
552  inline T const& Ref<C, T, F>::operator*() const {
553  return *getRefPtr<C, T, F>(product_, index_);
554  }
555  template <typename E>
557  return *getRefPtr<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), key());
558  }
559 
561  template <typename C, typename T, typename F>
562  inline T const* Ref<C, T, F>::operator->() const {
563  return getRefPtr<C, T, F>(product_, index_);
564  }
565  template <typename E>
567  return getRefPtr<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), key());
568  }
569 
570  template <typename C, typename T, typename F>
571  inline bool operator==(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
572  return lhs.key() == rhs.key() && lhs.refCore() == rhs.refCore();
573  }
574 
575  template <typename C, typename T, typename F>
576  inline bool operator!=(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
577  return !(lhs == rhs);
578  }
579 
580  template <typename C, typename T, typename F>
581  inline bool operator<(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
584  return (lhs.refCore() == rhs.refCore() ? compare_key<C>(lhs.key(), rhs.key()) : lhs.refCore() < rhs.refCore());
585  }
586 
587 } // namespace edm
588 
589 //Handle specialization here
591 #endif
bool hasProductCache() const
Returns true if container referenced by the Ref has been cached.
Definition: Ref.h:250
RefCore const & refCore() const
Definition: Ref.h:261
std::remove_cv< typename std::remove_reference< argument_type >::type >::type key_type
Definition: Ref.h:158
ProductID id() const
Accessor for product ID.
Definition: Ref.h:238
void checkTypeAtCompileTime(C const *)
Definition: Ref.h:272
bool operator!=(Ref< C, T, F > const &lhs, Ref< C, T, F > const &rhs)
Definition: Ref.h:576
requires requires
Definition: RefToBase.h:238
T const & operator*() const
Dereference operator.
Definition: Ref.h:552
Ref(ProductID const &iProductID, T const *item, key_type itemKey, product_type const *)
Constructor for use in the various X::fillView(...) functions.
Definition: Ref.h:347
bool operator==(Ref< C, T, F > const &lhs, Ref< C, T, F > const &rhs)
Definition: Ref.h:571
boost::binary_traits< F >::second_argument_type argument_type
Definition: Ref.h:157
~Ref()
Destructor.
Definition: Ref.h:217
key_type index_
Definition: Ref.h:275
ProductID id() const
Definition: RefCore.h:48
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:232
T const * operator->() const
Member dereference operator.
Definition: Ref.h:562
RefCore product_
Definition: Ref.h:274
EDProductGetter const * mustBeNonZero(EDProductGetter const *prodGetter, std::string refType, ProductID const &productID)
#define REF_FOR_VECTOR_ARGS
Definition: Ref.h:281
#define CMS_CLASS_VERSION(_version_)
void const * productPtr() const
Definition: RefCore.h:51
EDProductGetter const * productGetter() const
Accessor for product getter.
Definition: Ref.h:241
key_type key() const
Accessor for product key.
Definition: Ref.h:244
Definition: VBF.py:1
RefCore const & refCore() const
Definition: RefProd.h:112
bool isTransient() const
Checks if this ref is transient (i.e. not persistable).
Definition: Ref.h:259
bool operator!() const
Checks for null.
Definition: Ref.h:235
bool compare_key(K const &lhs, K const &rhs)
Definition: Ref.h:124
Ref(ProductID const &productID, key_type itemKey, EDProductGetter const *prodGetter)
Definition: Ref.h:188
bool isAvailable() const
Definition: Ref.h:535
bool isTransient() const
Definition: RefCore.h:105
static key_type invalidKey()
Definition: Ref.h:162
Ref(ProductID const &iProductID, T const *item, key_type itemKey)
Definition: Ref.h:201
key
prepare the HTCondor submission files and eventually submit them
Definition: value.py:1
T const element_type
Definition: Ref.h:155
refhelper::FindRefVectorUsingAdvance< RefToBaseVector< T > > VBF
Definition: Ref.h:145
bool isNull() const
Checks for null.
Definition: Ref.h:229
refhelper::FindRefVectorUsingAdvance< RefVector< C, T, F > > VF
Definition: Ref.h:144
T value_type
Definition: Ref.h:154
key_type index() const
Definition: Ref.h:247
F finder_type
Definition: Ref.h:156
Ref(ProductID const &iProductID, T const *item, key_type itemKey, bool transient)
Definition: Ref.h:204
C product_type
for export
Definition: Ref.h:153
Ref(ProductID const &iId)
Definition: Ref.h:211
Ref()
Default constructor needed for reading from persistent store. Not for direct use. ...
Definition: Ref.h:165
HLT enums.
EDProductGetter const * productGetter(std::atomic< void const *> const &iCache)
MatrixMeschach operator*(const MatrixMeschach &mat1, const MatrixMeschach &mat2)
FindUsingAdvance< C, T > value
Definition: RefTraits.h:42
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:163
Ref(ProductID const &iProductID, T const *item, key_type itemKey, C const *)
Constructor for use in the various X::fillView(...) functions.
Definition: Ref.h:198
EDProductGetter const * productGetter() const
Definition: RefCore.h:81
long double T
edm::RefVector< Container > RefVector