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
weakPtrFacade.h
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_WEAK_PTR_FACADE_H
8#define PXR_BASE_TF_WEAK_PTR_FACADE_H
9
10#include "pxr/pxr.h"
11
13#include "pxr/base/tf/hash.h"
14#include "pxr/base/tf/refPtr.h"
16
18
19#include <type_traits>
20
21PXR_NAMESPACE_OPEN_SCOPE
22
23template <class U> class TfRefPtr;
24
25template <template <class> class PtrTemplate, class DataType>
26class TfWeakPtrFacade;
27
34public:
35 template <template <class> class PtrTemplate, class DataType>
36 friend class TfWeakPtrFacade;
37
38 template <class Facade>
39 static typename Facade::DataType *FetchPointer(Facade const &f) {
40 return f._FetchPointer();
41 }
42
43 template <class Facade>
44 static void const *GetUniqueIdentifier(Facade const &f) {
45 return f._GetUniqueIdentifier();
46 }
47
48 template <class Facade>
49 static void EnableExtraNotification(Facade const &f) {
50 return f._EnableExtraNotification();
51 }
52
53 template <class Facade>
54 static bool IsInvalid(Facade const &f) {
55 return f._IsInvalid();
56 }
57
58private:
60};
61
62template <template <class> class X, class Y>
63Y *get_pointer(TfWeakPtrFacade<X, Y> const &p) {
64 return TfWeakPtrFacadeAccess::FetchPointer(p);
65}
66
67// Common base class, used to identify subtypes in enable_if expressions.
68class TfWeakPtrFacadeBase {};
69
70template <template <class> class PtrTemplate, class Type>
71class TfWeakPtrFacade : public TfWeakPtrFacadeBase {
72
73public:
74
75 friend class TfWeakPtrFacadeAccess;
76
77 typedef Type DataType;
78 typedef PtrTemplate<DataType> Derived;
79 typedef TfWeakPtrFacadeAccess Access;
80
81 typedef Type element_type;
82
83 template <class Other>
84 bool operator == (PtrTemplate<Other> const &p) const {
85 if (false)
86 return _FetchPointer() == TfWeakPtrFacadeAccess::FetchPointer(p);
87 return GetUniqueIdentifier() == p.GetUniqueIdentifier();
88 }
89
90 template <class Other>
91 bool operator != (PtrTemplate<Other> const &p) const {
92 return !(*this == p);
93 }
94
95 template <class T>
96 bool operator == (TfRefPtr<T> const &p) const {
97 if (!GetUniqueIdentifier())
98 return !p;
99 DataType *ptr = _FetchPointer();
100 return ptr && ptr == get_pointer(p);
101 }
102
103 template <class T>
104 bool operator != (TfRefPtr<T> const &p) const {
105 return !(*this == p);
106 }
107
108 template <class T>
109 friend bool operator == (const TfRefPtr<T>& p1, Derived const &p2) {
110 return p2 == p1;
111 }
112
113 template <class T>
114 friend bool operator != (const TfRefPtr<T>& p1, Derived const &p2) {
115 return !(p1 == p2);
116 }
117
118 template <class Other>
119 bool operator < (PtrTemplate<Other> const &p) const {
120 if (false)
121 return _FetchPointer() < TfWeakPtrFacadeAccess::FetchPointer(p);
122 return GetUniqueIdentifier() < p.GetUniqueIdentifier();
123 }
124
125 template <class Other>
126 bool operator > (PtrTemplate<Other> const &p) const {
127 return !(*this < p) && !(*this == p);
128 }
129
130 template <class Other>
131 bool operator <= (PtrTemplate<Other> const &p) const {
132 return (*this < p) || (*this == p);
133 }
134
135 template <class Other>
136 bool operator >= (PtrTemplate<Other> const &p) const {
137 return !(*this < p);
138 }
139
140 using UnspecifiedBoolType = DataType * (TfWeakPtrFacade::*)(void) const;
141
142 operator UnspecifiedBoolType () const {
143 return _FetchPointer() ? &TfWeakPtrFacade::_FetchPointer : nullptr;
144 }
145
146 bool operator ! () const {
147 return !(bool(*this));
148 }
149
150 template <class T>
151 bool PointsTo(T const &obj) const {
152 return _FetchPointer() == &obj;
153 }
154
158 template <class T>
159 bool PointsToA() const {
160 return dynamic_cast<T *>(_FetchPointer());
161 }
162
163 bool IsInvalid() const {
164 return Access::IsInvalid(_Derived());
165 }
166
167 void const *GetUniqueIdentifier() const {
168 return Access::GetUniqueIdentifier(_Derived());
169 }
170
171 TfWeakBase const *GetWeakBase() const {
172 return &_Derived()->__GetTfWeakBase__();
173 }
174
175 void EnableExtraNotification() const {
176 Access::EnableExtraNotification(_Derived());
177 }
178
179 DataType *operator -> () const {
180 DataType *ptr = _FetchPointer();
181 if (ptr) {
182 return ptr;
183 }
184 Tf_PostNullSmartPtrDereferenceFatalError(
185 TF_CALL_CONTEXT, typeid(Derived).name());
186 }
187
188 DataType &operator * () const {
189 return * operator->();
190 }
191
194 void Reset() {
195 _Derived() = TfNullPtr;
196 }
197
198private:
199
200 friend std::type_info const &TfTypeid(Derived const &p) {
201 if (ARCH_UNLIKELY(!p))
202 TF_FATAL_ERROR("Called TfTypeid on invalid %s",
203 ArchGetDemangled(typeid(Derived)).c_str());
204 return typeid(*get_pointer(p));
205 }
206
207 DataType *_FetchPointer() const {
208 return Access::FetchPointer(_Derived());
209 }
210
211 Derived &_Derived() {
212 return static_cast<Derived &>(*this);
213 }
214
215 Derived const &_Derived() const {
216 return static_cast<Derived const &>(*this);
217 }
218
219};
220
221
230
231template <template <class> class X, class Y>
232inline bool operator== (TfWeakPtrFacade<X, Y> const &p, std::nullptr_t)
233{
234 return !p;
235}
236template <template <class> class X, class Y>
237inline bool operator== (std::nullptr_t, TfWeakPtrFacade<X, Y> const &p)
238{
239 return !p;
240}
241
242template <template <class> class X, class Y>
243inline bool operator!= (TfWeakPtrFacade<X, Y> const &p, std::nullptr_t)
244{
245 return !(p == nullptr);
246}
247template <template <class> class X, class Y>
248inline bool operator!= (std::nullptr_t, TfWeakPtrFacade<X, Y> const &p)
249{
250 return !(nullptr == p);
251}
252
253template <template <class> class X, class Y>
254inline bool operator< (TfWeakPtrFacade<X, Y> const &p, std::nullptr_t)
255{
256 return std::less<void const *>()(p.GetUniqueIdentifier(), nullptr);
257}
258template <template <class> class X, class Y>
259inline bool operator< (std::nullptr_t, TfWeakPtrFacade<X, Y> const &p)
260{
261 return std::less<void const *>()(nullptr, p.GetUniqueIdentifier());
262}
263
264template <template <class> class X, class Y>
265inline bool operator<= (TfWeakPtrFacade<X, Y> const &p, std::nullptr_t)
266{
267 return !(nullptr < p);
268}
269template <template <class> class X, class Y>
270inline bool operator<= (std::nullptr_t, TfWeakPtrFacade<X, Y> const &p)
271{
272 return !(p < nullptr);
273}
274
275template <template <class> class X, class Y>
276inline bool operator> (TfWeakPtrFacade<X, Y> const &p, std::nullptr_t)
277{
278 return nullptr < p;
279}
280template <template <class> class X, class Y>
281inline bool operator> (std::nullptr_t, TfWeakPtrFacade<X, Y> const &p)
282{
283 return p < nullptr;
284}
285
286template <template <class> class X, class Y>
287inline bool operator>= (TfWeakPtrFacade<X, Y> const &p, std::nullptr_t)
288{
289 return !(p < nullptr);
290}
291template <template <class> class X, class Y>
292inline bool operator>= (std::nullptr_t, TfWeakPtrFacade<X, Y> const &p)
293{
294 return !(nullptr < p);
295}
296
298
299template <class ToPtr, template <class> class X, class Y>
300ToPtr TfDynamic_cast(TfWeakPtrFacade<X, Y> const &p) {
301 return ToPtr(dynamic_cast<typename ToPtr::DataType *>
302 (get_pointer(p)));
303}
304
305template <class ToPtr, template <class> class X, class Y>
306ToPtr TfSafeDynamic_cast(TfWeakPtrFacade<X, Y> const &p) {
307 return ToPtr(TfSafeDynamic_cast<typename ToPtr::DataType *>
308 (get_pointer(p)));
309}
310
311template <class ToPtr, template <class> class X, class Y>
312ToPtr TfStatic_cast(TfWeakPtrFacade<X, Y> const &p) {
313 return ToPtr(static_cast<typename ToPtr::DataType *>
314 (get_pointer(p)));
315}
316
317template <class ToPtr, template <class> class X, class Y>
318ToPtr TfConst_cast(TfWeakPtrFacade<X, Y> const &p) {
319 return ToPtr(const_cast<typename ToPtr::DataType *>
320 (get_pointer(p)));
321}
322
323//
324// This is the implementation; the declaration and doxygen
325// is in refPtr.h.
326//
327// If _remnant itself is NULL, then wp doesn't point to anything.
328//
329
330template <class T>
331template <template <class> class X, class U>
332inline TfRefPtr<T>::TfRefPtr(const TfWeakPtrFacade<X, U>& p,
333 typename std::enable_if<
334 std::is_convertible<U*, T*>::value
335 >::type *)
336 : _refBase(get_pointer(p))
337{
338 _AddRef();
339 Tf_RefPtrTracker_New(this, _refBase, _NullT);
340}
341
342//
343// See typeFunctions.h for documention.
344//
345template <template <class> class Ptr, class T>
346struct TfTypeFunctions<Ptr<T>,
347 std::enable_if_t<
348 std::is_base_of<TfWeakPtrFacadeBase, Ptr<T>>::value
349 >>
350{
351 static T* GetRawPtr(const Ptr<T>& t) {
352 return get_pointer(t);
353 }
354
355 static Ptr<T> ConstructFromRawPtr(T* ptr) {
356 return Ptr<T>(ptr);
357 }
358
359 static bool IsNull(const Ptr<T>& t) {
360 return !t;
361 }
362
363 static void Class_Object_MUST_Be_Passed_By_Address() { }
364 static void Class_Object_MUST_Not_Be_Const() { }
365};
366
367template <template <class> class Ptr, class T>
368struct TfTypeFunctions<Ptr<const T>,
369 std::enable_if_t<
370 std::is_base_of<TfWeakPtrFacadeBase, Ptr<const T>>::value
371 >>
372{
373 static const T* GetRawPtr(const Ptr<const T>& t) {
374 return get_pointer(t);
375 }
376
377 static Ptr<const T> ConstructFromRawPtr(const T* ptr) {
378 return Ptr<const T>(ptr);
379 }
380
381 static bool IsNull(const Ptr<const T>& t) {
382 return !t;
383 }
384
385 static void Class_Object_MUST_Be_Passed_By_Address() { }
386};
387
388// TfHash support.
389template <class HashState, template <class> class X, class T>
390inline void
391TfHashAppend(HashState &h, TfWeakPtrFacade<X, T> const &ptr)
392{
393 return h.Append(ptr.GetUniqueIdentifier());
394}
395
396// Extend boost::hash to support TfWeakPtrFacade.
397template <template <class> class X, class T>
398inline size_t
399hash_value(TfWeakPtrFacade<X, T> const &ptr)
400{
401 return TfHash()(ptr);
402}
403
404PXR_NAMESPACE_CLOSE_SCOPE
405
406#endif // PXR_BASE_TF_WEAK_PTR_FACADE_H
Low-level utilities for informing users of various internal and external diagnostic conditions.
A user-extensible hashing mechanism for use with runtime hash tables.
Definition: hash.h:460
Reference-counted smart pointer utility class.
Definition: refPtr.h:590
TfRefPtr()
Initialize pointer to nullptr.
Definition: refPtr.h:614
T DataType
Convenience type accessor to underlying type T for template code.
Definition: refPtr.h:602
Enable a concrete base class for use with TfWeakPtr.
Definition: weakBase.h:124
This access class is befriended by TfWeakPtrFacade -derived classes to grant TfWeakPtrFacade access t...
Definition: weakPtrFacade.h:33
Demangle C++ typenames generated by the typeid() facility.
std::string ArchGetDemangled()
Return demangled RTTI generated-type name.
Definition: demangle.h:86
#define TF_FATAL_ERROR(fmt, args)
Issue a fatal error and end the program.
Definition: diagnostic.h:91
size_t hash_value(const half h)
Overload hash_value for half.
Definition: half.h:28
STL namespace.
Reference counting.
TO TfSafeDynamic_cast(FROM *ptr)
Safely perform a dynamic cast.
Implements assorted functions based on compile-time type information.
Definition: typeFunctions.h:37