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>
59  class RefToBaseVector;
60  template <typename C, typename T, typename F>
61  class Ref;
62  template <typename C>
63  class RefProd;
64  template <typename T>
66  template <typename T>
67  class View;
68 
69  template <class T>
70  class RefToBase {
71  public:
72  typedef T value_type;
73 
74  RefToBase();
75  RefToBase(RefToBase const& other);
76  RefToBase(RefToBase&& other) noexcept;
77  RefToBase& operator=(RefToBase&& other) noexcept;
78 
79  template <typename C1, typename T1, typename F1>
80  explicit RefToBase(Ref<C1, T1, F1> const& r);
81  template <typename C>
82  explicit RefToBase(RefProd<C> const& r);
83  RefToBase(RefToBaseProd<T> const& r, size_t i);
84  RefToBase(Handle<View<T>> const& handle, size_t i);
85  template <typename T1>
86  explicit RefToBase(RefToBase<T1> const& r);
88  RefToBase(std::shared_ptr<reftobase::RefHolderBase> p);
89 
90  ~RefToBase() noexcept;
91 
93 
97 
98  ProductID id() const;
99  size_t key() const;
100 
101  template <class REF>
102  REF castTo() const;
103 
104  bool isNull() const;
105  bool isNonnull() const;
106  bool operator!() const;
107 
108  bool operator==(RefToBase const& rhs) const;
109  bool operator!=(RefToBase const& rhs) const;
110 
111  void swap(RefToBase& other);
112 
113  std::unique_ptr<reftobase::RefHolderBase> holder() const;
114 
116 
121  bool isAvailable() const { return holder_ ? holder_->isAvailable() : false; }
122 
123  bool isTransient() const { return holder_ ? holder_->isTransient() : false; }
124 
125  //Needed for ROOT storage
127  private:
129  reftobase::BaseHolder<value_type>* holder_;
130  friend class RefToBaseVector<T>;
131  friend class RefToBaseProd<T>;
132  template <typename B>
133  friend class RefToBase;
134  };
135 
136  //--------------------------------------------------------------------
137  // Implementation of RefToBase<T>
138  //--------------------------------------------------------------------
139 
140  template <class T>
141  inline RefToBase<T>::RefToBase() : holder_(nullptr) {}
142 
143  template <class T>
145 
146  template <class T>
147  inline RefToBase<T>::RefToBase(RefToBase&& other) noexcept : holder_(other.holder_) {
148  other.holder_ = nullptr;
149  }
150 
151  template <class T>
153  delete holder_;
154  holder_ = other.holder_;
155  other.holder_ = nullptr;
156  return *this;
157  }
158 
159  template <class T>
160  template <typename C1, typename T1, typename F1>
162  : holder_(new reftobase::Holder<T, Ref<C1, T1, F1>>(iRef)) {}
163 
164  template <class T>
165  template <typename C>
166  inline RefToBase<T>::RefToBase(RefProd<C> const& iRef) : holder_(new reftobase::Holder<T, RefProd<C>>(iRef)) {}
167 
168  template <class T>
169  template <typename T1>
171  : holder_(
172  new reftobase::IndirectHolder<T>(std::shared_ptr<edm::reftobase::RefHolderBase>(iRef.holder().release()))) {
173  // OUT: holder_( new reftobase::Holder<T,RefToBase<T1> >(iRef ) ) {
174  // Forcing the conversion through IndirectHolder,
175  // as Holder<T,RefToBase<T1>> would need dictionaries we will never have.
176  // In this way we only need the IndirectHolder<T> and the RefHolder of the real type of the item
177  // This might cause a small performance penalty.
178  static_assert(std::is_base_of<T, T1>::value, "RefToBase::RefToBase T not base of T1");
179  }
180 
181  template <class T>
183 
184  template <class T>
185  inline RefToBase<T>::RefToBase(std::shared_ptr<reftobase::RefHolderBase> p)
186  : holder_(new reftobase::IndirectHolder<T>(p)) {}
187 
188  template <class T>
189  inline RefToBase<T>::~RefToBase() noexcept {
190  delete holder_;
191  }
192 
193  template <class T>
194  inline RefToBase<T>& RefToBase<T>::operator=(RefToBase<T> const& iRHS) {
195  RefToBase<T> temp(iRHS);
196  temp.swap(*this);
197  return *this;
198  }
199 
200  template <class T>
201  inline T const& RefToBase<T>::operator*() const {
202  return *getPtrImpl();
203  }
204 
205  template <class T>
206  inline T const* RefToBase<T>::operator->() const {
207  return getPtrImpl();
208  }
209 
210  template <class T>
211  inline T const* RefToBase<T>::get() const {
212  return getPtrImpl();
213  }
214 
215  template <class T>
216  inline ProductID RefToBase<T>::id() const {
217  return holder_ ? holder_->id() : ProductID();
218  }
219 
220  template <class T>
221  inline size_t RefToBase<T>::key() const {
222  if (holder_ == nullptr) {
223  Exception::throwThis(errors::InvalidReference,
224  "attempting get key from null RefToBase;\n"
225  "You should check for nullity before calling key().");
226  return 0;
227  }
228  return holder_->key();
229  }
230 
231  namespace {
232  // If the template parameters are classes or structs they should be
233  // related by inheritance, otherwise they should be the same type.
234  template <typename T, typename U>
235  typename std::enable_if<std::is_class<T>::value>::type checkTypeCompatibility() {
237  "RefToBase::castTo error element types are not related by inheritance");
238  }
239 
240  template <typename T, typename U>
241  typename std::enable_if<!std::is_class<T>::value>::type checkTypeCompatibility() {
242  static_assert(std::is_same<T, U>::value, "RefToBase::castTo error non-class element types are not the same");
243  }
244 
245  // Convert the pointer types, use dynamic_cast if they are classes
246  template <typename T, typename OUT>
247  typename std::enable_if<std::is_class<T>::value, OUT const*>::type convertTo(T const* t) {
248  return dynamic_cast<OUT const*>(t);
249  }
250 
251  template <typename T, typename OUT>
252  typename std::enable_if<!std::is_class<T>::value, OUT const*>::type convertTo(T const* t) {
253  return t;
254  }
255  } // namespace
256 
257  template <class T>
258  template <class REF>
259  REF RefToBase<T>::castTo() const {
260  if (!holder_) {
261  Exception::throwThis(errors::InvalidReference,
262  "attempting to cast a null RefToBase;\n"
263  "You should check for nullity before casting.");
264  }
265 
266  checkTypeCompatibility<T, typename REF::value_type>();
267 
268  // If REF is type edm::Ref<C,T,F>, then it is impossible to
269  // check the container type C here. We just have to assume
270  // that the caller provided the correct type.
271 
272  EDProductGetter const* getter = productGetter();
273  if (getter) {
274  return REF(id(), key(), getter);
275  }
276 
277  T const* value = get();
278  if (value == nullptr) {
279  return REF(id());
280  }
281  typename REF::value_type const* newValue = convertTo<T, typename REF::value_type>(value);
282  if (newValue) {
283  return REF(id(), newValue, key(), isTransient());
284  }
285 
286  Exception::throwThis(errors::InvalidReference,
287  "RefToBase<T>::castTo Error attempting to cast mismatched types\n"
288  "casting from RefToBase with T: ",
289  typeid(T).name(),
290  "\ncasting to: ",
291  typeid(REF).name());
292  return REF();
293  }
294 
296  template <class T>
297  inline bool RefToBase<T>::isNull() const {
298  return !id().isValid();
299  }
300 
302  template <class T>
303  inline bool RefToBase<T>::isNonnull() const {
304  return !isNull();
305  }
306 
308  template <class T>
309  inline bool RefToBase<T>::operator!() const {
310  return isNull();
311  }
312 
313  template <class T>
314  inline bool RefToBase<T>::operator==(RefToBase<T> const& rhs) const {
315  return holder_ ? holder_->isEqualTo(*rhs.holder_) : holder_ == rhs.holder_;
316  }
317 
318  template <class T>
319  inline bool RefToBase<T>::operator!=(RefToBase<T> const& rhs) const {
320  return !(*this == rhs);
321  }
322 
323  template <class T>
325  std::swap(holder_, other.holder_);
326  }
327 
328  template <class T>
330  return holder_ ? holder_->productGetter() : nullptr;
331  }
332 
333  template <class T>
334  inline T const* RefToBase<T>::getPtrImpl() const {
335  return holder_ ? holder_->getPtr() : nullptr;
336  }
337 
338  template <class T>
339  std::unique_ptr<reftobase::RefHolderBase> RefToBase<T>::holder() const {
340  return holder_ ? holder_->holder() : std::unique_ptr<reftobase::RefHolderBase>();
341  }
342 
343  // Free swap function
344  template <class T>
345  inline void swap(RefToBase<T>& a, RefToBase<T>& b) {
346  a.swap(b);
347  }
348 } // namespace edm
349 
353 
354 namespace edm {
355  template <class T>
356  inline RefToBase<T>::RefToBase(RefToBaseProd<T> const& r, size_t i)
357  : holder_(r.operator->()->refAt(i).holder_->clone()) {}
358 
359  template <typename T>
361  : holder_(handle.operator->()->refAt(i).holder_->clone()) {}
362 
363 } // namespace edm
364 
365 #endif
RefToBase & operator=(RefToBase &&other) noexcept
Definition: RefToBase.h:152
bool isAvailable() const
Definition: RefToBase.h:121
std::unique_ptr< reftobase::RefHolderBase > holder() const
Definition: RefToBase.h:339
Definition: APVGainStruct.h:7
REF castTo() const
Definition: RefToBase.h:259
void swap(RefToBase< T > &a, RefToBase< T > &b)
Definition: RefToBase.h:345
virtual bool isTransient() const =0
bool isNonnull() const
Checks for non-null.
Definition: RefToBase.h:303
bool isTransient() const
Definition: RefToBase.h:123
virtual bool isAvailable() const =0
#define CMS_CLASS_VERSION(_version_)
std::unique_ptr< T, impl::DeviceDeleter > unique_ptr
void swap(RefToBase &other)
Definition: RefToBase.h:324
reftobase::BaseHolder< value_type > * holder_
Definition: RefToBase.h:129
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
EDProductGetter const * productGetter() const
Definition: RefToBase.h:329
bool operator==(const QGLikelihoodParameters &lhs, const QGLikelihoodCategory &rhs)
Test if parameters are compatible with category.
value_type const * getPtrImpl() const
Definition: RefToBase.h:334
def template(fileName, svg, replaceme="REPLACEME")
Definition: svgfig.py:521
Definition: value.py:1
bool isNull() const
Checks for null.
Definition: RefToBase.h:297
bool operator!=(DTCELinkId const &lhs, DTCELinkId const &rhs)
Definition: DTCELinkId.h:81
size_t key() const
Definition: RefToBase.h:221
edm::RefProd< Container > RefProd
T castTo(const char *arg)
Definition: Parameter.h:159
double b
Definition: hdecay.h:120
~RefToBase() noexcept
Definition: RefToBase.h:189
TEveGeoShape * clone(const TEveElement *element, TEveElement *parent)
Definition: eve_macros.cc:135
HLT enums.
double a
Definition: hdecay.h:121
EDProductGetter const * productGetter(std::atomic< void const *> const &iCache)
MatrixMeschach operator*(const MatrixMeschach &mat1, const MatrixMeschach &mat2)
#define get
long double T
value_type const * get() const
Definition: RefToBase.h:211