HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
weakPtrFacade.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_WEAK_PTR_FACADE_H
8 #define PXR_BASE_TF_WEAK_PTR_FACADE_H
9 
10 #include "pxr/pxr.h"
11 
12 #include "pxr/base/tf/diagnostic.h"
13 #include "pxr/base/tf/hash.h"
14 #include "pxr/base/tf/refPtr.h"
15 #include "pxr/base/tf/weakBase.h"
16 
17 #include "pxr/base/arch/demangle.h"
18 
19 #include <type_traits>
20 
22 
23 template <class U> class TfRefPtr;
24 
25 template <template <class> class PtrTemplate, class DataType>
26 class TfWeakPtrFacade;
27 
28 /// \class TfWeakPtrFacadeAccess
29 ///
30 /// This access class is befriended by \c TfWeakPtrFacade -derived classes to
31 /// grant \c TfWeakPtrFacade access to specific internal functions provided by
32 /// the derived classes.
34 public:
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 
58 private:
60 };
61 
62 template <template <class> class X, class Y>
65 }
66 
67 // Common base class, used to identify subtypes in enable_if expressions.
69 
70 template <template <class> class PtrTemplate, class Type>
71 class TfWeakPtrFacade : public TfWeakPtrFacadeBase {
72 
73 public:
74 
75  friend class TfWeakPtrFacadeAccess;
76 
77  typedef Type DataType;
78  typedef PtrTemplate<DataType> Derived;
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 
155  /// Return true if this object points to an object of type \a T. \a T
156  /// must either be the same as or a base class of \a DataType or DataType
157  /// must be polymorphic.
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 {
177  }
178 
180  DataType *ptr = _FetchPointer();
181  if (ptr) {
182  return ptr;
183  }
185  TF_CALL_CONTEXT, typeid(Derived).name());
186  }
187 
189  return * operator->();
190  }
191 
192  /// Reset this pointer to point at no object. Equivalent to assignment
193  /// with \a TfNullPtr.
194  void Reset() {
195  _Derived() = TfNullPtr;
196  }
197 
198 private:
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 
222 /// \section nullptr comparisons
223 ///@{
224 ///
225 /// These are provided both to avoid ambiguous overloads due to
226 /// TfWeakPtrFacade::Derived comparisons with TfRefPtr and because implicitly
227 /// converting a nullptr to a TfWeakPtrFacade-derived type can add an unknown
228 /// amount of overhead.
229 ///
230 
231 template <template <class> class X, class Y>
232 inline bool operator== (TfWeakPtrFacade<X, Y> const &p, std::nullptr_t)
233 {
234  return !p;
235 }
236 template <template <class> class X, class Y>
237 inline bool operator== (std::nullptr_t, TfWeakPtrFacade<X, Y> const &p)
238 {
239  return !p;
240 }
241 
242 template <template <class> class X, class Y>
243 inline bool operator!= (TfWeakPtrFacade<X, Y> const &p, std::nullptr_t)
244 {
245  return !(p == nullptr);
246 }
247 template <template <class> class X, class Y>
248 inline bool operator!= (std::nullptr_t, TfWeakPtrFacade<X, Y> const &p)
249 {
250  return !(nullptr == p);
251 }
252 
253 template <template <class> class X, class Y>
254 inline bool operator< (TfWeakPtrFacade<X, Y> const &p, std::nullptr_t)
255 {
256  return std::less<void const *>()(p.GetUniqueIdentifier(), nullptr);
257 }
258 template <template <class> class X, class Y>
259 inline bool operator< (std::nullptr_t, TfWeakPtrFacade<X, Y> const &p)
260 {
261  return std::less<void const *>()(nullptr, p.GetUniqueIdentifier());
262 }
263 
264 template <template <class> class X, class Y>
265 inline bool operator<= (TfWeakPtrFacade<X, Y> const &p, std::nullptr_t)
266 {
267  return !(nullptr < p);
268 }
269 template <template <class> class X, class Y>
270 inline bool operator<= (std::nullptr_t, TfWeakPtrFacade<X, Y> const &p)
271 {
272  return !(p < nullptr);
273 }
274 
275 template <template <class> class X, class Y>
276 inline bool operator> (TfWeakPtrFacade<X, Y> const &p, std::nullptr_t)
277 {
278  return nullptr < p;
279 }
280 template <template <class> class X, class Y>
281 inline bool operator> (std::nullptr_t, TfWeakPtrFacade<X, Y> const &p)
282 {
283  return p < nullptr;
284 }
285 
286 template <template <class> class X, class Y>
287 inline bool operator>= (TfWeakPtrFacade<X, Y> const &p, std::nullptr_t)
288 {
289  return !(p < nullptr);
290 }
291 template <template <class> class X, class Y>
292 inline bool operator>= (std::nullptr_t, TfWeakPtrFacade<X, Y> const &p)
293 {
294  return !(nullptr < p);
295 }
296 
297 ///@}
298 
299 template <class ToPtr, template <class> class X, class Y>
301  return ToPtr(dynamic_cast<typename ToPtr::DataType *>
302  (get_pointer(p)));
303 }
304 
305 template <class ToPtr, template <class> class X, class Y>
307  return ToPtr(TfSafeDynamic_cast<typename ToPtr::DataType *>
308  (get_pointer(p)));
309 }
310 
311 template <class ToPtr, template <class> class X, class Y>
313  return ToPtr(static_cast<typename ToPtr::DataType *>
314  (get_pointer(p)));
315 }
316 
317 template <class ToPtr, template <class> class X, class Y>
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 
330 template <class T>
331 template <template <class> class X, class U>
333  typename std::enable_if<
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 //
345 template <template <class> class Ptr, class T>
346 struct 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 
365 };
366 
367 template <template <class> class Ptr, class T>
368 struct 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 
386 };
387 
388 // TfHash support.
389 template <class HashState, template <class> class X, class T>
390 inline void
392 {
393  return h.Append(ptr.GetUniqueIdentifier());
394 }
395 
396 // Extend boost::hash to support TfWeakPtrFacade.
397 template <template <class> class X, class T>
398 inline size_t
400 {
401  return TfHash()(ptr);
402 }
403 
405 
406 #endif // PXR_BASE_TF_WEAK_PTR_FACADE_H
DataType & operator*() const
#define TF_CALL_CONTEXT
Definition: callContext.h:30
typename std::enable_if< B, T >::type enable_if_t
Define Imath::enable_if_t to be std for C++14, equivalent for C++11.
void const * GetUniqueIdentifier() const
void EnableExtraNotification() const
Y
Definition: ImathEuler.h:184
bool operator==(PtrTemplate< Other > const &p) const
Definition: weakPtrFacade.h:84
bool operator!=(PtrTemplate< Other > const &p) const
Definition: weakPtrFacade.h:91
bool operator>(PtrTemplate< Other > const &p) const
GLsizei const GLfloat * value
Definition: glcorearb.h:824
ToPtr TfStatic_cast(TfWeakPtrFacade< X, Y > const &p)
TF_API const TfNullPtrType TfNullPtr
ARCH_API std::string ArchGetDemangled(const std::string &typeName)
X
Definition: ImathEuler.h:183
bool operator!() const
size_t hash_value(TfWeakPtrFacade< X, T > const &ptr)
static Facade::DataType * FetchPointer(Facade const &f)
Definition: weakPtrFacade.h:39
OutGridT const XformOp bool bool
Y * get_pointer(TfWeakPtrFacade< X, Y > const &p)
Definition: weakPtrFacade.h:63
Definition: hash.h:472
DataType *(TfWeakPtrFacade::*)(void) const UnspecifiedBoolType
#define ARCH_UNLIKELY(x)
Definition: hints.h:30
GLfloat f
Definition: glcorearb.h:1926
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
bool operator>(TfWeakPtrFacade< X, Y > const &p, std::nullptr_t)
TF_API void Tf_PostNullSmartPtrDereferenceFatalError(const TfCallContext &, const char *)
bool PointsToA() const
#define TF_FATAL_ERROR
bool operator!=(const Mat3< T0 > &m0, const Mat3< T1 > &m1)
Inequality operator, does exact floating point comparisons.
Definition: Mat3.h:556
bool IsInvalid() const
GLuint const GLchar * name
Definition: glcorearb.h:786
ToPtr TfSafeDynamic_cast(TfWeakPtrFacade< X, Y > const &p)
bool PointsTo(T const &obj) const
void TfHashAppend(HashState &h, TfWeakPtrFacade< X, T > const &ptr)
GLdouble t
Definition: glad.h:2397
PtrTemplate< DataType > Derived
Definition: weakPtrFacade.h:78
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
ToPtr TfDynamic_cast(TfWeakPtrFacade< X, Y > const &p)
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
static void const * GetUniqueIdentifier(Facade const &f)
Definition: weakPtrFacade.h:44
bool operator>=(TfWeakPtrFacade< X, Y > const &p, std::nullptr_t)
TfRefPtr()
Definition: refPtr.h:614
void Tf_RefPtrTracker_New(const void *, const TfRefBase *, const void *)
Definition: refPtr.h:456
auto ptr(T p) -> const void *
Definition: format.h:4331
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
DataType * operator->() const
friend std::type_info const & TfTypeid(Derived const &p)
static bool IsInvalid(Facade const &f)
Definition: weakPtrFacade.h:54
OIIO_UTIL_API const char * c_str(string_view str)
ToPtr TfConst_cast(TfWeakPtrFacade< X, Y > const &p)
bool operator>=(PtrTemplate< Other > const &p) const
static void EnableExtraNotification(Facade const &f)
Definition: weakPtrFacade.h:49
friend class TfWeakPtrFacadeAccess
Definition: weakPtrFacade.h:75
TfWeakBase const * GetWeakBase() const
bool operator==(const Mat3< T0 > &m0, const Mat3< T1 > &m1)
Equality operator, does exact floating point comparisons.
Definition: Mat3.h:542
TfWeakPtrFacadeAccess Access
Definition: weakPtrFacade.h:79