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
17#ifndef vtkSmartPointer_h
18#define vtkSmartPointer_h
19
20#include "vtkSmartPointerBase.h"
21
22#include "vtkMeta.h" // for IsComplete
23#include "vtkNew.h" // for vtkNew.h
24
25#include <functional> // for std::hash
26#include <type_traits> // for is_base_of
27#include <utility> // for std::move
28
29VTK_ABI_NAMESPACE_BEGIN
30template <class T>
32{
33 // These static asserts only fire when the function calling CheckTypes is
34 // used. Thus, this smart pointer class may still be used as a member variable
35 // with a forward declared T, so long as T is defined by the time the calling
36 // function is used.
37 template <typename U = T>
38 static void CheckTypes() noexcept
39 {
41 "vtkSmartPointer<T>'s T type has not been defined. Missing "
42 "include?");
44 "Cannot store an object with undefined type in "
45 "vtkSmartPointer. Missing include?");
46 static_assert(std::is_base_of<T, U>::value,
47 "Argument type is not compatible with vtkSmartPointer<T>'s "
48 "T type.");
49 static_assert(std::is_base_of<vtkObjectBase, T>::value,
50 "vtkSmartPointer can only be used with subclasses of "
51 "vtkObjectBase.");
52 }
53
54public:
58 vtkSmartPointer() noexcept
60 {
61 }
62
68 // Need both overloads because the copy-constructor must be non-templated:
71 {
72 }
73
74 template <class U>
77 {
78 vtkSmartPointer::CheckTypes<U>();
79 }
80 /* @} **/
81
86 // Need both overloads because the move-constructor must be non-templated:
88 : vtkSmartPointerBase(std::move(r))
89 {
90 }
91
92 template <class U>
94 : vtkSmartPointerBase(std::move(r))
95 {
96 vtkSmartPointer::CheckTypes<U>();
97 }
106 {
107 vtkSmartPointer::CheckTypes();
108 }
109
110 template <typename U>
113 { // Create a new reference on copy
114 vtkSmartPointer::CheckTypes<U>();
115 }
117
122 template <typename U>
125 { // Steal the reference on move
126 vtkSmartPointer::CheckTypes<U>();
127
128 r.Object = nullptr;
129 }
130
132
136 // Need this since the compiler won't recognize template functions as
137 // assignment operators.
139 {
141 return *this;
142 }
143
144 template <class U>
146 {
147 vtkSmartPointer::CheckTypes<U>();
148
150 return *this;
151 }
153
158 template <typename U>
160 {
161 vtkSmartPointer::CheckTypes<U>();
162
163 this->vtkSmartPointerBase::operator=(r.Object);
164 return *this;
165 }
166
171 template <typename U>
173 {
174 vtkSmartPointer::CheckTypes<U>();
175
177 return *this;
178 }
179
181
184 T* GetPointer() const noexcept { return static_cast<T*>(this->Object); }
185 T* Get() const noexcept { return static_cast<T*>(this->Object); }
187
191 operator T*() const noexcept { return static_cast<T*>(this->Object); }
192
197 T& operator*() const noexcept { return *static_cast<T*>(this->Object); }
198
202 T* operator->() const noexcept { return static_cast<T*>(this->Object); }
203
216 void TakeReference(T* t) { *this = vtkSmartPointer<T>(t, NoReference()); }
217
219
222 static vtkSmartPointer<T> New() { return vtkSmartPointer<T>(T::New(), NoReference()); }
223 template <class... ArgsT>
224 static vtkSmartPointer<T> New(ArgsT&&... args)
225 {
226 return vtkSmartPointer<T>(T::New(std::forward<ArgsT>(args)...), NoReference());
227 }
229
236 {
237 return vtkSmartPointer<T>(T::ExtendedNew(), NoReference());
238 }
239
244 {
245 return vtkSmartPointer<T>(t->NewInstance(), NoReference());
246 }
247
262
263 // Work-around for HP and IBM overload resolution bug. Since
264 // NullPointerOnly is a private type the only pointer value that can
265 // be passed by user code is a null pointer. This operator will be
266 // chosen by the compiler when comparing against null explicitly and
267 // avoid the bogus ambiguous overload error.
268#if defined(__HP_aCC) || defined(__IBMCPP__)
269#define VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(op) \
270 bool operator op(NullPointerOnly*) const { return ::operator op(*this, 0); }
271
272private:
273 class NullPointerOnly
274 {
275 };
276
277public:
278 VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(==)
279 VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(!=)
280 VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(<)
281 VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(<=)
282 VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(>)
283 VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND(>=)
284#undef VTK_SMART_POINTER_DEFINE_OPERATOR_WORKAROUND
285#endif
286protected:
288 : vtkSmartPointerBase(r, n)
289 {
290 }
291
292private:
293 // These are purposely not implemented to prevent callers from
294 // trying to take references from other smart pointers.
295 void TakeReference(const vtkSmartPointerBase&) = delete;
296 static void Take(const vtkSmartPointerBase&) = delete;
297};
298VTK_ABI_NAMESPACE_END
299
300namespace std
301{
302template <class T>
303struct hash<vtkSmartPointer<T>>
304{
305 std::size_t operator()(const vtkSmartPointer<T>& p) const { return this->Hasher(p.Get()); }
306
307 std::hash<T*> Hasher;
308};
309}
310
311VTK_ABI_NAMESPACE_BEGIN
312#define VTK_SMART_POINTER_DEFINE_OPERATOR(op) \
313 template <class T, class U> \
314 inline bool operator op(const vtkSmartPointer<T>& l, const vtkSmartPointer<U>& r) \
315 { \
316 return (l.GetPointer() op r.GetPointer()); \
317 } \
318 template <class T, class U> \
319 inline bool operator op(T* l, const vtkSmartPointer<U>& r) \
320 { \
321 return (l op r.GetPointer()); \
322 } \
323 template <class T, class U> \
324 inline bool operator op(const vtkSmartPointer<T>& l, U* r) \
325 { \
326 return (l.GetPointer() op r); \
327 } \
328 template <class T, class U> \
329 inline bool operator op(const vtkNew<T>& l, const vtkSmartPointer<U>& r) \
330 { \
331 return (l.GetPointer() op r.GetPointer()); \
332 } \
333 template <class T, class U> \
334 inline bool operator op(const vtkSmartPointer<T>& l, const vtkNew<U>& r) \
335 { \
336 return (l.GetPointer() op r.GetPointer); \
337 }
338
348
349#undef VTK_SMART_POINTER_DEFINE_OPERATOR
350VTK_ABI_NAMESPACE_END
351
352namespace vtk
353{
354VTK_ABI_NAMESPACE_BEGIN
355
358template <typename T>
360{
361 return vtkSmartPointer<T>{ obj };
362}
363
366template <typename T>
368{
369 return vtkSmartPointer<T>::Take(obj);
370}
371
372VTK_ABI_NAMESPACE_END
373} // end namespace vtk
374
375VTK_ABI_NAMESPACE_BEGIN
379template <class T>
380inline ostream& operator<<(ostream& os, const vtkSmartPointer<T>& p)
381{
382 return os << static_cast<const vtkSmartPointerBase&>(p);
383}
384
385VTK_ABI_NAMESPACE_END
386#endif
387// VTK-HeaderTest-Exclude: vtkSmartPointer.h
Allocate and hold a VTK object.
Definition vtkNew.h:51
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)