VTK  9.2.6
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 =========================================================================*/
138 #ifndef vtkSmartPointer_h
139 #define vtkSmartPointer_h
140 
141 #include "vtkSmartPointerBase.h"
142 
143 #include "vtkMeta.h" // for IsComplete
144 #include "vtkNew.h" // for vtkNew.h
145 
146 #include <type_traits> // for is_base_of
147 #include <utility> // for std::move
148 
149 template <class T>
151 {
152  // These static asserts only fire when the function calling CheckTypes is
153  // used. Thus, this smart pointer class may still be used as a member variable
154  // with a forward declared T, so long as T is defined by the time the calling
155  // function is used.
156  template <typename U = T>
157  static void CheckTypes() noexcept
158  {
159  static_assert(vtk::detail::IsComplete<T>::value,
160  "vtkSmartPointer<T>'s T type has not been defined. Missing "
161  "include?");
162  static_assert(vtk::detail::IsComplete<U>::value,
163  "Cannot store an object with undefined type in "
164  "vtkSmartPointer. Missing include?");
165  static_assert(std::is_base_of<T, U>::value,
166  "Argument type is not compatible with vtkSmartPointer<T>'s "
167  "T type.");
169  "vtkSmartPointer can only be used with subclasses of "
170  "vtkObjectBase.");
171  }
172 
173 public:
177  vtkSmartPointer() noexcept
179  {
180  }
181 
187  // Need both overloads because the copy-constructor must be non-templated:
190  {
191  }
192 
193  template <class U>
196  {
197  vtkSmartPointer::CheckTypes<U>();
198  }
199  /* @} **/
200 
205  // Need both overloads because the move-constructor must be non-templated:
207  : vtkSmartPointerBase(std::move(r))
208  {
209  }
210 
211  template <class U>
213  : vtkSmartPointerBase(std::move(r))
214  {
215  vtkSmartPointer::CheckTypes<U>();
216  }
225  {
226  vtkSmartPointer::CheckTypes();
227  }
228 
229  template <typename U>
232  { // Create a new reference on copy
233  vtkSmartPointer::CheckTypes<U>();
234  }
236 
241  template <typename U>
244  { // Steal the reference on move
245  vtkSmartPointer::CheckTypes<U>();
246 
247  r.Object = nullptr;
248  }
249 
251 
255  // Need this since the compiler won't recognize template functions as
256  // assignment operators.
258  {
260  return *this;
261  }
262 
263  template <class U>
265  {
266  vtkSmartPointer::CheckTypes<U>();
267 
269  return *this;
270  }
272 
277  template <typename U>
279  {
280  vtkSmartPointer::CheckTypes<U>();
281 
282  this->vtkSmartPointerBase::operator=(r.Object);
283  return *this;
284  }
285 
290  template <typename U>
292  {
293  vtkSmartPointer::CheckTypes<U>();
294 
296  return *this;
297  }
298 
300 
303  T* GetPointer() const noexcept { return static_cast<T*>(this->Object); }
304  T* Get() const noexcept { return static_cast<T*>(this->Object); }
306 
310  operator T*() const noexcept { return static_cast<T*>(this->Object); }
311 
316  T& operator*() const noexcept { return *static_cast<T*>(this->Object); }
317 
321  T* operator->() const noexcept { return static_cast<T*>(this->Object); }
322 
335  void TakeReference(T* t) { *this = vtkSmartPointer<T>(t, NoReference()); }
336 
340  static vtkSmartPointer<T> New() { return vtkSmartPointer<T>(T::New(), NoReference()); }
347  {
348  return vtkSmartPointer<T>(T::ExtendedNew(), NoReference());
349  }
350 
355  {
356  return vtkSmartPointer<T>(t->NewInstance(), NoReference());
357  }
358 
372  static vtkSmartPointer<T> Take(T* t) { return vtkSmartPointer<T>(t, NoReference()); }
373 
374  // Work-around for HP and IBM overload resolution bug. Since
375  // NullPointerOnly is a private type the only pointer value that can
376  // be passed by user code is a null pointer. This operator will be
377  // chosen by the compiler when comparing against null explicitly and
378  // avoid the bogus ambiguous overload error.
379 #if defined(__HP_aCC) || defined(__IBMCPP__)
380 #define VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(op) \
381  bool operator op(NullPointerOnly*) const { return ::operator op(*this, 0); }
382 
383 private:
384  class NullPointerOnly
385  {
386  };
387 
388 public:
389  VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(==)
390  VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(!=)
391  VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(<)
392  VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(<=)
393  VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(>)
394  VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(>=)
395 #undef VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND
396 #endif
397 protected:
398  vtkSmartPointer(T* r, const NoReference& n)
399  : vtkSmartPointerBase(r, n)
400  {
401  }
402 
403 private:
404  // These are purposely not implemented to prevent callers from
405  // trying to take references from other smart pointers.
406  void TakeReference(const vtkSmartPointerBase&) = delete;
407  static void Take(const vtkSmartPointerBase&) = delete;
408 };
409 
410 #define VTK_SMART_POINTER_DEFINE_OPERATOR(op) \
411  template <class T, class U> \
412  inline bool operator op(const vtkSmartPointer<T>& l, const vtkSmartPointer<U>& r) \
413  { \
414  return (l.GetPointer() op r.GetPointer()); \
415  } \
416  template <class T, class U> \
417  inline bool operator op(T* l, const vtkSmartPointer<U>& r) \
418  { \
419  return (l op r.GetPointer()); \
420  } \
421  template <class T, class U> \
422  inline bool operator op(const vtkSmartPointer<T>& l, U* r) \
423  { \
424  return (l.GetPointer() op r); \
425  } \
426  template <class T, class U> \
427  inline bool operator op(const vtkNew<T>& l, const vtkSmartPointer<U>& r) \
428  { \
429  return (l.GetPointer() op r.GetPointer()); \
430  } \
431  template <class T, class U> \
432  inline bool operator op(const vtkSmartPointer<T>& l, const vtkNew<U>& r) \
433  { \
434  return (l.GetPointer() op r.GetPointer); \
435  }
436 
446 
447 #undef VTK_SMART_POINTER_DEFINE_OPERATOR
448 
449 namespace vtk
450 {
451 
454 template <typename T>
456 {
457  return vtkSmartPointer<T>{ obj };
458 }
459 
462 template <typename T>
464 {
465  return vtkSmartPointer<T>::Take(obj);
466 }
467 
468 } // end namespace vtk
469 
473 template <class T>
474 inline ostream& operator<<(ostream& os, const vtkSmartPointer<T>& p)
475 {
476  return os << static_cast<const vtkSmartPointerBase&>(p);
477 }
478 
479 #endif
480 // VTK-HeaderTest-Exclude: vtkSmartPointer.h
Allocate and hold a VTK object.
Definition: vtkNew.h:171
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.