This document is for a version of USD that is under development. See this page for the current release.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules 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
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
24#include "pxr/base/tf/pyObjWrapper.h"
25
26#include <cstddef>
27#include <type_traits>
28#include <utility>
29
30PXR_NAMESPACE_OPEN_SCOPE
31
37{
38 struct _Data {
39 void* space[4];
40 };
41
42public:
43 typedef TfAnyWeakPtr This;
44
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
57 static_assert(sizeof(_EmptyHolder) <= sizeof(_Data),
58 "Ptr is too big to fit in a TfAnyWeakPtr");
59 new (&_ptrStorage) _EmptyHolder;
60 }
61
63 TfAnyWeakPtr(TfNullPtrType) : TfAnyWeakPtr() {}
64
66 TfAnyWeakPtr(std::nullptr_t) : TfAnyWeakPtr() {}
67
68 TfAnyWeakPtr(TfAnyWeakPtr const &other) {
69 other._Get()->Clone(&_ptrStorage);
70 }
71
72 TfAnyWeakPtr &operator=(TfAnyWeakPtr const &other) {
73 if (this != &other) {
74 _Get()->~_PointerHolderBase();
75 other._Get()->Clone(&_ptrStorage);
76 }
77 return *this;
78 }
79
81 _Get()->~_PointerHolderBase();
82 }
83
86 TF_API bool IsInvalid() const;
87
89 TF_API void const *GetUniqueIdentifier() const;
90
92 TF_API TfWeakBase const *GetWeakBase() const;
93
95 TF_API operator bool() const;
96
98 TF_API bool operator !() const;
99
101 TF_API bool operator ==(const TfAnyWeakPtr &rhs) const;
102
104 bool operator !=(const TfAnyWeakPtr &rhs) const {
105 return !(*this == rhs);
106 }
107
109 TF_API bool operator <(const TfAnyWeakPtr &rhs) const;
110
112 bool operator <=(const TfAnyWeakPtr& rhs) const {
113 return !(rhs < *this);
114 }
115
117 bool operator >(const TfAnyWeakPtr& rhs) const {
118 return rhs < *this;
119 }
120
122 bool operator >=(const TfAnyWeakPtr& rhs) const {
123 return !(*this < rhs);
124 }
125
127 TF_API const std::type_info & GetTypeInfo() const;
128
130 TF_API TfType const& GetType() const;
131
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.
143 friend pxr_boost::python::api::object
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.
216template <class HashState,
217 class T, class = typename std::enable_if<
218 std::is_same<T, TfAnyWeakPtr>::value>::type>
219inline void
220TfHashAppend(HashState &h, const T& ptr)
221{
222 h.Append(ptr.GetUniqueIdentifier());
223}
224
225template <class Ptr>
226TfAnyWeakPtr::_PointerHolder<Ptr>::~_PointerHolder() {}
227
228template <class Ptr>
229void
230TfAnyWeakPtr::_PointerHolder<Ptr>::Clone(_Data *target) const
231{
232 new (target) _PointerHolder<Ptr>(_ptr);
233}
234
235template <class Ptr>
236bool
237TfAnyWeakPtr::_PointerHolder<Ptr>::IsInvalid() const
238{
239 return _ptr.IsInvalid();
240}
241
242template <class Ptr>
243void const *
244TfAnyWeakPtr::_PointerHolder<Ptr>::GetUniqueIdentifier() const
245{
246 return _ptr.GetUniqueIdentifier();
247}
248
249template <class Ptr>
250TfWeakBase const *
251TfAnyWeakPtr::_PointerHolder<Ptr>::GetWeakBase() const
252{
253 return &(_ptr->__GetTfWeakBase__());
254}
255
256template <class Ptr>
257TfAnyWeakPtr::_PointerHolder<Ptr>::operator bool() const
258{
259 return bool(_ptr);
260}
261
262template <class Ptr>
264TfAnyWeakPtr::_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}
272template <class Ptr>
273const std::type_info &
274TfAnyWeakPtr::_PointerHolder<Ptr>::GetTypeInfo() const
275{
276 return TfTypeid(_ptr);
277}
278
279template <class Ptr>
280TfType const&
281TfAnyWeakPtr::_PointerHolder<Ptr>::GetType() const
282{
283 return TfType::Find(_ptr);
284}
285
286template <class Ptr>
287const void *
288TfAnyWeakPtr::_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
298template <class Ptr>
299bool
300TfAnyWeakPtr::_PointerHolder<Ptr>::_IsPolymorphic() const
301{
302 return std::is_polymorphic<typename Ptr::DataType>::value;
303}
304
305template <class Ptr>
306bool
307TfAnyWeakPtr::_PointerHolder<Ptr>::_IsConst() const
308{
309 return std::is_const<typename Ptr::DataType>::value;
310}
311
312PXR_NAMESPACE_CLOSE_SCOPE
313
314#endif
Miscellaneous Utilities for dealing with script.
pxr_boost::python::object TfPyObject(T const &t, bool complainOnFailure=true)
Return a python object for the given C++ object, loading the appropriate wrapper code if necessary.
Definition: pyUtils.h:127
Provides the ability to hold an arbitrary TfWeakPtr in a non-type-specific manner in order to observe...
Definition: anyWeakPtr.h:37
TF_API const std::type_info & GetTypeInfo() const
returns the type_info of the underlying WeakPtr
bool operator!=(const TfAnyWeakPtr &rhs) const
inequality operator
Definition: anyWeakPtr.h:104
TF_API TfType const & GetType() const
Returns the TfType of the underlying WeakPtr.
bool operator>(const TfAnyWeakPtr &rhs) const
greater than operator
Definition: anyWeakPtr.h:117
bool operator<=(const TfAnyWeakPtr &rhs) const
less than or equal operator
Definition: anyWeakPtr.h:112
TF_API bool operator!() const
operator !
TF_API bool IsInvalid() const
Return true only if this expiry checker is watching a weak pointer which has expired.
TF_API void const * GetUniqueIdentifier() const
Return the unique identifier of the WeakPtr this AnyWeakPtr contains.
bool operator>=(const TfAnyWeakPtr &rhs) const
greater than or equal operator
Definition: anyWeakPtr.h:122
TfAnyWeakPtr(Ptr const &ptr)
Construct an AnyWeakPtr watching ptr.
Definition: anyWeakPtr.h:49
TF_API TfWeakBase const * GetWeakBase() const
Return the TfWeakBase object of the WeakPtr we are holding.
size_t GetHash() const
Return a hash value for this instance.
Definition: anyWeakPtr.h:133
TF_API bool operator<(const TfAnyWeakPtr &rhs) const
comparison operator
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
equality operator
TfAnyWeakPtr()
Construct an AnyWeakPtr not watching any ptr.
Definition: anyWeakPtr.h:56
Boost Python object wrapper.
Definition: pyObjWrapper.h:79
TfType represents a dynamic runtime type.
Definition: type.h:48
static TfType const & Find()
Retrieve the TfType corresponding to type T.
Definition: type.h:136
Enable a concrete base class for use with TfWeakPtr.
Definition: weakBase.h:124
C++ Cast Utilities.
std::enable_if< std::is_polymorphic< T >::value, Tf_CopyCV< T, void > * >::type TfCastToMostDerivedType(T *ptr)
Return a pointer to the most-derived object.
Definition: cxxCast.h:50
Pointer storage with deletion detection.