Loading...
Searching...
No Matches
anyWeakPtr.h
Go to the documentation of this file.
1//
2// Copyright 2016 Pixar
3//
4// Licensed under the Apache License, Version 2.0 (the "Apache License")
5// with the following modification; you may not use this file except in
6// compliance with the Apache License and the following modification to it:
7// Section 6. Trademarks. is deleted and replaced with:
8//
9// 6. Trademarks. This License does not grant permission to use the trade
10// names, trademarks, service marks, or product names of the Licensor
11// and its affiliates, except as required to comply with Section 4(c) of
12// the License and to reproduce the content of the NOTICE file.
13//
14// You may obtain a copy of the Apache License at
15//
16// http://www.apache.org/licenses/LICENSE-2.0
17//
18// Unless required by applicable law or agreed to in writing, software
19// distributed under the Apache License with the above modification is
20// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21// KIND, either express or implied. See the Apache License for the specific
22// language governing permissions and limitations under the Apache License.
23//
24#ifndef PXR_BASE_TF_ANY_WEAK_PTR_H
25#define PXR_BASE_TF_ANY_WEAK_PTR_H
26
30
31#include "pxr/pxr.h"
32#include "pxr/base/tf/api.h"
33#include "pxr/base/tf/cxxCast.h"
34#include "pxr/base/tf/type.h"
35#include "pxr/base/tf/weakPtr.h"
36
37#ifdef PXR_PYTHON_SUPPORT_ENABLED
38#include "pxr/base/tf/pyUtils.h"
39#endif // PXR_PYTHON_SUPPORT_ENABLED
40
41#include "pxr/base/tf/pyObjWrapper.h"
42
43#include <cstddef>
44#include <type_traits>
45#include <utility>
46
47PXR_NAMESPACE_OPEN_SCOPE
48
54{
55 struct _Data {
56 void* space[4];
57 };
58
59public:
60 typedef TfAnyWeakPtr This;
61
63 template <class Ptr, class = typename
64 std::enable_if<Tf_SupportsWeakPtr<
65 typename Ptr::DataType>::value>::type>
66 TfAnyWeakPtr(Ptr const &ptr) {
67 static_assert(sizeof(_PointerHolder<Ptr>) <= sizeof(_Data),
68 "Ptr is too big to fit in a TfAnyWeakPtr");
69 new (&_ptrStorage) _PointerHolder<Ptr>(ptr);
70 }
71
74 static_assert(sizeof(_EmptyHolder) <= sizeof(_Data),
75 "Ptr is too big to fit in a TfAnyWeakPtr");
76 new (&_ptrStorage) _EmptyHolder;
77 }
78
80 TfAnyWeakPtr(TfNullPtrType) : TfAnyWeakPtr() {}
81
83 TfAnyWeakPtr(std::nullptr_t) : TfAnyWeakPtr() {}
84
85 TfAnyWeakPtr(TfAnyWeakPtr const &other) {
86 other._Get()->Clone(&_ptrStorage);
87 }
88
89 TfAnyWeakPtr &operator=(TfAnyWeakPtr const &other) {
90 if (this != &other) {
91 _Get()->~_PointerHolderBase();
92 other._Get()->Clone(&_ptrStorage);
93 }
94 return *this;
95 }
96
98 _Get()->~_PointerHolderBase();
99 }
100
103 TF_API bool IsInvalid() const;
104
106 TF_API void const *GetUniqueIdentifier() const;
107
109 TF_API TfWeakBase const *GetWeakBase() const;
110
112 TF_API operator bool() const;
113
115 TF_API bool operator !() const;
116
118 TF_API bool operator ==(const TfAnyWeakPtr &rhs) const;
119
121 bool operator !=(const TfAnyWeakPtr &rhs) const {
122 return !(*this == rhs);
123 }
124
126 TF_API bool operator <(const TfAnyWeakPtr &rhs) const;
127
129 bool operator <=(const TfAnyWeakPtr& rhs) const {
130 return !(rhs < *this);
131 }
132
134 bool operator >(const TfAnyWeakPtr& rhs) const {
135 return rhs < *this;
136 }
137
139 bool operator >=(const TfAnyWeakPtr& rhs) const {
140 return !(*this < rhs);
141 }
142
144 TF_API const std::type_info & GetTypeInfo() const;
145
147 TF_API TfType const& GetType() const;
148
150 size_t GetHash() const {
151 return reinterpret_cast<uintptr_t>(GetUniqueIdentifier()) >> 3;
152 }
153
154 private:
155#ifdef PXR_PYTHON_SUPPORT_ENABLED
156 // This grants friend access to a function in the wrapper file for this
157 // class. This lets the wrapper reach down into an AnyWeakPtr to get a
158 // boost::python wrapped object corresponding to the held type. This
159 // facility is necessary to get the python API we want.
160 friend boost::python::api::object
161 Tf_GetPythonObjectFromAnyWeakPtr(This const &self);
162
163 TF_API
164 boost::python::api::object _GetPythonObject() const;
165#endif // PXR_PYTHON_SUPPORT_ENABLED
166
167 template <class WeakPtr>
168 friend WeakPtr TfAnyWeakPtrDynamicCast(const TfAnyWeakPtr &anyWeak, WeakPtr*);
169
170 // This is using the standard type-erasure pattern.
171 struct _PointerHolderBase {
172 TF_API virtual ~_PointerHolderBase();
173 virtual void Clone(_Data *target) const = 0;
174 virtual bool IsInvalid() const = 0;
175 virtual void const * GetUniqueIdentifier() const = 0;
176 virtual TfWeakBase const *GetWeakBase() const = 0;
177 virtual operator bool() const = 0;
178 virtual bool _IsConst() const = 0;
179 virtual TfPyObjWrapper GetPythonObject() const = 0;
180 virtual const std::type_info & GetTypeInfo() const = 0;
181 virtual TfType const& GetType() const = 0;
182 virtual const void* _GetMostDerivedPtr() const = 0;
183 virtual bool _IsPolymorphic() const = 0;
184 };
185
186 struct _EmptyHolder : _PointerHolderBase {
187 TF_API virtual ~_EmptyHolder();
188 TF_API virtual void Clone(_Data *target) const;
189 TF_API virtual bool IsInvalid() const;
190 TF_API virtual void const * GetUniqueIdentifier() const;
191 TF_API virtual TfWeakBase const *GetWeakBase() const;
192 TF_API virtual operator bool() const;
193 TF_API virtual bool _IsConst() const;
194 TF_API virtual TfPyObjWrapper GetPythonObject() const;
195 TF_API virtual const std::type_info & GetTypeInfo() const;
196 TF_API virtual TfType const& GetType() const;
197 TF_API virtual const void* _GetMostDerivedPtr() const;
198 TF_API virtual bool _IsPolymorphic() const;
199 };
200
201 template <typename Ptr>
202 struct _PointerHolder : _PointerHolderBase {
203 _PointerHolder(Ptr const &ptr) : _ptr(ptr) {
204 }
205
206 virtual ~_PointerHolder();
207 virtual void Clone(_Data *target) const;
208 virtual bool IsInvalid() const;
209 virtual void const *GetUniqueIdentifier() const;
210 virtual TfWeakBase const *GetWeakBase() const;
211 virtual operator bool() const;
212 virtual bool _IsConst() const;
213 virtual TfPyObjWrapper GetPythonObject() const;
214 virtual const std::type_info & GetTypeInfo() const;
215 virtual TfType const& GetType() const;
216 virtual const void* _GetMostDerivedPtr() const;
217 virtual bool _IsPolymorphic() const;
218 private:
219 Ptr _ptr;
220 };
221
222 _PointerHolderBase* _Get() const {
223 return (_PointerHolderBase*)(&_ptrStorage);
224 }
225
226 _Data _ptrStorage;
227};
228
229// TfHash support. We don't want to choose the TfAnyWeakPtr overload unless the
230// passed argument is exactly TfAnyWeakPtr. By making this a function template
231// that's only enabled for TfAnyWeakPtr, C++ will not perform implicit
232// conversions since T is deduced.
233template <class HashState,
234 class T, class = typename std::enable_if<
235 std::is_same<T, TfAnyWeakPtr>::value>::type>
236inline void
237TfHashAppend(HashState &h, const T& ptr)
238{
239 h.Append(ptr.GetUniqueIdentifier());
240}
241
242template <class Ptr>
243TfAnyWeakPtr::_PointerHolder<Ptr>::~_PointerHolder() {}
244
245template <class Ptr>
246void
247TfAnyWeakPtr::_PointerHolder<Ptr>::Clone(_Data *target) const
248{
249 new (target) _PointerHolder<Ptr>(_ptr);
250}
251
252template <class Ptr>
253bool
254TfAnyWeakPtr::_PointerHolder<Ptr>::IsInvalid() const
255{
256 return _ptr.IsInvalid();
257}
258
259template <class Ptr>
260void const *
261TfAnyWeakPtr::_PointerHolder<Ptr>::GetUniqueIdentifier() const
262{
263 return _ptr.GetUniqueIdentifier();
264}
265
266template <class Ptr>
267TfWeakBase const *
268TfAnyWeakPtr::_PointerHolder<Ptr>::GetWeakBase() const
269{
270 return &(_ptr->__GetTfWeakBase__());
271}
272
273template <class Ptr>
274TfAnyWeakPtr::_PointerHolder<Ptr>::operator bool() const
275{
276 return bool(_ptr);
277}
278
279template <class Ptr>
281TfAnyWeakPtr::_PointerHolder<Ptr>::GetPythonObject() const
282{
283#ifdef PXR_PYTHON_SUPPORT_ENABLED
284 return TfPyObject(_ptr);
285#else
286 return {};
287#endif // PXR_PYTHON_SUPPORT_ENABLED
288}
289template <class Ptr>
290const std::type_info &
291TfAnyWeakPtr::_PointerHolder<Ptr>::GetTypeInfo() const
292{
293 return TfTypeid(_ptr);
294}
295
296template <class Ptr>
297TfType const&
298TfAnyWeakPtr::_PointerHolder<Ptr>::GetType() const
299{
300 return TfType::Find(_ptr);
301}
302
303template <class Ptr>
304const void *
305TfAnyWeakPtr::_PointerHolder<Ptr>::_GetMostDerivedPtr() const
306{
307 if (!_ptr) {
308 return 0;
309 }
310
311 typename Ptr::DataType const *rawPtr = get_pointer(_ptr);
312 return TfCastToMostDerivedType(rawPtr);
313}
314
315template <class Ptr>
316bool
317TfAnyWeakPtr::_PointerHolder<Ptr>::_IsPolymorphic() const
318{
319 return std::is_polymorphic<typename Ptr::DataType>::value;
320}
321
322template <class Ptr>
323bool
324TfAnyWeakPtr::_PointerHolder<Ptr>::_IsConst() const
325{
326 return std::is_const<typename Ptr::DataType>::value;
327}
328
329PXR_NAMESPACE_CLOSE_SCOPE
330
331#endif
Miscellaneous Utilities for dealing with script.
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:144
Provides the ability to hold an arbitrary TfWeakPtr in a non-type-specific manner in order to observe...
Definition: anyWeakPtr.h:54
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:121
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:134
bool operator<=(const TfAnyWeakPtr &rhs) const
less than or equal operator
Definition: anyWeakPtr.h:129
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:139
TfAnyWeakPtr(Ptr const &ptr)
Construct an AnyWeakPtr watching ptr.
Definition: anyWeakPtr.h:66
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:150
TF_API bool operator<(const TfAnyWeakPtr &rhs) const
comparison operator
TfAnyWeakPtr(TfNullPtrType)
Construct and implicitly convert from TfNullPtr.
Definition: anyWeakPtr.h:80
TfAnyWeakPtr(std::nullptr_t)
Construct and implicitly convert from std::nullptr_t.
Definition: anyWeakPtr.h:83
TF_API bool operator==(const TfAnyWeakPtr &rhs) const
equality operator
TfAnyWeakPtr()
Construct an AnyWeakPtr not watching any ptr.
Definition: anyWeakPtr.h:73
Boost Python object wrapper.
Definition: pyObjWrapper.h:97
TfType represents a dynamic runtime type.
Definition: type.h:65
static TfType const & Find()
Retrieve the TfType corresponding to type T.
Definition: type.h:153
Enable a concrete base class for use with TfWeakPtr.
Definition: weakBase.h:141
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:67
Pointer storage with deletion detection.