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