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/hash.h"
31 #include "pxr/base/tf/refPtr.h"
32 #include "pxr/base/tf/weakBase.h"
33 
34 #include "pxr/base/arch/demangle.h"
35 
36 #include <type_traits>
37 
39 
40 template <class U> class TfRefPtr;
41 
42 template <template <class> class PtrTemplate, class DataType>
43 class TfWeakPtrFacade;
44 
45 /// \class TfWeakPtrFacadeAccess
46 ///
47 /// This access class is befriended by \c TfWeakPtrFacade -derived classes to
48 /// grant \c TfWeakPtrFacade access to specific internal functions provided by
49 /// the derived classes.
51 public:
52  template <template <class> class PtrTemplate, class DataType>
53  friend class TfWeakPtrFacade;
54 
55  template <class Facade>
56  static typename Facade::DataType *FetchPointer(Facade const &f) {
57  return f._FetchPointer();
58  }
59 
60  template <class Facade>
61  static void const *GetUniqueIdentifier(Facade const &f) {
62  return f._GetUniqueIdentifier();
63  }
64 
65  template <class Facade>
66  static void EnableExtraNotification(Facade const &f) {
67  return f._EnableExtraNotification();
68  }
69 
70  template <class Facade>
71  static bool IsInvalid(Facade const &f) {
72  return f._IsInvalid();
73  }
74 
75 private:
77 };
78 
79 // Provide an overload of get_pointer for WeakPtrFacade. Boost libraries do
80 // unqualified calls to get_pointer to get the underlying pointer from a smart
81 // pointer, expecting the right overload will be found by ADL.
82 template <template <class> class X, class Y>
85 }
86 
88 
89 // Inject the global-scope operator for clients that make qualified calls to our
90 // previous overload in the hboost namespace.
91 namespace hboost {
92  using PXR_NS::get_pointer;
93 };
94 
96 
97 // Common base class, used to identify subtypes in enable_if expressions.
99 
100 template <template <class> class PtrTemplate, class Type>
101 class TfWeakPtrFacade : public TfWeakPtrFacadeBase {
102 
103 public:
104 
105  friend class TfWeakPtrFacadeAccess;
106 
107  typedef Type DataType;
108  typedef PtrTemplate<DataType> Derived;
110 
112 
113  template <class Other>
114  bool operator == (PtrTemplate<Other> const &p) const {
115  if (false)
116  return _FetchPointer() == TfWeakPtrFacadeAccess::FetchPointer(p);
117  return GetUniqueIdentifier() == p.GetUniqueIdentifier();
118  }
119 
120  template <class Other>
121  bool operator != (PtrTemplate<Other> const &p) const {
122  return !(*this == p);
123  }
124 
125  template <class T>
126  bool operator == (TfRefPtr<T> const &p) const {
127  if (!GetUniqueIdentifier())
128  return !p;
129  DataType *ptr = _FetchPointer();
130  return ptr && ptr == get_pointer(p);
131  }
132 
133  template <class T>
134  bool operator != (TfRefPtr<T> const &p) const {
135  return !(*this == p);
136  }
137 
138  template <class T>
139  friend bool operator == (const TfRefPtr<T>& p1, Derived const &p2) {
140  return p2 == p1;
141  }
142 
143  template <class T>
144  friend bool operator != (const TfRefPtr<T>& p1, Derived const &p2) {
145  return !(p1 == p2);
146  }
147 
148  template <class Other>
149  bool operator < (PtrTemplate<Other> const &p) const {
150  if (false)
151  return _FetchPointer() < TfWeakPtrFacadeAccess::FetchPointer(p);
152  return GetUniqueIdentifier() < p.GetUniqueIdentifier();
153  }
154 
155  template <class Other>
156  bool operator > (PtrTemplate<Other> const &p) const {
157  return !(*this < p) && !(*this == p);
158  }
159 
160  template <class Other>
161  bool operator <= (PtrTemplate<Other> const &p) const {
162  return (*this < p) || (*this == p);
163  }
164 
165  template <class Other>
166  bool operator >= (PtrTemplate<Other> const &p) const {
167  return !(*this < p);
168  }
169 
170  using UnspecifiedBoolType = DataType * (TfWeakPtrFacade::*)(void) const;
171 
172  operator UnspecifiedBoolType () const {
173  return _FetchPointer() ? &TfWeakPtrFacade::_FetchPointer : nullptr;
174  }
175 
176  bool operator ! () const {
177  return !(bool(*this));
178  }
179 
180  template <class T>
181  bool PointsTo(T const &obj) const {
182  return _FetchPointer() == &obj;
183  }
184 
185  /// Return true if this object points to an object of type \a T. \a T
186  /// must either be the same as or a base class of \a DataType or DataType
187  /// must be polymorphic.
188  template <class T>
189  bool PointsToA() const {
190  return dynamic_cast<T *>(_FetchPointer());
191  }
192 
193  bool IsInvalid() const {
194  return Access::IsInvalid(_Derived());
195  }
196 
197  void const *GetUniqueIdentifier() const {
198  return Access::GetUniqueIdentifier(_Derived());
199  }
200 
201  TfWeakBase const *GetWeakBase() const {
202  return &_Derived()->__GetTfWeakBase__();
203  }
204 
205  void EnableExtraNotification() const {
207  }
208 
210  DataType *ptr = _FetchPointer();
211  if (ptr) {
212  return ptr;
213  }
215  TF_CALL_CONTEXT, typeid(Derived).name());
216  }
217 
219  return * operator->();
220  }
221 
222  /// Reset this pointer to point at no object. Equivalent to assignment
223  /// with \a TfNullPtr.
224  void Reset() {
225  _Derived() = TfNullPtr;
226  }
227 
228 private:
229 
230  friend std::type_info const &TfTypeid(Derived const &p) {
231  if (ARCH_UNLIKELY(!p))
232  TF_FATAL_ERROR("Called TfTypeid on invalid %s",
233  ArchGetDemangled(typeid(Derived)).c_str());
234  return typeid(*get_pointer(p));
235  }
236 
237  DataType *_FetchPointer() const {
238  return Access::FetchPointer(_Derived());
239  }
240 
241  Derived &_Derived() {
242  return static_cast<Derived &>(*this);
243  }
244 
245  Derived const &_Derived() const {
246  return static_cast<Derived const &>(*this);
247  }
248 
249 };
250 
251 
252 /// \section nullptr comparisons
253 ///@{
254 ///
255 /// These are provided both to avoid ambiguous overloads due to
256 /// TfWeakPtrFacade::Derived comparisons with TfRefPtr and because implicitly
257 /// converting a nullptr to a TfWeakPtrFacade-derived type can add an unknown
258 /// amount of overhead.
259 ///
260 
261 template <template <class> class X, class Y>
262 inline bool operator== (TfWeakPtrFacade<X, Y> const &p, std::nullptr_t)
263 {
264  return !p;
265 }
266 template <template <class> class X, class Y>
267 inline bool operator== (std::nullptr_t, TfWeakPtrFacade<X, Y> const &p)
268 {
269  return !p;
270 }
271 
272 template <template <class> class X, class Y>
273 inline bool operator!= (TfWeakPtrFacade<X, Y> const &p, std::nullptr_t)
274 {
275  return !(p == nullptr);
276 }
277 template <template <class> class X, class Y>
278 inline bool operator!= (std::nullptr_t, TfWeakPtrFacade<X, Y> const &p)
279 {
280  return !(nullptr == p);
281 }
282 
283 template <template <class> class X, class Y>
284 inline bool operator< (TfWeakPtrFacade<X, Y> const &p, std::nullptr_t)
285 {
286  return std::less<void const *>()(p.GetUniqueIdentifier(), nullptr);
287 }
288 template <template <class> class X, class Y>
289 inline bool operator< (std::nullptr_t, TfWeakPtrFacade<X, Y> const &p)
290 {
291  return std::less<void const *>()(nullptr, p.GetUniqueIdentifier());
292 }
293 
294 template <template <class> class X, class Y>
295 inline bool operator<= (TfWeakPtrFacade<X, Y> const &p, std::nullptr_t)
296 {
297  return !(nullptr < p);
298 }
299 template <template <class> class X, class Y>
300 inline bool operator<= (std::nullptr_t, TfWeakPtrFacade<X, Y> const &p)
301 {
302  return !(p < nullptr);
303 }
304 
305 template <template <class> class X, class Y>
306 inline bool operator> (TfWeakPtrFacade<X, Y> const &p, std::nullptr_t)
307 {
308  return nullptr < p;
309 }
310 template <template <class> class X, class Y>
311 inline bool operator> (std::nullptr_t, TfWeakPtrFacade<X, Y> const &p)
312 {
313  return p < nullptr;
314 }
315 
316 template <template <class> class X, class Y>
317 inline bool operator>= (TfWeakPtrFacade<X, Y> const &p, std::nullptr_t)
318 {
319  return !(p < nullptr);
320 }
321 template <template <class> class X, class Y>
322 inline bool operator>= (std::nullptr_t, TfWeakPtrFacade<X, Y> const &p)
323 {
324  return !(nullptr < p);
325 }
326 
327 ///@}
328 
329 template <class ToPtr, template <class> class X, class Y>
331  return ToPtr(dynamic_cast<typename ToPtr::DataType *>
332  (get_pointer(p)));
333 }
334 
335 template <class ToPtr, template <class> class X, class Y>
337  return ToPtr(TfSafeDynamic_cast<typename ToPtr::DataType *>
338  (get_pointer(p)));
339 }
340 
341 template <class ToPtr, template <class> class X, class Y>
343  return ToPtr(static_cast<typename ToPtr::DataType *>
344  (get_pointer(p)));
345 }
346 
347 template <class ToPtr, template <class> class X, class Y>
349  return ToPtr(const_cast<typename ToPtr::DataType *>
350  (get_pointer(p)));
351 }
352 
353 //
354 // This is the implementation; the declaration and doxygen
355 // is in refPtr.h.
356 //
357 // If _remnant itself is NULL, then wp doesn't point to anything.
358 //
359 
360 template <class T>
361 template <template <class> class X, class U>
363  typename std::enable_if<
365  >::type *)
366  : _refBase(get_pointer(p))
367 {
368  _AddRef();
369  Tf_RefPtrTracker_New(this, _GetObjectForTracking());
370 }
371 
372 //
373 // See typeFunctions.h for documention.
374 //
375 template <template <class> class Ptr, class T>
376 struct TfTypeFunctions<Ptr<T>,
377  std::enable_if_t<
378  std::is_base_of<TfWeakPtrFacadeBase, Ptr<T>>::value
379  >>
380 {
381  static T* GetRawPtr(const Ptr<T>& t) {
382  return get_pointer(t);
383  }
384 
385  static Ptr<T> ConstructFromRawPtr(T* ptr) {
386  return Ptr<T>(ptr);
387  }
388 
389  static bool IsNull(const Ptr<T>& t) {
390  return !t;
391  }
392 
395 };
396 
397 template <template <class> class Ptr, class T>
398 struct TfTypeFunctions<Ptr<const T>,
399  std::enable_if_t<
400  std::is_base_of<TfWeakPtrFacadeBase, Ptr<const T>>::value
401  >>
402 {
403  static const T* GetRawPtr(const Ptr<const T>& t) {
404  return get_pointer(t);
405  }
406 
407  static Ptr<const T> ConstructFromRawPtr(const T* ptr) {
408  return Ptr<const T>(ptr);
409  }
410 
411  static bool IsNull(const Ptr<const T>& t) {
412  return !t;
413  }
414 
416 };
417 
418 // TfHash support.
419 template <class HashState, template <class> class X, class T>
420 inline void
422 {
423  return h.Append(ptr.GetUniqueIdentifier());
424 }
425 
426 // Extend hboost::hash to support TfWeakPtrFacade.
427 template <template <class> class X, class T>
428 inline size_t
430 {
431  return TfHash()(ptr);
432 }
433 
435 
436 #endif // PXR_BASE_TF_WEAK_PTR_FACADE_H
DataType & operator*() const
#define TF_CALL_CONTEXT
Definition: callContext.h:47
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
bool operator!=(PtrTemplate< Other > const &p) const
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:56
Y * get_pointer(TfWeakPtrFacade< X, Y > const &p)
Definition: weakPtrFacade.h:83
Definition: hash.h:504
DataType *(TfWeakPtrFacade::*)(void) const UnspecifiedBoolType
#define ARCH_UNLIKELY(x)
Definition: hints.h:47
GLfloat f
Definition: glcorearb.h:1926
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
ToPtr TfSafeDynamic_cast(TfWeakPtrFacade< X, Y > const &p)
void Tf_RefPtrTracker_New(const void *, const void *)
Definition: refPtr.h:470
bool PointsTo(T const &obj) const
void TfHashAppend(HashState &h, TfWeakPtrFacade< X, T > const &ptr)
GLdouble t
Definition: glad.h:2397
PtrTemplate< DataType > Derived
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:1441
static void const * GetUniqueIdentifier(Facade const &f)
Definition: weakPtrFacade.h:61
bool operator>=(TfWeakPtrFacade< X, Y > const &p, std::nullptr_t)
TfRefPtr()
Definition: refPtr.h:598
auto ptr(T p) -> const void *
Definition: format.h:2448
#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:71
ToPtr TfConst_cast(TfWeakPtrFacade< X, Y > const &p)
bool operator>=(PtrTemplate< Other > const &p) const
#define const
Definition: zconf.h:214
static void EnableExtraNotification(Facade const &f)
Definition: weakPtrFacade.h:66
type
Definition: core.h:1059
friend class TfWeakPtrFacadeAccess
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