CMS 3D CMS Logo

Ptr.h
Go to the documentation of this file.
1 #ifndef DataFormats_Common_Ptr_h
2 #define DataFormats_Common_Ptr_h
3 // -*- C++ -*-
4 //
5 // Package: Common
6 // Class : Ptr
7 //
16 //
17 // Original Author: Chris Jones
18 // Created: Thu Oct 18 14:41:33 CEST 2007
19 //
20 
21 // user include files
33 
34 // system include files
35 #include <type_traits>
36 
37 // forward declarations
38 namespace edm {
39  template<typename T>
40  class Ptr {
41  friend class PtrVectorBase;
42  public:
43 
44  typedef unsigned long key_type;
45  typedef T value_type;
46 
47  // General purpose constructor from handle.
48  template<typename C>
49  Ptr(Handle<C> const& handle, key_type itemKey, bool /*setNow*/ = true):
50  core_(handle.id(), getItem_(handle.product(), itemKey), nullptr, false), key_(itemKey) {}
51 
52  // General purpose constructor from orphan handle.
53  template<typename C>
54  Ptr(OrphanHandle<C> const& handle, key_type itemKey, bool /*setNow*/ = true):
55  core_(handle.id(), getItem_(handle.product(), itemKey), nullptr, false), key_(itemKey) {}
56 
57  // General purpose "constructor" from a Ref.
58  // Use the conversion function template:
59  // ptr = refToPtr(ref)
60  // defined in DataFormats/Common/interface/RefToPtr.h
61  // to construct a Ptr<T> from a Ref<C>, where T is C::value_type.
62 
63  // Constructors for ref to object that is not in an event.
64  // An exception will be thrown if an attempt is made to persistify
65  // any object containing this Ptr. Also, in the future work will
66  // be done to throw an exception if an attempt is made to put any object
67  // containing this Ptr into an event(or run or lumi).
68 
69  template<typename C>
70  Ptr(C const* iProduct, key_type iItemKey, bool /*setNow*/ = true):
71  core_(ProductID(), iProduct != nullptr ? getItem_(iProduct,iItemKey) : nullptr, nullptr, true),
72  key_(iProduct != nullptr ? iItemKey : key_traits<key_type>::value) {}
73 
74  Ptr(T const* item, key_type iItemKey):
75  core_(ProductID(), item, nullptr, true),
76  key_(item != nullptr ? iItemKey : key_traits<key_type>::value) {}
77 
78  // Constructor from test handle.
79  // An exception will be thrown if an attempt is made to persistify
80  // any object containing this Ptr.
81  template<typename C>
82  Ptr(TestHandle<C> const& handle, key_type itemKey, bool /*setNow*/ = true):
83  core_(handle.id(), getItem_(handle.product(), itemKey), 0, true), key_(itemKey) {}
84 
88  Ptr(ProductID const& productID, key_type itemKey, EDProductGetter const* prodGetter) :
89  core_(productID, nullptr, mustBeNonZero(prodGetter, "Ptr", productID), false), key_(itemKey) {
90  }
91 
99  Ptr(ProductID const& productID, T const* item, key_type item_key) :
100  core_(productID, item, nullptr, false),
101  key_(item_key) {
102  }
103 
104  Ptr(ProductID const& productID, T const* item, key_type item_key, bool transient) :
105  core_(productID, item, nullptr, transient),
106  key_(item_key) {
107  }
108 
113  explicit Ptr(ProductID const& iId) :
114  core_(iId, nullptr, nullptr, false),
115  key_(key_traits<key_type>::value)
116  { }
117 
118  Ptr():
119  core_(),
120  key_(key_traits<key_type>::value)
121  {}
122 
123  template<typename U>
124  Ptr(Ptr<U> const& iOther, std::enable_if_t<std::is_base_of<T, U>::value> * = nullptr):
125  core_(iOther.id(),
126  (iOther.hasProductCache() ? static_cast<T const*>(iOther.get()): static_cast<T const*>(nullptr)),
127  iOther.productGetter(),
128  iOther.isTransient()),
129  key_(iOther.key()) {
130  //make sure a race condition didn't happen where between the call to hasProductCache() and
131  // productGetter() the object was gotten
132  if(iOther.hasProductCache() and not hasProductCache()) {
133  core_.setProductPtr(static_cast<T const*>(iOther.get()) );
134  }
135  }
136 
137  template<typename U>
138  explicit
139  Ptr(Ptr<U> const& iOther, std::enable_if_t<std::is_base_of<U, T>::value> * = nullptr):
140  core_(iOther.id(),
141  dynamic_cast<T const*>(iOther.get()),
142  nullptr,
143  iOther.isTransient()),
144  key_(iOther.key()) {
145  }
146 
148  ~Ptr() {}
149 
151  T const&
152  operator*() const;
153 
155  T const*
156  operator->() const;
157 
159  T const* get() const {
160  return isNull() ? nullptr : this->operator->();
161  }
162 
164  bool isNull() const {return !isNonnull(); }
165 
167  //bool isNonnull() const {return id().isValid(); }
168  bool isNonnull() const {return key_traits<key_type>::value != key_;}
170  bool operator!() const {return isNull();}
171 
174  bool isAvailable() const;
175 
177  bool isTransient() const {return core_.isTransient();}
178 
180  ProductID id() const {return core_.id();}
181 
184 
185  key_type key() const {return key_;}
186 
187  bool hasProductCache() const { return nullptr != core_.productPtr(); }
188 
189  RefCore const& refCore() const {return core_;}
190  // ---------- member functions ---------------------------
191 
192  void const* product() const {return nullptr;}
193 
194  //Used by ROOT storage
196 
197  private:
198 
199  template<typename C>
200  T const* getItem_(C const* product, key_type iKey);
201 
202  void getData_(bool throwIfNotFound = true) const {
203  EDProductGetter const* getter = productGetter();
204  if(getter != nullptr) {
205  WrapperBase const* prod = getter->getIt(core_.id());
206  unsigned int iKey = key_;
207  if(prod == nullptr) {
208  prod = getter->getThinnedProduct(core_.id(), iKey);
209  if(prod == nullptr) {
210  if(throwIfNotFound) {
212  } else {
213  return;
214  }
215  }
216  }
217  void const* ad = nullptr;
218  prod->setPtr(typeid(T), iKey, ad);
219  core_.setProductPtr(ad);
220  }
221  }
222  // ---------- member data --------------------------------
224  key_type key_;
225  };
226 
227  template<typename T>
228  template<typename C>
229  T const* Ptr<T>::getItem_(C const* iProduct, key_type iKey) {
230  assert (iProduct != nullptr);
231  typename C::const_iterator it = iProduct->begin();
232  std::advance(it,iKey);
233  T const* address = detail::GetProduct<C>::address(it);
234  return address;
235  }
236 
238  template<typename T>
239  inline
240  T const&
242  getData_();
243  return *reinterpret_cast<T const*>(core_.productPtr());
244  }
245 
247  template<typename T>
248  inline
249  T const*
251  getData_();
252  return reinterpret_cast<T const*>(core_.productPtr());
253  }
254 
255  template<typename T>
256  inline
257  bool
259  getData_(false);
260  return hasProductCache();
261  }
262 
263  template<typename T>
264  inline
265  bool
266  operator==(Ptr<T> const& lhs, Ptr<T> const& rhs) {
267  return lhs.refCore() == rhs.refCore() && lhs.key() == rhs.key();
268  }
269 
270  template<typename T>
271  inline
272  bool
273  operator!=(Ptr<T> const& lhs, Ptr<T> const& rhs) {
274  return !(lhs == rhs);
275  }
276 
277  template<typename T>
278  inline
279  bool
280  operator<(Ptr<T> const& lhs, Ptr<T> const& rhs) {
283  return (lhs.refCore() == rhs.refCore() ? lhs.key() < rhs.key() : lhs.refCore() < rhs.refCore());
284  }
285 }
286 
287 //The following is needed to get RefToBase to work with an edm::Ptr
288 //Handle specialization here
290 #include <vector>
291 
292 namespace edm {
293  template <typename T>
294  inline
295  void
296  fillView(std::vector<edm::Ptr<T> > const& obj,
297  ProductID const& id,
298  std::vector<void const*>& pointers,
300  pointers.reserve(obj.size());
301  helpers.reserve(obj.size());
302  for (auto const& p: obj) {
303  if(p.isAvailable()) {
304  pointers.push_back(p.get());
305  }else {
306  pointers.push_back(nullptr);
307  }
308  helpers.emplace_back(p.id(),p.key());
309  }
310  }
311 }
312 
313 #endif
void getData_(bool throwIfNotFound=true) const
Definition: Ptr.h:202
Ptr(Handle< C > const &handle, key_type itemKey, bool=true)
Definition: Ptr.h:49
EDProductGetter const * mustBeNonZero(EDProductGetter const *prodGetter, std::string refType, ProductID const &productID)
void setProductPtr(void const *prodPtr) const
Definition: RefCore.h:58
static const element_type * address(const iter &i)
Definition: GetProduct.h:33
key_type key() const
Definition: Ptr.h:185
void setPtr(std::type_info const &iToType, unsigned long iIndex, void const *&oPtr) const
Definition: WrapperBase.cc:27
Ptr(C const *iProduct, key_type iItemKey, bool=true)
Definition: Ptr.h:70
T const * get() const
Returns C++ pointer to the item.
Definition: Ptr.h:159
bool isAvailable() const
Definition: Ptr.h:258
virtual WrapperBase const * getThinnedProduct(ProductID const &, unsigned int &key) const =0
T const * getItem_(C const *product, key_type iKey)
Definition: Ptr.h:229
#define nullptr
void const * product() const
Definition: Ptr.h:192
EDProductGetter const * productGetter() const
Accessor for product getter.
Definition: Ptr.h:183
T const * operator->() const
Member dereference operator.
Definition: Ptr.h:250
unsigned long key_type
Definition: Ptr.h:44
#define CMS_CLASS_VERSION(_version_)
Ptr(OrphanHandle< C > const &handle, key_type itemKey, bool=true)
Definition: Ptr.h:54
T value_type
Definition: Ptr.h:45
T const & operator*() const
Dereference operator.
Definition: Ptr.h:241
Ptr(TestHandle< C > const &handle, key_type itemKey, bool=true)
Definition: Ptr.h:82
bool operator==(debugging_allocator< X > const &, debugging_allocator< Y > const &) noexcept
bool isTransient() const
Checks if this Ptr is transient (i.e. not persistable).
Definition: Ptr.h:177
Ptr()
Definition: Ptr.h:118
Ptr(T const *item, key_type iItemKey)
Definition: Ptr.h:74
key_type key_
Definition: Ptr.h:224
void const * productPtr() const
Definition: RefCore.h:52
void fillView(AssociationVector< KeyRefProd, CVal, KeyRef, SizeType, KeyReferenceHelper > const &obj, ProductID const &id, std::vector< void const * > &pointers, FillViewHelperVector &helpers)
bool isNull() const
Checks for null.
Definition: Ptr.h:164
RefCore const & refCore() const
Definition: Ptr.h:189
def template(fileName, svg, replaceme="REPLACEME")
Definition: svgfig.py:521
Definition: value.py:1
virtual WrapperBase const * getIt(ProductID const &) const =0
void productNotFoundException(std::type_info const &type) const
Definition: RefCore.cc:141
bool operator!=(debugging_allocator< X > const &, debugging_allocator< Y > const &) noexcept
Ptr(ProductID const &productID, T const *item, key_type item_key, bool transient)
Definition: Ptr.h:104
bool isNonnull() const
Checks for non-null.
Definition: Ptr.h:168
Ptr(ProductID const &productID, T const *item, key_type item_key)
Definition: Ptr.h:99
Ptr(Ptr< U > const &iOther, std::enable_if_t< std::is_base_of< U, T >::value > *=nullptr)
Definition: Ptr.h:139
bool hasProductCache() const
Definition: Ptr.h:187
Ptr(ProductID const &productID, key_type itemKey, EDProductGetter const *prodGetter)
Definition: Ptr.h:88
RefCore core_
Definition: Ptr.h:223
Ptr(ProductID const &iId)
Definition: Ptr.h:113
ProductID id() const
Accessor for product ID.
Definition: Ptr.h:180
EDProductGetter const * productGetter() const
Definition: RefCore.h:84
ProductID id() const
Definition: RefCore.h:49
bool isTransient() const
Definition: RefCore.h:106
HLT enums.
bool operator!() const
Checks for null.
Definition: Ptr.h:170
long double T
std::vector< std::pair< edm::ProductID, unsigned long > > FillViewHelperVector
~Ptr()
Destructor.
Definition: Ptr.h:148
Ptr(Ptr< U > const &iOther, std::enable_if_t< std::is_base_of< T, U >::value > *=nullptr)
Definition: Ptr.h:124