VTK  9.6.20260313
vtkWeakPtr.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
36
37#ifndef vtkWeakPtr_h
38#define vtkWeakPtr_h
39
40#include "vtkMeta.h" // for IsComplete
41#include "vtkObjectBase.h" // for vtkObjectBase
42#include "vtkSmartPointer.h" // for vtkSmartPointer
43
44#include <memory> // for std::shared_ptr
45#include <mutex> // for std::mutex
46#include <type_traits> // for std::is_base_of
47
48VTK_ABI_NAMESPACE_BEGIN
49
50template <typename T>
52{
53 // These static asserts only fire when the function calling CheckTypes is
54 // used. Thus, this smart pointer class may still be used as a member variable
55 // with a forward declared T, so long as T is defined by the time the calling
56 // function is used.
57 template <typename U = T>
58 static void CheckTypes() noexcept
59 {
61 "vtkWeakPtr<T>'s T type has not been defined. Missing include?");
63 "Cannot store an object with undefined type in vtkWeakPtr. Missing include?");
64 static_assert(
65 std::is_base_of<T, U>::value, "Argument type is not compatible with vtkWeakPtr<T>'s T type.");
66 static_assert(std::is_base_of<vtkObjectBase, T>::value,
67 "vtkWeakPtr can only be used with subclasses of vtkObjectBase.");
68 }
69
70public:
72
75 vtkWeakPtr() noexcept { vtkWeakPtr::CheckTypes<T>(); }
77
79
88 : Block(r ? r->GetWeakControlBlock() : nullptr)
89 {
90 vtkWeakPtr::CheckTypes<T>();
91 }
92 template <typename U>
94 : Block(r ? r->GetWeakControlBlock() : nullptr)
95 {
96 vtkWeakPtr::CheckTypes<U>();
97 }
99 {
100 this->Block = r ? r->GetWeakControlBlock() : nullptr;
101 vtkWeakPtr::CheckTypes<T>();
102 return *this;
103 }
104 template <typename U>
106 {
107 this->Block = r ? r->GetWeakControlBlock() : nullptr;
108 vtkWeakPtr::CheckTypes<U>();
109 return *this;
110 }
112 : Block(r ? r->GetWeakControlBlock() : nullptr)
113 {
114 vtkWeakPtr::CheckTypes<T>();
115 }
116 template <typename U>
118 : Block(r ? r->GetWeakControlBlock() : nullptr)
119 {
120 vtkWeakPtr::CheckTypes<U>();
121 }
123 {
124 this->Block = r ? r->GetWeakControlBlock() : nullptr;
125 vtkWeakPtr::CheckTypes<T>();
126 return *this;
127 }
128 template <typename U>
130 {
131 this->Block = r ? r->GetWeakControlBlock() : nullptr;
132 vtkWeakPtr::CheckTypes<U>();
133 return *this;
134 }
135
136
138
145 static vtkWeakPtr FromOwningRawPointer(T* r) { return vtkWeakPtr(r); }
146 template <typename U>
148 {
149 return vtkWeakPtr(r);
150 }
152 {
153 this->Block = r ? r->GetWeakControlBlock() : nullptr;
154 return *this;
155 }
156 template <typename U>
158 {
159 this->Block = r ? r->GetWeakControlBlock() : nullptr;
160 vtkWeakPtr::CheckTypes<U>();
161 return vtkWeakPtr(r);
162 }
163
164
166
169 vtkWeakPtr(const vtkWeakPtr& r) = default;
170 template <typename U>
172 : Block(r.Block)
173 {
174 vtkWeakPtr::CheckTypes<U>();
175 }
176 vtkWeakPtr& operator=(const vtkWeakPtr& r) = default;
177 template <typename U>
179 {
180 this->Block = r.Block;
181 vtkWeakPtr::CheckTypes<U>();
182 return *this;
183 }
184
185
187
190 vtkWeakPtr(vtkWeakPtr&& r) noexcept = default;
191 template <typename U>
193 : Block(std::move(r.Block))
194 {
195 vtkWeakPtr::CheckTypes<U>();
196 }
197 vtkWeakPtr& operator=(vtkWeakPtr&& r) noexcept = default;
198 template <typename U>
200 {
201 this->Block = std::move(r.Block);
202 vtkWeakPtr::CheckTypes<U>();
203 return *this;
204 }
205
206
208 ~vtkWeakPtr() noexcept = default;
210
212
224 bool Expired() const { return !this->Block || !this->Block->Object; }
226
228
235 vtkSmartPointer<T> Lock(vtkObjectBase* owner = nullptr) const
236 {
237 if (this->Block)
238 {
239 // Ensure that while we're working on the block, another thread does not
240 // make `obj` `nullptr` behind us.
241 std::lock_guard<std::mutex> guard(this->Block->Mutex);
242 (void)guard;
243
244 if (T* obj = static_cast<T*>(this->Block->Object))
245 {
246 // Add a reference, but check if we're working with a doomed instance
247 // first. This is because `Register` is only safe when a strong
248 // reference exists already, so this call checks to see if it can
249 // create a new one from the collective ownership of the program.
250 if (obj->TryUpgradeRegister(owner))
251 {
252 // We added a strong reference, give it to a smart pointer.
253 return vtkSmartPointer<T>::Take(obj);
254 }
255 else
256 {
257 // We tried, but we're working with a doomed instance, so return
258 // `nullptr`.
259 return nullptr;
260 }
261 }
262 }
263
264 return nullptr;
265 }
266
267
269
272 bool owner_before(const vtkWeakPtr& r) const { return this->Block < r.Block; }
274
275private:
277
280 vtkWeakPtr(T* r)
281 : Block(r ? r->GetWeakControlBlock() : nullptr)
282 {
283 vtkWeakPtr::CheckTypes<T>();
284 }
285 template <typename U>
286 vtkWeakPtr(U* r)
287 : Block(r ? r->GetWeakControlBlock() : nullptr)
288 {
289 vtkWeakPtr::CheckTypes<U>();
290 }
292
293 template <typename U>
294 friend class vtkWeakPtr;
295 std::shared_ptr<vtkObjectBase::WeakControlBlock> Block;
296};
297
298VTK_ABI_NAMESPACE_END
299
300#endif
301
302// VTK-HeaderTest-Exclude: vtkWeakPtr.h
Allocate and hold a VTK object.
Definition vtkNew.h:167
abstract base class for most VTK objects
Hold a reference to a vtkObjectBase instance.
static vtkSmartPointer< T > Take(T *t)
Transfer ownership of one reference to the given VTK object to a new smart pointer.
vtkWeakPtr & operator=(vtkSmartPointer< U > &r)
Pointer construction and assignment.
Definition vtkWeakPtr.h:129
vtkWeakPtr(const vtkSmartPointer< T > &r)
Pointer construction and assignment.
Definition vtkWeakPtr.h:111
vtkWeakPtr(const vtkWeakPtr< U > &r)
Copy construction and assignment.
Definition vtkWeakPtr.h:171
vtkWeakPtr & operator=(const vtkWeakPtr< U > &r)
Copy construction and assignment.
Definition vtkWeakPtr.h:178
vtkWeakPtr & Reset(U *r)
Raw pointer constructors and assignment.
Definition vtkWeakPtr.h:157
static vtkWeakPtr FromOwningRawPointer(T *r)
Raw pointer constructors and assignment.
Definition vtkWeakPtr.h:145
bool Expired() const
Check whether the held object has expired or not.
Definition vtkWeakPtr.h:224
vtkWeakPtr(vtkWeakPtr< U > &&r) noexcept
Move construction and assignment.
Definition vtkWeakPtr.h:192
vtkWeakPtr(vtkWeakPtr &&r) noexcept=default
Move construction and assignment.
bool owner_before(const vtkWeakPtr &r) const
Compatibility with std::owner_less for use in comparison-based containers.
Definition vtkWeakPtr.h:272
vtkWeakPtr(const vtkNew< T > &r)
Pointer construction and assignment.
Definition vtkWeakPtr.h:87
vtkWeakPtr() noexcept
Default construction.
Definition vtkWeakPtr.h:75
friend class vtkWeakPtr
Definition vtkWeakPtr.h:294
vtkWeakPtr & Reset(T *r)
Raw pointer constructors and assignment.
Definition vtkWeakPtr.h:151
vtkWeakPtr & operator=(vtkSmartPointer< T > &r)
Pointer construction and assignment.
Definition vtkWeakPtr.h:122
vtkWeakPtr(const vtkWeakPtr &r)=default
Copy construction and assignment.
vtkWeakPtr & operator=(vtkNew< T > &r)
Pointer construction and assignment.
Definition vtkWeakPtr.h:98
vtkWeakPtr & operator=(vtkNew< U > &r)
Pointer construction and assignment.
Definition vtkWeakPtr.h:105
vtkWeakPtr & operator=(vtkWeakPtr &&r) noexcept=default
Move construction and assignment.
vtkWeakPtr(vtkNew< U > &r)
Pointer construction and assignment.
Definition vtkWeakPtr.h:93
vtkWeakPtr & operator=(vtkWeakPtr< U > &&r) noexcept
Move construction and assignment.
Definition vtkWeakPtr.h:199
vtkSmartPointer< T > Lock(vtkObjectBase *owner=nullptr) const
Obtain a new reference to the held object, if available.
Definition vtkWeakPtr.h:235
vtkWeakPtr(vtkSmartPointer< U > &r)
Pointer construction and assignment.
Definition vtkWeakPtr.h:117
vtkWeakPtr & operator=(const vtkWeakPtr &r)=default
Copy construction and assignment.
static vtkWeakPtr FromOwningRawPointer(U *r)
Raw pointer constructors and assignment.
Definition vtkWeakPtr.h:147
~vtkWeakPtr() noexcept=default
static constexpr bool value
Definition vtkMeta.h:87
This file contains a variety of metaprogramming constructs for working with vtk types.