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 TF_ANYWEAKPTR_H
25 #define TF_ANYWEAKPTR_H
26 
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/traits.h"
35 #include "pxr/base/tf/type.h"
36 #include "pxr/base/tf/weakPtr.h"
37 
38 #ifdef PXR_PYTHON_SUPPORT_ENABLED
39 #include "pxr/base/tf/pyUtils.h"
40 #include <boost/python/object.hpp>
41 #endif // PXR_PYTHON_SUPPORT_ENABLED
42 
43 #include <boost/operators.hpp>
44 
45 #include <cstddef>
46 #include <type_traits>
47 #include <utility>
48 
49 PXR_NAMESPACE_OPEN_SCOPE
50 
55 class TfAnyWeakPtr : boost::totally_ordered<TfAnyWeakPtr>
56 {
57  struct _Data {
58  void* space[4];
59  };
60 
61 public:
62  typedef TfAnyWeakPtr This;
63 
65  template <class Ptr, class = typename
66  std::enable_if<Tf_SupportsWeakPtr<
67  typename Ptr::DataType>::value>::type>
68  TfAnyWeakPtr(Ptr const &ptr) {
69  static_assert(sizeof(_PointerHolder<Ptr>) <= sizeof(_Data),
70  "Ptr is too big to fit in a TfAnyWeakPtr");
71  new (&_ptrStorage) _PointerHolder<Ptr>(ptr);
72  }
73 
76  static_assert(sizeof(_EmptyHolder) <= sizeof(_Data),
77  "Ptr is too big to fit in a TfAnyWeakPtr");
78  new (&_ptrStorage) _EmptyHolder;
79  }
80 
82  TfAnyWeakPtr(TfNullPtrType) : TfAnyWeakPtr() {}
83 
85  TfAnyWeakPtr(std::nullptr_t) : TfAnyWeakPtr() {}
86 
87  TfAnyWeakPtr(TfAnyWeakPtr const &other) {
88  other._Get()->Clone(&_ptrStorage);
89  }
90 
91  TfAnyWeakPtr &operator=(TfAnyWeakPtr const &other) {
92  if (this != &other) {
93  _Get()->~_PointerHolderBase();
94  other._Get()->Clone(&_ptrStorage);
95  }
96  return *this;
97  }
98 
99  ~TfAnyWeakPtr() {
100  _Get()->~_PointerHolderBase();
101  }
102 
105  TF_API bool IsInvalid() const;
106 
108  TF_API void const *GetUniqueIdentifier() const;
109 
111  TF_API TfWeakBase const *GetWeakBase() const;
112 
114  TF_API operator bool() const;
115 
117  TF_API bool operator !() const;
118 
120  TF_API bool operator ==(const TfAnyWeakPtr &rhs) const;
121 
123  TF_API bool operator <(const TfAnyWeakPtr &rhs) const;
124 
126  TF_API const std::type_info & GetTypeInfo() const;
127 
129  TF_API TfType const& GetType() const;
130 
132  size_t GetHash() const {
133  return reinterpret_cast<uintptr_t>(GetUniqueIdentifier()) >> 3;
134  }
135 
136  private:
137 #ifdef PXR_PYTHON_SUPPORT_ENABLED
138  // This grants friend access to a function in the wrapper file for this
139  // class. This lets the wrapper reach down into an AnyWeakPtr to get a
140  // boost::python wrapped object corresponding to the held type. This
141  // facility is necessary to get the python API we want.
142  friend boost::python::api::object
143  Tf_GetPythonObjectFromAnyWeakPtr(This const &self);
144 
145  TF_API
146  boost::python::api::object _GetPythonObject() const;
147 #endif // PXR_PYTHON_SUPPORT_ENABLED
148 
149  template <class WeakPtr>
150  friend WeakPtr TfAnyWeakPtrDynamicCast(const TfAnyWeakPtr &anyWeak, WeakPtr*);
151 
152  // This is using the standard type-erasure pattern.
153  struct _PointerHolderBase {
154  TF_API virtual ~_PointerHolderBase();
155  virtual void Clone(_Data *target) const = 0;
156  virtual bool IsInvalid() const = 0;
157  virtual void const * GetUniqueIdentifier() const = 0;
158  virtual TfWeakBase const *GetWeakBase() const = 0;
159  virtual operator bool() const = 0;
160  virtual bool _IsConst() const = 0;
161 #ifdef PXR_PYTHON_SUPPORT_ENABLED
162  virtual boost::python::api::object GetPythonObject() const = 0;
163 #endif // PXR_PYTHON_SUPPORT_ENABLED
164  virtual const std::type_info & GetTypeInfo() const = 0;
165  virtual TfType const& GetType() const = 0;
166  virtual const void* _GetMostDerivedPtr() const = 0;
167  virtual bool _IsPolymorphic() const = 0;
168  };
169 
170  struct _EmptyHolder : _PointerHolderBase {
171  TF_API virtual ~_EmptyHolder();
172  TF_API virtual void Clone(_Data *target) const;
173  TF_API virtual bool IsInvalid() const;
174  TF_API virtual void const * GetUniqueIdentifier() const;
175  TF_API virtual TfWeakBase const *GetWeakBase() const;
176  TF_API virtual operator bool() const;
177  TF_API virtual bool _IsConst() const;
178 #ifdef PXR_PYTHON_SUPPORT_ENABLED
179  TF_API virtual boost::python::api::object GetPythonObject() const;
180 #endif // PXR_PYTHON_SUPPORT_ENABLED
181  TF_API virtual const std::type_info & GetTypeInfo() const;
182  TF_API virtual TfType const& GetType() const;
183  TF_API virtual const void* _GetMostDerivedPtr() const;
184  TF_API virtual bool _IsPolymorphic() const;
185  };
186 
187  template <typename Ptr>
188  struct _PointerHolder : _PointerHolderBase {
189  _PointerHolder(Ptr const &ptr) : _ptr(ptr) {
190  }
191 
192  virtual ~_PointerHolder();
193  virtual void Clone(_Data *target) const;
194  virtual bool IsInvalid() const;
195  virtual void const *GetUniqueIdentifier() const;
196  virtual TfWeakBase const *GetWeakBase() const;
197  virtual operator bool() const;
198  virtual bool _IsConst() const;
199 #ifdef PXR_PYTHON_SUPPORT_ENABLED
200  virtual boost::python::api::object GetPythonObject() const;
201 #endif // PXR_PYTHON_SUPPORT_ENABLED
202  virtual const std::type_info & GetTypeInfo() const;
203  virtual TfType const& GetType() const;
204  virtual const void* _GetMostDerivedPtr() const;
205  virtual bool _IsPolymorphic() const;
206  private:
207  Ptr _ptr;
208  };
209 
210  _PointerHolderBase* _Get() const {
211  return (_PointerHolderBase*)(&_ptrStorage);
212  }
213 
214  _Data _ptrStorage;
215 };
216 
217 template <class Ptr>
218 TfAnyWeakPtr::_PointerHolder<Ptr>::~_PointerHolder() {}
219 
220 template <class Ptr>
221 void
222 TfAnyWeakPtr::_PointerHolder<Ptr>::Clone(_Data *target) const
223 {
224  new (target) _PointerHolder<Ptr>(_ptr);
225 }
226 
227 template <class Ptr>
228 bool
229 TfAnyWeakPtr::_PointerHolder<Ptr>::IsInvalid() const
230 {
231  return _ptr.IsInvalid();
232 }
233 
234 template <class Ptr>
235 void const *
236 TfAnyWeakPtr::_PointerHolder<Ptr>::GetUniqueIdentifier() const
237 {
238  return _ptr.GetUniqueIdentifier();
239 }
240 
241 template <class Ptr>
242 TfWeakBase const *
243 TfAnyWeakPtr::_PointerHolder<Ptr>::GetWeakBase() const
244 {
245  return &(_ptr->__GetTfWeakBase__());
246 }
247 
248 template <class Ptr>
249 TfAnyWeakPtr::_PointerHolder<Ptr>::operator bool() const
250 {
251  return bool(_ptr);
252 }
253 
254 #ifdef PXR_PYTHON_SUPPORT_ENABLED
255 template <class Ptr>
256 boost::python::api::object
257 TfAnyWeakPtr::_PointerHolder<Ptr>::GetPythonObject() const
258 {
259  return TfPyObject(_ptr);
260 }
261 #endif // PXR_PYTHON_SUPPORT_ENABLED
262 
263 template <class Ptr>
264 const std::type_info &
265 TfAnyWeakPtr::_PointerHolder<Ptr>::GetTypeInfo() const
266 {
267  return TfTypeid(_ptr);
268 }
269 
270 template <class Ptr>
271 TfType const&
272 TfAnyWeakPtr::_PointerHolder<Ptr>::GetType() const
273 {
274  return TfType::Find(_ptr);
275 }
276 
277 template <class Ptr>
278 const void *
279 TfAnyWeakPtr::_PointerHolder<Ptr>::_GetMostDerivedPtr() const
280 {
281  if (!_ptr) {
282  return 0;
283  }
284 
285  typename Ptr::DataType const *rawPtr = get_pointer(_ptr);
286  return TfCastToMostDerivedType(rawPtr);
287 }
288 
289 template <class Ptr>
290 bool
291 TfAnyWeakPtr::_PointerHolder<Ptr>::_IsPolymorphic() const
292 {
293  return std::is_polymorphic<typename Ptr::DataType>::value;
294 }
295 
296 template <class Ptr>
297 bool
298 TfAnyWeakPtr::_PointerHolder<Ptr>::_IsConst() const
299 {
300  return TfTraits::Type<typename Ptr::DataType>::isConst;
301 }
302 
303 PXR_NAMESPACE_CLOSE_SCOPE
304 
305 #endif
TF_API bool operator==(const TfAnyWeakPtr &rhs) const
equality operator
TF_API bool operator!() const
operator !
TF_API TfType const & GetType() const
Returns the TfType of the underlying WeakPtr.
static TfType const & Find()
Retrieve the TfType corresponding to type T.
Definition: type.h:155
TF_API const std::type_info & GetTypeInfo() const
returns the type_info of the underlying WeakPtr
Provides the ability to hold an arbitrary TfWeakPtr in a non-type-specific manner in order to observe...
Definition: anyWeakPtr.h:55
TfAnyWeakPtr(Ptr const &ptr)
Construct an AnyWeakPtr watching ptr.
Definition: anyWeakPtr.h:68
TfAnyWeakPtr(TfNullPtrType)
Construct and implicitly convert from TfNullPtr.
Definition: anyWeakPtr.h:82
std::enable_if< std::is_polymorphic< T >::value, Tf_CopyCV< T, void > * >::type TfCastToMostDerivedType(T *ptr)
Return a pointer to the most-derived object.
Definition: cxxCast.h:67
size_t GetHash() const
Return a hash value for this instance.
Definition: anyWeakPtr.h:132
TF_API bool IsInvalid() const
Return true only if this expiry checker is watching a weak pointer which has expired.
TF_API void const * GetUniqueIdentifier() const
Return the unique identifier of the WeakPtr this AnyWeakPtr contains.
TfAnyWeakPtr()
Construct an AnyWeakPtr not watching any ptr.
Definition: anyWeakPtr.h:75
TF_API TfWeakBase const * GetWeakBase() const
Return the TfWeakBase object of the WeakPtr we are holding.
TfAnyWeakPtr(std::nullptr_t)
Construct and implicitly convert from std::nullptr_t.
Definition: anyWeakPtr.h:85
TfType represents a dynamic runtime type.
Definition: type.h:70
boost::python::object TfPyObject(T const &t, bool complainOnFailure=true)
Return a python object for the given C++ object, loading the appropriate wrapper code if necessary...
Definition: pyUtils.h:100
Enable a concrete base class for use with TfWeakPtr.
Definition: weakBase.h:142
TF_API bool operator<(const TfAnyWeakPtr &rhs) const
comparison operator