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 )
253  {
255  "attempting get key from null RefToBase;\n"
256  "You should check for nullity before calling key().");
257  return 0;
258  }
259  return holder_->key();
260  }
261 
262  namespace {
263  // If the template parameters are classes or structs they should be
264  // related by inheritance, otherwise they should be the same type.
265  template<typename T, typename U>
267  checkTypeCompatibility() { static_assert(std::is_base_of<T, U>::value ||
269  "RefToBase::castTo error element types are not related by inheritance"); }
270 
271  template<typename T, typename U>
273  checkTypeCompatibility() { static_assert(std::is_same<T, U>::value,
274  "RefToBase::castTo error non-class element types are not the same"); }
275 
276  // Convert the pointer types, use dynamic_cast if they are classes
277  template<typename T, typename OUT>
279  convertTo(T const* t) { return dynamic_cast<OUT const*>(t); }
280 
281  template<typename T, typename OUT>
283  convertTo(T const* t) { return t;}
284  }
285 
286  template <class T>
287  template <class REF>
288  REF
290 
291  if (!holder_) {
293  "attempting to cast a null RefToBase;\n"
294  "You should check for nullity before casting.");
295  }
296 
297  checkTypeCompatibility<T, typename REF::value_type>();
298 
299  // If REF is type edm::Ref<C,T,F>, then it is impossible to
300  // check the container type C here. We just have to assume
301  // that the caller provided the correct type.
302 
303  EDProductGetter const* getter = productGetter();
304  if(getter) {
305  return REF(id(), key(), getter);
306  }
307 
308  T const* value = get();
309  if(value == nullptr) {
310  return REF(id());
311  }
312  typename REF::value_type const* newValue = convertTo<T, typename REF::value_type>(value);
313  if(newValue) {
314  return REF(id(), newValue, key(), isTransient());
315  }
316 
318  "RefToBase<T>::castTo Error attempting to cast mismatched types\n"
319  "casting from RefToBase with T: ",
320  typeid(T).name(),
321  "\ncasting to: ",
322  typeid(REF).name()
323  );
324  return REF();
325  }
326 
328  template <class T>
329  inline
330  bool
332  {
333  return !id().isValid();
334  }
335 
337  template <class T>
338  inline
339  bool
341  {
342  return !isNull();
343  }
344 
346  template <class T>
347  inline
348  bool
350  {
351  return isNull();
352  }
353 
354  template <class T>
355  inline
356  bool
358  {
359  return holder_
360  ? holder_->isEqualTo(*rhs.holder_)
361  : holder_ == rhs.holder_;
362  }
363 
364  template <class T>
365  inline
366  bool
368  {
369  return !(*this == rhs);
370  }
371 
372  template <class T>
373  inline
374  void
376  {
377  std::swap(holder_, other.holder_);
378  }
379 
380  template <class T>
381  inline
383  return holder_? holder_->productGetter():nullptr;
384  }
385 
386  template <class T>
387  inline
388  T const*
390  {
391  return holder_ ? holder_->getPtr() : nullptr;
392  }
393 
394  template <class T>
395  std::unique_ptr<reftobase::RefHolderBase> RefToBase<T>::holder() const {
396  return holder_? holder_->holder() : std::unique_ptr<reftobase::RefHolderBase>();
397  }
398 
399  // Free swap function
400  template <class T>
401  inline
402  void
404  {
405  a.swap(b);
406  }
407 }
408 
412 
413 namespace edm {
414  template <class T>
415  inline
417  holder_( r.operator->()->refAt( i ).holder_->clone() ) {
418  }
419 
420  template<typename T>
421  inline
423  holder_( handle.operator->()->refAt( i ).holder_->clone() ) {
424  }
425 
426 }
427 
428 #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:340
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:357
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:375
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
static const std::string B
bool operator!=(RefToBase const &rhs) const
Definition: RefToBase.h:367
edm::RefProd< Container > RefProd
REF castTo() const
Definition: RefToBase.h:289
bool isNull() const
Checks for null.
Definition: RefToBase.h:331
value_type const * getPtrImpl() const
Definition: RefToBase.h:389
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:382
bool operator!() const
Checks for null.
Definition: RefToBase.h:349
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:395