24 #ifndef PXR_BASE_VT_VALUE_H 25 #define PXR_BASE_VT_VALUE_H 31 #include "pxr/base/tf/pyObjWrapper.h" 33 #include "pxr/base/tf/pyLock.h" 37 #include "pxr/base/tf/anyUniquePtr.h" 38 #include "pxr/base/tf/pointerAndBits.h" 42 #include "pxr/base/tf/type.h" 44 #include "pxr/base/vt/api.h" 45 #include "pxr/base/vt/hash.h" 46 #include "pxr/base/vt/streamOut.h" 50 #include <boost/intrusive_ptr.hpp> 51 #include <boost/type_traits/has_trivial_assign.hpp> 52 #include <boost/type_traits/has_trivial_constructor.hpp> 53 #include <boost/type_traits/has_trivial_copy.hpp> 54 #include <boost/type_traits/has_trivial_destructor.hpp> 58 #include <type_traits> 60 PXR_NAMESPACE_OPEN_SCOPE
66 struct Vt_DefaultValueFactory;
70 struct Vt_DefaultValueHolder
75 static Vt_DefaultValueHolder Create() {
76 return Vt_DefaultValueHolder(TfAnyUniquePtr::New<T>(),
typeid(T));
82 static Vt_DefaultValueHolder Create(T
const &val) {
83 return Vt_DefaultValueHolder(TfAnyUniquePtr::New(val),
typeid(T));
87 std::type_info
const &GetType()
const {
93 void const *GetPointer()
const {
98 Vt_DefaultValueHolder(
TfAnyUniquePtr &&ptr, std::type_info
const &type)
99 : _ptr(std::move(ptr)), _type(&type) {}
102 std::type_info
const *_type;
109 VT_API std::ostream &VtStreamOut(std::vector<VtValue>
const &val, std::ostream &);
111 #define VT_VALUE_SET_STORED_TYPE(SRC, DST) \ 112 template <> struct Vt_ValueStoredType<SRC> { typedef DST Type; } 114 template <
class T>
struct Vt_ValueStoredType {
typedef T Type; };
115 VT_VALUE_SET_STORED_TYPE(
char const *, std::string);
116 VT_VALUE_SET_STORED_TYPE(
char *, std::string);
118 #ifdef PXR_PYTHON_SUPPORT_ENABLED 120 #endif // PXR_PYTHON_SUPPORT_ENABLED 122 #undef VT_VALUE_SET_STORED_TYPE 126 struct Vt_ValueGetStored
127 : Vt_ValueStoredType<std::decay_t<T>> {};
168 static const unsigned int _LocalFlag = 1 << 0;
169 static const unsigned int _TrivialCopyFlag = 1 << 1;
170 static const unsigned int _ProxyFlag = 1 << 2;
174 explicit _Counted(T
const &obj) : _obj(obj) {
177 bool IsUnique()
const {
return _refCount == 1; }
178 T
const &
Get()
const {
return _obj; }
179 T &GetMutable() {
return _obj; }
183 mutable std::atomic<int> _refCount;
185 friend inline void intrusive_ptr_add_ref(_Counted
const *d) {
186 d->_refCount.fetch_add(1, std::memory_order_relaxed);
188 friend inline void intrusive_ptr_release(_Counted
const *d) {
189 if (d->_refCount.fetch_sub(1, std::memory_order_release) == 1) {
190 std::atomic_thread_fence(std::memory_order_acquire);
199 static const size_t _MaxLocalSize =
sizeof(
void*);
200 typedef std::aligned_storage<
201 _MaxLocalSize, _MaxLocalSize>::type _Storage;
204 using _IsTriviallyCopyable = std::integral_constant<bool,
205 boost::has_trivial_constructor<T>::value &&
206 boost::has_trivial_copy<T>::value &&
207 boost::has_trivial_assign<T>::value &&
208 boost::has_trivial_destructor<T>::value>;
213 using _UsesLocalStore = std::integral_constant<bool,
214 (
sizeof(T) <=
sizeof(_Storage)) &&
215 VtValueTypeHasCheapCopy<T>::value &&
216 std::is_nothrow_move_constructible<T>::value &&
217 std::is_nothrow_move_assignable<T>::value>;
222 using _CopyInitFunc = void (*)(_Storage
const &, _Storage &);
223 using _DestroyFunc = void (*)(_Storage &);
224 using _MoveFunc = void (*)(_Storage &, _Storage &);
225 using _CanHashFunc = bool (*)(_Storage
const &);
226 using _HashFunc = size_t (*)(_Storage
const &);
227 using _EqualFunc = bool (*)(_Storage
const &, _Storage
const &);
228 using _EqualPtrFunc = bool (*)(_Storage
const &,
void const *);
229 using _MakeMutableFunc = void (*)(_Storage &);
231 using _StreamOutFunc =
232 std::ostream & (*)(_Storage
const &, std::ostream &);
233 using _GetTypeidFunc = std::type_info
const & (*)(_Storage
const &);
234 using _IsArrayValuedFunc = bool (*)(_Storage
const &);
235 using _GetElementTypeidFunc =
236 std::type_info
const & (*)(_Storage
const &);
237 using _GetShapeDataFunc =
const Vt_ShapeData* (*)(_Storage
const &);
238 using _GetNumElementsFunc = size_t (*)(_Storage
const &);
239 using _ProxyHoldsTypeFunc = bool (*)(_Storage
const &, std::type_info
const &);
240 using _GetProxiedTypeFunc =
TfType (*)(_Storage
const &);
241 using _GetProxiedTypeidFunc =
242 std::type_info
const & (*)(_Storage
const &);
243 using _GetProxiedObjPtrFunc =
void const *(*)(_Storage
const &);
244 using _GetProxiedAsVtValueFunc =
VtValue (*)(_Storage
const &);
247 constexpr _TypeInfo(
const std::type_info &ti,
248 const std::type_info &elementTi,
253 _CopyInitFunc copyInit,
254 _DestroyFunc destroy,
256 _CanHashFunc canHash,
259 _EqualPtrFunc equalPtr,
260 _MakeMutableFunc makeMutable,
261 _GetPyObjFunc getPyObj,
262 _StreamOutFunc streamOut,
263 _GetTypeidFunc getTypeid,
264 _IsArrayValuedFunc isArrayValued,
265 _GetElementTypeidFunc getElementTypeid,
266 _GetShapeDataFunc getShapeData,
267 _GetNumElementsFunc getNumElements,
268 _ProxyHoldsTypeFunc proxyHoldsType,
269 _GetProxiedTypeFunc getProxiedType,
270 _GetProxiedTypeidFunc getProxiedTypeid,
271 _GetProxiedObjPtrFunc getProxiedObjPtr,
272 _GetProxiedAsVtValueFunc getProxiedAsVtValue)
274 , elementTypeInfo(elementTi)
275 , knownTypeIndex(knownTypeIndex)
278 , isHashable(isHashable)
280 , _copyInit(copyInit)
286 , _equalPtr(equalPtr)
287 , _makeMutable(makeMutable)
288 , _getPyObj(getPyObj)
289 , _streamOut(streamOut)
290 , _getTypeid(getTypeid)
291 , _isArrayValued(isArrayValued)
292 , _getElementTypeid(getElementTypeid)
293 , _getShapeData(getShapeData)
294 , _getNumElements(getNumElements)
295 , _proxyHoldsType(proxyHoldsType)
296 , _getProxiedType(getProxiedType)
297 , _getProxiedTypeid(getProxiedTypeid)
298 , _getProxiedObjPtr(getProxiedObjPtr)
299 , _getProxiedAsVtValue(getProxiedAsVtValue)
303 void CopyInit(_Storage
const &src, _Storage &dst)
const {
306 void Destroy(_Storage &storage)
const {
309 void Move(_Storage &src, _Storage &dst)
const noexcept {
312 bool CanHash(_Storage
const &storage)
const {
313 return _canHash(storage);
315 size_t Hash(_Storage
const &storage)
const {
316 return _hash(storage);
318 bool Equal(_Storage
const &lhs, _Storage
const &rhs)
const {
319 return _equal(lhs, rhs);
321 bool EqualPtr(_Storage
const &lhs,
void const *rhs)
const {
322 return _equalPtr(lhs, rhs);
324 void MakeMutable(_Storage &storage)
const {
325 _makeMutable(storage);
328 return _getPyObj(storage);
330 std::ostream &StreamOut(_Storage
const &storage,
331 std::ostream &out)
const {
332 return _streamOut(storage, out);
335 return _isArrayValued(storage);
338 return _getElementTypeid(storage);
340 std::type_info
const &
GetTypeid(_Storage
const &storage)
const {
341 return _getTypeid(storage);
343 const Vt_ShapeData* GetShapeData(_Storage
const &storage)
const {
344 return _getShapeData(storage);
346 size_t GetNumElements(_Storage
const &storage)
const {
347 return _getNumElements(storage);
349 bool ProxyHoldsType(_Storage
const &storage,
350 std::type_info
const &t)
const {
351 return _proxyHoldsType(storage, t);
353 TfType GetProxiedType(_Storage
const &storage)
const {
354 return _getProxiedType(storage);
356 std::type_info
const &GetProxiedTypeid(_Storage
const &storage)
const {
357 return _getProxiedTypeid(storage);
359 VtValue GetProxiedAsVtValue(_Storage
const &storage)
const {
360 return _getProxiedAsVtValue(storage);
362 void const *GetProxiedObjPtr(_Storage
const &storage)
const {
363 return _getProxiedObjPtr(storage);
366 const std::type_info &typeInfo;
367 const std::type_info &elementTypeInfo;
374 _CopyInitFunc _copyInit;
375 _DestroyFunc _destroy;
377 _CanHashFunc _canHash;
380 _EqualPtrFunc _equalPtr;
381 _MakeMutableFunc _makeMutable;
382 _GetPyObjFunc _getPyObj;
383 _StreamOutFunc _streamOut;
384 _GetTypeidFunc _getTypeid;
385 _IsArrayValuedFunc _isArrayValued;
386 _GetElementTypeidFunc _getElementTypeid;
387 _GetShapeDataFunc _getShapeData;
388 _GetNumElementsFunc _getNumElements;
389 _ProxyHoldsTypeFunc _proxyHoldsType;
390 _GetProxiedTypeFunc _getProxiedType;
391 _GetProxiedTypeidFunc _getProxiedTypeid;
392 _GetProxiedObjPtrFunc _getProxiedObjPtr;
393 _GetProxiedAsVtValueFunc _getProxiedAsVtValue;
399 template <
class T,
class Enable=
void>
402 static const Vt_ShapeData* GetShapeData(T
const &) {
return NULL; }
403 static size_t GetNumElements(T
const &) {
return 0; }
408 template <
class Array>
410 Array, typename std::enable_if<VtIsArray<Array>::value>::type>
412 static const Vt_ShapeData* GetShapeData(Array
const &obj) {
413 return obj._GetShapeData();
415 static size_t GetNumElements(Array
const &obj) {
419 return typeid(
typename Array::ElementType);
426 _TypedProxyEqualityImpl(T
const &a, T
const &b,
int) -> decltype(a == b) {
430 template <
class NoEqual>
432 _TypedProxyEqualityImpl(NoEqual
const &a, NoEqual
const &b,
long) {
433 return VtGetProxiedObject(a) == VtGetProxiedObject(b);
438 _ErasedProxyEqualityImpl(T
const &a, T
const &b,
int) -> decltype(a == b) {
442 template <
class NoEqual>
444 _ErasedProxyEqualityImpl(NoEqual
const &a, NoEqual
const &b,
long) {
445 return *VtGetErasedProxiedVtValue(a) == *VtGetErasedProxiedVtValue(b);
449 template <
class T,
class Enable =
void>
452 using ProxiedType =
typename VtGetProxiedType<T>::type;
454 static bool CanHash(T
const &) {
return VtIsHashable<ProxiedType>(); }
455 static size_t Hash(T
const &obj) {
456 return VtHashValue(VtGetProxiedObject(obj));
458 static bool Equal(T
const &a, T
const &b) {
463 return _TypedProxyEqualityImpl(a, b, 0);
466 #ifdef PXR_PYTHON_SUPPORT_ENABLED 467 ProxiedType
const &p = VtGetProxiedObject(obj);
469 return boost::python::api::object(p);
472 #endif //PXR_PYTHON_SUPPORT_ENABLED 474 static std::ostream &StreamOut(T
const &obj, std::ostream &out) {
475 return VtStreamOut(VtGetProxiedObject(obj), out);
477 static Vt_ShapeData
const *GetShapeData(T
const &obj) {
478 return _ArrayHelper<ProxiedType>::GetShapeData(
479 VtGetProxiedObject(obj));
481 static size_t GetNumElements(T
const &obj) {
482 return _ArrayHelper<ProxiedType>::GetNumElements(
483 VtGetProxiedObject(obj));
488 static std::type_info
const &
GetTypeid(T
const &) {
489 return typeid(ProxiedType);
492 return _ArrayHelper<ProxiedType>::GetElementTypeid();
494 static VtValue GetProxiedAsVtValue(T
const &obj) {
495 return VtValue(VtGetProxiedObject(obj));
497 static bool HoldsType(T
const &tp, std::type_info
const &query) {
500 static TfType GetTfType(T
const &tp) {
501 return TfType::Find<ProxiedType>();
503 static void const *GetObjPtr(T
const &tp) {
504 return static_cast<void const *>(&VtGetProxiedObject(tp));
508 template <
class ErasedProxy>
510 ErasedProxy, typename std::enable_if<
511 VtIsErasedValueProxy<ErasedProxy>::value>::type>
513 static bool CanHash(ErasedProxy
const &proxy) {
514 return VtGetErasedProxiedVtValue(proxy)->CanHash();
516 static size_t Hash(ErasedProxy
const &proxy) {
517 return VtGetErasedProxiedVtValue(proxy)->GetHash();
519 static bool Equal(ErasedProxy
const &a, ErasedProxy
const &b) {
524 return _ErasedProxyEqualityImpl(a, b, 0);
527 #ifdef PXR_PYTHON_SUPPORT_ENABLED 528 VtValue const *val = VtGetErasedProxiedVtValue(obj);
530 return boost::python::api::object(*val);
533 #endif //PXR_PYTHON_SUPPORT_ENABLED 535 static std::ostream &
536 StreamOut(ErasedProxy
const &obj, std::ostream &out) {
537 return VtStreamOut(obj, out);
539 static Vt_ShapeData
const *GetShapeData(ErasedProxy
const &obj) {
540 return VtGetErasedProxiedVtValue(obj)->_GetShapeData();
542 static size_t GetNumElements(ErasedProxy
const &obj) {
543 return VtGetErasedProxiedVtValue(obj)->_GetNumElements();
546 return VtGetErasedProxiedVtValue(obj)->IsArrayValued();
548 static std::type_info
const &
GetTypeid(ErasedProxy
const &obj) {
549 return VtGetErasedProxiedVtValue(obj)->GetTypeid();
552 return VtGetErasedProxiedVtValue(obj)->GetElementTypeid();
554 static VtValue GetProxiedAsVtValue(ErasedProxy
const &ep) {
555 return *VtGetErasedProxiedVtValue(ep);
558 HoldsType(ErasedProxy
const &ep, std::type_info
const &query) {
559 return VtErasedProxyHoldsType(ep, query);
561 static TfType GetTfType(ErasedProxy
const &ep) {
562 return VtGetErasedProxiedTfType(ep);
564 static void const *GetObjPtr(ErasedProxy
const &ep) {
565 VtValue const *val = VtGetErasedProxiedVtValue(ep);
566 return val ? val->_GetProxiedObjPtr() :
nullptr;
573 template <
class T,
class Container,
class Derived>
574 struct _TypeInfoImpl :
public _TypeInfo
576 static const bool IsLocal = _UsesLocalStore<T>::value;
577 static const bool HasTrivialCopy = _IsTriviallyCopyable<T>::value;
578 static const bool IsProxy = VtIsValueProxy<T>::value;
580 using ProxyHelper = _ProxyHelper<T>;
582 using This = _TypeInfoImpl;
584 constexpr _TypeInfoImpl()
585 : _TypeInfo(
typeid(T),
586 _ArrayHelper<T>::GetElementTypeid(),
587 Vt_KnownValueTypeDetail::GetIndex<T>(),
605 &This::_IsArrayValued,
606 &This::_GetElementTypeid,
607 &This::_GetShapeData,
608 &This::_GetNumElements,
611 &This::_ProxyHoldsType,
612 &This::_GetProxiedType,
613 &This::_GetProxiedTypeid,
614 &This::_GetProxiedObjPtr,
615 &This::_GetProxiedAsVtValue)
620 static T
const &GetObj(_Storage
const &storage) {
621 return Derived::_GetObj(_Container(storage));
624 static T &GetMutableObj(_Storage &storage) {
625 return Derived::_GetMutableObj(_Container(storage));
628 static void CopyInitObj(T
const &objSrc, _Storage &dst) {
629 Derived::_PlaceCopy(&_Container(dst), objSrc);
633 static_assert(
sizeof(Container) <=
sizeof(_Storage),
634 "Container size cannot exceed storage size.");
638 static void _CopyInit(_Storage
const &src, _Storage &dst) {
639 new (&_Container(dst)) Container(_Container(src));
642 static void _Destroy(_Storage &storage) {
643 _Container(storage).~Container();
646 static bool _CanHash(_Storage
const &storage) {
647 return ProxyHelper::CanHash(GetObj(storage));
650 static size_t _Hash(_Storage
const &storage) {
651 return ProxyHelper::Hash(GetObj(storage));
654 static bool _Equal(_Storage
const &lhs, _Storage
const &rhs) {
658 return ProxyHelper::Equal(GetObj(lhs), GetObj(rhs));
661 static bool _EqualPtr(_Storage
const &lhs,
void const *rhs) {
665 return ProxyHelper::Equal(
666 GetObj(lhs), *static_cast<T const *>(rhs));
669 static void _Move(_Storage &src, _Storage &dst) noexcept {
670 new (&_Container(dst)) Container(std::move(_Container(src)));
674 static void _MakeMutable(_Storage &storage) {
675 GetMutableObj(storage);
679 return ProxyHelper::GetPyObj(GetObj(storage));
682 static std::ostream &_StreamOut(
683 _Storage
const &storage, std::ostream &out) {
684 return ProxyHelper::StreamOut(GetObj(storage), out);
687 static std::type_info
const &_GetTypeid(_Storage
const &storage) {
688 return ProxyHelper::GetTypeid(GetObj(storage));
691 static bool _IsArrayValued(_Storage
const &storage) {
692 return ProxyHelper::IsArrayValued(GetObj(storage));
695 static std::type_info
const &
696 _GetElementTypeid(_Storage
const &storage) {
697 return ProxyHelper::GetElementTypeid(GetObj(storage));
700 static const Vt_ShapeData* _GetShapeData(_Storage
const &storage) {
701 return ProxyHelper::GetShapeData(GetObj(storage));
704 static size_t _GetNumElements(_Storage
const &storage) {
705 return ProxyHelper::GetNumElements(GetObj(storage));
709 _ProxyHoldsType(_Storage
const &storage, std::type_info
const &t) {
710 return ProxyHelper::HoldsType(GetObj(storage), t);
714 _GetProxiedType(_Storage
const &storage) {
715 return ProxyHelper::GetTfType(GetObj(storage));
718 static std::type_info
const &
719 _GetProxiedTypeid(_Storage
const &storage) {
720 return ProxyHelper::GetTypeid(GetObj(storage));
724 _GetProxiedObjPtr(_Storage
const &storage) {
725 return ProxyHelper::GetObjPtr(GetObj(storage));
729 _GetProxiedAsVtValue(_Storage
const &storage) {
730 return ProxyHelper::GetProxiedAsVtValue(GetObj(storage));
736 static Container &_Container(_Storage &storage) {
738 return *reinterpret_cast<Container *>(&storage);
740 static Container
const &_Container(_Storage
const &storage) {
742 return *reinterpret_cast<Container const *>(&storage);
750 struct _LocalTypeInfo : _TypeInfoImpl<
756 constexpr _LocalTypeInfo()
757 : _TypeInfoImpl<T, T, _LocalTypeInfo<T>>()
761 static T &_GetMutableObj(T &obj) {
return obj; }
762 static T
const &_GetObj(T
const &obj) {
return obj; }
764 static void _PlaceCopy(T *dst, T
const &src) {
new (dst) T(src); }
771 struct _RemoteTypeInfo : _TypeInfoImpl<
773 boost::intrusive_ptr<_Counted<T> >,
777 constexpr _RemoteTypeInfo()
779 T, boost::intrusive_ptr<_Counted<T>>, _RemoteTypeInfo<T>>()
782 typedef boost::intrusive_ptr<_Counted<T> > Ptr;
784 static T &_GetMutableObj(Ptr &ptr) {
785 if (!ptr->IsUnique())
786 ptr.reset(
new _Counted<T>(ptr->Get()));
787 return ptr->GetMutable();
789 static T
const &_GetObj(Ptr
const &ptr) {
return ptr->Get(); }
791 static void _PlaceCopy(Ptr *dst, T
const &src) {
792 new (dst) Ptr(
new _Counted<T>(src));
798 struct _TypeInfoFor {
800 typedef std::conditional_t<_UsesLocalStore<T>::value,
802 _RemoteTypeInfo<T>> Type;
807 struct _TypeInfoFor<char[N]> : _TypeInfoFor<std::string> {};
813 typedef typename _TypeInfoFor<T>::Type TI;
815 static constexpr
unsigned int flags =
816 (TI::IsLocal ? _LocalFlag : 0) |
817 (TI::HasTrivialCopy ? _TrivialCopyFlag : 0) |
818 (TI::IsProxy ? _ProxyFlag : 0);
828 friend struct _HoldAside;
830 explicit _HoldAside(
VtValue *val)
831 : info((val->
IsEmpty() || val->_IsLocalAndTriviallyCopyable())
832 ? static_cast<_TypeInfo const *>(NULL) : val->_info.
Get()) {
834 info->Move(val->_storage, storage);
838 info->Destroy(storage);
841 _TypeInfo
const *info;
846 std::is_same<T, typename Vt_ValueGetStored<T>::Type>::value>
847 _Init(T
const &obj) {
848 _info = GetTypeInfo<T>();
849 typedef typename _TypeInfoFor<T>::Type TypeInfo;
850 TypeInfo::CopyInitObj(obj, _storage);
855 !std::is_same<T, typename Vt_ValueGetStored<T>::Type>::value>
856 _Init(T
const &obj) {
857 _Init(
typename Vt_ValueGetStored<T>::Type(obj));
916 if (ARCH_LIKELY(
this != &other))
923 if (ARCH_LIKELY(
this != &other))
932 _TypeInfoFor<T>::Type::IsLocal &&
933 _TypeInfoFor<T>::Type::HasTrivialCopy,
950 !_TypeInfoFor<T>::Type::IsLocal ||
951 !_TypeInfoFor<T>::Type::HasTrivialCopy,
954 _HoldAside tmp(
this);
962 std::string tmp(cstr);
970 return *
this = const_cast<char const *>(cstr);
976 if (!
IsEmpty() || !rhs.IsEmpty()) {
999 std::is_same<T, typename Vt_ValueGetStored<T>::Type>::value>
1001 if (!IsHolding<T>())
1018 std::is_same<T, typename Vt_ValueGetStored<T>::Type>::value>
1021 swap(_GetMutable<T>(), rhs);
1065 VT_API std::type_info
const &
GetTypeid()
const;
1082 if (ARCH_UNLIKELY(_IsProxy())) {
1083 return _info->GetProxiedAsVtValue(
1084 _storage).GetKnownValueTypeIndex();
1086 return _info.
GetLiteral() ? _info->knownTypeIndex : -1;
1110 typedef Vt_DefaultValueFactory<T> Factory;
1114 if (ARCH_UNLIKELY(!IsHolding<T>())) {
1115 return *(static_cast<T const *>(
1116 _FailGet(Factory::Invoke,
typeid(T))));
1126 typedef Vt_DefaultValueFactory<T> Factory;
1130 if (ARCH_UNLIKELY(!IsHolding<T>())) {
1131 return *(static_cast<T const *>(
1132 _FailGet(Factory::Invoke,
typeid(T))));
1135 return UncheckedRemove<T>();
1144 return IsHolding<T>() ? UncheckedGet<T>() : def;
1148 template <
typename From,
typename To>
1150 _RegisterCast(
typeid(From),
typeid(To), castFn);
1155 template <
typename From,
typename To>
1157 _RegisterCast(
typeid(From),
typeid(To), _SimpleCast<From, To>);
1162 template <
typename From,
typename To>
1164 RegisterSimpleCast<From, To>();
1165 RegisterSimpleCast<To, From>();
1175 template <
typename T>
1178 return ret.
Cast<T>();
1205 std::type_info
const &to) {
1206 return _CanCast(from, to);
1216 template <
typename T>
1220 return *
this = _PerformCast(
typeid(T), *
this);
1243 *
this = _PerformCast(type, *
this);
1251 template <
typename T>
1253 return _CanCast(
GetTypeid(),
typeid(T));
1277 VT_API
size_t GetHash()
const;
1279 friend inline size_t hash_value(
VtValue const &val) {
1284 template <
typename T>
1286 typedef typename Vt_ValueGetStored<T>::Type Stored;
1289 template <
typename T>
1295 template <
typename T>
1297 return !(lhs == rhs);
1299 template <
typename T>
1301 return !(lhs == rhs);
1307 if (empty || rhsEmpty) {
1309 return empty == rhsEmpty;
1313 return _info.
Get()->Equal(_storage, rhs._storage);
1315 return _EqualityImpl(rhs);
1320 VT_API
friend std::ostream &
1324 VT_API
const Vt_ShapeData* _GetShapeData()
const;
1325 VT_API
size_t _GetNumElements()
const;
1326 friend struct Vt_ValueShapeDataAccess;
1334 _HoldAside tmp(&dst);
1335 dst._info = src._info;
1336 if (src._IsLocalAndTriviallyCopyable()) {
1337 dst._storage = src._storage;
1339 dst._info->CopyInit(src._storage, dst._storage);
1349 _HoldAside tmp(&dst);
1350 dst._info = src._info;
1351 if (src._IsLocalAndTriviallyCopyable()) {
1352 dst._storage = src._storage;
1354 dst._info->Move(src._storage, dst._storage);
1357 src._info.
Set(
nullptr, 0);
1361 inline std::enable_if_t<VtIsKnownValueType_Workaround<T>::value,
bool>
1363 return _info->knownTypeIndex == VtGetKnownValueTypeIndex<T>() ||
1364 ARCH_UNLIKELY(_IsProxy() && _TypeIsImpl(
typeid(T)));
1368 inline std::enable_if_t<!VtIsKnownValueType_Workaround<T>::value,
bool>
1370 std::type_info
const &t =
typeid(T);
1372 ARCH_UNLIKELY(_IsProxy() && _TypeIsImpl(t));
1375 VT_API
bool _TypeIsImpl(std::type_info
const &queriedType)
const;
1377 VT_API
bool _EqualityImpl(
VtValue const &rhs)
const;
1379 template <
class Proxy>
1380 std::enable_if_t<VtIsValueProxy<Proxy>::value, Proxy &>
1382 typedef typename _TypeInfoFor<Proxy>::Type TypeInfo;
1383 return TypeInfo::GetMutableObj(_storage);
1387 std::enable_if_t<!VtIsValueProxy<T>::value, T &>
1390 if (ARCH_UNLIKELY(_IsProxy())) {
1391 *
this = _info->GetProxiedAsVtValue(_storage);
1393 typedef typename _TypeInfoFor<T>::Type TypeInfo;
1394 return TypeInfo::GetMutableObj(_storage);
1397 template <
class Proxy>
1398 std::enable_if_t<VtIsValueProxy<Proxy>::value, Proxy
const &>
1400 typedef typename _TypeInfoFor<Proxy>::Type TypeInfo;
1401 return TypeInfo::GetObj(_storage);
1405 std::enable_if_t<!VtIsValueProxy<T>::value, T
const &>
1407 typedef typename _TypeInfoFor<T>::Type TypeInfo;
1408 if (ARCH_UNLIKELY(_IsProxy())) {
1409 return *static_cast<T const *>(_GetProxiedObjPtr());
1411 return TypeInfo::GetObj(_storage);
1414 void const *_GetProxiedObjPtr()
const {
1415 return _info->GetProxiedObjPtr(_storage);
1421 _FailGet(Vt_DefaultValueHolder (*factory)(),
1422 std::type_info
const &queryType)
const;
1424 inline void _Clear() {
1426 if (_info.
GetLiteral() && !_IsLocalAndTriviallyCopyable())
1427 _info.
Get()->Destroy(_storage);
1428 _info.
Set(
nullptr, 0);
1431 inline bool _IsLocalAndTriviallyCopyable()
const {
1432 unsigned int bits = _info.
BitsAs<
unsigned int>();
1433 return (bits & (_LocalFlag | _TrivialCopyFlag)) ==
1434 (_LocalFlag | _TrivialCopyFlag);
1437 inline bool _IsProxy()
const {
1438 return _info.
BitsAs<
unsigned int>() & _ProxyFlag;
1441 VT_API
static void _RegisterCast(std::type_info
const &from,
1442 std::type_info
const &to,
1448 _PerformCast(std::type_info
const &to,
VtValue const &val);
1453 _CanCast(std::type_info
const &from, std::type_info
const &to);
1456 template <
typename From,
typename To>
1466 Vt_GetPythonObjectFromHeldValue(
VtValue const &
self);
1476 struct Vt_ValueShapeDataAccess {
1477 static const Vt_ShapeData* _GetShapeData(
const VtValue& value) {
1478 return value._GetShapeData();
1481 static size_t _GetNumElements(
const VtValue& value) {
1482 return value._GetNumElements();
1490 struct Vt_DefaultValueFactory {
1491 static Vt_DefaultValueHolder Invoke();
1495 inline Vt_DefaultValueHolder
1496 Vt_DefaultValueFactory<T>::Invoke() {
1497 return Vt_DefaultValueHolder::Create<T>();
1508 #define _VT_DECLARE_ZERO_VALUE_FACTORY(r, unused, elem) \ 1510 VT_API Vt_DefaultValueHolder Vt_DefaultValueFactory<VT_TYPE(elem)>::Invoke(); 1512 BOOST_PP_SEQ_FOR_EACH(_VT_DECLARE_ZERO_VALUE_FACTORY,
1515 VT_MATRIX_VALUE_TYPES
1516 VT_QUATERNION_VALUE_TYPES
1517 VT_DUALQUATERNION_VALUE_TYPES)
1519 #undef _VT_DECLARE_ZERO_VALUE_FACTORY 1528 VtValue::Get<VtValue>() const & {
1534 VtValue::Get<VtValue>() && {
1535 return std::move(*
this);
1540 VtValue::UncheckedGet<VtValue>() const & {
1546 VtValue::UncheckedGet<VtValue>() && {
1547 return std::move(*
this);
1552 VtValue::IsHolding<VtValue>()
const {
1559 VtValue::IsHolding<void>()
const {
1567 PXR_NAMESPACE_CLOSE_SCOPE
1569 #endif // PXR_BASE_VT_VALUE_H size_t GetArraySize() const
Return the number of elements in the held value if IsArrayValued(), return 0 otherwise.
static void RegisterSimpleBidirectionalCast()
Register a two-way cast from VtValue holding From to VtValue holding To.
constexpr T * Get() const noexcept
Retrieve the pointer.
Safely compare C++ RTTI type structures.
VtValue(VtValue &&other) noexcept
Move construct with other.
T const & UncheckedGet() const &
Returns a const reference to the held object if the held object is of type T.
VtValue & operator=(char const *cstr)
Assigning a char const * gives a VtValue holding a std::string.
VtValue & Cast()
Return this holding value type cast to T.
Definitions of basic string utilities in tf.
VT_API std::string GetTypeName() const
Return the type name of the held typeid.
bool CanCastToTypeOf(VtValue const &other) const
Return if this can be cast to type.
void UncheckedSwap(T &rhs)
Swap the held value with rhs.
constexpr uintptr_t GetLiteral() const noexcept
Retrieve the raw underlying value.
VtValue(VtValue const &other)
Copy construct with other.
VT_API bool CanHash() const
Return true if the held object provides a hash implementation.
T UncheckedRemove()
Make this value empty and return the held T instance.
Demangle C++ typenames generated by the typeid() facility.
static void RegisterSimpleCast()
Register a simple cast from VtValue holding From to VtValue.
static VT_API VtValue CastToTypeOf(VtValue const &val, VtValue const &other)
Return a VtValue holding val cast to same type that other is holding.
static bool CanCastFromTypeidToTypeid(std::type_info const &from, std::type_info const &to)
Return if a value of type from can be cast to type to.
VtValue & CastToTypeOf(VtValue const &other)
Return this holding value type cast to same type that other is holding.
static VtValue Take(T &obj)
Create a new VtValue, taking its contents from obj.
VT_API std::type_info const & GetTypeid() const
Returns the typeid of the type held by this value.
Convenience class for accessing the Python Global Interpreter Lock.
void swap(UsdStageLoadRules &l, UsdStageLoadRules &r)
Swap the contents of rules l and r.
bool IsEmpty() const
Returns true iff this value is empty.
friend bool operator==(VtValue const &lhs, T const &rhs)
Tests for equality.
VT_API bool IsArrayValued() const
Returns true iff this is holding an array type (see VtIsArray<>).
static VtValue Cast(VtValue const &val)
Return a VtValue holding val cast to hold T.
VtValue & operator=(VtValue &&other) noexcept
Move assignment from another VtValue.
int GetKnownValueTypeIndex() const
Return VtKnownValueTypeIndex<T> for the held type T.
static VT_API VtValue CastToTypeid(VtValue const &val, std::type_info const &type)
Return a VtValue holding val cast to type.
T const & Get() const &
Returns a const reference to the held object if the held object is of type T.
Defines all the types "TYPED" for which Vt creates a VtTYPEDArray typedef.
A simple type-erased container that provides only destruction, moves and immutable,...
Array concept. By default, types are not arrays.
static void RegisterCast(VtValue(*castFn)(VtValue const &))
Register a cast from VtValue holding From to VtValue holding To.
VtValue & operator=(char *cstr)
Assigning a char * gives a VtValue holding a std::string.
Boost Python object wrapper.
VT_API std::type_info const & GetElementTypeid() const
Return the typeid of elements in a array valued type.
VtValue(T const &obj)
Construct a VtValue holding a copy of obj.
bool CanCast() const
Return if this can be cast to T.
VtValue & Swap(VtValue &rhs) noexcept
Swap this with rhs.
VT_API size_t GetHash() const
Return a hash code for the held object by calling VtHashValue() on it.
void UncheckedSwap(VtValue &rhs)
friend void swap(VtValue &lhs, VtValue &rhs)
Overloaded swap() for generic code/stl/etc.
bool CanCastToTypeid(std::type_info const &type) const
Return if this can be cast to type.
T GetWithDefault(T const &def=T()) const
Return a copy of the held object if the held object is of type T.
TfType represents a dynamic runtime type.
constexpr Integral BitsAs() const noexcept
Retrieve the stored bits as the integral type Integral.
friend bool operator !=(VtValue const &lhs, T const &rhs)
Tests for inequality.
void Set(T *ptr) noexcept
Set the pointer value to ptr.
VtValue & CastToTypeid(std::type_info const &type)
Return this holding value type cast to type.
VT_API friend std::ostream & operator<<(std::ostream &out, const VtValue &self)
Calls through to operator << on the held object.
VtValue()
Default ctor gives empty VtValue.
T Remove()
Make this value empty and return the held T instance.
bool IsHolding() const
Return true if this value is holding an object of type T, false otherwise.
VT_API TfType GetType() const
Returns the TfType of the type held by this value.
Provides a container which may hold any type, and provides introspection and iteration over array typ...
A file containing basic constants and definitions.
VtValue & operator=(VtValue const &other)
Copy assignment from another VtValue.
bool TfSafeTypeCompare(const std::type_info &t1, const std::type_info &t2)
Safely compare std::type_info structures.