VTK  9.7.1
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
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 
48 VTK_ABI_NAMESPACE_BEGIN
49 
50 template <typename T>
51 class vtkWeakPtr
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.");
67  "vtkWeakPtr can only be used with subclasses of vtkObjectBase.");
68  }
69 
70 public:
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  }
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 *this;
162  }
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  }
185 
187 
190  vtkWeakPtr(vtkWeakPtr&& r) noexcept = default;
191  template <typename U>
192  vtkWeakPtr(vtkWeakPtr<U>&& r) noexcept
193  : Block(std::move(r.Block))
194  {
195  vtkWeakPtr::CheckTypes<U>();
196  }
197  vtkWeakPtr& operator=(vtkWeakPtr&& r) noexcept = default;
198  template <typename U>
199  vtkWeakPtr& operator=(vtkWeakPtr<U>&& r) noexcept
200  {
201  this->Block = std::move(r.Block);
202  vtkWeakPtr::CheckTypes<U>();
203  return *this;
204  }
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  }
267 
269 
272  bool owner_before(const vtkWeakPtr& r) const { return this->Block < r.Block; }
274 
275 private:
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 
298 VTK_ABI_NAMESPACE_END
299 
300 #endif
301 
302 // VTK-HeaderTest-Exclude: vtkWeakPtr.h
vtkWeakPtr & Reset(T *r)
Raw pointer constructors and assignment.
Definition: vtkWeakPtr.h:151
vtkWeakPtr & operator=(const vtkWeakPtr< U > &r)
Copy construction and assignment.
Definition: vtkWeakPtr.h:178
static vtkSmartPointer< T > Take(T *t)
Transfer ownership of one reference to the given VTK object to a new smart pointer.
vtkWeakPtr(vtkSmartPointer< U > &r)
Pointer construction and assignment.
Definition: vtkWeakPtr.h:117
Hold a reference to a vtkObjectBase instance.
Definition: vtkMeta.h:23
vtkWeakPtr & Reset(U *r)
Raw pointer constructors and assignment.
Definition: vtkWeakPtr.h:157
This file contains a variety of metaprogramming constructs for working with vtk types.
vtkWeakPtr & operator=(vtkNew< U > &r)
Pointer construction and assignment.
Definition: vtkWeakPtr.h:105
vtkWeakPtr(vtkNew< U > &r)
Pointer construction and assignment.
Definition: vtkWeakPtr.h:93
vtkWeakPtr & operator=(vtkSmartPointer< T > &r)
Pointer construction and assignment.
Definition: vtkWeakPtr.h:122
vtkWeakPtr(const vtkWeakPtr< U > &r)
Copy construction and assignment.
Definition: vtkWeakPtr.h:171
vtkWeakPtr & operator=(vtkNew< T > &r)
Pointer construction and assignment.
Definition: vtkWeakPtr.h:98
bool owner_before(const vtkWeakPtr &r) const
Compatibility with std::owner_less for use in comparison-based containers.
Definition: vtkWeakPtr.h:272
static vtkWeakPtr FromOwningRawPointer(T *r)
Raw pointer constructors and assignment.
Definition: vtkWeakPtr.h:145
static vtkWeakPtr FromOwningRawPointer(U *r)
Raw pointer constructors and assignment.
Definition: vtkWeakPtr.h:147
vtkWeakPtr() noexcept
Default construction.
Definition: vtkWeakPtr.h:75
vtkWeakPtr(const vtkSmartPointer< T > &r)
Pointer construction and assignment.
Definition: vtkWeakPtr.h:111
abstract base class for most VTK objects
Definition: vtkObjectBase.h:68
~vtkWeakPtr() noexcept=default
bool Expired() const
Check whether the held object has expired or not.
Definition: vtkWeakPtr.h:224
Allocate and hold a VTK object.
vtkWeakPtr(const vtkNew< T > &r)
Pointer construction and assignment.
Definition: vtkWeakPtr.h:87
vtkSmartPointer< T > Lock(vtkObjectBase *owner=nullptr) const
Obtain a new reference to the held object, if available.
Definition: vtkWeakPtr.h:235
vtkWeakPtr & operator=(vtkSmartPointer< U > &r)
Pointer construction and assignment.
Definition: vtkWeakPtr.h:129
a weak reference to a vtkObjectBase.
Definition: vtkMeta.h:27