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 ----------------------------------------------------------------------*/
74 /*----------------------------------------------------------------------
75 // This defines the public interface to the class Ref<C, T, F>.
76 // C is the collection type.
77 // T (default C::value_type) is the type of an element in the collection.
78 //
79 // ProductID productID is the product ID of the collection.
80 // key_type itemKey is the key of the element in the collection.
81 // C::value_type *itemPtr is a C++ pointer to the element
82 // Ref<C, T, F> const& ref is another Ref<C, T, F>
83 
84 // Constructors
85  Ref(); // Default constructor
86  Ref(Ref<C, T> const& ref); // Copy constructor (default, not explicitly specified)
87 
88  Ref(Handle<C> const& handle, key_type itemKey);
89  Ref(ProductID pid, key_type itemKey, EDProductGetter const* prodGetter);
90 
91 // Destructor
92  virtual ~Ref() {}
93 
94  // Operators and methods
95  Ref<C, T>& operator=(Ref<C, T> const&); // assignment (default, not explicitly specified)
96  T const& operator*() const; // dereference
97  T const* const operator->() const; // member dereference
98  bool operator==(Ref<C, T> const& ref) const; // equality
99  bool operator!=(Ref<C, T> const& ref) const; // inequality
100  bool operator<(Ref<C, T> const& ref) const; // ordering
101  bool isNonnull() const; // true if an object is referenced
102  bool isNull() const; // equivalent to !isNonnull()
103  bool operator!() const; // equivalent to !isNonnull()
104  ----------------------------------------------------------------------*/
105 
116 
117 #include "boost/functional.hpp"
118 #include "boost/call_traits.hpp"
119 #include "boost/type_traits.hpp"
120 #include "boost/mpl/has_xxx.hpp"
121 #include "boost/utility/enable_if.hpp"
122 
123 #include <vector>
124 #include <type_traits>
125 
126 BOOST_MPL_HAS_XXX_TRAIT_DEF(key_compare)
127 
128  template <typename C, typename K>
129  typename boost::enable_if<has_key_compare<C>, bool>::type
130  compare_key(K const& lhs, K const& rhs) {
131  typedef typename C::key_compare comparison_functor;
132  return comparison_functor()(lhs, rhs);
133  }
134 
135  template <typename C, typename K>
136  typename boost::disable_if<has_key_compare<C>, bool>::type
137  compare_key(K const& lhs, K const& rhs) {
138  return lhs < rhs;
139  }
140 
142 
143 namespace edm {
144  template<typename C, typename T, typename F>
145  class RefVector;
146 
147  template<typename T>
148  class RefToBaseVector;
149 
150  template <typename C,
151  typename T = typename refhelper::ValueTrait<C>::value,
152  typename F = typename refhelper::FindTrait<C, T>::value>
153  class Ref {
154  private:
157  friend class RefVectorIterator<C, T, F>;
158  friend class RefVector<C, T, F>;
159  friend class RefVector<RefVector<C, T, F>, T, VF>;
160  friend class RefVector<RefVector<C, T, F>, T, VBF>;
161 
162  public:
164  typedef C product_type;
165  typedef T value_type;
166  typedef T const element_type; //used for generic programming
167  typedef F finder_type;
168  typedef typename boost::binary_traits<F>::second_argument_type argument_type;
172 
173  static key_type invalidKey() { return key_traits<key_type>::value; }
174 
176  Ref() : product_(), index_(key_traits<key_type>::value) {}
177 
179  Ref(Handle<C> const& handle, key_type itemKey, bool setNow=true);
180 
182  Ref(OrphanHandle<C> const& handle, key_type itemKey, bool setNow=true);
183 
185  // An exception will be thrown if an attempt is made to persistify
186  // any object containing this Ref. Also, in the future work will
187  // be done to throw an exception if an attempt is made to put any object
188  // containing this Ref into an event(or run or lumi).
189  Ref(C const* product, key_type itemKey, bool setNow=true);
190 
192  // An exception will be thrown if an attempt is made to persistify
193  // any object containing this Ref. Also, in the future work will
194  Ref(TestHandle<C> const& handle, key_type itemKey, bool setNow=true);
195 
199  Ref(ProductID const& productID, key_type itemKey, EDProductGetter const* prodGetter) :
200  product_(productID, 0, mustBeNonZero(prodGetter, "Ref", productID), false), index_(itemKey) {
201  }
202 
204  // It is an error (not diagnosable at compile- or run-time) to call
205  // this constructor with a pointer to a T unless the pointed-to T
206  // object is already in a collection of type C stored in the
207  // Event. The given ProductID must be the id of the collection in
208  // the Event.
209 
210  Ref(ProductID const& iProductID, T const* item, key_type itemKey, C const* /* iProduct */) :
211  product_(iProductID, item, 0, false), index_(itemKey)
212  { }
213 
214  Ref(ProductID const& iProductID, T const* item, key_type itemKey) :
215  product_(iProductID, item, 0, false), index_(itemKey)
216  { }
217 
218  Ref(ProductID const& iProductID, T const* item, key_type itemKey, bool transient) :
219  product_(iProductID, item, 0, transient), index_(itemKey)
220  { }
221 
225 
226  explicit Ref(ProductID const& iId) :
227  product_(iId, 0, 0, false), index_(key_traits<key_type>::value)
228  { }
229 
231  Ref(RefProd<C> const& refProd, key_type itemKey);
232 
234  ~Ref() {}
235 
237  T const&
238  operator*() const;
239 
241  T const*
242  operator->() const;
243 
245  T const* get() const {
246  return isNull() ? 0 : this->operator->();
247  }
248 
250  bool isNull() const {return !isNonnull(); }
251 
254 
256  bool operator!() const {return isNull();}
257 
259  ProductID id() const {return product_.id();}
260 
263 
265  key_type key() const {return index_;}
266 
267  // This one just for backward compatibility. Will be removed soon.
268  key_type index() const {return index_;}
269 
271  bool hasProductCache() const {return product_.productPtr() != 0;}
272 
275  bool isAvailable() const;
276 
278  bool isTransient() const {return product_.isTransient();}
279 
280  RefCore const& refCore() const {return product_;}
281 
282  //Used by ROOT storage
284  // private:
285  // Constructor from member of RefVector
286  Ref(RefCore const& iRefCore, key_type const& iKey) :
287  product_(iRefCore), index_(iKey) {
288  }
289 
290  private:
291 
292  // Compile time check that the argument is a C* or C const*
293  // or derived from it.
294  void checkTypeAtCompileTime(C const*) {}
295 
297  key_type index_;
298  };
299 
300  //***************************
301  //Specialization for a vector
302  //***************************
303 #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
304 
305  template <typename E>
307  private:
310 
313  friend class RefVectorIterator<std::vector<E>, T, F>;
314  friend class RefVector<std::vector<E>, T, F>;
315  friend class RefVector<RefVector<std::vector<E>, T, F>, T, VF>;
316  friend class RefVector<RefVector<std::vector<E>, T, F>, T, VBF>;
317 
318  public:
320  typedef std::vector<E> product_type;
321  typedef typename refhelper::ValueTrait<std::vector<E> >::value value_type;
322  typedef value_type const element_type; //used for generic programming
323  typedef typename refhelper::FindTrait<std::vector<E>,
324  typename refhelper::ValueTrait<std::vector<E> >::value>::value finder_type;
325  typedef typename boost::binary_traits<F>::second_argument_type argument_type;
326  typedef unsigned int key_type;
329 
331 
333  Ref() : product_() {}
334 
336  Ref(Handle<product_type> const& handle, key_type itemKey, bool setNow=true);
337 
339  Ref(OrphanHandle<product_type> const& handle, key_type itemKey, bool setNow=true);
340 
342  // An exception will be thrown if an attempt is made to persistify
343  // any object containing this Ref. Also, in the future work will
344  // be done to throw an exception if an attempt is made to put any object
345  // containing this Ref into an event(or run or lumi).
346  Ref(product_type const* product, key_type itemKey, bool setNow=true);
347 
349  // An exception will be thrown if an attempt is made to persistify
350  // any object containing this Ref. Also, in the future work will
351  Ref(TestHandle<product_type> const& handle, key_type itemKey, bool setNow=true);
352 
356  Ref(ProductID const& productID, key_type itemKey, EDProductGetter const* prodGetter) :
357  product_(productID, 0, mustBeNonZero(prodGetter, "Ref", productID), false,itemKey) {
358  }
359 
361  // It is an error (not diagnosable at compile- or run-time) to call
362  // this constructor with a pointer to a T unless the pointed-to T
363  // object is already in a collection of type C stored in the
364  // Event. The given ProductID must be the id of the collection in
365  // the Event.
366 
367  Ref(ProductID const& iProductID, T const* item, key_type itemKey, product_type const* /* iProduct */) :
368  product_(iProductID, item, 0, false, itemKey)
369  { }
370 
371  Ref(ProductID const& iProductID, T const* item, key_type itemKey) :
372  product_(iProductID, item, 0, false, itemKey)
373  { }
374 
375  Ref(ProductID const& iProductID, T const* item, key_type itemKey, bool transient) :
376  product_(iProductID, item, 0, transient, itemKey)
377  { }
378 
382 
383  explicit Ref(ProductID const& iId) :
384  product_(iId, 0, 0, false,key_traits<key_type>::value)
385  { }
386 
388  Ref(RefProd<product_type> const& refProd, key_type itemKey);
389 
391  ~Ref() {}
392 
394  T const&
395  operator*() const;
396 
398  T const*
399  operator->() const;
400 
402  T const* get() const {
403  return isNull() ? 0 : this->operator->();
404  }
405 
407  bool isNull() const {return !isNonnull(); }
408 
410  bool isNonnull() const { return key()!=edm::key_traits<key_type>::value; }
411 
413  bool operator!() const {return isNull();}
414 
416  ProductID id() const {return product_.id();}
417 
420 
422  key_type key() const {return product_.index();}
423 
424  // This one just for backward compatibility. Will be removed soon.
425  key_type index() const {return product_.index();}
426 
428  bool hasProductCache() const {return product_.productPtr() != 0;}
429 
432  bool isAvailable() const;
433 
435  bool isTransient() const {return product_.isTransient();}
436 
437  RefCore const& refCore() const {return product_.toRefCore();}
438 
439  //Used by ROOT storage
441  // private:
442  // Constructor from member of RefVector
443  Ref(RefCore const& iRefCore, key_type const& iKey) :
444  product_(iRefCore,iKey) {
445  }
446 
447  private:
448  // Compile time check that the argument is a C* or C const*
449  // or derived from it.
451 
453  };
454 }
455 
459 
460 namespace edm {
461 
463  template <typename C, typename T, typename F>
464  inline
465  Ref<C, T, F>::Ref(Handle<C> const& handle, key_type itemKey, bool) :
466  product_(handle.id(), nullptr, nullptr, false), index_(itemKey) {
467  if(itemKey == key_traits<key_type>::value) return;
468  refitem::findRefItem<C, T, F, key_type>(product_, handle.product(), itemKey);
469  }
470 
472  template <typename E>
473  inline
474  Ref<REF_FOR_VECTOR_ARGS>::Ref(Handle<std::vector<E> > const& handle, key_type itemKey, bool) :
475  product_(handle.id(), nullptr, nullptr, false, itemKey){
476  if(itemKey == key_traits<key_type>::value) return;
477  refitem::findRefItem<product_type, value_type, finder_type, key_type>(product_.toRefCore(),
478  handle.product(),
479  itemKey);
480  }
481 
483  template <typename C, typename T, typename F>
484  inline
486  product_(handle.id(), nullptr, nullptr, false), index_(itemKey) {
487  if(itemKey == key_traits<key_type>::value) return;
488  refitem::findRefItem<C, T, F, key_type>(product_, handle.product(), itemKey);
489  }
490 
492  template <typename E>
493  inline
494  Ref<REF_FOR_VECTOR_ARGS>::Ref(OrphanHandle<std::vector<E> > const& handle, key_type itemKey, bool) :
495  product_(handle.id(), nullptr, nullptr, false, itemKey){
496  if(itemKey == key_traits<key_type>::value) return;
497  refitem::findRefItem<product_type, value_type, finder_type, key_type>(product_.toRefCore(),
498  handle.product(),
499  itemKey);
500  }
501 
503  // An exception will be thrown if an attempt is made to persistify
504  // any object containing this Ref. Also, in the future work will
505  // be done to throw an exception if an attempt is made to put any object
506  // containing this Ref into an event(or run or lumi).
507  // Note: It is legal for the referenced object to be put into the event
508  // and persistified. It is this Ref itself that cannot be persistified.
509  template <typename C, typename T, typename F>
510  inline
511  Ref<C, T, F>::Ref(C const* iProduct, key_type itemKey, bool) :
512  product_(ProductID(), nullptr, nullptr, true), index_(iProduct != nullptr ? itemKey : key_traits<key_type>::value) {
513  if(iProduct != nullptr) {
514  refitem::findRefItem<C, T, F, key_type>(product_, iProduct, itemKey);
515  }
516  }
517 
518  template <typename E>
519  inline
520  Ref<REF_FOR_VECTOR_ARGS>::Ref(std::vector<E> const* iProduct, key_type itemKey, bool) :
521  product_(ProductID(), nullptr, nullptr, true, iProduct != 0 ? itemKey : key_traits<key_type>::value) {
522  if(iProduct != nullptr) {
523  refitem::findRefItem<product_type, value_type, finder_type, key_type>(product_.toRefCore(), iProduct, itemKey);
524  }
525  }
526 
528  // An exception will be thrown if an attempt is made to persistify any object containing this Ref.
529  template <typename C, typename T, typename F>
530  inline
532  product_(handle.id(), nullptr, nullptr, true), index_(itemKey) {
533  if(itemKey == key_traits<key_type>::value) return;
534  refitem::findRefItem<C, T, F, key_type>(product_, handle.product(), itemKey);
535  }
536 
537  template <typename E>
538  inline
539  Ref<REF_FOR_VECTOR_ARGS>::Ref(TestHandle<std::vector<E> > const& handle, key_type itemKey, bool) :
540  product_(handle.id(), nullptr, nullptr, true, itemKey){
541  if(itemKey == key_traits<key_type>::value) return;
542  refitem::findRefItem<product_type, value_type, finder_type, key_type>(product_.toRefCore(),
543  handle.product(),
544  itemKey);
545  }
546 
548  template <typename C, typename T, typename F>
549  inline
550  Ref<C, T, F>::Ref(RefProd<C> const& refProd, key_type itemKey) :
551  product_(refProd.id(), nullptr, refProd.refCore().productGetter(), refProd.refCore().isTransient()),
552  index_(itemKey) {
553 
554  if(refProd.refCore().productPtr() != nullptr && itemKey != key_traits<key_type>::value) {
555  refitem::findRefItem<C, T, F, key_type>(product_,
556  static_cast<product_type const*>(refProd.refCore().productPtr()),
557  itemKey);
558  }
559  }
560 
561  template <typename E>
562  inline
563  Ref<REF_FOR_VECTOR_ARGS>::Ref(RefProd<std::vector<E> > const& refProd, key_type itemKey) :
564  product_(refProd.id(), nullptr, refProd.refCore().productGetter(), refProd.refCore().isTransient(), itemKey) {
565 
566  if(refProd.refCore().productPtr() != nullptr && itemKey != key_traits<key_type>::value) {
567  refitem::findRefItem<product_type, value_type, finder_type, key_type>(
568  product_.toRefCore(),
569  static_cast<product_type const*>(refProd.refCore().productPtr()),
570  itemKey);
571  }
572  }
573 
574  template <typename C, typename T, typename F>
575  inline
576  bool
578  if(product_.isAvailable()) {
579  return true;
580  }
581  return isThinnedAvailable<C>(product_, index_);
582  }
583 
584  template <typename E>
585  inline
586  bool
588  if(product_.isAvailable()) {
589  return true;
590  }
591  return isThinnedAvailable<std::vector<E> >(product_.toRefCore(), key());
592  }
593 
595  template <typename C, typename T, typename F>
596  inline
597  T const&
599  return *getRefPtr<C, T, F>(product_, index_);
600  }
601  template <typename E>
602  inline
605  return *getRefPtr<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), key());
606  }
607 
609  template <typename C, typename T, typename F>
610  inline
611  T const*
613  return getRefPtr<C, T, F>(product_, index_);
614  }
615  template <typename E>
616  inline
619  return getRefPtr<REF_FOR_VECTOR_ARGS>(product_.toRefCore(), key());
620  }
621 
622  template <typename C, typename T, typename F>
623  inline
624  bool
625  operator==(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
626  return lhs.key() == rhs.key() && lhs.refCore() == rhs.refCore() ;
627  }
628 
629  template <typename C, typename T, typename F>
630  inline
631  bool
632  operator!=(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
633  return !(lhs == rhs);
634  }
635 
636  template <typename C, typename T, typename F>
637  inline
638  bool
639  operator<(Ref<C, T, F> const& lhs, Ref<C, T, F> const& rhs) {
642  return (lhs.refCore() == rhs.refCore() ? compare_key<C>(lhs.key(), rhs.key()) : lhs.refCore() < rhs.refCore());
643  }
644 
645 }
646 
647 //Handle specialization here
649 #endif
bool isAvailable() const
Definition: Ref.h:577
type
Definition: HCALResponse.h:21
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:169
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:253
void checkTypeAtCompileTime(C const *)
Definition: Ref.h:294
Definition: CLHEP.h:16
T const * product() const
Definition: TestHandle.h:60
boost::enable_if< has_key_compare< C >, bool >::type compare_key(K const &lhs, K const &rhs)
Definition: Ref.h:130
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:367
boost::binary_traits< F >::second_argument_type argument_type
Definition: Ref.h:168
~Ref()
Destructor.
Definition: Ref.h:234
bool isTransient() const
Checks if this ref is transient (i.e. not persistable).
Definition: Ref.h:278
key_type index_
Definition: Ref.h:297
bool hasProductCache() const
Returns true if container referenced by the Ref has been cached.
Definition: Ref.h:271
RefCore const & refCore() const
Definition: Ref.h:280
key_type index() const
Definition: Ref.h:268
key_type key() const
Accessor for product key.
Definition: Ref.h:265
RefCore product_
Definition: Ref.h:296
#define REF_FOR_VECTOR_ARGS
Definition: Ref.h:303
#define nullptr
#define CMS_CLASS_VERSION(_version_)
Definition: classes.h:31
ProductID id() const
Accessor for product ID.
Definition: Ref.h:259
bool operator==(debugging_allocator< X > const &, debugging_allocator< Y > const &) noexcept
Ref(ProductID const &productID, key_type itemKey, EDProductGetter const *prodGetter)
Definition: Ref.h:199
void const * productPtr() const
Definition: RefCore.h:52
bool isAvailable() const
Definition: RefCore.cc:169
static key_type invalidKey()
Definition: Ref.h:173
Ref(ProductID const &iProductID, T const *item, key_type itemKey)
Definition: Ref.h:214
RefCore const & refCore() const
Definition: RefProd.h:123
def template(fileName, svg, replaceme="REPLACEME")
Definition: svgfig.py:520
Definition: value.py:1
T const element_type
Definition: Ref.h:166
refhelper::FindRefVectorUsingAdvance< RefToBaseVector< T > > VBF
Definition: Ref.h:156
bool operator!=(debugging_allocator< X > const &, debugging_allocator< Y > const &) noexcept
bool isNull() const
Checks for null.
Definition: Ref.h:250
refhelper::FindRefVectorUsingAdvance< RefVector< C, T, F > > VF
Definition: Ref.h:155
T const * product() const
Definition: Handle.h:81
T value_type
Definition: Ref.h:165
T const * product() const
Definition: OrphanHandle.h:57
F finder_type
Definition: Ref.h:167
Ref(ProductID const &iProductID, T const *item, key_type itemKey, bool transient)
Definition: Ref.h:218
C product_type
for export
Definition: Ref.h:164
Ref(ProductID const &iId)
Definition: Ref.h:226
EDProductGetter const * productGetter() const
Definition: RefCore.h:84
bool operator!() const
Checks for null.
Definition: Ref.h:256
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:176
HLT enums.
EDProductGetter const * productGetter() const
Accessor for product getter.
Definition: Ref.h:262
T const * operator->() const
Member dereference operator.
Definition: Ref.h:612
FindUsingAdvance< C, T > value
Definition: RefTraits.h:41
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:210
long double T
edm::RefVector< Container > RefVector
T const & operator*() const
Dereference operator.
Definition: Ref.h:598