Loading...
Searching...
No Matches
declareHandles.h
Go to the documentation of this file.
1//
2// Copyright 2016 Pixar
3//
4// Licensed under the terms set forth in the LICENSE.txt file available at
5// https://openusd.org/license.
6//
7#ifndef PXR_USD_SDF_DECLARE_HANDLES_H
8#define PXR_USD_SDF_DECLARE_HANDLES_H
9
11
12#include "pxr/pxr.h"
13#include "pxr/usd/sdf/api.h"
15#include "pxr/base/arch/hints.h"
16#include "pxr/base/tf/delegatedCountPtr.h"
18#include "pxr/base/tf/weakPtrFacade.h"
20
21#include <set>
22#include <typeinfo>
23#include <type_traits>
24#include <vector>
25
26PXR_NAMESPACE_OPEN_SCOPE
27
28class SdfLayer;
29class SdfSpec;
30template <class T> class TfRefPtr;
31class Sdf_Identity;
32
33// Sdf_Identities are held via TfDelegatedCountPtr so that we can carefully
34// manage the ref-count to avoid race conditions -- see
35// Sdf_IdentityRegistry::Identify().
37
44template <class T>
45class SdfHandle {
46public:
47 typedef SdfHandle<T> This;
48 typedef T SpecType;
49
50 typedef typename std::remove_const<SpecType>::type NonConstSpecType;
52
53 SdfHandle() { }
54 SdfHandle(TfNullPtrType) { }
55 explicit SdfHandle(const Sdf_IdentityRefPtr& id) : _spec(id) { }
56 SdfHandle(const SpecType& spec) : _spec(spec) { }
57
58 template <class U>
59 SdfHandle(const SdfHandle<U>& x) : _spec(x._spec) { }
60
61 This& operator=(const This& x)
62 {
63 const_cast<NonConstSpecType&>(_spec) = x._spec;
64 return *this;
65 }
66
67 template <class U>
68 This& operator=(const SdfHandle<U>& x)
69 {
70 const_cast<NonConstSpecType&>(_spec) = x._spec;
71 return *this;
72 }
73
76 SpecType* operator->() const
77 {
78 if (ARCH_UNLIKELY(_spec.IsDormant())) {
79 TF_FATAL_ERROR("Dereferenced an invalid %s",
80 ArchGetDemangled(typeid(SpecType)).c_str());
81 return 0;
82 }
83 return const_cast<SpecType*>(&_spec);
84 }
85
86 const SpecType & GetSpec() const
87 {
88 return _spec;
89 }
90
91 void Reset()
92 {
93 const_cast<SpecType&>(_spec) = SpecType();
94 }
95
96#if !defined(doxygen)
97 typedef SpecType This::*UnspecifiedBoolType;
98#endif
99
102 operator UnspecifiedBoolType() const
103 {
104 return _spec.IsDormant() ? 0 : &This::_spec;
105 }
108 bool operator!() const
109 {
110 return _spec.IsDormant();
111 }
112
114 template <class U>
115 bool operator==(const SdfHandle<U>& other) const
116 {
117 return _spec == other._spec;
118 }
119
121 friend bool operator!=(const SdfHandle& lhs, const SdfHandle& rhs)
122 {
123 return !(lhs == rhs);
124 }
125
128 template <class U>
129 bool operator<(const SdfHandle<U>& other) const
130 {
131 return _spec < other._spec;
132 }
133
135 friend bool operator>(const SdfHandle& lhs, const SdfHandle& rhs)
136 {
137 return rhs < lhs;
138 }
139
141 friend bool operator<=(const SdfHandle& lhs, const SdfHandle& rhs)
142 {
143 return !(rhs < lhs);
144 }
145
147 friend bool operator>=(const SdfHandle& lhs, const SdfHandle& rhs)
148 {
149 return !(lhs < rhs);
150 }
151
153 friend size_t hash_value(const This &x) {
154 return hash_value(x._spec);
155 }
156
157private:
158 friend
159 inline SpecType *get_pointer(const SdfHandle &x) {
160 return ARCH_UNLIKELY(x._spec.IsDormant()) ?
161 nullptr : const_cast<SpecType*>(&x._spec);
162 }
163
164 SpecType _spec;
165
166 template <class U> friend class SdfHandle;
167};
168
169PXR_NAMESPACE_CLOSE_SCOPE
170
171namespace boost {
172
173using PXR_NS::get_pointer;
174
175}
176
177PXR_NAMESPACE_OPEN_SCOPE
178
179template <class T>
180struct SdfHandleTo {
181 typedef SdfHandle<T> Handle;
182 typedef SdfHandle<const T> ConstHandle;
183 typedef std::vector<Handle> Vector;
184 typedef std::vector<ConstHandle> ConstVector;
185};
186
187template <>
188struct SdfHandleTo<SdfLayer> {
189 typedef TfWeakPtr<SdfLayer> Handle;
190 typedef TfWeakPtr<const SdfLayer> ConstHandle;
191 typedef std::vector<Handle> Vector;
192 typedef std::vector<ConstHandle> ConstVector;
193};
194
195template <typename T>
197SdfCreateHandle(T *p)
198{
199 return typename SdfHandleTo<T>::Handle(p ? *p : T());
200}
201
202template <>
204SdfCreateHandle(SdfLayer *p);
205
206template <typename T>
208SdfCreateNonConstHandle(T const *p)
209{
210 return SdfCreateHandle(const_cast<T *>(p));
211}
212
213struct Sdf_CastAccess {
214 template<class DST, class SRC>
215 static DST CastSpec(const SRC& spec) {
216 return DST(spec);
217 }
218};
219
220SDF_API bool
221Sdf_CanCastToType(
222 const SdfSpec& srcSpec, const std::type_info& destType);
223
224SDF_API bool
225Sdf_CanCastToTypeCheckSchema(
226 const SdfSpec& srcSpec, const std::type_info& destType);
227
228template <class DST, class SRC>
229struct Sdf_SpecTypesAreDirectlyRelated
230 : std::integral_constant<bool,
231 std::is_base_of<DST, SRC>::value ||
232 std::is_base_of<SRC, DST>::value>
233{ };
234
245template <typename DST, typename SRC>
246inline
249{
250 typedef typename DST::SpecType Spec;
251 typedef SdfHandle<Spec> Handle;
252
253 if (Sdf_CanCastToType(x.GetSpec(), typeid(Spec))) {
254 return Handle(Sdf_CastAccess::CastSpec<Spec,SRC>(x.GetSpec()));
255 }
256
257 return Handle();
258}
259
260template <typename DST, typename SRC>
261inline
264{
265 return TfDynamic_cast(x);
266}
267
272template <typename DST, typename SRC>
273inline
276{
277 typedef typename DST::SpecType Spec;
278 typedef SdfHandle<Spec> Handle;
279 static_assert(Sdf_SpecTypesAreDirectlyRelated<Spec, SRC>::value,
280 "Spec and SRC must be directly related.");
281
282 return Handle(Sdf_CastAccess::CastSpec<Spec,SRC>(x.GetSpec()));
283}
284
285template <typename T>
286inline
288TfConst_cast(const SdfHandle<const typename T::SpecType>& x)
289{
290 return TfStatic_cast<T>(x);
291}
292
297template <typename DST, typename SRC>
298inline
301{
302 typedef typename DST::SpecType Spec;
303 typedef SdfHandle<Spec> Handle;
304
305 if (Sdf_CanCastToTypeCheckSchema(x.GetSpec(), typeid(Spec))) {
306 return Handle(Sdf_CastAccess::CastSpec<Spec,SRC>(x.GetSpec()));
307 }
308
309 return Handle();
310}
311
315template <typename DST, typename SRC>
316inline
319{
320 typedef typename DST::SpecType Spec;
321 typedef SdfHandle<Spec> Handle;
322 return Handle(Sdf_CastAccess::CastSpec<Spec,SRC>(x.GetSpec()));
323}
324
326template <typename DST_SPEC, typename SRC_SPEC>
327inline
328DST_SPEC
329SdfSpecStatic_cast(const SRC_SPEC& x)
330{
331 return Sdf_CastAccess::CastSpec<DST_SPEC,SRC_SPEC>(x);
332}
333
335typedef std::vector<TfRefPtr<SdfLayer> > SdfLayerRefPtrVector;
336typedef std::set<SdfHandleTo<SdfLayer>::Handle> SdfLayerHandleSet;
337
338#define SDF_DECLARE_HANDLES(cls) \
339 typedef SdfHandleTo<class cls>::Handle cls##Handle; \
340 typedef SdfHandleTo<class cls>::ConstHandle cls##ConstHandle; \
341 typedef SdfHandleTo<class cls>::Vector cls##HandleVector; \
342 typedef SdfHandleTo<class cls>::ConstVector cls##ConstHandleVector
343
344PXR_NAMESPACE_CLOSE_SCOPE
345
346#endif // PXR_USD_SDF_DECLARE_HANDLES_H
Low-level utilities for informing users of various internal and external diagnostic conditions.
SdfHandle is a smart ptr that calls IsDormant() on the pointed-to object as an extra expiration check...
friend bool operator>=(const SdfHandle &lhs, const SdfHandle &rhs)
bool operator<(const SdfHandle< U > &other) const
Arranges handles in an arbitrary strict weak ordering.
bool operator!() const
Returns false in a boolean context if the object is valid, true otherwise.
friend size_t hash_value(const This &x)
Hash.
SpecType * operator->() const
Dereference.
friend bool operator<=(const SdfHandle &lhs, const SdfHandle &rhs)
friend bool operator!=(const SdfHandle &lhs, const SdfHandle &rhs)
friend bool operator>(const SdfHandle &lhs, const SdfHandle &rhs)
bool operator==(const SdfHandle< U > &other) const
Compares handles for equality.
A scene description container that can combine with other such containers to form simple component as...
Definition: layer.h:83
Base class for all Sdf spec classes.
Definition: spec.h:33
Reference-counted smart pointer utility class.
Definition: refPtr.h:584
Pointer storage with deletion detection.
Definition: weakPtr.h:128
SdfHandle< typename DST::SpecType > TfStatic_cast(const SdfHandle< SRC > &x)
Convert SdfHandle<SRC> x to an SdfHandle<DST>.
SdfHandle< typename DST::SpecType > TfDynamic_cast(const SdfHandle< SRC > &x)
Convert SdfHandle<SRC> x to an SdfHandle<DST>.
SdfHandle< typename DST::SpecType > SdfSpecDynamic_cast(const SdfHandle< SRC > &x)
Convert SdfHandle<SRC> x to an SdfHandle<DST>.
SdfHandle< typename DST::SpecType > SdfSpecStatic_cast(const SdfHandle< SRC > &x)
Convert SdfHandle<SRC> x to an SdfHandle<DST>.
Standard pointer typedefs.
Demangle C++ typenames generated by the typeid() facility.
std::string ArchGetDemangled()
Return demangled RTTI generated-type name.
Definition: demangle.h:86
#define TF_FATAL_ERROR(fmt, args)
Issue a fatal error and end the program.
Definition: diagnostic.h:91
Compiler hints.
TO TfSafeDynamic_cast(FROM *ptr)
Safely perform a dynamic cast.