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 
262  bool isAvailable() const;
263 
265  bool isTransient() const { return product_.isTransient(); }
266 
267  RefCore const& refCore() const { return product_; }
268 
269  //Used by ROOT storage
271  // private:
272  // Constructor from member of RefVector
273  Ref(RefCore const& iRefCore, key_type const& iKey) : product_(iRefCore), index_(iKey) {}
274 
275  private:
276  // Compile time check that the argument is a C* or C const*
277  // or derived from it.
278  void checkTypeAtCompileTime(C const*) {}
279 
282  };
283 
284  //***************************
285  //Specialization for a vector
286  //***************************
287 #define REF_FOR_VECTOR_ARGS \
288  std::vector<E>, typename refhelper::ValueTrait<std::vector<E>>::value, \
289  typename refhelper::FindTrait<std::vector<E>, typename refhelper::ValueTrait<std::vector<E>>::value>::value
290 
291  template <typename E>
293  private:
295  typedef
297 
300  friend class RefVectorIterator<std::vector<E>, T, F>;
301  friend class RefVector<std::vector<E>, T, F>;
302  friend class RefVector<RefVector<std::vector<E>, T, F>, T, VF>;
303  friend class RefVector<RefVector<std::vector<E>, T, F>, T, VBF>;
304 
305  public:
308  typedef typename refhelper::ValueTrait<std::vector<E>>::value value_type;
309  typedef value_type const element_type; //used for generic programming
310  typedef typename refhelper::FindTrait<std::vector<E>, typename refhelper::ValueTrait<std::vector<E>>::value>::value
312  typedef typename boost::binary_traits<F>::second_argument_type argument_type;
313  typedef unsigned int key_type;
316 
318 
320  Ref() : product_() {}
321 
323  Ref(Handle<product_type> const& handle, key_type itemKey, bool setNow = true);
324 
326  Ref(OrphanHandle<product_type> const& handle, key_type itemKey, bool setNow = true);
327 
329  // An exception will be thrown if an attempt is made to persistify
330  // any object containing this Ref. Also, in the future work will
331  // be done to throw an exception if an attempt is made to put any object
332  // containing this Ref into an event(or run or lumi).
333  Ref(product_type const* product, key_type itemKey, bool setNow = true);
334 
336  // An exception will be thrown if an attempt is made to persistify
337  // any object containing this Ref. Also, in the future work will
338  Ref(TestHandle<product_type> const& handle, key_type itemKey, bool setNow = true);
339 
343  Ref(ProductID const& productID, key_type itemKey, EDProductGetter const* prodGetter)
344  : product_(productID, nullptr, mustBeNonZero(prodGetter, "Ref", productID), false, itemKey) {}
345 
347  // It is an error (not diagnosable at compile- or run-time) to call
348  // this constructor with a pointer to a T unless the pointed-to T
349  // object is already in a collection of type C stored in the
350  // Event. The given ProductID must be the id of the collection in
351  // the Event.
352 
353  Ref(ProductID const& iProductID, T const* item, key_type itemKey, product_type const* /* iProduct */)
354  : product_(iProductID, item, nullptr, false, itemKey) {}
355 
356  Ref(ProductID const& iProductID, T const* item, key_type itemKey)
357  : product_(iProductID, item, nullptr, false, itemKey) {}
358 
359  Ref(ProductID const& iProductID, T const* item, key_type itemKey, bool transient)
360  : product_(iProductID, item, nullptr, transient, itemKey) {}
361 
365 
366  explicit Ref(ProductID const& iId) : product_(iId, nullptr, nullptr, false, key_traits<key_type>::value) {}
367 
369  Ref(RefProd<product_type> const& refProd, key_type itemKey);
370 
372  ~Ref() {}
373 
375  T const& operator*() const;
376 
378  T const* operator->() const;
379 
381  T const* get() const { return isNull() ? nullptr : this->operator->(); }
382 
384  bool isNull() const { return !isNonnull(); }
385 
387  bool isNonnull() const { return key() != edm::key_traits<key_type>::value; }
388 
390  bool operator!() const { return isNull(); }
391 
393  ProductID id() const { return product_.id(); }
394 
397 
399  key_type key() const { return product_.index(); }
400 
401  // This one just for backward compatibility. Will be removed soon.
402  key_type index() const { return product_.index(); }
403 
405  bool hasProductCache() const { return product_.productPtr() != nullptr; }
406 
411  bool isAvailable() const;
412 
414  bool isTransient() const { return product_.isTransient(); }
415 
416  RefCore const& refCore() const { return product_.toRefCore(); }
417 
418  //Used by ROOT storage
420  // private:
421  // Constructor from member of RefVector
422  Ref(RefCore const& iRefCore, key_type const& iKey) : product_(iRefCore, iKey) {}
423 
424  private:
425  // Compile time check that the argument is a C* or C const*
426  // or derived from it.
428 
430  };
431 } // namespace edm
432 
436 
437 namespace edm {
438 
440  template <typename C, typename T, typename F>
441  inline Ref<C, T, F>::Ref(Handle<C> const& handle, key_type itemKey, bool)
442  : product_(handle.id(), nullptr, nullptr, false), index_(itemKey) {
443  if (itemKey == key_traits<key_type>::value)
444  return;
445  refitem::findRefItem<C, T, F, key_type>(product_, handle.product(), itemKey);
446  }
447 
449  template <typename E>
450  inline Ref<REF_FOR_VECTOR_ARGS>::Ref(Handle<std::vector<E>> const& handle, key_type itemKey, bool)
451  : product_(handle.id(), nullptr, nullptr, false, itemKey) {
452  if (itemKey == key_traits<key_type>::value)
453  return;
454  refitem::findRefItem<product_type, value_type, finder_type, key_type>(
455  product_.toRefCore(), handle.product(), itemKey);
456  }
457 
459  template <typename C, typename T, typename F>
460  inline Ref<C, T, F>::Ref(OrphanHandle<C> const& handle, key_type itemKey, bool)
461  : product_(handle.id(), nullptr, nullptr, false), index_(itemKey) {
462  if (itemKey == key_traits<key_type>::value)
463  return;
464  refitem::findRefItem<C, T, F, key_type>(product_, handle.product(), itemKey);
465  }
466 
468  template <typename E>
469  inline Ref<REF_FOR_VECTOR_ARGS>::Ref(OrphanHandle<std::vector<E>> const& handle, key_type itemKey, bool)
470  : product_(handle.id(), nullptr, nullptr, false, itemKey) {
471  if (itemKey == key_traits<key_type>::value)
472  return;
473  refitem::findRefItem<product_type, value_type, finder_type, key_type>(
474  product_.toRefCore(), handle.product(), itemKey);
475  }
476 
478  // An exception will be thrown if an attempt is made to persistify
479  // any object containing this Ref. Also, in the future work will
480  // be done to throw an exception if an attempt is made to put any object
481  // containing this Ref into an event(or run or lumi).
482  // Note: It is legal for the referenced object to be put into the event
483  // and persistified. It is this Ref itself that cannot be persistified.
484  template <typename C, typename T, typename F>
485  inline Ref<C, T, F>::Ref(C const* iProduct, key_type itemKey, bool)
486  : product_(ProductID(), nullptr, nullptr, true),
487  index_(iProduct != nullptr ? itemKey : key_traits<key_type>::value) {
488  if (iProduct != nullptr) {
489  refitem::findRefItem<C, T, F, key_type>(product_, iProduct, itemKey);
490  }
491  }
492 
493  template <typename E>
494  inline Ref<REF_FOR_VECTOR_ARGS>::Ref(std::vector<E> const* iProduct, key_type itemKey, bool)
495  : product_(ProductID(), nullptr, nullptr, true, iProduct != nullptr ? itemKey : key_traits<key_type>::value) {
496  if (iProduct != nullptr) {
497  refitem::findRefItem<product_type, value_type, finder_type, key_type>(product_.toRefCore(), iProduct, itemKey);
498  }
499  }
500 
502  // An exception will be thrown if an attempt is made to persistify any object containing this Ref.
503  template <typename C, typename T, typename F>
504  inline Ref<C, T, F>::Ref(TestHandle<C> const& handle, key_type itemKey, bool)
505  : product_(handle.id(), nullptr, nullptr, true), index_(itemKey) {
506  if (itemKey == key_traits<key_type>::value)
507  return;
508  refitem::findRefItem<C, T, F, key_type>(product_, handle.product(), itemKey);
509  }
510 
511  template <typename E>
512  inline Ref<REF_FOR_VECTOR_ARGS>::Ref(TestHandle<std::vector<E>> const& handle, key_type itemKey, bool)
513  : product_(handle.id(), nullptr, nullptr, true, itemKey) {
514  if (itemKey == key_traits<key_type>::value)
515  return;
516  refitem::findRefItem<product_type, value_type, finder_type, key_type>(
517  product_.toRefCore(), handle.product(), itemKey);
518  }
519 
521  template <typename C, typename T, typename F>
522  inline Ref<C, T, F>::Ref(RefProd<C> const& refProd, key_type itemKey)
523  : product_(refProd.id(), nullptr, refProd.refCore().productGetter(), refProd.refCore().isTransient()),
524  index_(itemKey) {
525  if (refProd.refCore().productPtr() != nullptr && itemKey != key_traits<key_type>::value) {
526  refitem::findRefItem<C, T, F, key_type>(
527  product_, static_cast<product_type const*>(refProd.refCore().productPtr()), itemKey);
528  }
529  }
530 
531  template <typename E>
532  inline Ref<REF_FOR_VECTOR_ARGS>::Ref(RefProd<std::vector<E>> const& refProd, key_type itemKey)
533  : product_(refProd.id(), nullptr, refProd.refCore().productGetter(), refProd.refCore().isTransient(), itemKey) {
534  if (refProd.refCore().productPtr() != nullptr && itemKey != key_traits<key_type>::value) {
535  refitem::findRefItem<product_type, value_type, finder_type, key_type>(
536  product_.toRefCore(), static_cast<product_type const*>(refProd.refCore().productPtr()), itemKey);
537  }
538  }
539 
540  template <typename C, typename T, typename F>
541  inline bool Ref<C, T, F>::isAvailable() const {
542  if (product_.isAvailable()) {
543  return true;
544  }
545  return isThinnedAvailable<C>(product_, index_);
546  }
547 
548  template <typename E>
550  if (product_.isAvailable()) {
551  return true;
552  }
553  return isThinnedAvailable<std::vector<E>>(product_.toRefCore(), key());
554  }
555 
557  template <typename C, typename T, typename F>
558  inline T const& Ref<C, T, F>::operator*() const {
559  return *getRefPtr<C, T, F>(product_, index_);
560  }
561  template <typename E>
563  return *getRefPtr<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), key());
564  }
565 
567  template <typename C, typename T, typename F>
568  inline T const* Ref<C, T, F>::operator->() const {
569  return getRefPtr<C, T, F>(product_, index_);
570  }
571  template <typename E>
573  return getRefPtr<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), key());
574  }
575 
576  template <typename C, typename T, typename F>
577  inline bool operator==(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
578  return lhs.key() == rhs.key() && lhs.refCore() == rhs.refCore();
579  }
580 
581  template <typename C, typename T, typename F>
582  inline bool operator!=(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
583  return !(lhs == rhs);
584  }
585 
586  template <typename C, typename T, typename F>
587  inline bool operator<(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
590  return (lhs.refCore() == rhs.refCore() ? compare_key<C>(lhs.key(), rhs.key()) : lhs.refCore() < rhs.refCore());
591  }
592 
593 } // namespace edm
594 
595 //Handle specialization here
597 #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:267
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:278
bool operator!=(Ref< C, T, F > const &lhs, Ref< C, T, F > const &rhs)
Definition: Ref.h:582
T const & operator*() const
Dereference operator.
Definition: Ref.h:558
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:353
bool operator==(Ref< C, T, F > const &lhs, Ref< C, T, F > const &rhs)
Definition: Ref.h:577
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:281
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:568
RefCore product_
Definition: Ref.h:280
EDProductGetter const * mustBeNonZero(EDProductGetter const *prodGetter, std::string refType, ProductID const &productID)
#define REF_FOR_VECTOR_ARGS
Definition: Ref.h:287
#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:265
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:541
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