CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
RefToBase.h
Go to the documentation of this file.
1 #ifndef DataFormats_Common_RefToBase_h
2 #define DataFormats_Common_RefToBase_h
3 // -*- C++ -*-
4 //
5 // Package: Common
6 // Class : RefToBase
7 //
28 //
29 // Original Author: Chris Jones
30 // Created: Mon Apr 3 16:37:59 EDT 2006
31 //
32 
33 // system include files
34 
35 // user include files
36 
41 
45 
46 #include <memory>
47 #include <type_traits>
48 
49 namespace edm {
50  //--------------------------------------------------------------------
51  // Class template RefToBase<T>
52  //--------------------------------------------------------------------
53 
57 
58  template<typename T> class RefToBaseVector;
59  template<typename C, typename T, typename F> class Ref;
60  template<typename C> class RefProd;
61  template<typename T> class RefToBaseProd;
62  template<typename T> class View;
63 
64  template <class T>
65  class RefToBase
66  {
67  public:
68  typedef T value_type;
69 
70  RefToBase();
71  RefToBase(RefToBase const& other);
72  template <typename C1, typename T1, typename F1>
73  explicit RefToBase(Ref<C1, T1, F1> const& r);
74  template <typename C>
75  explicit RefToBase(RefProd<C> const& r);
76  RefToBase(RefToBaseProd<T> const& r, size_t i);
77  RefToBase(Handle<View<T> > const& handle, size_t i);
78  template <typename T1>
79  explicit RefToBase(RefToBase<T1> const & r );
81  RefToBase(std::shared_ptr<reftobase::RefHolderBase> p);
82 
83  ~RefToBase();
84 
85  RefToBase& operator= (RefToBase const& rhs);
86 
87  value_type const& operator*() const;
88  value_type const* operator->() const;
89  value_type const* get() const;
90 
91  ProductID id() const;
92  size_t key() const;
93 
94  template <class REF> REF castTo() const;
95 
96  bool isNull() const;
97  bool isNonnull() const;
98  bool operator!() const;
99 
100  bool operator==(RefToBase const& rhs) const;
101  bool operator!=(RefToBase const& rhs) const;
102 
103  void swap(RefToBase& other);
104 
105  std::auto_ptr<reftobase::RefHolderBase> holder() const;
106 
107  EDProductGetter const* productGetter() const;
108 
111  bool isAvailable() const { return holder_? holder_->isAvailable(): false; }
112 
113  bool isTransient() const { return holder_ ? holder_->isTransient() : false; }
114 
115  //Needed for ROOT storage
117  private:
119  reftobase::BaseHolder<value_type>* holder_;
120  friend class RefToBaseVector<T>;
121  friend class RefToBaseProd<T>;
122  template<typename B> friend class RefToBase;
123  };
124 
125  //--------------------------------------------------------------------
126  // Implementation of RefToBase<T>
127  //--------------------------------------------------------------------
128 
129  template <class T>
130  inline
131  RefToBase<T>::RefToBase() :
132  holder_(nullptr)
133  { }
134 
135  template <class T>
136  inline
138  holder_(other.holder_ ? other.holder_->clone() : nullptr)
139  { }
140 
141  template <class T>
142  template <typename C1, typename T1, typename F1>
143  inline
145  holder_(new reftobase::Holder<T,Ref<C1, T1, F1> >(iRef))
146  { }
147 
148  template <class T>
149  template <typename C>
150  inline
152  holder_(new reftobase::Holder<T,RefProd<C> >(iRef))
153  { }
154 
155  template <class T>
156  template <typename T1>
157  inline
159  holder_(new reftobase::IndirectHolder<T> (
160  std::shared_ptr< edm::reftobase::RefHolderBase>(iRef.holder().release())
161  ) )
162  {
163  // OUT: holder_( new reftobase::Holder<T,RefToBase<T1> >(iRef ) ) {
164  // Forcing the conversion through IndirectHolder,
165  // as Holder<T,RefToBase<T1>> would need dictionaries we will never have.
166  // In this way we only need the IndirectHolder<T> and the RefHolder of the real type of the item
167  // This might cause a small performance penalty.
168  static_assert( std::is_base_of<T, T1>::value, "RefToBase::RefToBase T not base of T1" );
169  }
170 
171  template <class T>
172  inline
174  holder_(p.release())
175  {}
176 
177  template <class T>
178  inline
179  RefToBase<T>::RefToBase(std::shared_ptr<reftobase::RefHolderBase> p) :
180  holder_(new reftobase::IndirectHolder<T>(p))
181  { }
182 
183  template <class T>
184  inline
186  {
187  delete holder_;
188  }
189 
190  template <class T>
191  inline
192  RefToBase<T>&
194  {
195  RefToBase<T> temp( iRHS);
196  temp.swap(*this);
197  return *this;
198  }
199 
200  template <class T>
201  inline
202  T const&
204  {
205  return *getPtrImpl();
206  }
207 
208  template <class T>
209  inline
210  T const*
212  {
213  return getPtrImpl();
214  }
215 
216  template <class T>
217  inline
218  T const*
220  {
221  return getPtrImpl();
222  }
223 
224  template <class T>
225  inline
226  ProductID
228  {
229  return holder_ ? holder_->id() : ProductID();
230  }
231 
232  template <class T>
233  inline
234  size_t
236  {
237  if ( holder_ == nullptr )
239  "attempting get key from null RefToBase;\n"
240  "You should check for nullity before calling key().");
241  return holder_->key();
242  }
243 
244  namespace {
245  // If the template parameters are classes or structs they should be
246  // related by inheritance, otherwise they should be the same type.
247  template<typename T, typename U>
249  checkTypeCompatibility() { static_assert(std::is_base_of<T, U>::value ||
251  "RefToBase::castTo error element types are not related by inheritance"); }
252 
253  template<typename T, typename U>
255  checkTypeCompatibility() { static_assert(std::is_same<T, U>::value,
256  "RefToBase::castTo error non-class element types are not the same"); }
257 
258  // Convert the pointer types, use dynamic_cast if they are classes
259  template<typename T, typename OUT>
261  convertTo(T const* t) { return dynamic_cast<OUT const*>(t); }
262 
263  template<typename T, typename OUT>
265  convertTo(T const* t) { return t;}
266  }
267 
268  template <class T>
269  template <class REF>
270  REF
272 
273  if (!holder_) {
275  "attempting to cast a null RefToBase;\n"
276  "You should check for nullity before casting.");
277  }
278 
279  checkTypeCompatibility<T, typename REF::value_type>();
280 
281  // If REF is type edm::Ref<C,T,F>, then it is impossible to
282  // check the container type C here. We just have to assume
283  // that the caller provided the correct type.
284 
285  EDProductGetter const* getter = productGetter();
286  if(getter) {
287  return REF(id(), key(), getter);
288  }
289 
290  T const* value = get();
291  if(value == nullptr) {
292  return REF(id());
293  }
294  typename REF::value_type const* newValue = convertTo<T, typename REF::value_type>(value);
295  if(newValue) {
296  return REF(id(), newValue, key(), isTransient());
297  }
298 
300  "RefToBase<T>::castTo Error attempting to cast mismatched types\n"
301  "casting from RefToBase with T: ",
302  typeid(T).name(),
303  "\ncasting to: ",
304  typeid(REF).name()
305  );
306  return REF();
307  }
308 
310  template <class T>
311  inline
312  bool
314  {
315  return !id().isValid();
316  }
317 
319  template <class T>
320  inline
321  bool
323  {
324  return !isNull();
325  }
326 
328  template <class T>
329  inline
330  bool
332  {
333  return isNull();
334  }
335 
336  template <class T>
337  inline
338  bool
340  {
341  return holder_
342  ? holder_->isEqualTo(*rhs.holder_)
343  : holder_ == rhs.holder_;
344  }
345 
346  template <class T>
347  inline
348  bool
350  {
351  return !(*this == rhs);
352  }
353 
354  template <class T>
355  inline
356  void
358  {
359  std::swap(holder_, other.holder_);
360  }
361 
362  template <class T>
363  inline
365  return holder_? holder_->productGetter():nullptr;
366  }
367 
368  template <class T>
369  inline
370  T const*
372  {
373  return holder_ ? holder_->getPtr() : nullptr;
374  }
375 
376  template <class T>
377  std::auto_ptr<reftobase::RefHolderBase> RefToBase<T>::holder() const {
378  return holder_? holder_->holder() : std::auto_ptr<reftobase::RefHolderBase>();
379  }
380 
381  // Free swap function
382  template <class T>
383  inline
384  void
386  {
387  a.swap(b);
388  }
389 }
390 
394 
395 namespace edm {
396  template <class T>
397  inline
399  holder_( r.operator->()->refAt( i ).holder_->clone() ) {
400  }
401 
402  template<typename T>
403  inline
405  holder_( handle.operator->()->refAt( i ).holder_->clone() ) {
406  }
407 
408 }
409 
410 #endif
type
Definition: HCALResponse.h:21
value_type const * get() const
Definition: RefToBase.h:219
int i
Definition: DBlmapReader.cc:9
virtual bool isTransient() const =0
bool isAvailable() const
Definition: RefToBase.h:111
bool isNonnull() const
Checks for non-null.
Definition: RefToBase.h:322
virtual bool isAvailable() const =0
std::auto_ptr< reftobase::RefHolderBase > holder() const
Definition: RefToBase.h:377
#define nullptr
#define CMS_CLASS_VERSION(_version_)
Definition: classes.h:31
EDProductGetter const * productGetter(std::atomic< void const * > const &iCache)
ProductID id() const
Definition: RefToBase.h:227
void swap(Association< C > &lhs, Association< C > &rhs)
Definition: Association.h:116
bool operator==(RefToBase const &rhs) const
Definition: RefToBase.h:339
static void throwThis(Code category, char const *message0="", char const *message1="", char const *message2="", char const *message3="", char const *message4="")
void swap(RefToBase &other)
Definition: RefToBase.h:357
reftobase::BaseHolder< value_type > * holder_
Definition: RefToBase.h:119
size_t key() const
Definition: RefToBase.h:235
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
value_type const * operator->() const
Definition: RefToBase.h:211
tuple handle
Definition: patZpeak.py:22
bool operator!=(RefToBase const &rhs) const
Definition: RefToBase.h:349
string key
FastSim: produces sample of signal events, overlayed with premixed minbias events.
edm::RefProd< Container > RefProd
REF castTo() const
Definition: RefToBase.h:271
bool isNull() const
Checks for null.
Definition: RefToBase.h:313
value_type const * getPtrImpl() const
Definition: RefToBase.h:371
double b
Definition: hdecay.h:120
string const
Definition: compareJSON.py:14
TEveGeoShape * clone(const TEveElement *element, TEveElement *parent)
Definition: eve_macros.cc:135
EDProductGetter const * productGetter() const
Definition: RefToBase.h:364
bool operator!() const
Checks for null.
Definition: RefToBase.h:331
double a
Definition: hdecay.h:121
value_type const & operator*() const
Definition: RefToBase.h:203
bool isTransient() const
Definition: RefToBase.h:113
ProductIndex id() const
Definition: ProductID.h:38
long double T
RefToBase & operator=(RefToBase const &rhs)
Definition: RefToBase.h:193
def template
Definition: svgfig.py:520