VTK  9.3.0
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
26#ifndef vtkSmartPointer_h
27#define vtkSmartPointer_h
28
29#include "vtkSmartPointerBase.h"
30
31#include "vtkMeta.h" // for IsComplete
32#include "vtkNew.h" // for vtkNew.h
33
34#include <functional> // for std::hash
35#include <type_traits> // for is_base_of
36#include <utility> // for std::move
37
38VTK_ABI_NAMESPACE_BEGIN
39template <class T>
41{
42 // These static asserts only fire when the function calling CheckTypes is
43 // used. Thus, this smart pointer class may still be used as a member variable
44 // with a forward declared T, so long as T is defined by the time the calling
45 // function is used.
46 template <typename U = T>
47 static void CheckTypes() noexcept
48 {
50 "vtkSmartPointer<T>'s T type has not been defined. Missing "
51 "include?");
53 "Cannot store an object with undefined type in "
54 "vtkSmartPointer. Missing include?");
55 static_assert(std::is_base_of<T, U>::value,
56 "Argument type is not compatible with vtkSmartPointer<T>'s "
57 "T type.");
58 static_assert(std::is_base_of<vtkObjectBase, T>::value,
59 "vtkSmartPointer can only be used with subclasses of "
60 "vtkObjectBase.");
61 }
62
63public:
67 vtkSmartPointer() noexcept
69 {
70 }
71
77 // Need both overloads because the copy-constructor must be non-templated:
80 {
81 }
82
83 template <class U>
86 {
87 vtkSmartPointer::CheckTypes<U>();
88 }
89 /* @} **/
90
95 // Need both overloads because the move-constructor must be non-templated:
97 : vtkSmartPointerBase(std::move(r))
98 {
99 }
100
101 template <class U>
103 : vtkSmartPointerBase(std::move(r))
104 {
105 vtkSmartPointer::CheckTypes<U>();
106 }
115 {
116 vtkSmartPointer::CheckTypes();
117 }
118
119 template <typename U>
122 { // Create a new reference on copy
123 vtkSmartPointer::CheckTypes<U>();
124 }
126
131 template <typename U>
134 { // Steal the reference on move
135 vtkSmartPointer::CheckTypes<U>();
136
137 r.Object = nullptr;
138 }
139
141
145 // Need this since the compiler won't recognize template functions as
146 // assignment operators.
148 {
150 return *this;
151 }
152
153 template <class U>
155 {
156 vtkSmartPointer::CheckTypes<U>();
157
159 return *this;
160 }
162
167 template <typename U>
169 {
170 vtkSmartPointer::CheckTypes<U>();
171
172 this->vtkSmartPointerBase::operator=(r.Object);
173 return *this;
174 }
175
180 template <typename U>
182 {
183 vtkSmartPointer::CheckTypes<U>();
184
186 return *this;
187 }
188
190
193 T* GetPointer() const noexcept { return static_cast<T*>(this->Object); }
194 T* Get() const noexcept { return static_cast<T*>(this->Object); }
196
200 operator T*() const noexcept { return static_cast<T*>(this->Object); }
201
206 T& operator*() const noexcept { return *static_cast<T*>(this->Object); }
207
211 T* operator->() const noexcept { return static_cast<T*>(this->Object); }
212
225 void TakeReference(T* t) { *this = vtkSmartPointer<T>(t, NoReference()); }
226
228
231 static vtkSmartPointer<T> New() { return vtkSmartPointer<T>(T::New(), NoReference()); }
232 template <class... ArgsT>
233 static vtkSmartPointer<T> New(ArgsT&&... args)
234 {
235 return vtkSmartPointer<T>(T::New(std::forward<ArgsT>(args)...), NoReference());
236 }
238
245 {
246 return vtkSmartPointer<T>(T::ExtendedNew(), NoReference());
247 }
248
253 {
254 return vtkSmartPointer<T>(t->NewInstance(), NoReference());
255 }
256
271
272 // Work-around for HP and IBM overload resolution bug. Since
273 // NullPointerOnly is a private type the only pointer value that can
274 // be passed by user code is a null pointer. This operator will be
275 // chosen by the compiler when comparing against null explicitly and
276 // avoid the bogus ambiguous overload error.
277#if defined(__HP_aCC) || defined(__IBMCPP__)
278#define VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(op) \
279 bool operator op(NullPointerOnly*) const { return ::operator op(*this, 0); }
280
281private:
282 class NullPointerOnly
283 {
284 };
285
286public:
287 VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(==)
288 VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(!=)
289 VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(<)
290 VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(<=)
291 VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(>)
292 VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(>=)
293#undef VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND
294#endif
295protected:
297 : vtkSmartPointerBase(r, n)
298 {
299 }
300
301private:
302 // These are purposely not implemented to prevent callers from
303 // trying to take references from other smart pointers.
304 void TakeReference(const vtkSmartPointerBase&) = delete;
305 static void Take(const vtkSmartPointerBase&) = delete;
306};
307VTK_ABI_NAMESPACE_END
308
309namespace std
310{
311template <class T>
312struct hash<vtkSmartPointer<T>>
313{
314 std::size_t operator()(const vtkSmartPointer<T>& p) const { return this->Hasher(p.Get()); }
315
316 std::hash<T*> Hasher;
317};
318}
319
320VTK_ABI_NAMESPACE_BEGIN
321#define VTK_SMART_POINTER_DEFINE_OPERATOR(op) \
322 template <class T, class U> \
323 inline bool operator op(const vtkSmartPointer<T>& l, const vtkSmartPointer<U>& r) \
324 { \
325 return (l.GetPointer() op r.GetPointer()); \
326 } \
327 template <class T, class U> \
328 inline bool operator op(T* l, const vtkSmartPointer<U>& r) \
329 { \
330 return (l op r.GetPointer()); \
331 } \
332 template <class T, class U> \
333 inline bool operator op(const vtkSmartPointer<T>& l, U* r) \
334 { \
335 return (l.GetPointer() op r); \
336 } \
337 template <class T, class U> \
338 inline bool operator op(const vtkNew<T>& l, const vtkSmartPointer<U>& r) \
339 { \
340 return (l.GetPointer() op r.GetPointer()); \
341 } \
342 template <class T, class U> \
343 inline bool operator op(const vtkSmartPointer<T>& l, const vtkNew<U>& r) \
344 { \
345 return (l.GetPointer() op r.GetPointer); \
346 }
347
357
358#undef VTK_SMART_POINTER_DEFINE_OPERATOR
359VTK_ABI_NAMESPACE_END
360
361namespace vtk
362{
363VTK_ABI_NAMESPACE_BEGIN
364
367template <typename T>
369{
370 return vtkSmartPointer<T>{ obj };
371}
372
375template <typename T>
377{
378 return vtkSmartPointer<T>::Take(obj);
379}
380
381VTK_ABI_NAMESPACE_END
382} // end namespace vtk
383
384VTK_ABI_NAMESPACE_BEGIN
388template <class T>
389inline ostream& operator<<(ostream& os, const vtkSmartPointer<T>& p)
390{
391 return os << static_cast<const vtkSmartPointerBase&>(p);
392}
393
394VTK_ABI_NAMESPACE_END
395#endif
396// VTK-HeaderTest-Exclude: vtkSmartPointer.h
Allocate and hold a VTK object.
Definition vtkNew.h:60
Non-templated superclass for vtkSmartPointer.
vtkSmartPointerBase & operator=(vtkObjectBase *r)
Assign object to reference.
vtkSmartPointerBase() noexcept
Initialize smart pointer to nullptr.
Hold a reference to a vtkObjectBase instance.
static vtkSmartPointer< T > NewInstance(T *t)
Create a new instance of the given VTK object.
vtkSmartPointer() noexcept
Initialize smart pointer to nullptr.
vtkSmartPointer(vtkNew< U > &&r) noexcept
Move the pointer from the vtkNew smart pointer to the new vtkSmartPointer, stealing its reference and...
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 & operator=(U *r)
Assign object to reference.
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 &r)
Assign object to reference.
static vtkSmartPointer< T > New(ArgsT &&... args)
Create an instance of a VTK object.
vtkSmartPointer & operator=(const vtkNew< U > &r)
Assign object to reference.
T * operator->() const noexcept
Provides normal pointer target member access using operator ->.
vtkSmartPointer(vtkSmartPointer< U > &&r) noexcept
Initialize smart pointer with a new reference to the same object referenced by given smart pointer.
static vtkSmartPointer< T > Take(T *t)
Transfer ownership of one reference to the given VTK object to a new smart pointer.
T * GetPointer() const noexcept
Get the contained pointer.
T & operator*() const noexcept
Dereference the pointer and return a reference to the contained object.
vtkSmartPointer & operator=(const vtkSmartPointer< U > &r)
Assign object to reference.
static vtkSmartPointer< T > ExtendedNew()
Create an instance of a VTK object in a memkind extended memory space.
vtkSmartPointer(T *r, const NoReference &n)
T * Get() const noexcept
Get the contained pointer.
vtkSmartPointer(const vtkNew< U > &r)
Initialize smart pointer to given object.
static vtkSmartPointer< T > New()
Create an instance of a VTK object.
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.
ostream & operator<<(ostream &os, const vtkSmartPointer< T > &p)
Streaming operator to print smart pointer like regular pointers.
#define VTK_SMART_POINTER_DEFINE_OPERATOR(op)