VTK  9.3.0
vtkSmartPointer.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2 // SPDX-License-Identifier: BSD-3-Clause
26 #ifndef vtkSmartPointer_h
27 #define vtkSmartPointer_h
28 
29 #include "vtkSmartPointerBase.h"
30 
31 #include "vtkMeta.h" // for IsComplete
32 #include "vtkNew.h" // for vtkNew.h
33 
34 #include <functional> // for std::hash
35 #include <type_traits> // for is_base_of
36 #include <utility> // for std::move
37 
38 VTK_ABI_NAMESPACE_BEGIN
39 template <class T>
41 {
42  // These static asserts only fire when the function calling CheckTypes is
43  // used. Thus, this smart pointer class may still be used as a member variable
44  // with a forward declared T, so long as T is defined by the time the calling
45  // function is used.
46  template <typename U = T>
47  static void CheckTypes() noexcept
48  {
50  "vtkSmartPointer<T>'s T type has not been defined. Missing "
51  "include?");
53  "Cannot store an object with undefined type in "
54  "vtkSmartPointer. Missing include?");
55  static_assert(std::is_base_of<T, U>::value,
56  "Argument type is not compatible with vtkSmartPointer<T>'s "
57  "T type.");
59  "vtkSmartPointer can only be used with subclasses of "
60  "vtkObjectBase.");
61  }
62 
63 public:
67  vtkSmartPointer() noexcept
69  {
70  }
71 
77  // Need both overloads because the copy-constructor must be non-templated:
80  {
81  }
82 
83  template <class U>
86  {
87  vtkSmartPointer::CheckTypes<U>();
88  }
89  /* @} **/
90 
95  // Need both overloads because the move-constructor must be non-templated:
97  : vtkSmartPointerBase(std::move(r))
98  {
99  }
100 
101  template <class U>
103  : vtkSmartPointerBase(std::move(r))
104  {
105  vtkSmartPointer::CheckTypes<U>();
106  }
115  {
116  vtkSmartPointer::CheckTypes();
117  }
118 
119  template <typename U>
122  { // Create a new reference on copy
123  vtkSmartPointer::CheckTypes<U>();
124  }
126 
131  template <typename U>
134  { // Steal the reference on move
135  vtkSmartPointer::CheckTypes<U>();
136 
137  r.Object = nullptr;
138  }
139 
141 
145  // Need this since the compiler won't recognize template functions as
146  // assignment operators.
148  {
150  return *this;
151  }
152 
153  template <class U>
155  {
156  vtkSmartPointer::CheckTypes<U>();
157 
159  return *this;
160  }
162 
167  template <typename U>
169  {
170  vtkSmartPointer::CheckTypes<U>();
171 
172  this->vtkSmartPointerBase::operator=(r.Object);
173  return *this;
174  }
175 
180  template <typename U>
182  {
183  vtkSmartPointer::CheckTypes<U>();
184 
186  return *this;
187  }
188 
190 
193  T* GetPointer() const noexcept { return static_cast<T*>(this->Object); }
194  T* Get() const noexcept { return static_cast<T*>(this->Object); }
196 
200  operator T*() const noexcept { return static_cast<T*>(this->Object); }
201 
206  T& operator*() const noexcept { return *static_cast<T*>(this->Object); }
207 
211  T* operator->() const noexcept { return static_cast<T*>(this->Object); }
212 
225  void TakeReference(T* t) { *this = vtkSmartPointer<T>(t, NoReference()); }
226 
228 
231  static vtkSmartPointer<T> New() { return vtkSmartPointer<T>(T::New(), NoReference()); }
232  template <class... ArgsT>
233  static vtkSmartPointer<T> New(ArgsT&&... args)
234  {
235  return vtkSmartPointer<T>(T::New(std::forward<ArgsT>(args)...), NoReference());
236  }
238 
245  {
246  return vtkSmartPointer<T>(T::ExtendedNew(), NoReference());
247  }
248 
253  {
254  return vtkSmartPointer<T>(t->NewInstance(), NoReference());
255  }
256 
270  static vtkSmartPointer<T> Take(T* t) { return vtkSmartPointer<T>(t, NoReference()); }
271 
272  // Work-around for HP and IBM overload resolution bug. Since
273  // NullPointerOnly is a private type the only pointer value that can
274  // be passed by user code is a null pointer. This operator will be
275  // chosen by the compiler when comparing against null explicitly and
276  // avoid the bogus ambiguous overload error.
277 #if defined(__HP_aCC) || defined(__IBMCPP__)
278 #define VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(op) \
279  bool operator op(NullPointerOnly*) const { return ::operator op(*this, 0); }
280 
281 private:
282  class NullPointerOnly
283  {
284  };
285 
286 public:
287  VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(==)
288  VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(!=)
289  VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(<)
290  VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(<=)
291  VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(>)
292  VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(>=)
293 #undef VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND
294 #endif
295 protected:
296  vtkSmartPointer(T* r, const NoReference& n)
297  : vtkSmartPointerBase(r, n)
298  {
299  }
300 
301 private:
302  // These are purposely not implemented to prevent callers from
303  // trying to take references from other smart pointers.
304  void TakeReference(const vtkSmartPointerBase&) = delete;
305  static void Take(const vtkSmartPointerBase&) = delete;
306 };
307 VTK_ABI_NAMESPACE_END
308 
309 namespace std
310 {
311 template <class T>
312 struct hash<vtkSmartPointer<T>>
313 {
314  std::size_t operator()(const vtkSmartPointer<T>& p) const { return this->Hasher(p.Get()); }
315 
316  std::hash<T*> Hasher;
317 };
318 }
319 
320 VTK_ABI_NAMESPACE_BEGIN
321 #define VTK_SMART_POINTER_DEFINE_OPERATOR(op) \
322  template <class T, class U> \
323  inline bool operator op(const vtkSmartPointer<T>& l, const vtkSmartPointer<U>& r) \
324  { \
325  return (l.GetPointer() op r.GetPointer()); \
326  } \
327  template <class T, class U> \
328  inline bool operator op(T* l, const vtkSmartPointer<U>& r) \
329  { \
330  return (l op r.GetPointer()); \
331  } \
332  template <class T, class U> \
333  inline bool operator op(const vtkSmartPointer<T>& l, U* r) \
334  { \
335  return (l.GetPointer() op r); \
336  } \
337  template <class T, class U> \
338  inline bool operator op(const vtkNew<T>& l, const vtkSmartPointer<U>& r) \
339  { \
340  return (l.GetPointer() op r.GetPointer()); \
341  } \
342  template <class T, class U> \
343  inline bool operator op(const vtkSmartPointer<T>& l, const vtkNew<U>& r) \
344  { \
345  return (l.GetPointer() op r.GetPointer); \
346  }
347 
357 
358 #undef VTK_SMART_POINTER_DEFINE_OPERATOR
359 VTK_ABI_NAMESPACE_END
360 
361 namespace vtk
362 {
363 VTK_ABI_NAMESPACE_BEGIN
364 
367 template <typename T>
369 {
370  return vtkSmartPointer<T>{ obj };
371 }
372 
375 template <typename T>
377 {
378  return vtkSmartPointer<T>::Take(obj);
379 }
380 
381 VTK_ABI_NAMESPACE_END
382 } // end namespace vtk
383 
384 VTK_ABI_NAMESPACE_BEGIN
388 template <class T>
389 inline ostream& operator<<(ostream& os, const vtkSmartPointer<T>& p)
390 {
391  return os << static_cast<const vtkSmartPointerBase&>(p);
392 }
393 
394 VTK_ABI_NAMESPACE_END
395 #endif
396 // VTK-HeaderTest-Exclude: vtkSmartPointer.h
Allocate and hold a VTK object.
Definition: vtkNew.h:60
Non-templated superclass for vtkSmartPointer.
vtkSmartPointerBase() noexcept
Initialize smart pointer to nullptr.
vtkSmartPointerBase & operator=(vtkObjectBase *r)
Assign object to reference.
vtkObjectBase * Object
Hold a reference to a vtkObjectBase instance.
vtkSmartPointer() noexcept
Initialize smart pointer to nullptr.
T * Get() const noexcept
Get the contained pointer.
vtkSmartPointer(vtkNew< U > &&r) noexcept
Move the pointer from the vtkNew smart pointer to the new vtkSmartPointer, stealing its reference and...
static vtkSmartPointer< T > NewInstance(T *t)
Create a new instance of the given VTK object.
vtkSmartPointer(const vtkSmartPointer &r)
Initialize smart pointer with a new reference to the same object referenced by given smart pointer.
vtkSmartPointer(T *r)
Initialize smart pointer to given object.
vtkSmartPointer(const vtkSmartPointer< U > &r)
Initialize smart pointer with a new reference to the same object referenced by given smart pointer.
void TakeReference(T *t)
Transfer ownership of one reference to the given VTK object to this smart pointer.
vtkSmartPointer(vtkSmartPointer &&r) noexcept
Move the contents of r into this.
vtkSmartPointer & operator=(const vtkSmartPointer< U > &r)
Assign object to reference.
static vtkSmartPointer< T > New()
Create an instance of a VTK object.
vtkSmartPointer(vtkSmartPointer< U > &&r) noexcept
Initialize smart pointer with a new reference to the same object referenced by given smart pointer.
static vtkSmartPointer< T > New(ArgsT &&... args)
Create an instance of a VTK object.
vtkSmartPointer & operator=(const vtkNew< U > &r)
Assign object to reference.
vtkSmartPointer & operator=(U *r)
Assign object to reference.
T & operator*() const noexcept
Dereference the pointer and return a reference to the contained object.
T * GetPointer() const noexcept
Get the contained pointer.
T * operator->() const noexcept
Provides normal pointer target member access using operator ->.
static vtkSmartPointer< T > ExtendedNew()
Create an instance of a VTK object in a memkind extended memory space.
vtkSmartPointer(T *r, const NoReference &n)
vtkSmartPointer & operator=(const vtkSmartPointer &r)
Assign object to reference.
static vtkSmartPointer< T > Take(T *t)
Transfer ownership of one reference to the given VTK object to a new smart pointer.
vtkSmartPointer(const vtkNew< U > &r)
Initialize smart pointer to given object.
@ value
Definition: vtkX3D.h:220
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.
vtkSmartPointer< T > TakeSmartPointer(T *obj)
Construct a vtkSmartPointer<T> containing obj.
vtkSmartPointer< T > MakeSmartPointer(T *obj)
Construct a vtkSmartPointer<T> containing obj.
std::size_t operator()(const vtkSmartPointer< T > &p) const
This file contains a variety of metaprogramming constructs for working with vtk types.
#define VTK_SMART_POINTER_DEFINE_OPERATOR(op)
ostream & operator<<(ostream &os, const vtkSmartPointer< T > &p)
Streaming operator to print smart pointer like regular pointers.