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
169template <class T>
170struct SdfHandleTo {
171 typedef SdfHandle<T> Handle;
172 typedef SdfHandle<const T> ConstHandle;
173 typedef std::vector<Handle> Vector;
174 typedef std::vector<ConstHandle> ConstVector;
175};
176
177template <>
178struct SdfHandleTo<SdfLayer> {
179 typedef TfWeakPtr<SdfLayer> Handle;
180 typedef TfWeakPtr<const SdfLayer> ConstHandle;
181 typedef std::vector<Handle> Vector;
182 typedef std::vector<ConstHandle> ConstVector;
183};
184
185template <typename T>
187SdfCreateHandle(T *p)
188{
189 return typename SdfHandleTo<T>::Handle(p ? *p : T());
190}
191
192template <>
194SdfCreateHandle(SdfLayer *p);
195
196template <typename T>
198SdfCreateNonConstHandle(T const *p)
199{
200 return SdfCreateHandle(const_cast<T *>(p));
201}
202
203struct Sdf_CastAccess {
204 template<class DST, class SRC>
205 static DST CastSpec(const SRC& spec) {
206 return DST(spec);
207 }
208};
209
210SDF_API bool
211Sdf_CanCastToType(
212 const SdfSpec& srcSpec, const std::type_info& destType);
213
214SDF_API bool
215Sdf_CanCastToTypeCheckSchema(
216 const SdfSpec& srcSpec, const std::type_info& destType);
217
218template <class DST, class SRC>
219struct Sdf_SpecTypesAreDirectlyRelated
220 : std::integral_constant<bool,
221 std::is_base_of<DST, SRC>::value ||
222 std::is_base_of<SRC, DST>::value>
223{ };
224
235template <typename DST, typename SRC>
236inline
239{
240 typedef typename DST::SpecType Spec;
241 typedef SdfHandle<Spec> Handle;
242
243 if (Sdf_CanCastToType(x.GetSpec(), typeid(Spec))) {
244 return Handle(Sdf_CastAccess::CastSpec<Spec,SRC>(x.GetSpec()));
245 }
246
247 return Handle();
248}
249
250template <typename DST, typename SRC>
251inline
254{
255 return TfDynamic_cast(x);
256}
257
262template <typename DST, typename SRC>
263inline
266{
267 typedef typename DST::SpecType Spec;
268 typedef SdfHandle<Spec> Handle;
269 static_assert(Sdf_SpecTypesAreDirectlyRelated<Spec, SRC>::value,
270 "Spec and SRC must be directly related.");
271
272 return Handle(Sdf_CastAccess::CastSpec<Spec,SRC>(x.GetSpec()));
273}
274
275template <typename T>
276inline
278TfConst_cast(const SdfHandle<const typename T::SpecType>& x)
279{
280 return TfStatic_cast<T>(x);
281}
282
287template <typename DST, typename SRC>
288inline
291{
292 typedef typename DST::SpecType Spec;
293 typedef SdfHandle<Spec> Handle;
294
295 if (Sdf_CanCastToTypeCheckSchema(x.GetSpec(), typeid(Spec))) {
296 return Handle(Sdf_CastAccess::CastSpec<Spec,SRC>(x.GetSpec()));
297 }
298
299 return Handle();
300}
301
305template <typename DST, typename SRC>
306inline
309{
310 typedef typename DST::SpecType Spec;
311 typedef SdfHandle<Spec> Handle;
312 return Handle(Sdf_CastAccess::CastSpec<Spec,SRC>(x.GetSpec()));
313}
314
316template <typename DST_SPEC, typename SRC_SPEC>
317inline
318DST_SPEC
319SdfSpecStatic_cast(const SRC_SPEC& x)
320{
321 return Sdf_CastAccess::CastSpec<DST_SPEC,SRC_SPEC>(x);
322}
323
325typedef std::vector<TfRefPtr<SdfLayer> > SdfLayerRefPtrVector;
326typedef std::set<SdfHandleTo<SdfLayer>::Handle> SdfLayerHandleSet;
327
328#define SDF_DECLARE_HANDLES(cls) \
329 typedef SdfHandleTo<class cls>::Handle cls##Handle; \
330 typedef SdfHandleTo<class cls>::ConstHandle cls##ConstHandle; \
331 typedef SdfHandleTo<class cls>::Vector cls##HandleVector; \
332 typedef SdfHandleTo<class cls>::ConstVector cls##ConstHandleVector
333
334PXR_NAMESPACE_CLOSE_SCOPE
335
336#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:84
Base class for all Sdf spec classes.
Definition: spec.h:33
Reference-counted smart pointer utility class.
Definition: refPtr.h:590
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.