VTK  9.3.20240415
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
126 #ifndef vtkSmartPointer_h
127 #define vtkSmartPointer_h
128 
129 #include "vtkSmartPointerBase.h"
130 
131 #include "vtkMeta.h" // for IsComplete
132 #include "vtkNew.h" // for vtkNew.h
133 
134 #include <functional> // for std::hash
135 #include <type_traits> // for is_base_of
136 #include <utility> // for std::move
137 
138 VTK_ABI_NAMESPACE_BEGIN
139 template <class T>
141 {
142  // These static asserts only fire when the function calling CheckTypes is
143  // used. Thus, this smart pointer class may still be used as a member variable
144  // with a forward declared T, so long as T is defined by the time the calling
145  // function is used.
146  template <typename U = T>
147  static void CheckTypes() noexcept
148  {
149  static_assert(vtk::detail::IsComplete<T>::value,
150  "vtkSmartPointer<T>'s T type has not been defined. Missing "
151  "include?");
152  static_assert(vtk::detail::IsComplete<U>::value,
153  "Cannot store an object with undefined type in "
154  "vtkSmartPointer. Missing include?");
155  static_assert(std::is_base_of<T, U>::value,
156  "Argument type is not compatible with vtkSmartPointer<T>'s "
157  "T type.");
159  "vtkSmartPointer can only be used with subclasses of "
160  "vtkObjectBase.");
161  }
162 
163 public:
167  vtkSmartPointer() noexcept
169  {
170  }
171 
177  // Need both overloads because the copy-constructor must be non-templated:
180  {
181  }
182 
183  template <class U>
186  {
187  vtkSmartPointer::CheckTypes<U>();
188  }
189  /* @} **/
190 
195  // Need both overloads because the move-constructor must be non-templated:
197  : vtkSmartPointerBase(std::move(r))
198  {
199  }
200 
201  template <class U>
203  : vtkSmartPointerBase(std::move(r))
204  {
205  vtkSmartPointer::CheckTypes<U>();
206  }
215  {
216  vtkSmartPointer::CheckTypes();
217  }
218 
219  template <typename U>
222  { // Create a new reference on copy
223  vtkSmartPointer::CheckTypes<U>();
224  }
226 
231  template <typename U>
234  { // Steal the reference on move
235  vtkSmartPointer::CheckTypes<U>();
236 
237  r.Object = nullptr;
238  }
239 
241 
245  // Need this since the compiler won't recognize template functions as
246  // assignment operators.
248  {
250  return *this;
251  }
252 
253  template <class U>
255  {
256  vtkSmartPointer::CheckTypes<U>();
257 
259  return *this;
260  }
262 
267  template <typename U>
269  {
270  vtkSmartPointer::CheckTypes<U>();
271 
272  this->vtkSmartPointerBase::operator=(r.Object);
273  return *this;
274  }
275 
280  template <typename U>
282  {
283  vtkSmartPointer::CheckTypes<U>();
284 
286  return *this;
287  }
288 
290 
293  T* GetPointer() const noexcept { return static_cast<T*>(this->Object); }
294  T* Get() const noexcept { return static_cast<T*>(this->Object); }
296 
300  operator T*() const noexcept { return static_cast<T*>(this->Object); }
301 
306  T& operator*() const noexcept { return *static_cast<T*>(this->Object); }
307 
311  T* operator->() const noexcept { return static_cast<T*>(this->Object); }
312 
325  void TakeReference(T* t) { *this = vtkSmartPointer<T>(t, NoReference()); }
326 
328 
331  static vtkSmartPointer<T> New() { return vtkSmartPointer<T>(T::New(), NoReference()); }
332  template <class... ArgsT>
333  static vtkSmartPointer<T> New(ArgsT&&... args)
334  {
335  return vtkSmartPointer<T>(T::New(std::forward<ArgsT>(args)...), NoReference());
336  }
338 
345  {
346  return vtkSmartPointer<T>(T::ExtendedNew(), NoReference());
347  }
348 
353  {
354  return vtkSmartPointer<T>(t->NewInstance(), NoReference());
355  }
356 
370  static vtkSmartPointer<T> Take(T* t) { return vtkSmartPointer<T>(t, NoReference()); }
371 
372  // Work-around for HP and IBM overload resolution bug. Since
373  // NullPointerOnly is a private type the only pointer value that can
374  // be passed by user code is a null pointer. This operator will be
375  // chosen by the compiler when comparing against null explicitly and
376  // avoid the bogus ambiguous overload error.
377 #if defined(__HP_aCC) || defined(__IBMCPP__)
378 #define VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(op) \
379  bool operator op(NullPointerOnly*) const { return ::operator op(*this, 0); }
380 
381 private:
382  class NullPointerOnly
383  {
384  };
385 
386 public:
387  VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(==)
388  VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(!=)
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 #undef VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND
394 #endif
395 protected:
396  vtkSmartPointer(T* r, const NoReference& n)
397  : vtkSmartPointerBase(r, n)
398  {
399  }
400 
401 private:
402  // These are purposely not implemented to prevent callers from
403  // trying to take references from other smart pointers.
404  void TakeReference(const vtkSmartPointerBase&) = delete;
405  static void Take(const vtkSmartPointerBase&) = delete;
406 };
407 VTK_ABI_NAMESPACE_END
408 
409 namespace std
410 {
411 template <class T>
412 struct hash<vtkSmartPointer<T>>
413 {
414  std::size_t operator()(const vtkSmartPointer<T>& p) const { return this->Hasher(p.Get()); }
415 
416  std::hash<T*> Hasher;
417 };
418 }
419 
420 VTK_ABI_NAMESPACE_BEGIN
421 #define VTK_SMART_POINTER_DEFINE_OPERATOR(op) \
422  template <class T, class U> \
423  inline bool operator op(const vtkSmartPointer<T>& l, const vtkSmartPointer<U>& r) \
424  { \
425  return (l.GetPointer() op r.GetPointer()); \
426  } \
427  template <class T, class U> \
428  inline bool operator op(T* l, const vtkSmartPointer<U>& r) \
429  { \
430  return (l op r.GetPointer()); \
431  } \
432  template <class T, class U> \
433  inline bool operator op(const vtkSmartPointer<T>& l, U* r) \
434  { \
435  return (l.GetPointer() op r); \
436  } \
437  template <class T, class U> \
438  inline bool operator op(const vtkNew<T>& l, const vtkSmartPointer<U>& r) \
439  { \
440  return (l.GetPointer() op r.GetPointer()); \
441  } \
442  template <class T, class U> \
443  inline bool operator op(const vtkSmartPointer<T>& l, const vtkNew<U>& r) \
444  { \
445  return (l.GetPointer() op r.GetPointer); \
446  }
447 
457 
458 #undef VTK_SMART_POINTER_DEFINE_OPERATOR
459 VTK_ABI_NAMESPACE_END
460 
461 namespace vtk
462 {
463 VTK_ABI_NAMESPACE_BEGIN
464 
467 template <typename T>
469 {
470  return vtkSmartPointer<T>{ obj };
471 }
472 
475 template <typename T>
477 {
478  return vtkSmartPointer<T>::Take(obj);
479 }
480 
481 VTK_ABI_NAMESPACE_END
482 } // end namespace vtk
483 
484 VTK_ABI_NAMESPACE_BEGIN
488 template <class T>
489 inline ostream& operator<<(ostream& os, const vtkSmartPointer<T>& p)
490 {
491  return os << static_cast<const vtkSmartPointerBase&>(p);
492 }
493 
494 VTK_ABI_NAMESPACE_END
495 #endif
496 // VTK-HeaderTest-Exclude: vtkSmartPointer.h
Allocate and hold a VTK object.
Definition: vtkNew.h:160
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.