Loading...
Searching...
No Matches
weakPtrFacade.h
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
30#include "pxr/base/tf/hash.h"
31#include "pxr/base/tf/refPtr.h"
33
35
36#include <type_traits>
37
38PXR_NAMESPACE_OPEN_SCOPE
39
40template <class U> class TfRefPtr;
41
42template <template <class> class PtrTemplate, class DataType>
43class TfWeakPtrFacade;
44
51public:
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
75private:
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.
82template <template <class> class X, class Y>
83Y *get_pointer(TfWeakPtrFacade<X, Y> const &p) {
84 return TfWeakPtrFacadeAccess::FetchPointer(p);
85}
86
87PXR_NAMESPACE_CLOSE_SCOPE
88
89// Inject the global-scope operator for clients that make qualified calls to our
90// previous overload in the boost namespace.
91namespace boost {
92 using PXR_NS::get_pointer;
93};
94
95PXR_NAMESPACE_OPEN_SCOPE
96
97// Common base class, used to identify subtypes in enable_if expressions.
98class TfWeakPtrFacadeBase {};
99
100template <template <class> class PtrTemplate, class Type>
101class TfWeakPtrFacade : public TfWeakPtrFacadeBase {
102
103public:
104
105 friend class TfWeakPtrFacadeAccess;
106
107 typedef Type DataType;
108 typedef PtrTemplate<DataType> Derived;
109 typedef TfWeakPtrFacadeAccess Access;
110
111 typedef Type element_type;
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
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 {
206 Access::EnableExtraNotification(_Derived());
207 }
208
209 DataType *operator -> () const {
210 DataType *ptr = _FetchPointer();
211 if (ptr) {
212 return ptr;
213 }
214 Tf_PostNullSmartPtrDereferenceFatalError(
215 TF_CALL_CONTEXT, typeid(Derived).name());
216 }
217
218 DataType &operator * () const {
219 return * operator->();
220 }
221
224 void Reset() {
225 _Derived() = TfNullPtr;
226 }
227
228private:
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
260
261template <template <class> class X, class Y>
262inline bool operator== (TfWeakPtrFacade<X, Y> const &p, std::nullptr_t)
263{
264 return !p;
265}
266template <template <class> class X, class Y>
267inline bool operator== (std::nullptr_t, TfWeakPtrFacade<X, Y> const &p)
268{
269 return !p;
270}
271
272template <template <class> class X, class Y>
273inline bool operator!= (TfWeakPtrFacade<X, Y> const &p, std::nullptr_t)
274{
275 return !(p == nullptr);
276}
277template <template <class> class X, class Y>
278inline bool operator!= (std::nullptr_t, TfWeakPtrFacade<X, Y> const &p)
279{
280 return !(nullptr == p);
281}
282
283template <template <class> class X, class Y>
284inline bool operator< (TfWeakPtrFacade<X, Y> const &p, std::nullptr_t)
285{
286 return std::less<void const *>()(p.GetUniqueIdentifier(), nullptr);
287}
288template <template <class> class X, class Y>
289inline bool operator< (std::nullptr_t, TfWeakPtrFacade<X, Y> const &p)
290{
291 return std::less<void const *>()(nullptr, p.GetUniqueIdentifier());
292}
293
294template <template <class> class X, class Y>
295inline bool operator<= (TfWeakPtrFacade<X, Y> const &p, std::nullptr_t)
296{
297 return !(nullptr < p);
298}
299template <template <class> class X, class Y>
300inline bool operator<= (std::nullptr_t, TfWeakPtrFacade<X, Y> const &p)
301{
302 return !(p < nullptr);
303}
304
305template <template <class> class X, class Y>
306inline bool operator> (TfWeakPtrFacade<X, Y> const &p, std::nullptr_t)
307{
308 return nullptr < p;
309}
310template <template <class> class X, class Y>
311inline bool operator> (std::nullptr_t, TfWeakPtrFacade<X, Y> const &p)
312{
313 return p < nullptr;
314}
315
316template <template <class> class X, class Y>
317inline bool operator>= (TfWeakPtrFacade<X, Y> const &p, std::nullptr_t)
318{
319 return !(p < nullptr);
320}
321template <template <class> class X, class Y>
322inline bool operator>= (std::nullptr_t, TfWeakPtrFacade<X, Y> const &p)
323{
324 return !(nullptr < p);
325}
326
328
329template <class ToPtr, template <class> class X, class Y>
330ToPtr TfDynamic_cast(TfWeakPtrFacade<X, Y> const &p) {
331 return ToPtr(dynamic_cast<typename ToPtr::DataType *>
332 (get_pointer(p)));
333}
334
335template <class ToPtr, template <class> class X, class Y>
336ToPtr TfSafeDynamic_cast(TfWeakPtrFacade<X, Y> const &p) {
337 return ToPtr(TfSafeDynamic_cast<typename ToPtr::DataType *>
338 (get_pointer(p)));
339}
340
341template <class ToPtr, template <class> class X, class Y>
342ToPtr TfStatic_cast(TfWeakPtrFacade<X, Y> const &p) {
343 return ToPtr(static_cast<typename ToPtr::DataType *>
344 (get_pointer(p)));
345}
346
347template <class ToPtr, template <class> class X, class Y>
348ToPtr TfConst_cast(TfWeakPtrFacade<X, Y> const &p) {
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
360template <class T>
361template <template <class> class X, class U>
362inline TfRefPtr<T>::TfRefPtr(const TfWeakPtrFacade<X, U>& p,
363 typename std::enable_if<
364 std::is_convertible<U*, T*>::value
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//
375template <template <class> class Ptr, class T>
376struct 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
393 static void Class_Object_MUST_Be_Passed_By_Address() { }
394 static void Class_Object_MUST_Not_Be_Const() { }
395};
396
397template <template <class> class Ptr, class T>
398struct 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
415 static void Class_Object_MUST_Be_Passed_By_Address() { }
416};
417
418// TfHash support.
419template <class HashState, template <class> class X, class T>
420inline void
421TfHashAppend(HashState &h, TfWeakPtrFacade<X, T> const &ptr)
422{
423 return h.Append(ptr.GetUniqueIdentifier());
424}
425
426// Extend boost::hash to support TfWeakPtrFacade.
427template <template <class> class X, class T>
428inline size_t
429hash_value(TfWeakPtrFacade<X, T> const &ptr)
430{
431 return TfHash()(ptr);
432}
433
434PXR_NAMESPACE_CLOSE_SCOPE
435
436#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:477
Reference-counted smart pointer utility class.
Definition: refPtr.h:601
TfRefPtr()
Initialize pointer to nullptr.
Definition: refPtr.h:623
T DataType
Convenience type accessor to underlying type T for template code.
Definition: refPtr.h:611
Enable a concrete base class for use with TfWeakPtr.
Definition: weakBase.h:141
This access class is befriended by TfWeakPtrFacade -derived classes to grant TfWeakPtrFacade access t...
Definition: weakPtrFacade.h:50
Demangle C++ typenames generated by the typeid() facility.
std::string ArchGetDemangled()
Return demangled RTTI generated-type name.
Definition: demangle.h:103
#define TF_FATAL_ERROR(fmt, args)
Issue a fatal error and end the program.
Definition: diagnostic.h:108
size_t hash_value(const half h)
Overload hash_value for half.
Definition: half.h:45
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:54