All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
declareHandles.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 SDF_DECLAREHANDLES_H
25 #define SDF_DECLAREHANDLES_H
26 
28 
29 #include "pxr/pxr.h"
30 #include "pxr/usd/sdf/api.h"
31 #include "pxr/base/arch/demangle.h"
32 #include "pxr/base/arch/hints.h"
33 #include "pxr/base/tf/diagnostic.h"
34 #include "pxr/base/tf/weakPtrFacade.h"
35 #include "pxr/base/tf/declarePtrs.h"
36 
37 #include <set>
38 #include <typeinfo>
39 #include <type_traits>
40 #include <vector>
41 #include <boost/intrusive_ptr.hpp>
42 #include <boost/operators.hpp>
43 
44 PXR_NAMESPACE_OPEN_SCOPE
45 
46 class SdfLayer;
47 class SdfSpec;
48 template <class T> class TfRefPtr;
49 class Sdf_Identity;
50 
51 // Sdf_Identities are held via intrusive_ptr so that we can carefully
52 // manage the ref-count to avoid race conditions -- see
53 // Sdf_IdentityRegistry::Identify().
54 typedef boost::intrusive_ptr<Sdf_Identity> Sdf_IdentityRefPtr;
55 
62 template <class T>
63 class SdfHandle : private boost::totally_ordered<SdfHandle<T> > {
64 public:
65  typedef SdfHandle<T> This;
66  typedef T SpecType;
67 
68  typedef typename std::remove_const<SpecType>::type NonConstSpecType;
70 
71  SdfHandle() { }
72  SdfHandle(TfNullPtrType) { }
73  explicit SdfHandle(const Sdf_IdentityRefPtr& id) : _spec(id) { }
74  SdfHandle(const SpecType& spec) : _spec(spec) { }
75 
76  template <class U>
77  SdfHandle(const SdfHandle<U>& x) : _spec(x._spec) { }
78 
79  This& operator=(const This& x)
80  {
81  const_cast<NonConstSpecType&>(_spec) = x._spec;
82  return *this;
83  }
84 
85  template <class U>
86  This& operator=(const SdfHandle<U>& x)
87  {
88  const_cast<NonConstSpecType&>(_spec) = x._spec;
89  return *this;
90  }
91 
94  SpecType* operator->() const
95  {
96  if (ARCH_UNLIKELY(_spec.IsDormant())) {
97  TF_FATAL_ERROR("Dereferenced an invalid %s",
98  ArchGetDemangled(typeid(SpecType)).c_str());
99  return 0;
100  }
101  return const_cast<SpecType*>(&_spec);
102  }
103 
104  const SpecType & GetSpec() const
105  {
106  return _spec;
107  }
108 
109  void Reset()
110  {
111  const_cast<SpecType&>(_spec) = SpecType();
112  }
113 
114 #if !defined(doxygen)
115  typedef SpecType This::*UnspecifiedBoolType;
116 #endif
117 
120  operator UnspecifiedBoolType() const
121  {
122  return _spec.IsDormant() ? 0 : &This::_spec;
123  }
126  bool operator!() const
127  {
128  return _spec.IsDormant();
129  }
130 
132  template <class U>
133  bool operator==(const SdfHandle<U>& other) const
134  {
135  return _spec == other._spec;
136  }
137 
140  template <class U>
141  bool operator<(const SdfHandle<U>& other) const
142  {
143  return _spec < other._spec;
144  }
145 
147  friend size_t hash_value(const This &x) {
148  return hash_value(x._spec);
149  }
150 
151 private:
152  SpecType _spec;
153 
154  template <class U> friend class SdfHandle;
155 };
156 
157 template <class T>
158 T*
159 get_pointer(const SdfHandle<T>& x)
160 {
161  return !x ? 0 : x.operator->();
162 }
163 
164 PXR_NAMESPACE_CLOSE_SCOPE
165 
166 namespace boost {
167 
168 using PXR_NS::get_pointer;
169 
170 }
171 
172 PXR_NAMESPACE_OPEN_SCOPE
173 
174 template <class T>
175 struct SdfHandleTo {
176  typedef SdfHandle<T> Handle;
177  typedef SdfHandle<const T> ConstHandle;
178  typedef std::vector<Handle> Vector;
179  typedef std::vector<ConstHandle> ConstVector;
180 };
181 
182 template <>
183 struct SdfHandleTo<SdfLayer> {
184  typedef TfWeakPtr<SdfLayer> Handle;
185  typedef TfWeakPtr<const SdfLayer> ConstHandle;
186  typedef std::vector<Handle> Vector;
187  typedef std::vector<ConstHandle> ConstVector;
188 };
189 
190 template <typename T>
191 typename SdfHandleTo<T>::Handle
192 SdfCreateHandle(T *p)
193 {
194  return typename SdfHandleTo<T>::Handle(p ? *p : T());
195 }
196 
197 template <>
198 SDF_API SdfHandleTo<SdfLayer>::Handle
199 SdfCreateHandle(SdfLayer *p);
200 
201 template <typename T>
202 typename SdfHandleTo<T>::Handle
203 SdfCreateNonConstHandle(T const *p)
204 {
205  return SdfCreateHandle(const_cast<T *>(p));
206 }
207 
208 struct Sdf_CastAccess {
209  template<class DST, class SRC>
210  static DST CastSpec(const SRC& spec) {
211  return DST(spec);
212  }
213 };
214 
215 SDF_API bool
216 Sdf_CanCastToType(
217  const SdfSpec& srcSpec, const std::type_info& destType);
218 
219 SDF_API bool
220 Sdf_CanCastToTypeCheckSchema(
221  const SdfSpec& srcSpec, const std::type_info& destType);
222 
223 template <class DST, class SRC>
224 struct Sdf_SpecTypesAreDirectlyRelated
225  : std::integral_constant<bool,
226  std::is_base_of<DST, SRC>::value ||
227  std::is_base_of<SRC, DST>::value>
228 { };
229 
240 template <typename DST, typename SRC>
241 inline
244 {
245  typedef typename DST::SpecType Spec;
246  typedef SdfHandle<Spec> Handle;
247 
248  if (Sdf_CanCastToType(x.GetSpec(), typeid(Spec))) {
249  return Handle(Sdf_CastAccess::CastSpec<Spec,SRC>(x.GetSpec()));
250  }
251 
252  return Handle();
253 }
254 
255 template <typename DST, typename SRC>
256 inline
259 {
260  return TfDynamic_cast(x);
261 }
262 
267 template <typename DST, typename SRC>
268 inline
271 {
272  typedef typename DST::SpecType Spec;
273  typedef SdfHandle<Spec> Handle;
274  static_assert(Sdf_SpecTypesAreDirectlyRelated<Spec, SRC>::value,
275  "Spec and SRC must be directly related.");
276 
277  return Handle(Sdf_CastAccess::CastSpec<Spec,SRC>(x.GetSpec()));
278 }
279 
280 template <typename T>
281 inline
283 TfConst_cast(const SdfHandle<const typename T::SpecType>& x)
284 {
285  return TfStatic_cast<T>(x);
286 }
287 
292 template <typename DST, typename SRC>
293 inline
296 {
297  typedef typename DST::SpecType Spec;
298  typedef SdfHandle<Spec> Handle;
299 
300  if (Sdf_CanCastToTypeCheckSchema(x.GetSpec(), typeid(Spec))) {
301  return Handle(Sdf_CastAccess::CastSpec<Spec,SRC>(x.GetSpec()));
302  }
303 
304  return Handle();
305 }
306 
310 template <typename DST, typename SRC>
311 inline
314 {
315  typedef typename DST::SpecType Spec;
316  typedef SdfHandle<Spec> Handle;
317  return Handle(Sdf_CastAccess::CastSpec<Spec,SRC>(x.GetSpec()));
318 }
319 
321 template <typename DST_SPEC, typename SRC_SPEC>
322 inline
323 DST_SPEC
324 SdfSpecStatic_cast(const SRC_SPEC& x)
325 {
326  return Sdf_CastAccess::CastSpec<DST_SPEC,SRC_SPEC>(x);
327 }
328 
330 typedef std::vector<TfRefPtr<SdfLayer> > SdfLayerRefPtrVector;
331 typedef std::set<SdfHandleTo<SdfLayer>::Handle> SdfLayerHandleSet;
332 
333 #define SDF_DECLARE_HANDLES(cls) \
334  typedef SdfHandleTo<class cls>::Handle cls##Handle; \
335  typedef SdfHandleTo<class cls>::ConstHandle cls##ConstHandle; \
336  typedef SdfHandleTo<class cls>::Vector cls##HandleVector; \
337  typedef SdfHandleTo<class cls>::ConstVector cls##ConstHandleVector
338 
339 PXR_NAMESPACE_CLOSE_SCOPE
340 
341 #endif // SDF_DECLAREHANDLES_H
A unit of scene description that you combine with other units of scene description to form a shot...
Definition: layer.h:93
TO TfSafeDynamic_cast(FROM *ptr)
Safely perform a dynamic cast.
bool operator!() const
Returns false in a boolean context if the object is valid, true otherwise.
SdfHandle< typename DST::SpecType > TfStatic_cast(const SdfHandle< SRC > &x)
Convert SdfHandle&lt;SRC&gt; x to an SdfHandle&lt;DST&gt;.
ARCH_API std::string ArchGetDemangled(const std::string &typeName)
Return demangled RTTI-generated type name.
Base class for all Sdf spec classes.
Definition: spec.h:51
SdfHandle is a smart ptr that calls IsDormant() on the pointed-to object as an extra expiration check...
Pointer storage with deletion detection.
Definition: hash.h:44
SdfHandle< typename DST::SpecType > TfDynamic_cast(const SdfHandle< SRC > &x)
Convert SdfHandle&lt;SRC&gt; x to an SdfHandle&lt;DST&gt;.
SdfHandle< typename DST::SpecType > SdfSpecDynamic_cast(const SdfHandle< SRC > &x)
Convert SdfHandle&lt;SRC&gt; x to an SdfHandle&lt;DST&gt;.
#define TF_FATAL_ERROR(fmt, args)
Issue a fatal error and end the program.
Definition: diagnostic.h:111
SpecType * operator->() const
Dereference.
bool operator==(const SdfHandle< U > &other) const
Compares handles for equality.
Reference-counted smart pointer utility class.
Definition: hash.h:45
friend size_t hash_value(const This &x)
Hash.
SdfHandle< typename DST::SpecType > SdfSpecStatic_cast(const SdfHandle< SRC > &x)
Convert SdfHandle&lt;SRC&gt; x to an SdfHandle&lt;DST&gt;.