HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
anyWeakPtr.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_ANY_WEAK_PTR_H
25 #define PXR_BASE_TF_ANY_WEAK_PTR_H
26 
27 /// \file tf/anyWeakPtr.h
28 /// \ingroup group_tf_Memory
29 /// Type independent WeakPtr holder class
30 
31 #include "pxr/pxr.h"
32 #include "pxr/base/tf/api.h"
33 #include "pxr/base/tf/cxxCast.h"
34 #include "pxr/base/tf/type.h"
35 #include "pxr/base/tf/weakPtr.h"
36 
37 #ifdef PXR_PYTHON_SUPPORT_ENABLED
38 #include "pxr/base/tf/pyUtils.h"
39 #endif // PXR_PYTHON_SUPPORT_ENABLED
40 
42 
43 #include <cstddef>
44 #include <type_traits>
45 #include <utility>
46 
48 
49 /// \class TfAnyWeakPtr
50 ///
51 /// Provides the ability to hold an arbitrary TfWeakPtr in a non-type-specific
52 /// manner in order to observe whether it has expired or not
54 {
55  struct _Data {
56  void* space[4];
57  };
58 
59 public:
60  typedef TfAnyWeakPtr This;
61 
62  /// Construct an AnyWeakPtr watching \a ptr.
63  template <class Ptr, class = typename
64  std::enable_if<Tf_SupportsWeakPtr<
65  typename Ptr::DataType>::value>::type>
66  TfAnyWeakPtr(Ptr const &ptr) {
67  static_assert(sizeof(_PointerHolder<Ptr>) <= sizeof(_Data),
68  "Ptr is too big to fit in a TfAnyWeakPtr");
69  new (&_ptrStorage) _PointerHolder<Ptr>(ptr);
70  }
71 
72  /// Construct an AnyWeakPtr not watching any \a ptr.
74  static_assert(sizeof(_EmptyHolder) <= sizeof(_Data),
75  "Ptr is too big to fit in a TfAnyWeakPtr");
76  new (&_ptrStorage) _EmptyHolder;
77  }
78 
79  /// Construct and implicitly convert from TfNullPtr.
81 
82  /// Construct and implicitly convert from std::nullptr_t.
83  TfAnyWeakPtr(std::nullptr_t) : TfAnyWeakPtr() {}
84 
85  TfAnyWeakPtr(TfAnyWeakPtr const &other) {
86  other._Get()->Clone(&_ptrStorage);
87  }
88 
90  if (this != &other) {
91  _Get()->~_PointerHolderBase();
92  other._Get()->Clone(&_ptrStorage);
93  }
94  return *this;
95  }
96 
98  _Get()->~_PointerHolderBase();
99  }
100 
101  /// Return true *only* if this expiry checker is watching a weak pointer
102  /// which has expired.
103  TF_API bool IsInvalid() const;
104 
105  /// Return the unique identifier of the WeakPtr this AnyWeakPtr contains
106  TF_API void const *GetUniqueIdentifier() const;
107 
108  /// Return the TfWeakBase object of the WeakPtr we are holding
109  TF_API TfWeakBase const *GetWeakBase() const;
110 
111  /// bool operator
112  TF_API operator bool() const;
113 
114  /// operator !
115  TF_API bool operator !() const;
116 
117  /// equality operator
118  TF_API bool operator ==(const TfAnyWeakPtr &rhs) const;
119 
120  /// inequality operator
121  bool operator !=(const TfAnyWeakPtr &rhs) const {
122  return !(*this == rhs);
123  }
124 
125  /// comparison operator
126  TF_API bool operator <(const TfAnyWeakPtr &rhs) const;
127 
128  /// less than or equal operator
129  bool operator <=(const TfAnyWeakPtr& rhs) const {
130  return !(rhs < *this);
131  }
132 
133  /// greater than operator
134  bool operator >(const TfAnyWeakPtr& rhs) const {
135  return rhs < *this;
136  }
137 
138  /// greater than or equal operator
139  bool operator >=(const TfAnyWeakPtr& rhs) const {
140  return !(*this < rhs);
141  }
142 
143  /// returns the type_info of the underlying WeakPtr
144  TF_API const std::type_info & GetTypeInfo() const;
145 
146  /// Returns the TfType of the underlying WeakPtr.
147  TF_API TfType const& GetType() const;
148 
149  /// Return a hash value for this instance.
150  size_t GetHash() const {
151  return reinterpret_cast<uintptr_t>(GetUniqueIdentifier()) >> 3;
152  }
153 
154  private:
155 #ifdef PXR_PYTHON_SUPPORT_ENABLED
156  // This grants friend access to a function in the wrapper file for this
157  // class. This lets the wrapper reach down into an AnyWeakPtr to get a
158  // hboost::python wrapped object corresponding to the held type. This
159  // facility is necessary to get the python API we want.
161  Tf_GetPythonObjectFromAnyWeakPtr(This const &self);
162 
163  TF_API
164  hboost::python::api::object _GetPythonObject() const;
165 #endif // PXR_PYTHON_SUPPORT_ENABLED
166 
167  template <class WeakPtr>
168  friend WeakPtr TfAnyWeakPtrDynamicCast(const TfAnyWeakPtr &anyWeak, WeakPtr*);
169 
170  // This is using the standard type-erasure pattern.
171  struct _PointerHolderBase {
172  TF_API virtual ~_PointerHolderBase();
173  virtual void Clone(_Data *target) const = 0;
174  virtual bool IsInvalid() const = 0;
175  virtual void const * GetUniqueIdentifier() const = 0;
176  virtual TfWeakBase const *GetWeakBase() const = 0;
177  virtual operator bool() const = 0;
178  virtual bool _IsConst() const = 0;
179  virtual TfPyObjWrapper GetPythonObject() const = 0;
180  virtual const std::type_info & GetTypeInfo() const = 0;
181  virtual TfType const& GetType() const = 0;
182  virtual const void* _GetMostDerivedPtr() const = 0;
183  virtual bool _IsPolymorphic() const = 0;
184  };
185 
186  struct _EmptyHolder : _PointerHolderBase {
187  TF_API virtual ~_EmptyHolder();
188  TF_API virtual void Clone(_Data *target) const;
189  TF_API virtual bool IsInvalid() const;
190  TF_API virtual void const * GetUniqueIdentifier() const;
191  TF_API virtual TfWeakBase const *GetWeakBase() const;
192  TF_API virtual operator bool() const;
193  TF_API virtual bool _IsConst() const;
194  TF_API virtual TfPyObjWrapper GetPythonObject() const;
195  TF_API virtual const std::type_info & GetTypeInfo() const;
196  TF_API virtual TfType const& GetType() const;
197  TF_API virtual const void* _GetMostDerivedPtr() const;
198  TF_API virtual bool _IsPolymorphic() const;
199  };
200 
201  template <typename Ptr>
202  struct _PointerHolder : _PointerHolderBase {
203  _PointerHolder(Ptr const &ptr) : _ptr(ptr) {
204  }
205 
206  virtual ~_PointerHolder();
207  virtual void Clone(_Data *target) const;
208  virtual bool IsInvalid() const;
209  virtual void const *GetUniqueIdentifier() const;
210  virtual TfWeakBase const *GetWeakBase() const;
211  virtual operator bool() const;
212  virtual bool _IsConst() const;
213  virtual TfPyObjWrapper GetPythonObject() const;
214  virtual const std::type_info & GetTypeInfo() const;
215  virtual TfType const& GetType() const;
216  virtual const void* _GetMostDerivedPtr() const;
217  virtual bool _IsPolymorphic() const;
218  private:
219  Ptr _ptr;
220  };
221 
222  _PointerHolderBase* _Get() const {
223  return (_PointerHolderBase*)(&_ptrStorage);
224  }
225 
226  _Data _ptrStorage;
227 };
228 
229 // TfHash support. We don't want to choose the TfAnyWeakPtr overload unless the
230 // passed argument is exactly TfAnyWeakPtr. By making this a function template
231 // that's only enabled for TfAnyWeakPtr, C++ will not perform implicit
232 // conversions since T is deduced.
233 template <class HashState,
234  class T, class = typename std::enable_if<
236 inline void
237 TfHashAppend(HashState &h, const T& ptr)
238 {
239  h.Append(ptr.GetUniqueIdentifier());
240 }
241 
242 template <class Ptr>
243 TfAnyWeakPtr::_PointerHolder<Ptr>::~_PointerHolder() {}
244 
245 template <class Ptr>
246 void
247 TfAnyWeakPtr::_PointerHolder<Ptr>::Clone(_Data *target) const
248 {
249  new (target) _PointerHolder<Ptr>(_ptr);
250 }
251 
252 template <class Ptr>
253 bool
254 TfAnyWeakPtr::_PointerHolder<Ptr>::IsInvalid() const
255 {
256  return _ptr.IsInvalid();
257 }
258 
259 template <class Ptr>
260 void const *
261 TfAnyWeakPtr::_PointerHolder<Ptr>::GetUniqueIdentifier() const
262 {
263  return _ptr.GetUniqueIdentifier();
264 }
265 
266 template <class Ptr>
267 TfWeakBase const *
268 TfAnyWeakPtr::_PointerHolder<Ptr>::GetWeakBase() const
269 {
270  return &(_ptr->__GetTfWeakBase__());
271 }
272 
273 template <class Ptr>
274 TfAnyWeakPtr::_PointerHolder<Ptr>::operator bool() const
275 {
276  return bool(_ptr);
277 }
278 
279 template <class Ptr>
281 TfAnyWeakPtr::_PointerHolder<Ptr>::GetPythonObject() const
282 {
283 #ifdef PXR_PYTHON_SUPPORT_ENABLED
284  return TfPyObject(_ptr);
285 #else
286  return {};
287 #endif // PXR_PYTHON_SUPPORT_ENABLED
288 }
289 template <class Ptr>
290 const std::type_info &
291 TfAnyWeakPtr::_PointerHolder<Ptr>::GetTypeInfo() const
292 {
293  return TfTypeid(_ptr);
294 }
295 
296 template <class Ptr>
297 TfType const&
298 TfAnyWeakPtr::_PointerHolder<Ptr>::GetType() const
299 {
300  return TfType::Find(_ptr);
301 }
302 
303 template <class Ptr>
304 const void *
305 TfAnyWeakPtr::_PointerHolder<Ptr>::_GetMostDerivedPtr() const
306 {
307  if (!_ptr) {
308  return 0;
309  }
310 
311  typename Ptr::DataType const *rawPtr = get_pointer(_ptr);
312  return TfCastToMostDerivedType(rawPtr);
313 }
314 
315 template <class Ptr>
316 bool
317 TfAnyWeakPtr::_PointerHolder<Ptr>::_IsPolymorphic() const
318 {
320 }
321 
322 template <class Ptr>
323 bool
324 TfAnyWeakPtr::_PointerHolder<Ptr>::_IsConst() const
325 {
327 }
328 
330 
331 #endif
TF_API const std::type_info & GetTypeInfo() const
returns the type_info of the underlying WeakPtr
void TfHashAppend(HashState &h, const T &ptr)
Definition: anyWeakPtr.h:237
#define TF_API
Definition: api.h:40
TfAnyWeakPtr(Ptr const &ptr)
Construct an AnyWeakPtr watching ptr.
Definition: anyWeakPtr.h:66
GLsizei const GLfloat * value
Definition: glcorearb.h:824
static TfType const & Find()
Definition: type.h:153
TfAnyWeakPtr(TfNullPtrType)
Construct and implicitly convert from TfNullPtr.
Definition: anyWeakPtr.h:80
fallback_uintptr uintptr_t
Definition: format.h:295
TfAnyWeakPtr(std::nullptr_t)
Construct and implicitly convert from std::nullptr_t.
Definition: anyWeakPtr.h:83
TF_API bool operator<(const TfAnyWeakPtr &rhs) const
comparison operator
Y * get_pointer(TfWeakPtrFacade< X, Y > const &p)
Definition: weakPtrFacade.h:83
TF_API bool operator!() const
operator !
TfAnyWeakPtr()
Construct an AnyWeakPtr not watching any ptr.
Definition: anyWeakPtr.h:73
TF_API void const * GetUniqueIdentifier() const
Return the unique identifier of the WeakPtr this AnyWeakPtr contains.
std::weak_ptr< T > WeakPtr
Definition: Types.h:115
TF_API bool IsInvalid() const
std::enable_if< std::is_polymorphic< T >::value, Tf_CopyCV< T, void > * >::type TfCastToMostDerivedType(T *ptr)
Definition: cxxCast.h:67
TF_API TfType const & GetType() const
Returns the TfType of the underlying WeakPtr.
bool operator<=(const TfAnyWeakPtr &rhs) const
less than or equal operator
Definition: anyWeakPtr.h:129
const std::type_info & TfTypeid(const TfRefPtr< T > &ptr)
Definition: refPtr.h:1204
friend WeakPtr TfAnyWeakPtrDynamicCast(const TfAnyWeakPtr &anyWeak, WeakPtr *)
TfAnyWeakPtr & operator=(TfAnyWeakPtr const &other)
Definition: anyWeakPtr.h:89
GLenum target
Definition: glcorearb.h:1667
hboost::python::object TfPyObject(T const &t, bool complainOnFailure=true)
Definition: pyUtils.h:144
TF_API bool operator==(const TfAnyWeakPtr &rhs) const
equality operator
size_t GetHash() const
Return a hash value for this instance.
Definition: anyWeakPtr.h:150
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
bool operator>=(const TfAnyWeakPtr &rhs) const
greater than or equal operator
Definition: anyWeakPtr.h:139
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1441
TfAnyWeakPtr(TfAnyWeakPtr const &other)
Definition: anyWeakPtr.h:85
TfAnyWeakPtr This
Definition: anyWeakPtr.h:60
auto ptr(T p) -> const void *
Definition: format.h:2448
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
bool operator!=(const TfAnyWeakPtr &rhs) const
inequality operator
Definition: anyWeakPtr.h:121
Definition: type.h:64
Definition: core.h:1131
TF_API TfWeakBase const * GetWeakBase() const
Return the TfWeakBase object of the WeakPtr we are holding.
type
Definition: core.h:1059
bool operator>(const TfAnyWeakPtr &rhs) const
greater than operator
Definition: anyWeakPtr.h:134