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.