VTK  9.4.20241221
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
138VTK_ABI_NAMESPACE_BEGIN
139template <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 {
150 "vtkSmartPointer<T>'s T type has not been defined. Missing "
151 "include?");
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.");
158 static_assert(std::is_base_of<vtkObjectBase, T>::value,
159 "vtkSmartPointer can only be used with subclasses of "
160 "vtkObjectBase.");
161 }
162
163public:
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
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
381private:
382 class NullPointerOnly
383 {
384 };
385
386public:
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
395protected:
397 : vtkSmartPointerBase(r, n)
398 {
399 }
400
401private:
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};
407VTK_ABI_NAMESPACE_END
408
409namespace std
410{
411template <class T>
412struct 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
420VTK_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
459VTK_ABI_NAMESPACE_END
460
461namespace vtk
462{
463VTK_ABI_NAMESPACE_BEGIN
464
467template <typename T>
469{
470 return vtkSmartPointer<T>{ obj };
471}
472
475template <typename T>
477{
478 return vtkSmartPointer<T>::Take(obj);
479}
480
481VTK_ABI_NAMESPACE_END
482} // end namespace vtk
483
484VTK_ABI_NAMESPACE_BEGIN
488template <class T>
489inline ostream& operator<<(ostream& os, const vtkSmartPointer<T>& p)
490{
491 return os << static_cast<const vtkSmartPointerBase&>(p);
492}
493
494VTK_ABI_NAMESPACE_END
495#endif
496// VTK-HeaderTest-Exclude: vtkSmartPointer.h
Allocate and hold a VTK object.
Definition vtkNew.h:167
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.
std::size_t operator()(const vtkSmartPointer< T > &p) const
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)