Loading...
Searching...
No Matches
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 PXR_USD_SDF_DECLARE_HANDLES_H
25#define PXR_USD_SDF_DECLARE_HANDLES_H
26
28
29#include "pxr/pxr.h"
30#include "pxr/usd/sdf/api.h"
32#include "pxr/base/arch/hints.h"
33#include "pxr/base/tf/delegatedCountPtr.h"
35#include "pxr/base/tf/weakPtrFacade.h"
37
38#include <set>
39#include <typeinfo>
40#include <type_traits>
41#include <vector>
42
43PXR_NAMESPACE_OPEN_SCOPE
44
45class SdfLayer;
46class SdfSpec;
47template <class T> class TfRefPtr;
48class Sdf_Identity;
49
50// Sdf_Identities are held via TfDelegatedCountPtr so that we can carefully
51// manage the ref-count to avoid race conditions -- see
52// Sdf_IdentityRegistry::Identify().
54
61template <class T>
62class SdfHandle {
63public:
64 typedef SdfHandle<T> This;
65 typedef T SpecType;
66
67 typedef typename std::remove_const<SpecType>::type NonConstSpecType;
69
70 SdfHandle() { }
71 SdfHandle(TfNullPtrType) { }
72 explicit SdfHandle(const Sdf_IdentityRefPtr& id) : _spec(id) { }
73 SdfHandle(const SpecType& spec) : _spec(spec) { }
74
75 template <class U>
76 SdfHandle(const SdfHandle<U>& x) : _spec(x._spec) { }
77
78 This& operator=(const This& x)
79 {
80 const_cast<NonConstSpecType&>(_spec) = x._spec;
81 return *this;
82 }
83
84 template <class U>
85 This& operator=(const SdfHandle<U>& x)
86 {
87 const_cast<NonConstSpecType&>(_spec) = x._spec;
88 return *this;
89 }
90
93 SpecType* operator->() const
94 {
95 if (ARCH_UNLIKELY(_spec.IsDormant())) {
96 TF_FATAL_ERROR("Dereferenced an invalid %s",
97 ArchGetDemangled(typeid(SpecType)).c_str());
98 return 0;
99 }
100 return const_cast<SpecType*>(&_spec);
101 }
102
103 const SpecType & GetSpec() const
104 {
105 return _spec;
106 }
107
108 void Reset()
109 {
110 const_cast<SpecType&>(_spec) = SpecType();
111 }
112
113#if !defined(doxygen)
114 typedef SpecType This::*UnspecifiedBoolType;
115#endif
116
119 operator UnspecifiedBoolType() const
120 {
121 return _spec.IsDormant() ? 0 : &This::_spec;
122 }
125 bool operator!() const
126 {
127 return _spec.IsDormant();
128 }
129
131 template <class U>
132 bool operator==(const SdfHandle<U>& other) const
133 {
134 return _spec == other._spec;
135 }
136
138 friend bool operator!=(const SdfHandle& lhs, const SdfHandle& rhs)
139 {
140 return !(lhs == rhs);
141 }
142
145 template <class U>
146 bool operator<(const SdfHandle<U>& other) const
147 {
148 return _spec < other._spec;
149 }
150
152 friend bool operator>(const SdfHandle& lhs, const SdfHandle& rhs)
153 {
154 return rhs < lhs;
155 }
156
158 friend bool operator<=(const SdfHandle& lhs, const SdfHandle& rhs)
159 {
160 return !(rhs < lhs);
161 }
162
164 friend bool operator>=(const SdfHandle& lhs, const SdfHandle& rhs)
165 {
166 return !(lhs < rhs);
167 }
168
170 friend size_t hash_value(const This &x) {
171 return hash_value(x._spec);
172 }
173
174private:
175 friend
176 inline SpecType *get_pointer(const SdfHandle &x) {
177 return ARCH_UNLIKELY(x._spec.IsDormant()) ?
178 nullptr : const_cast<SpecType*>(&x._spec);
179 }
180
181 SpecType _spec;
182
183 template <class U> friend class SdfHandle;
184};
185
186PXR_NAMESPACE_CLOSE_SCOPE
187
188namespace boost {
189
190using PXR_NS::get_pointer;
191
192}
193
194PXR_NAMESPACE_OPEN_SCOPE
195
196template <class T>
197struct SdfHandleTo {
198 typedef SdfHandle<T> Handle;
199 typedef SdfHandle<const T> ConstHandle;
200 typedef std::vector<Handle> Vector;
201 typedef std::vector<ConstHandle> ConstVector;
202};
203
204template <>
205struct SdfHandleTo<SdfLayer> {
206 typedef TfWeakPtr<SdfLayer> Handle;
207 typedef TfWeakPtr<const SdfLayer> ConstHandle;
208 typedef std::vector<Handle> Vector;
209 typedef std::vector<ConstHandle> ConstVector;
210};
211
212template <typename T>
214SdfCreateHandle(T *p)
215{
216 return typename SdfHandleTo<T>::Handle(p ? *p : T());
217}
218
219template <>
221SdfCreateHandle(SdfLayer *p);
222
223template <typename T>
225SdfCreateNonConstHandle(T const *p)
226{
227 return SdfCreateHandle(const_cast<T *>(p));
228}
229
230struct Sdf_CastAccess {
231 template<class DST, class SRC>
232 static DST CastSpec(const SRC& spec) {
233 return DST(spec);
234 }
235};
236
237SDF_API bool
238Sdf_CanCastToType(
239 const SdfSpec& srcSpec, const std::type_info& destType);
240
241SDF_API bool
242Sdf_CanCastToTypeCheckSchema(
243 const SdfSpec& srcSpec, const std::type_info& destType);
244
245template <class DST, class SRC>
246struct Sdf_SpecTypesAreDirectlyRelated
247 : std::integral_constant<bool,
248 std::is_base_of<DST, SRC>::value ||
249 std::is_base_of<SRC, DST>::value>
250{ };
251
262template <typename DST, typename SRC>
263inline
266{
267 typedef typename DST::SpecType Spec;
268 typedef SdfHandle<Spec> Handle;
269
270 if (Sdf_CanCastToType(x.GetSpec(), typeid(Spec))) {
271 return Handle(Sdf_CastAccess::CastSpec<Spec,SRC>(x.GetSpec()));
272 }
273
274 return Handle();
275}
276
277template <typename DST, typename SRC>
278inline
281{
282 return TfDynamic_cast(x);
283}
284
289template <typename DST, typename SRC>
290inline
293{
294 typedef typename DST::SpecType Spec;
295 typedef SdfHandle<Spec> Handle;
296 static_assert(Sdf_SpecTypesAreDirectlyRelated<Spec, SRC>::value,
297 "Spec and SRC must be directly related.");
298
299 return Handle(Sdf_CastAccess::CastSpec<Spec,SRC>(x.GetSpec()));
300}
301
302template <typename T>
303inline
305TfConst_cast(const SdfHandle<const typename T::SpecType>& x)
306{
307 return TfStatic_cast<T>(x);
308}
309
314template <typename DST, typename SRC>
315inline
318{
319 typedef typename DST::SpecType Spec;
320 typedef SdfHandle<Spec> Handle;
321
322 if (Sdf_CanCastToTypeCheckSchema(x.GetSpec(), typeid(Spec))) {
323 return Handle(Sdf_CastAccess::CastSpec<Spec,SRC>(x.GetSpec()));
324 }
325
326 return Handle();
327}
328
332template <typename DST, typename SRC>
333inline
336{
337 typedef typename DST::SpecType Spec;
338 typedef SdfHandle<Spec> Handle;
339 return Handle(Sdf_CastAccess::CastSpec<Spec,SRC>(x.GetSpec()));
340}
341
343template <typename DST_SPEC, typename SRC_SPEC>
344inline
345DST_SPEC
346SdfSpecStatic_cast(const SRC_SPEC& x)
347{
348 return Sdf_CastAccess::CastSpec<DST_SPEC,SRC_SPEC>(x);
349}
350
352typedef std::vector<TfRefPtr<SdfLayer> > SdfLayerRefPtrVector;
353typedef std::set<SdfHandleTo<SdfLayer>::Handle> SdfLayerHandleSet;
354
355#define SDF_DECLARE_HANDLES(cls) \
356 typedef SdfHandleTo<class cls>::Handle cls##Handle; \
357 typedef SdfHandleTo<class cls>::ConstHandle cls##ConstHandle; \
358 typedef SdfHandleTo<class cls>::Vector cls##HandleVector; \
359 typedef SdfHandleTo<class cls>::ConstVector cls##ConstHandleVector
360
361PXR_NAMESPACE_CLOSE_SCOPE
362
363#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:100
Base class for all Sdf spec classes.
Definition: spec.h:50
Reference-counted smart pointer utility class.
Definition: refPtr.h:601
Pointer storage with deletion detection.
Definition: weakPtr.h:145
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:103
#define TF_FATAL_ERROR(fmt, args)
Issue a fatal error and end the program.
Definition: diagnostic.h:108
Compiler hints.
TO TfSafeDynamic_cast(FROM *ptr)
Safely perform a dynamic cast.