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 =========================================================================*/
132 #ifndef vtkSmartPointer_h
133 #define vtkSmartPointer_h
134 
135 #include "vtkSmartPointerBase.h"
136 
137 #include "vtkMeta.h" // for IsComplete
138 #include "vtkNew.h" // for vtkNew.h
139 
140 #include <type_traits> // for is_base_of
141 #include <utility> // for std::move
142 
143 template <class T>
145 {
146  // These static asserts only fire when the function calling CheckTypes is
147  // used. Thus, this smart pointer class may still be used as a member variable
148  // with a forward declared T, so long as T is defined by the time the calling
149  // function is used.
150  template <typename U = T>
151  static void CheckTypes() noexcept
152  {
153  static_assert(vtk::detail::IsComplete<T>::value,
154  "vtkSmartPointer<T>'s T type has not been defined. Missing "
155  "include?");
156  static_assert(vtk::detail::IsComplete<U>::value,
157  "Cannot store an object with undefined type in "
158  "vtkSmartPointer. Missing include?");
159  static_assert(std::is_base_of<T, U>::value,
160  "Argument type is not compatible with vtkSmartPointer<T>'s "
161  "T type.");
163  "vtkSmartPointer can only be used with subclasses of "
164  "vtkObjectBase.");
165  }
166 
167 public:
171  vtkSmartPointer() noexcept
173  {
174  }
175 
181  // Need both overloads because the copy-constructor must be non-templated:
184  {
185  }
186 
187  template <class U>
190  {
191  vtkSmartPointer::CheckTypes<U>();
192  }
193  /* @} **/
194 
199  // Need both overloads because the move-constructor must be non-templated:
201  : vtkSmartPointerBase(std::move(r))
202  {
203  }
204 
205  template <class U>
207  : vtkSmartPointerBase(std::move(r))
208  {
209  vtkSmartPointer::CheckTypes<U>();
210  }
219  {
220  vtkSmartPointer::CheckTypes();
221  }
222 
223  template <typename U>
226  { // Create a new reference on copy
227  vtkSmartPointer::CheckTypes<U>();
228  }
230 
235  template <typename U>
238  { // Steal the reference on move
239  vtkSmartPointer::CheckTypes<U>();
240 
241  r.Object = nullptr;
242  }
243 
245 
249  // Need this since the compiler won't recognize template functions as
250  // assignment operators.
252  {
254  return *this;
255  }
256 
257  template <class U>
259  {
260  vtkSmartPointer::CheckTypes<U>();
261 
263  return *this;
264  }
266 
271  template <typename U>
273  {
274  vtkSmartPointer::CheckTypes<U>();
275 
276  this->vtkSmartPointerBase::operator=(r.Object);
277  return *this;
278  }
279 
284  template <typename U>
286  {
287  vtkSmartPointer::CheckTypes<U>();
288 
290  return *this;
291  }
292 
294 
297  T* GetPointer() const noexcept { return static_cast<T*>(this->Object); }
298  T* Get() const noexcept { return static_cast<T*>(this->Object); }
300 
304  operator T*() const noexcept { return static_cast<T*>(this->Object); }
305 
310  T& operator*() const noexcept { return *static_cast<T*>(this->Object); }
311 
315  T* operator->() const noexcept { return static_cast<T*>(this->Object); }
316 
329  void TakeReference(T* t) { *this = vtkSmartPointer<T>(t, NoReference()); }
330 
334  static vtkSmartPointer<T> New() { return vtkSmartPointer<T>(T::New(), NoReference()); }
341  {
342  return vtkSmartPointer<T>(T::ExtendedNew(), NoReference());
343  }
344 
349  {
350  return vtkSmartPointer<T>(t->NewInstance(), NoReference());
351  }
352 
366  static vtkSmartPointer<T> Take(T* t) { return vtkSmartPointer<T>(t, NoReference()); }
367 
368  // Work-around for HP and IBM overload resolution bug. Since
369  // NullPointerOnly is a private type the only pointer value that can
370  // be passed by user code is a null pointer. This operator will be
371  // chosen by the compiler when comparing against null explicitly and
372  // avoid the bogus ambiguous overload error.
373 #if defined(__HP_aCC) || defined(__IBMCPP__)
374 #define VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(op) \
375  bool operator op(NullPointerOnly*) const { return ::operator op(*this, 0); }
376 
377 private:
378  class NullPointerOnly
379  {
380  };
381 
382 public:
383  VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(==)
384  VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(!=)
385  VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(<)
386  VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(<=)
387  VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(>)
388  VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(>=)
389 #undef VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND
390 #endif
391 protected:
392  vtkSmartPointer(T* r, const NoReference& n)
393  : vtkSmartPointerBase(r, n)
394  {
395  }
396 
397 private:
398  // These are purposely not implemented to prevent callers from
399  // trying to take references from other smart pointers.
400  void TakeReference(const vtkSmartPointerBase&) = delete;
401  static void Take(const vtkSmartPointerBase&) = delete;
402 };
403 
404 #define VTK_SMART_POINTER_DEFINE_OPERATOR(op) \
405  template <class T, class U> \
406  inline bool operator op(const vtkSmartPointer<T>& l, const vtkSmartPointer<U>& r) \
407  { \
408  return (l.GetPointer() op r.GetPointer()); \
409  } \
410  template <class T, class U> \
411  inline bool operator op(T* l, const vtkSmartPointer<U>& r) \
412  { \
413  return (l op r.GetPointer()); \
414  } \
415  template <class T, class U> \
416  inline bool operator op(const vtkSmartPointer<T>& l, U* r) \
417  { \
418  return (l.GetPointer() op r); \
419  } \
420  template <class T, class U> \
421  inline bool operator op(const vtkNew<T>& l, const vtkSmartPointer<U>& r) \
422  { \
423  return (l.GetPointer() op r.GetPointer()); \
424  } \
425  template <class T, class U> \
426  inline bool operator op(const vtkSmartPointer<T>& l, const vtkNew<U>& r) \
427  { \
428  return (l.GetPointer() op r.GetPointer); \
429  }
430 
440 
441 #undef VTK_SMART_POINTER_DEFINE_OPERATOR
442 
443 namespace vtk
444 {
445 
448 template <typename T>
450 {
451  return vtkSmartPointer<T>{ obj };
452 }
453 
456 template <typename T>
458 {
459  return vtkSmartPointer<T>::Take(obj);
460 }
461 
462 } // end namespace vtk
463 
467 template <class T>
468 inline ostream& operator<<(ostream& os, const vtkSmartPointer<T>& p)
469 {
470  return os << static_cast<const vtkSmartPointerBase&>(p);
471 }
472 
473 #endif
474 // VTK-HeaderTest-Exclude: vtkSmartPointer.h
Allocate and hold a VTK object.
Definition: vtkNew.h:165
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.