HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
anyWeakPtr.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 #ifndef PXR_BASE_TF_ANY_WEAK_PTR_H
8 #define PXR_BASE_TF_ANY_WEAK_PTR_H
9 
10 /// \file tf/anyWeakPtr.h
11 /// \ingroup group_tf_Memory
12 /// Type independent WeakPtr holder class
13 
14 #include "pxr/pxr.h"
15 #include "pxr/base/tf/api.h"
16 #include "pxr/base/tf/cxxCast.h"
17 #include "pxr/base/tf/type.h"
18 #include "pxr/base/tf/weakPtr.h"
19 
20 #ifdef PXR_PYTHON_SUPPORT_ENABLED
21 #include "pxr/base/tf/pyUtils.h"
22 #endif // PXR_PYTHON_SUPPORT_ENABLED
23 
25 
26 #include <cstddef>
27 #include <type_traits>
28 #include <utility>
29 
31 
32 /// \class TfAnyWeakPtr
33 ///
34 /// Provides the ability to hold an arbitrary TfWeakPtr in a non-type-specific
35 /// manner in order to observe whether it has expired or not
37 {
38  struct _Data {
39  void* space[4];
40  };
41 
42 public:
43  typedef TfAnyWeakPtr This;
44 
45  /// Construct an AnyWeakPtr watching \a ptr.
46  template <class Ptr, class = typename
47  std::enable_if<Tf_SupportsWeakPtr<
48  typename Ptr::DataType>::value>::type>
49  TfAnyWeakPtr(Ptr const &ptr) {
50  static_assert(sizeof(_PointerHolder<Ptr>) <= sizeof(_Data),
51  "Ptr is too big to fit in a TfAnyWeakPtr");
52  new (&_ptrStorage) _PointerHolder<Ptr>(ptr);
53  }
54 
55  /// Construct an AnyWeakPtr not watching any \a ptr.
57  static_assert(sizeof(_EmptyHolder) <= sizeof(_Data),
58  "Ptr is too big to fit in a TfAnyWeakPtr");
59  new (&_ptrStorage) _EmptyHolder;
60  }
61 
62  /// Construct and implicitly convert from TfNullPtr.
64 
65  /// Construct and implicitly convert from std::nullptr_t.
66  TfAnyWeakPtr(std::nullptr_t) : TfAnyWeakPtr() {}
67 
68  TfAnyWeakPtr(TfAnyWeakPtr const &other) {
69  other._Get()->Clone(&_ptrStorage);
70  }
71 
73  if (this != &other) {
74  _Get()->~_PointerHolderBase();
75  other._Get()->Clone(&_ptrStorage);
76  }
77  return *this;
78  }
79 
81  _Get()->~_PointerHolderBase();
82  }
83 
84  /// Return true *only* if this expiry checker is watching a weak pointer
85  /// which has expired.
86  TF_API bool IsInvalid() const;
87 
88  /// Return the unique identifier of the WeakPtr this AnyWeakPtr contains
89  TF_API void const *GetUniqueIdentifier() const;
90 
91  /// Return the TfWeakBase object of the WeakPtr we are holding
92  TF_API TfWeakBase const *GetWeakBase() const;
93 
94  /// bool operator
95  TF_API operator bool() const;
96 
97  /// operator !
98  TF_API bool operator !() const;
99 
100  /// equality operator
101  TF_API bool operator ==(const TfAnyWeakPtr &rhs) const;
102 
103  /// inequality operator
104  bool operator !=(const TfAnyWeakPtr &rhs) const {
105  return !(*this == rhs);
106  }
107 
108  /// comparison operator
109  TF_API bool operator <(const TfAnyWeakPtr &rhs) const;
110 
111  /// less than or equal operator
112  bool operator <=(const TfAnyWeakPtr& rhs) const {
113  return !(rhs < *this);
114  }
115 
116  /// greater than operator
117  bool operator >(const TfAnyWeakPtr& rhs) const {
118  return rhs < *this;
119  }
120 
121  /// greater than or equal operator
122  bool operator >=(const TfAnyWeakPtr& rhs) const {
123  return !(*this < rhs);
124  }
125 
126  /// returns the type_info of the underlying WeakPtr
127  TF_API const std::type_info & GetTypeInfo() const;
128 
129  /// Returns the TfType of the underlying WeakPtr.
130  TF_API TfType const& GetType() const;
131 
132  /// Return a hash value for this instance.
133  size_t GetHash() const {
134  return reinterpret_cast<uintptr_t>(GetUniqueIdentifier()) >> 3;
135  }
136 
137  private:
138 #ifdef PXR_PYTHON_SUPPORT_ENABLED
139  // This grants friend access to a function in the wrapper file for this
140  // class. This lets the wrapper reach down into an AnyWeakPtr to get a
141  // pxr_boost::python wrapped object corresponding to the held type. This
142  // facility is necessary to get the python API we want.
144  Tf_GetPythonObjectFromAnyWeakPtr(This const &self);
145 
146  TF_API
147  pxr_boost::python::api::object _GetPythonObject() const;
148 #endif // PXR_PYTHON_SUPPORT_ENABLED
149 
150  template <class WeakPtr>
151  friend WeakPtr TfAnyWeakPtrDynamicCast(const TfAnyWeakPtr &anyWeak, WeakPtr*);
152 
153  // This is using the standard type-erasure pattern.
154  struct _PointerHolderBase {
155  TF_API virtual ~_PointerHolderBase();
156  virtual void Clone(_Data *target) const = 0;
157  virtual bool IsInvalid() const = 0;
158  virtual void const * GetUniqueIdentifier() const = 0;
159  virtual TfWeakBase const *GetWeakBase() const = 0;
160  virtual operator bool() const = 0;
161  virtual bool _IsConst() const = 0;
162  virtual TfPyObjWrapper GetPythonObject() const = 0;
163  virtual const std::type_info & GetTypeInfo() const = 0;
164  virtual TfType const& GetType() const = 0;
165  virtual const void* _GetMostDerivedPtr() const = 0;
166  virtual bool _IsPolymorphic() const = 0;
167  };
168 
169  struct _EmptyHolder : _PointerHolderBase {
170  TF_API virtual ~_EmptyHolder();
171  TF_API virtual void Clone(_Data *target) const;
172  TF_API virtual bool IsInvalid() const;
173  TF_API virtual void const * GetUniqueIdentifier() const;
174  TF_API virtual TfWeakBase const *GetWeakBase() const;
175  TF_API virtual operator bool() const;
176  TF_API virtual bool _IsConst() const;
177  TF_API virtual TfPyObjWrapper GetPythonObject() const;
178  TF_API virtual const std::type_info & GetTypeInfo() const;
179  TF_API virtual TfType const& GetType() const;
180  TF_API virtual const void* _GetMostDerivedPtr() const;
181  TF_API virtual bool _IsPolymorphic() const;
182  };
183 
184  template <typename Ptr>
185  struct _PointerHolder : _PointerHolderBase {
186  _PointerHolder(Ptr const &ptr) : _ptr(ptr) {
187  }
188 
189  virtual ~_PointerHolder();
190  virtual void Clone(_Data *target) const;
191  virtual bool IsInvalid() const;
192  virtual void const *GetUniqueIdentifier() const;
193  virtual TfWeakBase const *GetWeakBase() const;
194  virtual operator bool() const;
195  virtual bool _IsConst() const;
196  virtual TfPyObjWrapper GetPythonObject() const;
197  virtual const std::type_info & GetTypeInfo() const;
198  virtual TfType const& GetType() const;
199  virtual const void* _GetMostDerivedPtr() const;
200  virtual bool _IsPolymorphic() const;
201  private:
202  Ptr _ptr;
203  };
204 
205  _PointerHolderBase* _Get() const {
206  return (_PointerHolderBase*)(&_ptrStorage);
207  }
208 
209  _Data _ptrStorage;
210 };
211 
212 // TfHash support. We don't want to choose the TfAnyWeakPtr overload unless the
213 // passed argument is exactly TfAnyWeakPtr. By making this a function template
214 // that's only enabled for TfAnyWeakPtr, C++ will not perform implicit
215 // conversions since T is deduced.
216 template <class HashState,
217  class T, class = typename std::enable_if<
219 inline void
220 TfHashAppend(HashState &h, const T& ptr)
221 {
222  h.Append(ptr.GetUniqueIdentifier());
223 }
224 
225 template <class Ptr>
226 TfAnyWeakPtr::_PointerHolder<Ptr>::~_PointerHolder() {}
227 
228 template <class Ptr>
229 void
230 TfAnyWeakPtr::_PointerHolder<Ptr>::Clone(_Data *target) const
231 {
232  new (target) _PointerHolder<Ptr>(_ptr);
233 }
234 
235 template <class Ptr>
236 bool
237 TfAnyWeakPtr::_PointerHolder<Ptr>::IsInvalid() const
238 {
239  return _ptr.IsInvalid();
240 }
241 
242 template <class Ptr>
243 void const *
244 TfAnyWeakPtr::_PointerHolder<Ptr>::GetUniqueIdentifier() const
245 {
246  return _ptr.GetUniqueIdentifier();
247 }
248 
249 template <class Ptr>
250 TfWeakBase const *
251 TfAnyWeakPtr::_PointerHolder<Ptr>::GetWeakBase() const
252 {
253  return &(_ptr->__GetTfWeakBase__());
254 }
255 
256 template <class Ptr>
257 TfAnyWeakPtr::_PointerHolder<Ptr>::operator bool() const
258 {
259  return bool(_ptr);
260 }
261 
262 template <class Ptr>
264 TfAnyWeakPtr::_PointerHolder<Ptr>::GetPythonObject() const
265 {
266 #ifdef PXR_PYTHON_SUPPORT_ENABLED
267  return TfPyObject(_ptr);
268 #else
269  return {};
270 #endif // PXR_PYTHON_SUPPORT_ENABLED
271 }
272 template <class Ptr>
273 const std::type_info &
274 TfAnyWeakPtr::_PointerHolder<Ptr>::GetTypeInfo() const
275 {
276  return TfTypeid(_ptr);
277 }
278 
279 template <class Ptr>
280 TfType const&
281 TfAnyWeakPtr::_PointerHolder<Ptr>::GetType() const
282 {
283  return TfType::Find(_ptr);
284 }
285 
286 template <class Ptr>
287 const void *
288 TfAnyWeakPtr::_PointerHolder<Ptr>::_GetMostDerivedPtr() const
289 {
290  if (!_ptr) {
291  return 0;
292  }
293 
294  typename Ptr::DataType const *rawPtr = get_pointer(_ptr);
295  return TfCastToMostDerivedType(rawPtr);
296 }
297 
298 template <class Ptr>
299 bool
300 TfAnyWeakPtr::_PointerHolder<Ptr>::_IsPolymorphic() const
301 {
303 }
304 
305 template <class Ptr>
306 bool
307 TfAnyWeakPtr::_PointerHolder<Ptr>::_IsConst() const
308 {
310 }
311 
313 
314 #endif
TF_API const std::type_info & GetTypeInfo() const
returns the type_info of the underlying WeakPtr
void TfHashAppend(HashState &h, const T &ptr)
Definition: anyWeakPtr.h:220
#define TF_API
Definition: api.h:23
TfAnyWeakPtr(Ptr const &ptr)
Construct an AnyWeakPtr watching ptr.
Definition: anyWeakPtr.h:49
pxr_boost::python::object TfPyObject(T const &t, bool complainOnFailure=true)
Definition: pyUtils.h:127
uint128_t uintptr_t
Definition: format.h:479
GLsizei const GLfloat * value
Definition: glcorearb.h:824
static TfType const & Find()
Definition: type.h:136
TfAnyWeakPtr(TfNullPtrType)
Construct and implicitly convert from TfNullPtr.
Definition: anyWeakPtr.h:63
TfAnyWeakPtr(std::nullptr_t)
Construct and implicitly convert from std::nullptr_t.
Definition: anyWeakPtr.h:66
TF_API bool operator<(const TfAnyWeakPtr &rhs) const
comparison operator
OutGridT const XformOp bool bool
Y * get_pointer(TfWeakPtrFacade< X, Y > const &p)
Definition: weakPtrFacade.h:63
TF_API bool operator!() const
operator !
TfAnyWeakPtr()
Construct an AnyWeakPtr not watching any ptr.
Definition: anyWeakPtr.h:56
TF_API void const * GetUniqueIdentifier() const
Return the unique identifier of the WeakPtr this AnyWeakPtr contains.
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
std::weak_ptr< T > WeakPtr
Definition: Types.h:115
TF_API bool IsInvalid() const
std::enable_if< std::is_polymorphic< T >::value, Tf_CopyCV< T, void > * >::type TfCastToMostDerivedType(T *ptr)
Definition: cxxCast.h:50
TF_API TfType const & GetType() const
Returns the TfType of the underlying WeakPtr.
bool operator<=(const TfAnyWeakPtr &rhs) const
less than or equal operator
Definition: anyWeakPtr.h:112
const std::type_info & TfTypeid(const TfRefPtr< T > &ptr)
Definition: refPtr.h:1196
friend WeakPtr TfAnyWeakPtrDynamicCast(const TfAnyWeakPtr &anyWeak, WeakPtr *)
TfAnyWeakPtr & operator=(TfAnyWeakPtr const &other)
Definition: anyWeakPtr.h:72
GLenum target
Definition: glcorearb.h:1667
TF_API bool operator==(const TfAnyWeakPtr &rhs) const
equality operator
size_t GetHash() const
Return a hash value for this instance.
Definition: anyWeakPtr.h:133
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
bool operator>=(const TfAnyWeakPtr &rhs) const
greater than or equal operator
Definition: anyWeakPtr.h:122
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
TfAnyWeakPtr(TfAnyWeakPtr const &other)
Definition: anyWeakPtr.h:68
TfAnyWeakPtr This
Definition: anyWeakPtr.h:43
auto ptr(T p) -> const void *
Definition: format.h:4331
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
bool operator!=(const TfAnyWeakPtr &rhs) const
inequality operator
Definition: anyWeakPtr.h:104
Definition: type.h:47
TF_API TfWeakBase const * GetWeakBase() const
Return the TfWeakBase object of the WeakPtr we are holding.
bool operator>(const TfAnyWeakPtr &rhs) const
greater than operator
Definition: anyWeakPtr.h:117