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  //Use SFINAE to test for embedded type with name key_compare
124  template <typename, typename = void>
125  struct has_key_compare : std::false_type {};
126  template <typename T>
127  struct has_key_compare<T, std::void_t<typename T::key_compare>> : std::true_type {};
128 
129  template <typename C, typename K>
130  bool compare_key(K const& lhs, K const& rhs) {
131  if constexpr (has_key_compare<C>::value) {
132  using comparison_functor = typename C::key_compare;
133  return comparison_functor()(lhs, rhs);
134  } else {
135  return lhs < rhs;
136  }
137  }
138 
139  template <typename C, typename T, typename F>
140  class RefVector;
141 
142  template <typename T>
143  class RefToBaseVector;
144 
145  template <typename C,
146  typename T = typename refhelper::ValueTrait<C>::value,
147  typename F = typename refhelper::FindTrait<C, T>::value>
148  class Ref {
149  private:
152  friend class RefVectorIterator<C, T, F>;
153  friend class RefVector<C, T, F>;
154  friend class RefVector<RefVector<C, T, F>, T, VF>;
155  friend class RefVector<RefVector<C, T, F>, T, VBF>;
156 
157  public:
159  typedef C product_type;
160  typedef T value_type;
161  typedef T const element_type; //used for generic programming
162  typedef F finder_type;
163  typedef typename boost::binary_traits<F>::second_argument_type argument_type;
167 
169 
172 
174  Ref(Handle<C> const& handle, key_type itemKey, bool setNow = true);
175 
177  Ref(OrphanHandle<C> const& handle, key_type itemKey, bool setNow = true);
178 
180  // An exception will be thrown if an attempt is made to persistify
181  // any object containing this Ref. Also, in the future work will
182  // be done to throw an exception if an attempt is made to put any object
183  // containing this Ref into an event(or run or lumi).
184  Ref(C const* product, key_type itemKey, bool setNow = true);
185 
187  // An exception will be thrown if an attempt is made to persistify
188  // any object containing this Ref. Also, in the future work will
189  Ref(TestHandle<C> const& handle, key_type itemKey, bool setNow = true);
190 
194  Ref(ProductID const& productID, key_type itemKey, EDProductGetter const* prodGetter)
195  : product_(productID, nullptr, mustBeNonZero(prodGetter, "Ref", productID), false), index_(itemKey) {}
196 
198  // It is an error (not diagnosable at compile- or run-time) to call
199  // this constructor with a pointer to a T unless the pointed-to T
200  // object is already in a collection of type C stored in the
201  // Event. The given ProductID must be the id of the collection in
202  // the Event.
203 
204  Ref(ProductID const& iProductID, T const* item, key_type itemKey, C const* /* iProduct */)
205  : product_(iProductID, item, 0, false), index_(itemKey) {}
206 
207  Ref(ProductID const& iProductID, T const* item, key_type itemKey)
208  : product_(iProductID, item, nullptr, false), index_(itemKey) {}
209 
210  Ref(ProductID const& iProductID, T const* item, key_type itemKey, bool transient)
211  : product_(iProductID, item, nullptr, transient), index_(itemKey) {}
212 
216 
217  explicit Ref(ProductID const& iId) : product_(iId, nullptr, nullptr, false), index_(key_traits<key_type>::value) {}
218 
220  Ref(RefProd<C> const& refProd, key_type itemKey);
221 
223  ~Ref() {}
224 
226  T const& operator*() const;
227 
229  T const* operator->() const;
230 
232  T const* get() const { return isNull() ? nullptr : this->operator->(); }
233 
235  bool isNull() const { return !isNonnull(); }
236 
239 
241  bool operator!() const { return isNull(); }
242 
244  ProductID id() const { return product_.id(); }
245 
248 
250  key_type key() const { return index_; }
251 
252  // This one just for backward compatibility. Will be removed soon.
253  key_type index() const { return index_; }
254 
256  bool hasProductCache() const { return product_.productPtr() != nullptr; }
257 
260  bool isAvailable() const;
261 
263  bool isTransient() const { return product_.isTransient(); }
264 
265  RefCore const& refCore() const { return product_; }
266 
267  //Used by ROOT storage
269  // private:
270  // Constructor from member of RefVector
271  Ref(RefCore const& iRefCore, key_type const& iKey) : product_(iRefCore), index_(iKey) {}
272 
273  private:
274  // Compile time check that the argument is a C* or C const*
275  // or derived from it.
276  void checkTypeAtCompileTime(C const*) {}
277 
280  };
281 
282  //***************************
283  //Specialization for a vector
284  //***************************
285 #define REF_FOR_VECTOR_ARGS \
286  std::vector<E>, typename refhelper::ValueTrait<std::vector<E>>::value, \
287  typename refhelper::FindTrait<std::vector<E>, typename refhelper::ValueTrait<std::vector<E>>::value>::value
288 
289  template <typename E>
291  private:
293  typedef
295 
298  friend class RefVectorIterator<std::vector<E>, T, F>;
299  friend class RefVector<std::vector<E>, T, F>;
300  friend class RefVector<RefVector<std::vector<E>, T, F>, T, VF>;
301  friend class RefVector<RefVector<std::vector<E>, T, F>, T, VBF>;
302 
303  public:
306  typedef typename refhelper::ValueTrait<std::vector<E>>::value value_type;
307  typedef value_type const element_type; //used for generic programming
308  typedef typename refhelper::FindTrait<std::vector<E>, typename refhelper::ValueTrait<std::vector<E>>::value>::value
310  typedef typename boost::binary_traits<F>::second_argument_type argument_type;
311  typedef unsigned int key_type;
314 
316 
318  Ref() : product_() {}
319 
321  Ref(Handle<product_type> const& handle, key_type itemKey, bool setNow = true);
322 
324  Ref(OrphanHandle<product_type> const& handle, key_type itemKey, bool setNow = true);
325 
327  // An exception will be thrown if an attempt is made to persistify
328  // any object containing this Ref. Also, in the future work will
329  // be done to throw an exception if an attempt is made to put any object
330  // containing this Ref into an event(or run or lumi).
331  Ref(product_type const* product, key_type itemKey, bool setNow = true);
332 
334  // An exception will be thrown if an attempt is made to persistify
335  // any object containing this Ref. Also, in the future work will
336  Ref(TestHandle<product_type> const& handle, key_type itemKey, bool setNow = true);
337 
341  Ref(ProductID const& productID, key_type itemKey, EDProductGetter const* prodGetter)
342  : product_(productID, nullptr, mustBeNonZero(prodGetter, "Ref", productID), false, itemKey) {}
343 
345  // It is an error (not diagnosable at compile- or run-time) to call
346  // this constructor with a pointer to a T unless the pointed-to T
347  // object is already in a collection of type C stored in the
348  // Event. The given ProductID must be the id of the collection in
349  // the Event.
350 
351  Ref(ProductID const& iProductID, T const* item, key_type itemKey, product_type const* /* iProduct */)
352  : product_(iProductID, item, nullptr, false, itemKey) {}
353 
354  Ref(ProductID const& iProductID, T const* item, key_type itemKey)
355  : product_(iProductID, item, nullptr, false, itemKey) {}
356 
357  Ref(ProductID const& iProductID, T const* item, key_type itemKey, bool transient)
358  : product_(iProductID, item, nullptr, transient, itemKey) {}
359 
363 
364  explicit Ref(ProductID const& iId) : product_(iId, nullptr, nullptr, false, key_traits<key_type>::value) {}
365 
367  Ref(RefProd<product_type> const& refProd, key_type itemKey);
368 
370  ~Ref() {}
371 
373  T const& operator*() const;
374 
376  T const* operator->() const;
377 
379  T const* get() const { return isNull() ? nullptr : this->operator->(); }
380 
382  bool isNull() const { return !isNonnull(); }
383 
385  bool isNonnull() const { return key() != edm::key_traits<key_type>::value; }
386 
388  bool operator!() const { return isNull(); }
389 
391  ProductID id() const { return product_.id(); }
392 
395 
397  key_type key() const { return product_.index(); }
398 
399  // This one just for backward compatibility. Will be removed soon.
400  key_type index() const { return product_.index(); }
401 
403  bool hasProductCache() const { return product_.productPtr() != nullptr; }
404 
407  bool isAvailable() const;
408 
410  bool isTransient() const { return product_.isTransient(); }
411 
412  RefCore const& refCore() const { return product_.toRefCore(); }
413 
414  //Used by ROOT storage
416  // private:
417  // Constructor from member of RefVector
418  Ref(RefCore const& iRefCore, key_type const& iKey) : product_(iRefCore, iKey) {}
419 
420  private:
421  // Compile time check that the argument is a C* or C const*
422  // or derived from it.
424 
426  };
427 } // namespace edm
428 
432 
433 namespace edm {
434 
436  template <typename C, typename T, typename F>
437  inline Ref<C, T, F>::Ref(Handle<C> const& handle, key_type itemKey, bool)
438  : product_(handle.id(), nullptr, nullptr, false), index_(itemKey) {
439  if (itemKey == key_traits<key_type>::value)
440  return;
441  refitem::findRefItem<C, T, F, key_type>(product_, handle.product(), itemKey);
442  }
443 
445  template <typename E>
446  inline Ref<REF_FOR_VECTOR_ARGS>::Ref(Handle<std::vector<E>> const& handle, key_type itemKey, bool)
447  : product_(handle.id(), nullptr, nullptr, false, itemKey) {
448  if (itemKey == key_traits<key_type>::value)
449  return;
450  refitem::findRefItem<product_type, value_type, finder_type, key_type>(
451  product_.toRefCore(), handle.product(), itemKey);
452  }
453 
455  template <typename C, typename T, typename F>
456  inline Ref<C, T, F>::Ref(OrphanHandle<C> const& handle, key_type itemKey, bool)
457  : product_(handle.id(), nullptr, nullptr, false), index_(itemKey) {
458  if (itemKey == key_traits<key_type>::value)
459  return;
460  refitem::findRefItem<C, T, F, key_type>(product_, handle.product(), itemKey);
461  }
462 
464  template <typename E>
465  inline Ref<REF_FOR_VECTOR_ARGS>::Ref(OrphanHandle<std::vector<E>> const& handle, key_type itemKey, bool)
466  : product_(handle.id(), nullptr, nullptr, false, itemKey) {
467  if (itemKey == key_traits<key_type>::value)
468  return;
469  refitem::findRefItem<product_type, value_type, finder_type, key_type>(
470  product_.toRefCore(), handle.product(), itemKey);
471  }
472 
474  // An exception will be thrown if an attempt is made to persistify
475  // any object containing this Ref. Also, in the future work will
476  // be done to throw an exception if an attempt is made to put any object
477  // containing this Ref into an event(or run or lumi).
478  // Note: It is legal for the referenced object to be put into the event
479  // and persistified. It is this Ref itself that cannot be persistified.
480  template <typename C, typename T, typename F>
481  inline Ref<C, T, F>::Ref(C const* iProduct, key_type itemKey, bool)
482  : product_(ProductID(), nullptr, nullptr, true),
483  index_(iProduct != nullptr ? itemKey : key_traits<key_type>::value) {
484  if (iProduct != nullptr) {
485  refitem::findRefItem<C, T, F, key_type>(product_, iProduct, itemKey);
486  }
487  }
488 
489  template <typename E>
490  inline Ref<REF_FOR_VECTOR_ARGS>::Ref(std::vector<E> const* iProduct, key_type itemKey, bool)
491  : product_(ProductID(), nullptr, nullptr, true, iProduct != nullptr ? itemKey : key_traits<key_type>::value) {
492  if (iProduct != nullptr) {
493  refitem::findRefItem<product_type, value_type, finder_type, key_type>(product_.toRefCore(), iProduct, itemKey);
494  }
495  }
496 
498  // An exception will be thrown if an attempt is made to persistify any object containing this Ref.
499  template <typename C, typename T, typename F>
500  inline Ref<C, T, F>::Ref(TestHandle<C> const& handle, key_type itemKey, bool)
501  : product_(handle.id(), nullptr, nullptr, true), index_(itemKey) {
502  if (itemKey == key_traits<key_type>::value)
503  return;
504  refitem::findRefItem<C, T, F, key_type>(product_, handle.product(), itemKey);
505  }
506 
507  template <typename E>
508  inline Ref<REF_FOR_VECTOR_ARGS>::Ref(TestHandle<std::vector<E>> const& handle, key_type itemKey, bool)
509  : product_(handle.id(), nullptr, nullptr, true, itemKey) {
510  if (itemKey == key_traits<key_type>::value)
511  return;
512  refitem::findRefItem<product_type, value_type, finder_type, key_type>(
513  product_.toRefCore(), handle.product(), itemKey);
514  }
515 
517  template <typename C, typename T, typename F>
518  inline Ref<C, T, F>::Ref(RefProd<C> const& refProd, key_type itemKey)
519  : product_(refProd.id(), nullptr, refProd.refCore().productGetter(), refProd.refCore().isTransient()),
520  index_(itemKey) {
521  if (refProd.refCore().productPtr() != nullptr && itemKey != key_traits<key_type>::value) {
522  refitem::findRefItem<C, T, F, key_type>(
523  product_, static_cast<product_type const*>(refProd.refCore().productPtr()), itemKey);
524  }
525  }
526 
527  template <typename E>
528  inline Ref<REF_FOR_VECTOR_ARGS>::Ref(RefProd<std::vector<E>> const& refProd, key_type itemKey)
529  : product_(refProd.id(), nullptr, refProd.refCore().productGetter(), refProd.refCore().isTransient(), itemKey) {
530  if (refProd.refCore().productPtr() != nullptr && itemKey != key_traits<key_type>::value) {
531  refitem::findRefItem<product_type, value_type, finder_type, key_type>(
532  product_.toRefCore(), static_cast<product_type const*>(refProd.refCore().productPtr()), itemKey);
533  }
534  }
535 
536  template <typename C, typename T, typename F>
537  inline bool Ref<C, T, F>::isAvailable() const {
538  if (product_.isAvailable()) {
539  return true;
540  }
541  return isThinnedAvailable<C>(product_, index_);
542  }
543 
544  template <typename E>
546  if (product_.isAvailable()) {
547  return true;
548  }
549  return isThinnedAvailable<std::vector<E>>(product_.toRefCore(), key());
550  }
551 
553  template <typename C, typename T, typename F>
554  inline T const& Ref<C, T, F>::operator*() const {
555  return *getRefPtr<C, T, F>(product_, index_);
556  }
557  template <typename E>
559  return *getRefPtr<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), key());
560  }
561 
563  template <typename C, typename T, typename F>
564  inline T const* Ref<C, T, F>::operator->() const {
565  return getRefPtr<C, T, F>(product_, index_);
566  }
567  template <typename E>
569  return getRefPtr<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), key());
570  }
571 
572  template <typename C, typename T, typename F>
573  inline bool operator==(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
574  return lhs.key() == rhs.key() && lhs.refCore() == rhs.refCore();
575  }
576 
577  template <typename C, typename T, typename F>
578  inline bool operator!=(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
579  return !(lhs == rhs);
580  }
581 
582  template <typename C, typename T, typename F>
583  inline bool operator<(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
586  return (lhs.refCore() == rhs.refCore() ? compare_key<C>(lhs.key(), rhs.key()) : lhs.refCore() < rhs.refCore());
587  }
588 
589 } // namespace edm
590 
591 //Handle specialization here
593 #endif
bool hasProductCache() const
Returns true if container referenced by the Ref has been cached.
Definition: Ref.h:256
RefCore const & refCore() const
Definition: Ref.h:265
std::remove_cv< typename std::remove_reference< argument_type >::type >::type key_type
Definition: Ref.h:164
ProductID id() const
Accessor for product ID.
Definition: Ref.h:244
void checkTypeAtCompileTime(C const *)
Definition: Ref.h:276
bool operator!=(Ref< C, T, F > const &lhs, Ref< C, T, F > const &rhs)
Definition: Ref.h:578
T const & operator*() const
Dereference operator.
Definition: Ref.h:554
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:351
bool operator==(Ref< C, T, F > const &lhs, Ref< C, T, F > const &rhs)
Definition: Ref.h:573
boost::binary_traits< F >::second_argument_type argument_type
Definition: Ref.h:163
~Ref()
Destructor.
Definition: Ref.h:223
key_type index_
Definition: Ref.h:279
ProductID id() const
Definition: RefCore.h:48
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:238
T const * operator->() const
Member dereference operator.
Definition: Ref.h:564
RefCore product_
Definition: Ref.h:278
EDProductGetter const * mustBeNonZero(EDProductGetter const *prodGetter, std::string refType, ProductID const &productID)
#define REF_FOR_VECTOR_ARGS
Definition: Ref.h:285
#define CMS_CLASS_VERSION(_version_)
void const * productPtr() const
Definition: RefCore.h:51
EDProductGetter const * productGetter() const
Accessor for product getter.
Definition: Ref.h:247
key_type key() const
Accessor for product key.
Definition: Ref.h:250
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:263
bool operator!() const
Checks for null.
Definition: Ref.h:241
bool compare_key(K const &lhs, K const &rhs)
Definition: Ref.h:130
Ref(ProductID const &productID, key_type itemKey, EDProductGetter const *prodGetter)
Definition: Ref.h:194
bool isAvailable() const
Definition: Ref.h:537
bool isTransient() const
Definition: RefCore.h:105
static key_type invalidKey()
Definition: Ref.h:168
Ref(ProductID const &iProductID, T const *item, key_type itemKey)
Definition: Ref.h:207
Definition: value.py:1
T const element_type
Definition: Ref.h:161
refhelper::FindRefVectorUsingAdvance< RefToBaseVector< T > > VBF
Definition: Ref.h:151
bool isNull() const
Checks for null.
Definition: Ref.h:235
refhelper::FindRefVectorUsingAdvance< RefVector< C, T, F > > VF
Definition: Ref.h:150
T value_type
Definition: Ref.h:160
key_type index() const
Definition: Ref.h:253
F finder_type
Definition: Ref.h:162
Ref(ProductID const &iProductID, T const *item, key_type itemKey, bool transient)
Definition: Ref.h:210
C product_type
for export
Definition: Ref.h:159
Ref(ProductID const &iId)
Definition: Ref.h:217
Ref()
Default constructor needed for reading from persistent store. Not for direct use. ...
Definition: Ref.h:171
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:204
EDProductGetter const * productGetter() const
Definition: RefCore.h:81
long double T
edm::RefVector< Container > RefVector