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 #include "boost/call_traits.hpp"
117 #include "boost/type_traits.hpp"
118 #include "boost/mpl/has_xxx.hpp"
119 #include "boost/utility/enable_if.hpp"
120 
121 #include <vector>
122 #include <type_traits>
123 
124 BOOST_MPL_HAS_XXX_TRAIT_DEF(key_compare)
125 
126  template <typename C, typename K>
127  typename boost::enable_if<has_key_compare<C>, bool>::type
128  compare_key(K const& lhs, K const& rhs) {
129  typedef typename C::key_compare comparison_functor;
130  return comparison_functor()(lhs, rhs);
131  }
132 
133  template <typename C, typename K>
134  typename boost::disable_if<has_key_compare<C>, bool>::type
135  compare_key(K const& lhs, K const& rhs) {
136  return lhs < rhs;
137  }
138 
140 
141 namespace edm {
142  template<typename C, typename T, typename F>
143  class RefVector;
144 
145  template<typename T>
146  class RefToBaseVector;
147 
148  template <typename C,
149  typename T = typename refhelper::ValueTrait<C>::value,
150  typename F = typename refhelper::FindTrait<C, T>::value>
151  class Ref {
152  private:
155  friend class RefVectorIterator<C, T, F>;
156  friend class RefVector<C, T, F>;
157  friend class RefVector<RefVector<C, T, F>, T, VF>;
158  friend class RefVector<RefVector<C, T, F>, T, VBF>;
159 
160  public:
162  typedef C product_type;
163  typedef T value_type;
164  typedef T const element_type; //used for generic programming
165  typedef F finder_type;
166  typedef typename boost::binary_traits<F>::second_argument_type argument_type;
170 
171  static key_type invalidKey() { return key_traits<key_type>::value; }
172 
174  Ref() : product_(), index_(key_traits<key_type>::value) {}
175 
177  Ref(Handle<C> const& handle, key_type itemKey, bool setNow=true);
178 
180  Ref(OrphanHandle<C> const& handle, key_type itemKey, bool setNow=true);
181 
183  // An exception will be thrown if an attempt is made to persistify
184  // any object containing this Ref. Also, in the future work will
185  // be done to throw an exception if an attempt is made to put any object
186  // containing this Ref into an event(or run or lumi).
187  Ref(C const* product, key_type itemKey, bool setNow=true);
188 
190  // An exception will be thrown if an attempt is made to persistify
191  // any object containing this Ref. Also, in the future work will
192  Ref(TestHandle<C> const& handle, key_type itemKey, bool setNow=true);
193 
197  Ref(ProductID const& productID, key_type itemKey, EDProductGetter const* prodGetter) :
198  product_(productID, nullptr, mustBeNonZero(prodGetter, "Ref", productID), false), index_(itemKey) {
199  }
200 
202  // It is an error (not diagnosable at compile- or run-time) to call
203  // this constructor with a pointer to a T unless the pointed-to T
204  // object is already in a collection of type C stored in the
205  // Event. The given ProductID must be the id of the collection in
206  // the Event.
207 
208  Ref(ProductID const& iProductID, T const* item, key_type itemKey, C const* /* iProduct */) :
209  product_(iProductID, item, 0, false), index_(itemKey)
210  { }
211 
212  Ref(ProductID const& iProductID, T const* item, key_type itemKey) :
213  product_(iProductID, item, nullptr, false), index_(itemKey)
214  { }
215 
216  Ref(ProductID const& iProductID, T const* item, key_type itemKey, bool transient) :
217  product_(iProductID, item, nullptr, transient), index_(itemKey)
218  { }
219 
223 
224  explicit Ref(ProductID const& iId) :
225  product_(iId, nullptr, nullptr, false), index_(key_traits<key_type>::value)
226  { }
227 
229  Ref(RefProd<C> const& refProd, key_type itemKey);
230 
232  ~Ref() {}
233 
235  T const&
236  operator*() const;
237 
239  T const*
240  operator->() const;
241 
243  T const* get() const {
244  return isNull() ? nullptr : this->operator->();
245  }
246 
248  bool isNull() const {return !isNonnull(); }
249 
252 
254  bool operator!() const {return isNull();}
255 
257  ProductID id() const {return product_.id();}
258 
261 
263  key_type key() const {return index_;}
264 
265  // This one just for backward compatibility. Will be removed soon.
266  key_type index() const {return index_;}
267 
269  bool hasProductCache() const {return product_.productPtr() != 0;}
270 
273  bool isAvailable() const;
274 
276  bool isTransient() const {return product_.isTransient();}
277 
278  RefCore const& refCore() const {return product_;}
279 
280  //Used by ROOT storage
282  // private:
283  // Constructor from member of RefVector
284  Ref(RefCore const& iRefCore, key_type const& iKey) :
285  product_(iRefCore), index_(iKey) {
286  }
287 
288  private:
289 
290  // Compile time check that the argument is a C* or C const*
291  // or derived from it.
292  void checkTypeAtCompileTime(C const*) {}
293 
295  key_type index_;
296  };
297 
298  //***************************
299  //Specialization for a vector
300  //***************************
301 #define REF_FOR_VECTOR_ARGS std::vector<E>,typename refhelper::ValueTrait<std::vector<E> >::value,typename refhelper::FindTrait<std::vector<E>, typename refhelper::ValueTrait<std::vector<E> >::value>::value
302 
303  template <typename E>
305  private:
308 
311  friend class RefVectorIterator<std::vector<E>, T, F>;
312  friend class RefVector<std::vector<E>, T, F>;
313  friend class RefVector<RefVector<std::vector<E>, T, F>, T, VF>;
314  friend class RefVector<RefVector<std::vector<E>, T, F>, T, VBF>;
315 
316  public:
318  typedef std::vector<E> product_type;
319  typedef typename refhelper::ValueTrait<std::vector<E> >::value value_type;
320  typedef value_type const element_type; //used for generic programming
321  typedef typename refhelper::FindTrait<std::vector<E>,
322  typename refhelper::ValueTrait<std::vector<E> >::value>::value finder_type;
323  typedef typename boost::binary_traits<F>::second_argument_type argument_type;
324  typedef unsigned int key_type;
327 
329 
331  Ref() : product_() {}
332 
334  Ref(Handle<product_type> const& handle, key_type itemKey, bool setNow=true);
335 
337  Ref(OrphanHandle<product_type> const& handle, key_type itemKey, bool setNow=true);
338 
340  // An exception will be thrown if an attempt is made to persistify
341  // any object containing this Ref. Also, in the future work will
342  // be done to throw an exception if an attempt is made to put any object
343  // containing this Ref into an event(or run or lumi).
344  Ref(product_type const* product, key_type itemKey, bool setNow=true);
345 
347  // An exception will be thrown if an attempt is made to persistify
348  // any object containing this Ref. Also, in the future work will
349  Ref(TestHandle<product_type> const& handle, key_type itemKey, bool setNow=true);
350 
354  Ref(ProductID const& productID, key_type itemKey, EDProductGetter const* prodGetter) :
355  product_(productID, nullptr, mustBeNonZero(prodGetter, "Ref", productID), false,itemKey) {
356  }
357 
359  // It is an error (not diagnosable at compile- or run-time) to call
360  // this constructor with a pointer to a T unless the pointed-to T
361  // object is already in a collection of type C stored in the
362  // Event. The given ProductID must be the id of the collection in
363  // the Event.
364 
365  Ref(ProductID const& iProductID, T const* item, key_type itemKey, product_type const* /* iProduct */) :
366  product_(iProductID, item, 0, false, itemKey)
367  { }
368 
369  Ref(ProductID const& iProductID, T const* item, key_type itemKey) :
370  product_(iProductID, item, nullptr, false, itemKey)
371  { }
372 
373  Ref(ProductID const& iProductID, T const* item, key_type itemKey, bool transient) :
374  product_(iProductID, item, nullptr, transient, itemKey)
375  { }
376 
380 
381  explicit Ref(ProductID const& iId) :
383  { }
384 
386  Ref(RefProd<product_type> const& refProd, key_type itemKey);
387 
389  ~Ref() {}
390 
392  T const&
393  operator*() const;
394 
396  T const*
397  operator->() const;
398 
400  T const* get() const {
401  return isNull() ? nullptr : this->operator->();
402  }
403 
405  bool isNull() const {return !isNonnull(); }
406 
408  bool isNonnull() const { return key()!=edm::key_traits<key_type>::value; }
409 
411  bool operator!() const {return isNull();}
412 
414  ProductID id() const {return product_.id();}
415 
418 
420  key_type key() const {return product_.index();}
421 
422  // This one just for backward compatibility. Will be removed soon.
423  key_type index() const {return product_.index();}
424 
426  bool hasProductCache() const {return product_.productPtr() != 0;}
427 
430  bool isAvailable() const;
431 
433  bool isTransient() const {return product_.isTransient();}
434 
435  RefCore const& refCore() const {return product_.toRefCore();}
436 
437  //Used by ROOT storage
439  // private:
440  // Constructor from member of RefVector
441  Ref(RefCore const& iRefCore, key_type const& iKey) :
442  product_(iRefCore,iKey) {
443  }
444 
445  private:
446  // Compile time check that the argument is a C* or C const*
447  // or derived from it.
449 
451  };
452 }
453 
457 
458 namespace edm {
459 
461  template <typename C, typename T, typename F>
462  inline
463  Ref<C, T, F>::Ref(Handle<C> const& handle, key_type itemKey, bool) :
464  product_(handle.id(), nullptr, nullptr, false), index_(itemKey) {
465  if(itemKey == key_traits<key_type>::value) return;
466  refitem::findRefItem<C, T, F, key_type>(product_, handle.product(), itemKey);
467  }
468 
470  template <typename E>
471  inline
472  Ref<REF_FOR_VECTOR_ARGS>::Ref(Handle<std::vector<E> > const& handle, key_type itemKey, bool) :
473  product_(handle.id(), nullptr, nullptr, false, itemKey){
474  if(itemKey == key_traits<key_type>::value) return;
475  refitem::findRefItem<product_type, value_type, finder_type, key_type>(product_.toRefCore(),
476  handle.product(),
477  itemKey);
478  }
479 
481  template <typename C, typename T, typename F>
482  inline
484  product_(handle.id(), nullptr, nullptr, false), index_(itemKey) {
485  if(itemKey == key_traits<key_type>::value) return;
486  refitem::findRefItem<C, T, F, key_type>(product_, handle.product(), itemKey);
487  }
488 
490  template <typename E>
491  inline
492  Ref<REF_FOR_VECTOR_ARGS>::Ref(OrphanHandle<std::vector<E> > const& handle, key_type itemKey, bool) :
493  product_(handle.id(), nullptr, nullptr, false, itemKey){
494  if(itemKey == key_traits<key_type>::value) return;
495  refitem::findRefItem<product_type, value_type, finder_type, key_type>(product_.toRefCore(),
496  handle.product(),
497  itemKey);
498  }
499 
501  // An exception will be thrown if an attempt is made to persistify
502  // any object containing this Ref. Also, in the future work will
503  // be done to throw an exception if an attempt is made to put any object
504  // containing this Ref into an event(or run or lumi).
505  // Note: It is legal for the referenced object to be put into the event
506  // and persistified. It is this Ref itself that cannot be persistified.
507  template <typename C, typename T, typename F>
508  inline
509  Ref<C, T, F>::Ref(C const* iProduct, key_type itemKey, bool) :
510  product_(ProductID(), nullptr, nullptr, true), index_(iProduct != nullptr ? itemKey : key_traits<key_type>::value) {
511  if(iProduct != nullptr) {
512  refitem::findRefItem<C, T, F, key_type>(product_, iProduct, itemKey);
513  }
514  }
515 
516  template <typename E>
517  inline
518  Ref<REF_FOR_VECTOR_ARGS>::Ref(std::vector<E> const* iProduct, key_type itemKey, bool) :
519  product_(ProductID(), nullptr, nullptr, true, iProduct != nullptr ? itemKey : key_traits<key_type>::value) {
520  if(iProduct != nullptr) {
521  refitem::findRefItem<product_type, value_type, finder_type, key_type>(product_.toRefCore(), iProduct, itemKey);
522  }
523  }
524 
526  // An exception will be thrown if an attempt is made to persistify any object containing this Ref.
527  template <typename C, typename T, typename F>
528  inline
530  product_(handle.id(), nullptr, nullptr, true), index_(itemKey) {
531  if(itemKey == key_traits<key_type>::value) return;
532  refitem::findRefItem<C, T, F, key_type>(product_, handle.product(), itemKey);
533  }
534 
535  template <typename E>
536  inline
537  Ref<REF_FOR_VECTOR_ARGS>::Ref(TestHandle<std::vector<E> > const& handle, key_type itemKey, bool) :
538  product_(handle.id(), nullptr, nullptr, true, itemKey){
539  if(itemKey == key_traits<key_type>::value) return;
540  refitem::findRefItem<product_type, value_type, finder_type, key_type>(product_.toRefCore(),
541  handle.product(),
542  itemKey);
543  }
544 
546  template <typename C, typename T, typename F>
547  inline
548  Ref<C, T, F>::Ref(RefProd<C> const& refProd, key_type itemKey) :
549  product_(refProd.id(), nullptr, refProd.refCore().productGetter(), refProd.refCore().isTransient()),
550  index_(itemKey) {
551 
552  if(refProd.refCore().productPtr() != nullptr && itemKey != key_traits<key_type>::value) {
553  refitem::findRefItem<C, T, F, key_type>(product_,
554  static_cast<product_type const*>(refProd.refCore().productPtr()),
555  itemKey);
556  }
557  }
558 
559  template <typename E>
560  inline
561  Ref<REF_FOR_VECTOR_ARGS>::Ref(RefProd<std::vector<E> > const& refProd, key_type itemKey) :
562  product_(refProd.id(), nullptr, refProd.refCore().productGetter(), refProd.refCore().isTransient(), itemKey) {
563 
564  if(refProd.refCore().productPtr() != nullptr && itemKey != key_traits<key_type>::value) {
565  refitem::findRefItem<product_type, value_type, finder_type, key_type>(
566  product_.toRefCore(),
567  static_cast<product_type const*>(refProd.refCore().productPtr()),
568  itemKey);
569  }
570  }
571 
572  template <typename C, typename T, typename F>
573  inline
574  bool
576  if(product_.isAvailable()) {
577  return true;
578  }
579  return isThinnedAvailable<C>(product_, index_);
580  }
581 
582  template <typename E>
583  inline
584  bool
586  if(product_.isAvailable()) {
587  return true;
588  }
589  return isThinnedAvailable<std::vector<E> >(product_.toRefCore(), key());
590  }
591 
593  template <typename C, typename T, typename F>
594  inline
595  T const&
597  return *getRefPtr<C, T, F>(product_, index_);
598  }
599  template <typename E>
600  inline
603  return *getRefPtr<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), key());
604  }
605 
607  template <typename C, typename T, typename F>
608  inline
609  T const*
611  return getRefPtr<C, T, F>(product_, index_);
612  }
613  template <typename E>
614  inline
617  return getRefPtr<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), key());
618  }
619 
620  template <typename C, typename T, typename F>
621  inline
622  bool
623  operator==(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
624  return lhs.key() == rhs.key() && lhs.refCore() == rhs.refCore() ;
625  }
626 
627  template <typename C, typename T, typename F>
628  inline
629  bool
630  operator!=(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
631  return !(lhs == rhs);
632  }
633 
634  template <typename C, typename T, typename F>
635  inline
636  bool
637  operator<(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
640  return (lhs.refCore() == rhs.refCore() ? compare_key<C>(lhs.key(), rhs.key()) : lhs.refCore() < rhs.refCore());
641  }
642 
643 }
644 
645 //Handle specialization here
647 #endif
bool isAvailable() const
Definition: Ref.h:575
type
Definition: HCALResponse.h:21
T const * product() const
Definition: TestHandle.h:60
EDProductGetter const * mustBeNonZero(EDProductGetter const *prodGetter, std::string refType, ProductID const &productID)
std::remove_cv< typename std::remove_reference< argument_type >::type >::type key_type
Definition: Ref.h:167
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:251
void checkTypeAtCompileTime(C const *)
Definition: Ref.h:292
Definition: CLHEP.h:16
boost::enable_if< has_key_compare< C >, bool >::type compare_key(K const &lhs, K const &rhs)
Definition: Ref.h:128
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:365
boost::binary_traits< F >::second_argument_type argument_type
Definition: Ref.h:166
~Ref()
Destructor.
Definition: Ref.h:232
bool isTransient() const
Checks if this ref is transient (i.e. not persistable).
Definition: Ref.h:276
key_type index_
Definition: Ref.h:295
bool hasProductCache() const
Returns true if container referenced by the Ref has been cached.
Definition: Ref.h:269
#define nullptr
RefCore const & refCore() const
Definition: Ref.h:278
key_type index() const
Definition: Ref.h:266
key_type key() const
Accessor for product key.
Definition: Ref.h:263
RefCore product_
Definition: Ref.h:294
#define REF_FOR_VECTOR_ARGS
Definition: Ref.h:301
#define CMS_CLASS_VERSION(_version_)
ProductID id() const
Accessor for product ID.
Definition: Ref.h:257
bool operator==(debugging_allocator< X > const &, debugging_allocator< Y > const &) noexcept
Ref(ProductID const &productID, key_type itemKey, EDProductGetter const *prodGetter)
Definition: Ref.h:197
void const * productPtr() const
Definition: RefCore.h:52
bool isAvailable() const
Definition: RefCore.cc:169
static key_type invalidKey()
Definition: Ref.h:171
Ref(ProductID const &iProductID, T const *item, key_type itemKey)
Definition: Ref.h:212
RefCore const & refCore() const
Definition: RefProd.h:123
def template(fileName, svg, replaceme="REPLACEME")
Definition: svgfig.py:521
Definition: value.py:1
T const element_type
Definition: Ref.h:164
refhelper::FindRefVectorUsingAdvance< RefToBaseVector< T > > VBF
Definition: Ref.h:154
bool operator!=(debugging_allocator< X > const &, debugging_allocator< Y > const &) noexcept
bool isNull() const
Checks for null.
Definition: Ref.h:248
refhelper::FindRefVectorUsingAdvance< RefVector< C, T, F > > VF
Definition: Ref.h:153
T const * product() const
Definition: Handle.h:74
T value_type
Definition: Ref.h:163
T const * product() const
Definition: OrphanHandle.h:57
F finder_type
Definition: Ref.h:165
Ref(ProductID const &iProductID, T const *item, key_type itemKey, bool transient)
Definition: Ref.h:216
C product_type
for export
Definition: Ref.h:162
Ref(ProductID const &iId)
Definition: Ref.h:224
EDProductGetter const * productGetter() const
Definition: RefCore.h:84
bool operator!() const
Checks for null.
Definition: Ref.h:254
ProductID id() const
Definition: RefCore.h:49
bool isTransient() const
Definition: RefCore.h:106
Ref()
Default constructor needed for reading from persistent store. Not for direct use. ...
Definition: Ref.h:174
HLT enums.
EDProductGetter const * productGetter() const
Accessor for product getter.
Definition: Ref.h:260
T const * operator->() const
Member dereference operator.
Definition: Ref.h:610
FindUsingAdvance< C, T > value
Definition: RefTraits.h:40
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:281
Ref(ProductID const &iProductID, T const *item, key_type itemKey, C const *)
Constructor for use in the various X::fillView(...) functions.
Definition: Ref.h:208
long double T
edm::RefVector< Container > RefVector
T const & operator*() const
Dereference operator.
Definition: Ref.h:596