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 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_WEAK_PTR_FACADE_H
25 #define PXR_BASE_TF_WEAK_PTR_FACADE_H
26 
27 #include "pxr/pxr.h"
28 
29 #include "pxr/base/tf/diagnostic.h"
30 #include "pxr/base/tf/refPtr.h"
31 #include "pxr/base/tf/weakBase.h"
32 
33 #include "pxr/base/arch/demangle.h"
34 
35 #include <hboost/functional/hash_fwd.hpp>
36 #include <hboost/mpl/or.hpp>
37 #include <hboost/type_traits/is_base_of.hpp>
38 #include <hboost/type_traits/is_same.hpp>
39 #include <hboost/utility/enable_if.hpp>
40 
42 
43 template <class U> class TfRefPtr;
44 
45 template <template <class> class PtrTemplate, class DataType>
46 class TfWeakPtrFacade;
47 
48 /// \class TfWeakPtrFacadeAccess
49 ///
50 /// This access class is befriended by \c TfWeakPtrFacade -derived classes to
51 /// grant \c TfWeakPtrFacade access to specific internal functions provided by
52 /// the derived classes.
54 public:
55  template <template <class> class PtrTemplate, class DataType>
56  friend class TfWeakPtrFacade;
57 
58  template <class Facade>
59  static typename Facade::DataType *FetchPointer(Facade const &f) {
60  return f._FetchPointer();
61  }
62 
63  template <class Facade>
64  static void const *GetUniqueIdentifier(Facade const &f) {
65  return f._GetUniqueIdentifier();
66  }
67 
68  template <class Facade>
69  static void EnableExtraNotification(Facade const &f) {
70  return f._EnableExtraNotification();
71  }
72 
73  template <class Facade>
74  static bool IsInvalid(Facade const &f) {
75  return f._IsInvalid();
76  }
77 
78 private:
80 };
81 
82 // Provide an overload of get_pointer for WeakPtrFacade. Boost libraries do
83 // unqualified calls to get_pointer to get the underlying pointer from a smart
84 // pointer, expecting the right overload will be found by ADL.
85 template <template <class> class X, class Y>
88 }
89 
91 
92 // Inject the global-scope operator for clients that make qualified calls to our
93 // previous overload in the hboost namespace.
94 namespace hboost {
95  using PXR_NS::get_pointer;
96 };
97 
99 
100 // Common base class, used to identify subtypes in enable_if expressions.
102 
103 template <template <class> class PtrTemplate, class Type>
104 class TfWeakPtrFacade : public TfWeakPtrFacadeBase {
105 
106 public:
107 
108  friend class TfWeakPtrFacadeAccess;
109 
110  typedef Type DataType;
111  typedef PtrTemplate<DataType> Derived;
113 
115 
116  template <class Other>
117  bool operator == (PtrTemplate<Other> const &p) const {
118  if (false)
119  return _FetchPointer() == TfWeakPtrFacadeAccess::FetchPointer(p);
120  return GetUniqueIdentifier() == p.GetUniqueIdentifier();
121  }
122 
123  template <class Other>
124  bool operator != (PtrTemplate<Other> const &p) const {
125  return !(*this == p);
126  }
127 
128  template <class T>
129  bool operator == (TfRefPtr<T> const &p) const {
130  if (!GetUniqueIdentifier())
131  return !p;
132  DataType *ptr = _FetchPointer();
133  return ptr && ptr == get_pointer(p);
134  }
135 
136  template <class T>
137  bool operator != (TfRefPtr<T> const &p) const {
138  return !(*this == p);
139  }
140 
141  template <class T>
142  friend bool operator == (const TfRefPtr<T>& p1, Derived const &p2) {
143  return p2 == p1;
144  }
145 
146  template <class T>
147  friend bool operator != (const TfRefPtr<T>& p1, Derived const &p2) {
148  return !(p1 == p2);
149  }
150 
151  template <class Other>
152  bool operator < (PtrTemplate<Other> const &p) const {
153  if (false)
154  return _FetchPointer() < TfWeakPtrFacadeAccess::FetchPointer(p);
155  return GetUniqueIdentifier() < p.GetUniqueIdentifier();
156  }
157 
158  template <class Other>
159  bool operator > (PtrTemplate<Other> const &p) const {
160  return !(*this < p) && !(*this == p);
161  }
162 
163  template <class Other>
164  bool operator <= (PtrTemplate<Other> const &p) const {
165  return (*this < p) || (*this == p);
166  }
167 
168  template <class Other>
169  bool operator >= (PtrTemplate<Other> const &p) const {
170  return !(*this < p);
171  }
172 
173  using UnspecifiedBoolType = DataType * (TfWeakPtrFacade::*)(void) const;
174 
175  operator UnspecifiedBoolType () const {
176  return _FetchPointer() ? &TfWeakPtrFacade::_FetchPointer : nullptr;
177  }
178 
179  bool operator ! () const {
180  return !(bool(*this));
181  }
182 
183  template <class T>
184  bool PointsTo(T const &obj) const {
185  return _FetchPointer() == &obj;
186  }
187 
188  /// Return true if this object points to an object of type \a T. \a T
189  /// must either be the same as or a base class of \a DataType or DataType
190  /// must be polymorphic.
191  template <class T>
192  bool PointsToA() const {
193  return dynamic_cast<T *>(_FetchPointer());
194  }
195 
196  bool IsInvalid() const {
197  return Access::IsInvalid(_Derived());
198  }
199 
200  void const *GetUniqueIdentifier() const {
201  return Access::GetUniqueIdentifier(_Derived());
202  }
203 
204  TfWeakBase const *GetWeakBase() const {
205  return &_Derived()->__GetTfWeakBase__();
206  }
207 
208  void EnableExtraNotification() const {
210  }
211 
213  DataType *ptr = _FetchPointer();
214  if (ARCH_LIKELY(ptr)) {
215  return ptr;
216  }
217  static const TfCallContext ctx(TF_CALL_CONTEXT);
219  }
220 
222  return * operator->();
223  }
224 
225  /// Reset this pointer to point at no object. Equivalent to assignment
226  /// with \a TfNullPtr.
227  void Reset() {
228  _Derived() = TfNullPtr;
229  }
230 
231 private:
232 
233  friend std::type_info const &TfTypeid(Derived const &p) {
234  if (ARCH_UNLIKELY(!p))
235  TF_FATAL_ERROR("Called TfTypeid on invalid %s",
236  ArchGetDemangled(typeid(Derived)).c_str());
237  return typeid(*get_pointer(p));
238  }
239 
240  DataType *_FetchPointer() const {
241  return Access::FetchPointer(_Derived());
242  }
243 
244  Derived &_Derived() {
245  return static_cast<Derived &>(*this);
246  }
247 
248  Derived const &_Derived() const {
249  return static_cast<Derived const &>(*this);
250  }
251 
252 };
253 
254 
255 /// \section nullptr comparisons
256 ///@{
257 ///
258 /// These are provided both to avoid ambiguous overloads due to
259 /// TfWeakPtrFacade::Derived comparisons with TfRefPtr and because implicitly
260 /// converting a nullptr to a TfWeakPtrFacade-derived type can add an unknown
261 /// amount of overhead.
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 !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;
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 !(p == nullptr);
279 }
280 template <template <class> class X, class Y>
281 inline bool operator!= (std::nullptr_t, TfWeakPtrFacade<X, Y> const &p)
282 {
283  return !(nullptr == p);
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 std::less<void const *>()(p.GetUniqueIdentifier(), 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 std::less<void const *>()(nullptr, p.GetUniqueIdentifier());
295 }
296 
297 template <template <class> class X, class Y>
298 inline bool operator<= (TfWeakPtrFacade<X, Y> const &p, std::nullptr_t)
299 {
300  return !(nullptr < p);
301 }
302 template <template <class> class X, class Y>
303 inline bool operator<= (std::nullptr_t, TfWeakPtrFacade<X, Y> const &p)
304 {
305  return !(p < nullptr);
306 }
307 
308 template <template <class> class X, class Y>
309 inline bool operator> (TfWeakPtrFacade<X, Y> const &p, std::nullptr_t)
310 {
311  return nullptr < p;
312 }
313 template <template <class> class X, class Y>
314 inline bool operator> (std::nullptr_t, TfWeakPtrFacade<X, Y> const &p)
315 {
316  return p < nullptr;
317 }
318 
319 template <template <class> class X, class Y>
320 inline bool operator>= (TfWeakPtrFacade<X, Y> const &p, std::nullptr_t)
321 {
322  return !(p < nullptr);
323 }
324 template <template <class> class X, class Y>
325 inline bool operator>= (std::nullptr_t, TfWeakPtrFacade<X, Y> const &p)
326 {
327  return !(nullptr < p);
328 }
329 
330 ///@}
331 
332 template <class ToPtr, template <class> class X, class Y>
334  return ToPtr(dynamic_cast<typename ToPtr::DataType *>
335  (get_pointer(p)));
336 }
337 
338 template <class ToPtr, template <class> class X, class Y>
340  return ToPtr(TfSafeDynamic_cast<typename ToPtr::DataType *>
341  (get_pointer(p)));
342 }
343 
344 template <class ToPtr, template <class> class X, class Y>
346  return ToPtr(static_cast<typename ToPtr::DataType *>
347  (get_pointer(p)));
348 }
349 
350 template <class ToPtr, template <class> class X, class Y>
352  return ToPtr(const_cast<typename ToPtr::DataType *>
353  (get_pointer(p)));
354 }
355 
356 //
357 // This is the implementation; the declaration and doxygen
358 // is in refPtr.h.
359 //
360 // If _remnant itself is NULL, then wp doesn't point to anything.
361 //
362 
363 template <class T>
364 template <template <class> class X, class U>
366  typename hboost::enable_if<
367  hboost::is_convertible<U*, T*>
368  >::type *dummy)
369  : _refBase(get_pointer(p))
370 {
371  _AddRef();
372  Tf_RefPtrTracker_New(this, _GetObjectForTracking());
373 }
374 
375 //
376 // See typeFunctions.h for documention.
377 //
378 template <template <class> class Ptr, class T>
379 struct TfTypeFunctions<Ptr<T>,
380  typename hboost::enable_if<
381  hboost::is_base_of<TfWeakPtrFacadeBase, Ptr<T> >
382  >::type>
383 {
384  static T* GetRawPtr(const Ptr<T>& t) {
385  return get_pointer(t);
386  }
387 
388  static Ptr<T> ConstructFromRawPtr(T* ptr) {
389  return Ptr<T>(ptr);
390  }
391 
392  static bool IsNull(const Ptr<T>& t) {
393  return !t;
394  }
395 
398 };
399 
400 template <template <class> class Ptr, class T>
401 struct TfTypeFunctions<Ptr<const T>,
402  typename hboost::enable_if<
403  hboost::is_base_of<TfWeakPtrFacadeBase, Ptr<const T> >
404  >::type>
405 {
406  static const T* GetRawPtr(const Ptr<const T>& t) {
407  return get_pointer(t);
408  }
409 
410  static Ptr<const T> ConstructFromRawPtr(const T* ptr) {
411  return Ptr<const T>(ptr);
412  }
413 
414  static bool IsNull(const Ptr<const T>& t) {
415  return !t;
416  }
417 
419 };
420 
421 // TfHash support.
422 template <class HashState, template <class> class X, class T>
423 inline void
425 {
426  return h.Append(ptr.GetUniqueIdentifier());
427 }
428 
429 // Extend hboost::hash to support TfWeakPtrFacade.
430 template <template <class> class X, class T>
431 inline size_t
433 {
434  // Make the hboost::hash type depend on T so that we don't have to always
435  // include hboost/functional/hash.hpp in this header for the definition of
436  // hboost::hash.
437  auto uniqueId = ptr.GetUniqueIdentifier();
438  return hboost::hash<decltype(uniqueId)>()(uniqueId);
439 }
440 
442 
443 #endif // PXR_BASE_TF_WEAK_PTR_FACADE_H
#define ARCH_LIKELY(x)
Definition: hints.h:46
DataType & operator*() const
#define TF_CALL_CONTEXT
Definition: callContext.h:47
void const * GetUniqueIdentifier() const
void EnableExtraNotification() const
bool operator==(PtrTemplate< Other > const &p) const
bool operator!=(PtrTemplate< Other > const &p) const
bool operator>(PtrTemplate< Other > const &p) const
ToPtr TfStatic_cast(TfWeakPtrFacade< X, Y > const &p)
TF_API const TfNullPtrType TfNullPtr
ARCH_API std::string ArchGetDemangled(const std::string &typeName)
bool operator!() const
size_t hash_value(TfWeakPtrFacade< X, T > const &ptr)
GLhandleARB obj
Definition: glew.h:6236
static Facade::DataType * FetchPointer(Facade const &f)
Definition: weakPtrFacade.h:59
Y * get_pointer(TfWeakPtrFacade< X, Y > const &p)
Definition: weakPtrFacade.h:86
DataType *(TfWeakPtrFacade::*)(void) const UnspecifiedBoolType
#define ARCH_UNLIKELY(x)
Definition: hints.h:47
bool operator>(TfWeakPtrFacade< X, Y > const &p, std::nullptr_t)
GLclampf f
Definition: glew.h:3499
TF_API void Tf_PostNullSmartPtrDereferenceFatalError(const TfCallContext &, const std::type_info &)
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:563
bool IsInvalid() const
GLfloat GLfloat GLfloat GLfloat h
Definition: glew.h:8011
ToPtr TfSafeDynamic_cast(TfWeakPtrFacade< X, Y > const &p)
void Tf_RefPtrTracker_New(const void *, const void *)
Definition: refPtr.h:475
bool PointsTo(T const &obj) const
GLuint GLuint GLsizei GLenum type
Definition: glew.h:1253
void TfHashAppend(HashState &h, TfWeakPtrFacade< X, T > const &ptr)
PtrTemplate< DataType > Derived
GLfloat GLfloat p
Definition: glew.h:16321
ToPtr TfDynamic_cast(TfWeakPtrFacade< X, Y > const &p)
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1346
static void const * GetUniqueIdentifier(Facade const &f)
Definition: weakPtrFacade.h:64
const void * ptr(const T *p)
Definition: format.h:3292
bool operator>=(TfWeakPtrFacade< X, Y > const &p, std::nullptr_t)
TfRefPtr()
Definition: refPtr.h:604
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
DataType * operator->() const
friend std::type_info const & TfTypeid(Derived const &p)
static bool IsInvalid(Facade const &f)
Definition: weakPtrFacade.h:74
ToPtr TfConst_cast(TfWeakPtrFacade< X, Y > const &p)
T DataType
Convenience type accessor to underlying type T for template code.
Definition: refPtr.h:592
bool operator>=(PtrTemplate< Other > const &p) const
#define const
Definition: zconf.h:214
static void EnableExtraNotification(Facade const &f)
Definition: weakPtrFacade.h:69
friend class TfWeakPtrFacadeAccess
TfWeakBase const * GetWeakBase() const
GLdouble GLdouble t
Definition: glew.h:1398
bool operator==(const Mat3< T0 > &m0, const Mat3< T1 > &m1)
Equality operator, does exact floating point comparisons.
Definition: Mat3.h:549
TfWeakPtrFacadeAccess Access