CMS 3D CMS Logo

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);
73  RefToBase & operator=(RefToBase && other) noexcept;
74 
75  template <typename C1, typename T1, typename F1>
76  explicit RefToBase(Ref<C1, T1, F1> const& r);
77  template <typename C>
78  explicit RefToBase(RefProd<C> const& r);
79  RefToBase(RefToBaseProd<T> const& r, size_t i);
80  RefToBase(Handle<View<T> > const& handle, size_t i);
81  template <typename T1>
82  explicit RefToBase(RefToBase<T1> const & r );
83  RefToBase(std::unique_ptr<reftobase::BaseHolder<value_type>>);
84  RefToBase(std::shared_ptr<reftobase::RefHolderBase> p);
85 
86  ~RefToBase() noexcept;
87 
88  RefToBase& operator= (RefToBase const& rhs);
89 
90  value_type const& operator*() const;
91  value_type const* operator->() const;
92  value_type const* get() const;
93 
94  ProductID id() const;
95  size_t key() const;
96 
97  template <class REF> REF castTo() const;
98 
99  bool isNull() const;
100  bool isNonnull() const;
101  bool operator!() const;
102 
103  bool operator==(RefToBase const& rhs) const;
104  bool operator!=(RefToBase const& rhs) const;
105 
106  void swap(RefToBase& other);
107 
108  std::unique_ptr<reftobase::RefHolderBase> holder() const;
109 
110  EDProductGetter const* productGetter() const;
111 
114  bool isAvailable() const { return holder_? holder_->isAvailable(): false; }
115 
116  bool isTransient() const { return holder_ ? holder_->isTransient() : false; }
117 
118  //Needed for ROOT storage
120  private:
121  value_type const* getPtrImpl() const;
122  reftobase::BaseHolder<value_type>* holder_;
123  friend class RefToBaseVector<T>;
124  friend class RefToBaseProd<T>;
125  template<typename B> friend class RefToBase;
126  };
127 
128  //--------------------------------------------------------------------
129  // Implementation of RefToBase<T>
130  //--------------------------------------------------------------------
131 
132  template <class T>
133  inline
134  RefToBase<T>::RefToBase() :
135  holder_(nullptr)
136  { }
137 
138  template <class T>
139  inline
141  holder_(other.holder_ ? other.holder_->clone() : nullptr)
142  { }
143 
144  template <class T>
145  inline
147  holder_(other.holder_) { other.holder_=nullptr;}
148 
149  template <class T>
150  inline
152  delete holder_; holder_=other.holder_; other.holder_=nullptr; return *this;
153  }
154 
155 
156  template <class T>
157  template <typename C1, typename T1, typename F1>
158  inline
160  holder_(new reftobase::Holder<T,Ref<C1, T1, F1> >(iRef))
161  { }
162 
163  template <class T>
164  template <typename C>
165  inline
167  holder_(new reftobase::Holder<T,RefProd<C> >(iRef))
168  { }
169 
170  template <class T>
171  template <typename T1>
172  inline
174  holder_(new reftobase::IndirectHolder<T> (
175  std::shared_ptr< edm::reftobase::RefHolderBase>(iRef.holder().release())
176  ) )
177  {
178  // OUT: holder_( new reftobase::Holder<T,RefToBase<T1> >(iRef ) ) {
179  // Forcing the conversion through IndirectHolder,
180  // as Holder<T,RefToBase<T1>> would need dictionaries we will never have.
181  // In this way we only need the IndirectHolder<T> and the RefHolder of the real type of the item
182  // This might cause a small performance penalty.
183  static_assert( std::is_base_of<T, T1>::value, "RefToBase::RefToBase T not base of T1" );
184  }
185 
186  template <class T>
187  inline
189  holder_(p.release())
190  {}
191 
192  template <class T>
193  inline
194  RefToBase<T>::RefToBase(std::shared_ptr<reftobase::RefHolderBase> p) :
195  holder_(new reftobase::IndirectHolder<T>(p))
196  { }
197 
198  template <class T>
199  inline
201  {
202  delete holder_;
203  }
204 
205  template <class T>
206  inline
207  RefToBase<T>&
209  {
210  RefToBase<T> temp( iRHS);
211  temp.swap(*this);
212  return *this;
213  }
214 
215  template <class T>
216  inline
217  T const&
219  {
220  return *getPtrImpl();
221  }
222 
223  template <class T>
224  inline
225  T const*
227  {
228  return getPtrImpl();
229  }
230 
231  template <class T>
232  inline
233  T const*
235  {
236  return getPtrImpl();
237  }
238 
239  template <class T>
240  inline
241  ProductID
243  {
244  return holder_ ? holder_->id() : ProductID();
245  }
246 
247  template <class T>
248  inline
249  size_t
251  {
252  if ( holder_ == nullptr )
254  "attempting get key from null RefToBase;\n"
255  "You should check for nullity before calling key().");
256  return holder_->key();
257  }
258 
259  namespace {
260  // If the template parameters are classes or structs they should be
261  // related by inheritance, otherwise they should be the same type.
262  template<typename T, typename U>
264  checkTypeCompatibility() { static_assert(std::is_base_of<T, U>::value ||
266  "RefToBase::castTo error element types are not related by inheritance"); }
267 
268  template<typename T, typename U>
270  checkTypeCompatibility() { static_assert(std::is_same<T, U>::value,
271  "RefToBase::castTo error non-class element types are not the same"); }
272 
273  // Convert the pointer types, use dynamic_cast if they are classes
274  template<typename T, typename OUT>
276  convertTo(T const* t) { return dynamic_cast<OUT const*>(t); }
277 
278  template<typename T, typename OUT>
280  convertTo(T const* t) { return t;}
281  }
282 
283  template <class T>
284  template <class REF>
285  REF
287 
288  if (!holder_) {
290  "attempting to cast a null RefToBase;\n"
291  "You should check for nullity before casting.");
292  }
293 
294  checkTypeCompatibility<T, typename REF::value_type>();
295 
296  // If REF is type edm::Ref<C,T,F>, then it is impossible to
297  // check the container type C here. We just have to assume
298  // that the caller provided the correct type.
299 
300  EDProductGetter const* getter = productGetter();
301  if(getter) {
302  return REF(id(), key(), getter);
303  }
304 
305  T const* value = get();
306  if(value == nullptr) {
307  return REF(id());
308  }
309  typename REF::value_type const* newValue = convertTo<T, typename REF::value_type>(value);
310  if(newValue) {
311  return REF(id(), newValue, key(), isTransient());
312  }
313 
315  "RefToBase<T>::castTo Error attempting to cast mismatched types\n"
316  "casting from RefToBase with T: ",
317  typeid(T).name(),
318  "\ncasting to: ",
319  typeid(REF).name()
320  );
321  return REF();
322  }
323 
325  template <class T>
326  inline
327  bool
329  {
330  return !id().isValid();
331  }
332 
334  template <class T>
335  inline
336  bool
338  {
339  return !isNull();
340  }
341 
343  template <class T>
344  inline
345  bool
347  {
348  return isNull();
349  }
350 
351  template <class T>
352  inline
353  bool
355  {
356  return holder_
357  ? holder_->isEqualTo(*rhs.holder_)
358  : holder_ == rhs.holder_;
359  }
360 
361  template <class T>
362  inline
363  bool
365  {
366  return !(*this == rhs);
367  }
368 
369  template <class T>
370  inline
371  void
373  {
374  std::swap(holder_, other.holder_);
375  }
376 
377  template <class T>
378  inline
380  return holder_? holder_->productGetter():nullptr;
381  }
382 
383  template <class T>
384  inline
385  T const*
387  {
388  return holder_ ? holder_->getPtr() : nullptr;
389  }
390 
391  template <class T>
392  std::unique_ptr<reftobase::RefHolderBase> RefToBase<T>::holder() const {
393  return holder_? holder_->holder() : std::unique_ptr<reftobase::RefHolderBase>();
394  }
395 
396  // Free swap function
397  template <class T>
398  inline
399  void
401  {
402  a.swap(b);
403  }
404 }
405 
409 
410 namespace edm {
411  template <class T>
412  inline
414  holder_( r.operator->()->refAt( i ).holder_->clone() ) {
415  }
416 
417  template<typename T>
418  inline
420  holder_( handle.operator->()->refAt( i ).holder_->clone() ) {
421  }
422 
423 }
424 
425 #endif
type
Definition: HCALResponse.h:21
value_type const * get() const
Definition: RefToBase.h:234
virtual std::unique_ptr< RefHolderBase > holder() const =0
virtual EDProductGetter const * productGetter() const =0
bool isAvailable() const
Definition: RefToBase.h:114
virtual bool isTransient() const =0
#define noexcept
bool isNonnull() const
Checks for non-null.
Definition: RefToBase.h:337
virtual T const * getPtr() const =0
virtual bool isAvailable() const =0
#define nullptr
#define CMS_CLASS_VERSION(_version_)
Definition: classes.h:31
ProductID id() const
Definition: RefToBase.h:242
bool operator==(RefToBase const &rhs) const
Definition: RefToBase.h:354
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:372
virtual ProductID id() const =0
reftobase::BaseHolder< value_type > * holder_
Definition: RefToBase.h:122
size_t key() const
Definition: RefToBase.h:250
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
value_type const * operator->() const
Definition: RefToBase.h:226
def template(fileName, svg, replaceme="REPLACEME")
Definition: svgfig.py:520
virtual size_t key() const =0
Definition: value.py:1
bool operator!=(RefToBase const &rhs) const
Definition: RefToBase.h:364
edm::RefProd< Container > RefProd
REF castTo() const
Definition: RefToBase.h:286
bool isNull() const
Checks for null.
Definition: RefToBase.h:328
value_type const * getPtrImpl() const
Definition: RefToBase.h:386
double b
Definition: hdecay.h:120
TEveGeoShape * clone(const TEveElement *element, TEveElement *parent)
Definition: eve_macros.cc:135
EDProductGetter const * productGetter() const
Definition: RefToBase.h:379
bool operator!() const
Checks for null.
Definition: RefToBase.h:346
RefToBase & operator=(RefToBase &&other)
Definition: RefToBase.h:151
HLT enums.
double a
Definition: hdecay.h:121
value_type const & operator*() const
Definition: RefToBase.h:218
bool isTransient() const
Definition: RefToBase.h:116
bool isValid() const
Definition: ProductID.h:35
long double T
virtual bool isEqualTo(BaseHolder< T > const &rhs) const =0
std::unique_ptr< reftobase::RefHolderBase > holder() const
Definition: RefToBase.h:392