VTK  9.3.1
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
17 #ifndef vtkSmartPointer_h
18 #define vtkSmartPointer_h
19 
20 #include "vtkSmartPointerBase.h"
21 
22 #include "vtkMeta.h" // for IsComplete
23 #include "vtkNew.h" // for vtkNew.h
24 
25 #include <functional> // for std::hash
26 #include <type_traits> // for is_base_of
27 #include <utility> // for std::move
28 
29 VTK_ABI_NAMESPACE_BEGIN
30 template <class T>
32 {
33  // These static asserts only fire when the function calling CheckTypes is
34  // used. Thus, this smart pointer class may still be used as a member variable
35  // with a forward declared T, so long as T is defined by the time the calling
36  // function is used.
37  template <typename U = T>
38  static void CheckTypes() noexcept
39  {
41  "vtkSmartPointer<T>'s T type has not been defined. Missing "
42  "include?");
44  "Cannot store an object with undefined type in "
45  "vtkSmartPointer. Missing include?");
46  static_assert(std::is_base_of<T, U>::value,
47  "Argument type is not compatible with vtkSmartPointer<T>'s "
48  "T type.");
50  "vtkSmartPointer can only be used with subclasses of "
51  "vtkObjectBase.");
52  }
53 
54 public:
58  vtkSmartPointer() noexcept
60  {
61  }
62 
68  // Need both overloads because the copy-constructor must be non-templated:
71  {
72  }
73 
74  template <class U>
77  {
78  vtkSmartPointer::CheckTypes<U>();
79  }
80  /* @} **/
81 
86  // Need both overloads because the move-constructor must be non-templated:
88  : vtkSmartPointerBase(std::move(r))
89  {
90  }
91 
92  template <class U>
94  : vtkSmartPointerBase(std::move(r))
95  {
96  vtkSmartPointer::CheckTypes<U>();
97  }
106  {
107  vtkSmartPointer::CheckTypes();
108  }
109 
110  template <typename U>
113  { // Create a new reference on copy
114  vtkSmartPointer::CheckTypes<U>();
115  }
117 
122  template <typename U>
125  { // Steal the reference on move
126  vtkSmartPointer::CheckTypes<U>();
127 
128  r.Object = nullptr;
129  }
130 
132 
136  // Need this since the compiler won't recognize template functions as
137  // assignment operators.
139  {
141  return *this;
142  }
143 
144  template <class U>
146  {
147  vtkSmartPointer::CheckTypes<U>();
148 
150  return *this;
151  }
153 
158  template <typename U>
160  {
161  vtkSmartPointer::CheckTypes<U>();
162 
163  this->vtkSmartPointerBase::operator=(r.Object);
164  return *this;
165  }
166 
171  template <typename U>
173  {
174  vtkSmartPointer::CheckTypes<U>();
175 
177  return *this;
178  }
179 
181 
184  T* GetPointer() const noexcept { return static_cast<T*>(this->Object); }
185  T* Get() const noexcept { return static_cast<T*>(this->Object); }
187 
191  operator T*() const noexcept { return static_cast<T*>(this->Object); }
192 
197  T& operator*() const noexcept { return *static_cast<T*>(this->Object); }
198 
202  T* operator->() const noexcept { return static_cast<T*>(this->Object); }
203 
216  void TakeReference(T* t) { *this = vtkSmartPointer<T>(t, NoReference()); }
217 
219 
222  static vtkSmartPointer<T> New() { return vtkSmartPointer<T>(T::New(), NoReference()); }
223  template <class... ArgsT>
224  static vtkSmartPointer<T> New(ArgsT&&... args)
225  {
226  return vtkSmartPointer<T>(T::New(std::forward<ArgsT>(args)...), NoReference());
227  }
229 
236  {
237  return vtkSmartPointer<T>(T::ExtendedNew(), NoReference());
238  }
239 
244  {
245  return vtkSmartPointer<T>(t->NewInstance(), NoReference());
246  }
247 
261  static vtkSmartPointer<T> Take(T* t) { return vtkSmartPointer<T>(t, NoReference()); }
262 
263  // Work-around for HP and IBM overload resolution bug. Since
264  // NullPointerOnly is a private type the only pointer value that can
265  // be passed by user code is a null pointer. This operator will be
266  // chosen by the compiler when comparing against null explicitly and
267  // avoid the bogus ambiguous overload error.
268 #if defined(__HP_aCC) || defined(__IBMCPP__)
269 #define VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(op) \
270  bool operator op(NullPointerOnly*) const { return ::operator op(*this, 0); }
271 
272 private:
273  class NullPointerOnly
274  {
275  };
276 
277 public:
278  VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(==)
279  VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(!=)
280  VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(<)
281  VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(<=)
282  VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(>)
283  VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(>=)
284 #undef VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND
285 #endif
286 protected:
287  vtkSmartPointer(T* r, const NoReference& n)
288  : vtkSmartPointerBase(r, n)
289  {
290  }
291 
292 private:
293  // These are purposely not implemented to prevent callers from
294  // trying to take references from other smart pointers.
295  void TakeReference(const vtkSmartPointerBase&) = delete;
296  static void Take(const vtkSmartPointerBase&) = delete;
297 };
298 VTK_ABI_NAMESPACE_END
299 
300 namespace std
301 {
302 template <class T>
303 struct hash<vtkSmartPointer<T>>
304 {
305  std::size_t operator()(const vtkSmartPointer<T>& p) const { return this->Hasher(p.Get()); }
306 
307  std::hash<T*> Hasher;
308 };
309 }
310 
311 VTK_ABI_NAMESPACE_BEGIN
312 #define VTK_SMART_POINTER_DEFINE_OPERATOR(op) \
313  template <class T, class U> \
314  inline bool operator op(const vtkSmartPointer<T>& l, const vtkSmartPointer<U>& r) \
315  { \
316  return (l.GetPointer() op r.GetPointer()); \
317  } \
318  template <class T, class U> \
319  inline bool operator op(T* l, const vtkSmartPointer<U>& r) \
320  { \
321  return (l op r.GetPointer()); \
322  } \
323  template <class T, class U> \
324  inline bool operator op(const vtkSmartPointer<T>& l, U* r) \
325  { \
326  return (l.GetPointer() op r); \
327  } \
328  template <class T, class U> \
329  inline bool operator op(const vtkNew<T>& l, const vtkSmartPointer<U>& r) \
330  { \
331  return (l.GetPointer() op r.GetPointer()); \
332  } \
333  template <class T, class U> \
334  inline bool operator op(const vtkSmartPointer<T>& l, const vtkNew<U>& r) \
335  { \
336  return (l.GetPointer() op r.GetPointer); \
337  }
338 
348 
349 #undef VTK_SMART_POINTER_DEFINE_OPERATOR
350 VTK_ABI_NAMESPACE_END
351 
352 namespace vtk
353 {
354 VTK_ABI_NAMESPACE_BEGIN
355 
358 template <typename T>
360 {
361  return vtkSmartPointer<T>{ obj };
362 }
363 
366 template <typename T>
368 {
369  return vtkSmartPointer<T>::Take(obj);
370 }
371 
372 VTK_ABI_NAMESPACE_END
373 } // end namespace vtk
374 
375 VTK_ABI_NAMESPACE_BEGIN
379 template <class T>
380 inline ostream& operator<<(ostream& os, const vtkSmartPointer<T>& p)
381 {
382  return os << static_cast<const vtkSmartPointerBase&>(p);
383 }
384 
385 VTK_ABI_NAMESPACE_END
386 #endif
387 // VTK-HeaderTest-Exclude: vtkSmartPointer.h
static vtkSmartPointer< T > Take(T *t)
Transfer ownership of one reference to the given VTK object to a new smart pointer.
static vtkSmartPointer< T > NewInstance(T *t)
Create a new instance of the given VTK object.
vtkSmartPointer(const vtkNew< U > &r)
Initialize smart pointer to given object.
#define VTK_SMART_POINTER_DEFINE_OPERATOR(op)
vtkSmartPointerBase & operator=(vtkObjectBase *r)
Assign object to reference.
vtkSmartPointer(T *r, const NoReference &n)
vtkSmartPointer(vtkSmartPointer< U > &&r) noexcept
Initialize smart pointer with a new reference to the same object referenced by given smart pointer...
Hold a reference to a vtkObjectBase instance.
Definition: vtkMeta.h:23
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.
vtkSmartPointer & operator=(U *r)
Assign object to reference.
static vtkSmartPointer< T > New()
Create an instance of a VTK object.
vtkSmartPointer(const vtkSmartPointer &r)
Initialize smart pointer with a new reference to the same object referenced by given smart pointer...
This file contains a variety of metaprogramming constructs for working with vtk types.
T * operator->() const noexcept
Provides normal pointer target member access using operator ->.
T * Get() const noexcept
Get the contained pointer.
vtkSmartPointer & operator=(const vtkSmartPointer< U > &r)
Assign object to reference.
vtkSmartPointer(vtkNew< U > &&r) noexcept
Move the pointer from the vtkNew smart pointer to the new vtkSmartPointer, stealing its reference and...
vtkSmartPointer(vtkSmartPointer &&r) noexcept
Move the contents of r into this.
vtkSmartPointer(T *r)
Initialize smart pointer to given object.
vtkSmartPointer & operator=(const vtkNew< U > &r)
Assign object to reference.
static vtkSmartPointer< T > ExtendedNew()
Create an instance of a VTK object in a memkind extended memory space.
std::size_t operator()(const vtkSmartPointer< T > &p) const
Non-templated superclass for vtkSmartPointer.
vtkSmartPointer() noexcept
Initialize smart pointer to nullptr.
vtkObjectBase * Object
void TakeReference(T *t)
Transfer ownership of one reference to the given VTK object to this smart pointer.
vtkSmartPointer< T > TakeSmartPointer(T *obj)
Construct a vtkSmartPointer containing obj.
vtkSmartPointer & operator=(const vtkSmartPointer &r)
Assign object to reference.
T & operator*() const noexcept
Dereference the pointer and return a reference to the contained object.
Allocate and hold a VTK object.
Definition: vtkMeta.h:21
vtkSmartPointer(const vtkSmartPointer< U > &r)
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.
T * GetPointer() const noexcept
Get the contained pointer.
vtkSmartPointer< T > MakeSmartPointer(T *obj)
Construct a vtkSmartPointer containing obj.