VTK  9.1.0
vtkSmartPointer.h
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Visualization Toolkit
4  Module: vtkSmartPointer.h
5 
6  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7  All rights reserved.
8  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10  This software is distributed WITHOUT ANY WARRANTY; without even
11  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12  PURPOSE. See the above copyright notice for more information.
13 
14 =========================================================================*/
23 #ifndef vtkSmartPointer_h
24 #define vtkSmartPointer_h
25 
26 #include "vtkSmartPointerBase.h"
27 
28 #include "vtkMeta.h" // for IsComplete
29 #include "vtkNew.h" // for vtkNew.h
30 
31 #include <type_traits> // for is_base_of
32 #include <utility> // for std::move
33 
34 template <class T>
36 {
37  // These static asserts only fire when the function calling CheckTypes is
38  // used. Thus, this smart pointer class may still be used as a member variable
39  // with a forward declared T, so long as T is defined by the time the calling
40  // function is used.
41  template <typename U = T>
42  static void CheckTypes() noexcept
43  {
45  "vtkSmartPointer<T>'s T type has not been defined. Missing "
46  "include?");
48  "Cannot store an object with undefined type in "
49  "vtkSmartPointer. Missing include?");
50  static_assert(std::is_base_of<T, U>::value,
51  "Argument type is not compatible with vtkSmartPointer<T>'s "
52  "T type.");
54  "vtkSmartPointer can only be used with subclasses of "
55  "vtkObjectBase.");
56  }
57 
58 public:
62  vtkSmartPointer() noexcept
64  {
65  }
66 
72  // Need both overloads because the copy-constructor must be non-templated:
75  {
76  }
77 
78  template <class U>
81  {
82  vtkSmartPointer::CheckTypes<U>();
83  }
84  /* @} **/
85 
90  // Need both overloads because the move-constructor must be non-templated:
92  : vtkSmartPointerBase(std::move(r))
93  {
94  }
95 
96  template <class U>
98  : vtkSmartPointerBase(std::move(r))
99  {
100  vtkSmartPointer::CheckTypes<U>();
101  }
110  {
111  vtkSmartPointer::CheckTypes();
112  }
113 
114  template <typename U>
117  { // Create a new reference on copy
118  vtkSmartPointer::CheckTypes<U>();
119  }
121 
126  template <typename U>
129  { // Steal the reference on move
130  vtkSmartPointer::CheckTypes<U>();
131 
132  r.Object = nullptr;
133  }
134 
136 
140  // Need this since the compiler won't recognize template functions as
141  // assignment operators.
143  {
145  return *this;
146  }
147 
148  template <class U>
150  {
151  vtkSmartPointer::CheckTypes<U>();
152 
154  return *this;
155  }
157 
162  template <typename U>
164  {
165  vtkSmartPointer::CheckTypes<U>();
166 
167  this->vtkSmartPointerBase::operator=(r.Object);
168  return *this;
169  }
170 
175  template <typename U>
177  {
178  vtkSmartPointer::CheckTypes<U>();
179 
181  return *this;
182  }
183 
185 
188  T* GetPointer() const noexcept { return static_cast<T*>(this->Object); }
189  T* Get() const noexcept { return static_cast<T*>(this->Object); }
191 
195  operator T*() const noexcept { return static_cast<T*>(this->Object); }
196 
201  T& operator*() const noexcept { return *static_cast<T*>(this->Object); }
202 
206  T* operator->() const noexcept { return static_cast<T*>(this->Object); }
207 
220  void TakeReference(T* t) { *this = vtkSmartPointer<T>(t, NoReference()); }
221 
225  static vtkSmartPointer<T> New() { return vtkSmartPointer<T>(T::New(), NoReference()); }
232  {
233  return vtkSmartPointer<T>(T::ExtendedNew(), NoReference());
234  }
235 
240  {
241  return vtkSmartPointer<T>(t->NewInstance(), NoReference());
242  }
243 
257  static vtkSmartPointer<T> Take(T* t) { return vtkSmartPointer<T>(t, NoReference()); }
258 
259  // Work-around for HP and IBM overload resolution bug. Since
260  // NullPointerOnly is a private type the only pointer value that can
261  // be passed by user code is a null pointer. This operator will be
262  // chosen by the compiler when comparing against null explicitly and
263  // avoid the bogus ambiguous overload error.
264 #if defined(__HP_aCC) || defined(__IBMCPP__)
265 #define VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(op) \
266  bool operator op(NullPointerOnly*) const { return ::operator op(*this, 0); }
267 
268 private:
269  class NullPointerOnly
270  {
271  };
272 
273 public:
274  VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(==)
275  VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(!=)
276  VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(<)
277  VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(<=)
278  VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(>)
279  VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(>=)
280 #undef VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND
281 #endif
282 protected:
283  vtkSmartPointer(T* r, const NoReference& n)
284  : vtkSmartPointerBase(r, n)
285  {
286  }
287 
288 private:
289  // These are purposely not implemented to prevent callers from
290  // trying to take references from other smart pointers.
291  void TakeReference(const vtkSmartPointerBase&) = delete;
292  static void Take(const vtkSmartPointerBase&) = delete;
293 };
294 
295 #define VTK_SMART_POINTER_DEFINE_OPERATOR(op) \
296  template <class T, class U> \
297  inline bool operator op(const vtkSmartPointer<T>& l, const vtkSmartPointer<U>& r) \
298  { \
299  return (l.GetPointer() op r.GetPointer()); \
300  } \
301  template <class T, class U> \
302  inline bool operator op(T* l, const vtkSmartPointer<U>& r) \
303  { \
304  return (l op r.GetPointer()); \
305  } \
306  template <class T, class U> \
307  inline bool operator op(const vtkSmartPointer<T>& l, U* r) \
308  { \
309  return (l.GetPointer() op r); \
310  } \
311  template <class T, class U> \
312  inline bool operator op(const vtkNew<T>& l, const vtkSmartPointer<U>& r) \
313  { \
314  return (l.GetPointer() op r.GetPointer()); \
315  } \
316  template <class T, class U> \
317  inline bool operator op(const vtkSmartPointer<T>& l, const vtkNew<U>& r) \
318  { \
319  return (l.GetPointer() op r.GetPointer); \
320  }
321 
331 
332 #undef VTK_SMART_POINTER_DEFINE_OPERATOR
333 
334 namespace vtk
335 {
336 
339 template <typename T>
341 {
342  return vtkSmartPointer<T>{ obj };
343 }
344 
347 template <typename T>
349 {
350  return vtkSmartPointer<T>::Take(obj);
351 }
352 
353 } // end namespace vtk
354 
358 template <class T>
359 inline ostream& operator<<(ostream& os, const vtkSmartPointer<T>& p)
360 {
361  return os << static_cast<const vtkSmartPointerBase&>(p);
362 }
363 
364 #endif
365 // VTK-HeaderTest-Exclude: vtkSmartPointer.h
Allocate and hold a VTK object.
Definition: vtkNew.h:56
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.
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:226
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.
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.