7#ifndef PXR_BASE_VT_VALUE_H
8#define PXR_BASE_VT_VALUE_H
14#include "pxr/base/tf/pyObjWrapper.h"
16#include "pxr/base/tf/pyLock.h"
21#include "pxr/base/tf/anyUniquePtr.h"
22#include "pxr/base/tf/delegatedCountPtr.h"
23#include "pxr/base/tf/pointerAndBits.h"
24#include "pxr/base/tf/preprocessorUtilsLite.h"
28#include "pxr/base/tf/type.h"
30#include "pxr/base/vt/api.h"
31#include "pxr/base/vt/hash.h"
32#include "pxr/base/vt/streamOut.h"
40PXR_NAMESPACE_OPEN_SCOPE
46struct Vt_DefaultValueFactory;
50struct Vt_DefaultValueHolder
55 static Vt_DefaultValueHolder Create() {
56 return Vt_DefaultValueHolder(TfAnyUniquePtr::New<T>(),
typeid(T));
62 static Vt_DefaultValueHolder Create(T
const &val) {
63 return Vt_DefaultValueHolder(TfAnyUniquePtr::New(val),
typeid(T));
67 std::type_info
const &GetType()
const {
73 void const *GetPointer()
const {
78 Vt_DefaultValueHolder(
TfAnyUniquePtr &&ptr, std::type_info
const &type)
79 : _ptr(
std::move(ptr)), _type(&type) {}
82 std::type_info
const *_type;
89VT_API std::ostream &VtStreamOut(std::vector<VtValue>
const &val, std::ostream &);
91#define VT_VALUE_SET_STORED_TYPE(SRC, DST) \
92 template <> struct Vt_ValueStoredType<SRC> { typedef DST Type; }
94template <
class T>
struct Vt_ValueStoredType {
typedef T Type; };
95VT_VALUE_SET_STORED_TYPE(
char const *, std::string);
96VT_VALUE_SET_STORED_TYPE(
char *, std::string);
98#ifdef PXR_PYTHON_SUPPORT_ENABLED
99VT_VALUE_SET_STORED_TYPE(pxr_boost::python::object,
TfPyObjWrapper);
102#undef VT_VALUE_SET_STORED_TYPE
106struct Vt_ValueGetStored
107 : Vt_ValueStoredType<std::decay_t<T>> {};
148 static const unsigned int _LocalFlag = 1 << 0;
149 static const unsigned int _TrivialCopyFlag = 1 << 1;
150 static const unsigned int _ProxyFlag = 1 << 2;
154 explicit _Counted(T
const &obj) : _obj(obj) {
157 bool IsUnique()
const {
return _refCount == 1; }
158 T
const &Get()
const {
return _obj; }
159 T &GetMutable() {
return _obj; }
163 mutable std::atomic<int> _refCount;
165 friend inline void TfDelegatedCountIncrement(_Counted
const *d) {
166 d->_refCount.fetch_add(1, std::memory_order_relaxed);
168 friend inline void TfDelegatedCountDecrement(_Counted
const *d)
noexcept {
169 if (d->_refCount.fetch_sub(1, std::memory_order_release) == 1) {
170 std::atomic_thread_fence(std::memory_order_acquire);
179 static const size_t _MaxLocalSize =
sizeof(
void*);
180 typedef std::aligned_storage<
181 _MaxLocalSize, _MaxLocalSize>::type _Storage;
184 using _IsTriviallyCopyable = std::integral_constant<bool,
185 std::is_trivially_default_constructible_v<T> &&
186 std::is_trivially_copyable_v<T> &&
187 std::is_trivially_copy_assignable_v<T> &&
188 std::is_trivially_destructible_v<T>>;
193 using _UsesLocalStore = std::integral_constant<bool,
194 (
sizeof(T) <=
sizeof(_Storage)) &&
195 VtValueTypeHasCheapCopy<T>::value &&
196 std::is_nothrow_move_constructible<T>::value &&
197 std::is_nothrow_move_assignable<T>::value>;
202 using _CopyInitFunc = void (*)(_Storage
const &, _Storage &);
203 using _DestroyFunc = void (*)(_Storage &);
204 using _MoveFunc = void (*)(_Storage &, _Storage &);
205 using _CanHashFunc = bool (*)(_Storage
const &);
206 using _HashFunc = size_t (*)(_Storage
const &);
207 using _EqualFunc = bool (*)(_Storage
const &, _Storage
const &);
208 using _EqualPtrFunc = bool (*)(_Storage
const &,
void const *);
209 using _MakeMutableFunc = void (*)(_Storage &);
211 using _StreamOutFunc =
212 std::ostream & (*)(_Storage
const &, std::ostream &);
213 using _GetTypeidFunc = std::type_info
const & (*)(_Storage
const &);
214 using _IsArrayValuedFunc = bool (*)(_Storage
const &);
215 using _GetElementTypeidFunc =
216 std::type_info
const & (*)(_Storage
const &);
217 using _GetShapeDataFunc =
const Vt_ShapeData* (*)(_Storage
const &);
218 using _GetNumElementsFunc = size_t (*)(_Storage
const &);
219 using _ProxyHoldsTypeFunc = bool (*)(_Storage
const &, std::type_info
const &);
220 using _GetProxiedTypeFunc =
TfType (*)(_Storage
const &);
221 using _GetProxiedTypeidFunc =
222 std::type_info
const & (*)(_Storage
const &);
223 using _GetProxiedObjPtrFunc =
void const *(*)(_Storage
const &);
224 using _GetProxiedAsVtValueFunc =
VtValue (*)(_Storage
const &);
227 constexpr _TypeInfo(
const std::type_info &ti,
228 const std::type_info &elementTi,
233 _CopyInitFunc copyInit,
234 _DestroyFunc destroy,
236 _CanHashFunc canHash,
239 _EqualPtrFunc equalPtr,
240 _MakeMutableFunc makeMutable,
241 _GetPyObjFunc getPyObj,
242 _StreamOutFunc streamOut,
243 _GetTypeidFunc getTypeid,
244 _IsArrayValuedFunc isArrayValued,
245 _GetElementTypeidFunc getElementTypeid,
246 _GetShapeDataFunc getShapeData,
247 _GetNumElementsFunc getNumElements,
248 _ProxyHoldsTypeFunc proxyHoldsType,
249 _GetProxiedTypeFunc getProxiedType,
250 _GetProxiedTypeidFunc getProxiedTypeid,
251 _GetProxiedObjPtrFunc getProxiedObjPtr,
252 _GetProxiedAsVtValueFunc getProxiedAsVtValue)
254 , elementTypeInfo(elementTi)
255 , knownTypeIndex(knownTypeIndex)
258 , isHashable(isHashable)
260 , _copyInit(copyInit)
266 , _equalPtr(equalPtr)
267 , _makeMutable(makeMutable)
268 , _getPyObj(getPyObj)
269 , _streamOut(streamOut)
270 , _getTypeid(getTypeid)
271 , _isArrayValued(isArrayValued)
272 , _getElementTypeid(getElementTypeid)
273 , _getShapeData(getShapeData)
274 , _getNumElements(getNumElements)
275 , _proxyHoldsType(proxyHoldsType)
276 , _getProxiedType(getProxiedType)
277 , _getProxiedTypeid(getProxiedTypeid)
278 , _getProxiedObjPtr(getProxiedObjPtr)
279 , _getProxiedAsVtValue(getProxiedAsVtValue)
283 void CopyInit(_Storage
const &src, _Storage &dst)
const {
286 void Destroy(_Storage &storage)
const {
289 void Move(_Storage &src, _Storage &dst)
const noexcept {
292 bool CanHash(_Storage
const &storage)
const {
293 return _canHash(storage);
295 size_t Hash(_Storage
const &storage)
const {
296 return _hash(storage);
298 bool Equal(_Storage
const &lhs, _Storage
const &rhs)
const {
299 return _equal(lhs, rhs);
301 bool EqualPtr(_Storage
const &lhs,
void const *rhs)
const {
302 return _equalPtr(lhs, rhs);
304 void MakeMutable(_Storage &storage)
const {
305 _makeMutable(storage);
308 return _getPyObj(storage);
310 std::ostream &StreamOut(_Storage
const &storage,
311 std::ostream &out)
const {
312 return _streamOut(storage, out);
315 return _isArrayValued(storage);
318 return _getElementTypeid(storage);
320 std::type_info
const &
GetTypeid(_Storage
const &storage)
const {
321 return _getTypeid(storage);
323 const Vt_ShapeData* GetShapeData(_Storage
const &storage)
const {
324 return _getShapeData(storage);
326 size_t GetNumElements(_Storage
const &storage)
const {
327 return _getNumElements(storage);
329 bool ProxyHoldsType(_Storage
const &storage,
330 std::type_info
const &t)
const {
331 return _proxyHoldsType(storage, t);
333 TfType GetProxiedType(_Storage
const &storage)
const {
334 return _getProxiedType(storage);
336 std::type_info
const &GetProxiedTypeid(_Storage
const &storage)
const {
337 return _getProxiedTypeid(storage);
339 VtValue GetProxiedAsVtValue(_Storage
const &storage)
const {
340 return _getProxiedAsVtValue(storage);
342 void const *GetProxiedObjPtr(_Storage
const &storage)
const {
343 return _getProxiedObjPtr(storage);
346 const std::type_info &typeInfo;
347 const std::type_info &elementTypeInfo;
354 _CopyInitFunc _copyInit;
355 _DestroyFunc _destroy;
357 _CanHashFunc _canHash;
360 _EqualPtrFunc _equalPtr;
361 _MakeMutableFunc _makeMutable;
362 _GetPyObjFunc _getPyObj;
363 _StreamOutFunc _streamOut;
364 _GetTypeidFunc _getTypeid;
365 _IsArrayValuedFunc _isArrayValued;
366 _GetElementTypeidFunc _getElementTypeid;
367 _GetShapeDataFunc _getShapeData;
368 _GetNumElementsFunc _getNumElements;
369 _ProxyHoldsTypeFunc _proxyHoldsType;
370 _GetProxiedTypeFunc _getProxiedType;
371 _GetProxiedTypeidFunc _getProxiedTypeid;
372 _GetProxiedObjPtrFunc _getProxiedObjPtr;
373 _GetProxiedAsVtValueFunc _getProxiedAsVtValue;
379 template <
class T,
class Enable=
void>
382 static const Vt_ShapeData* GetShapeData(T
const &) {
return NULL; }
383 static size_t GetNumElements(T
const &) {
return 0; }
384 constexpr static std::type_info
const &GetElementTypeid() {
388 template <
class Array>
390 Array, typename
std::enable_if<VtIsArray<Array>::value>::type>
392 static const Vt_ShapeData* GetShapeData(Array
const &obj) {
393 return obj._GetShapeData();
395 static size_t GetNumElements(Array
const &obj) {
398 constexpr static std::type_info
const &GetElementTypeid() {
399 return typeid(
typename Array::ElementType);
406 _TypedProxyEqualityImpl(T
const &a, T
const &b,
int) ->
decltype(a == b) {
410 template <
class NoEqual>
412 _TypedProxyEqualityImpl(NoEqual
const &a, NoEqual
const &b,
long) {
413 return VtGetProxiedObject(a) == VtGetProxiedObject(b);
418 _ErasedProxyEqualityImpl(T
const &a, T
const &b,
int) ->
decltype(a == b) {
422 template <
class NoEqual>
424 _ErasedProxyEqualityImpl(NoEqual
const &a, NoEqual
const &b,
long) {
425 return *VtGetErasedProxiedVtValue(a) == *VtGetErasedProxiedVtValue(b);
429 template <
class T,
class Enable =
void>
432 using ProxiedType =
typename VtGetProxiedType<T>::type;
434 static bool CanHash(T
const &) {
return VtIsHashable<ProxiedType>(); }
435 static size_t Hash(T
const &obj) {
436 return VtHashValue(VtGetProxiedObject(obj));
438 static bool Equal(T
const &a, T
const &b) {
443 return _TypedProxyEqualityImpl(a, b, 0);
446#ifdef PXR_PYTHON_SUPPORT_ENABLED
447 ProxiedType
const &p = VtGetProxiedObject(obj);
449 return pxr_boost::python::api::object(p);
454 static std::ostream &StreamOut(T
const &obj, std::ostream &out) {
455 return VtStreamOut(VtGetProxiedObject(obj), out);
457 static Vt_ShapeData
const *GetShapeData(T
const &obj) {
458 return _ArrayHelper<ProxiedType>::GetShapeData(
459 VtGetProxiedObject(obj));
461 static size_t GetNumElements(T
const &obj) {
462 return _ArrayHelper<ProxiedType>::GetNumElements(
463 VtGetProxiedObject(obj));
468 static std::type_info
const &
GetTypeid(T
const &) {
469 return typeid(ProxiedType);
472 return _ArrayHelper<ProxiedType>::GetElementTypeid();
474 static VtValue GetProxiedAsVtValue(T
const &obj) {
475 return VtValue(VtGetProxiedObject(obj));
477 static bool HoldsType(T
const &tp, std::type_info
const &query) {
480 static TfType GetTfType(T
const &tp) {
481 return TfType::Find<ProxiedType>();
483 static void const *GetObjPtr(T
const &tp) {
484 return static_cast<void const *
>(&VtGetProxiedObject(tp));
488 template <
class ErasedProxy>
490 ErasedProxy, typename
std::enable_if<
491 VtIsErasedValueProxy<ErasedProxy>::value>::type>
493 static bool CanHash(ErasedProxy
const &proxy) {
494 return VtGetErasedProxiedVtValue(proxy)->CanHash();
496 static size_t Hash(ErasedProxy
const &proxy) {
497 return VtGetErasedProxiedVtValue(proxy)->GetHash();
499 static bool Equal(ErasedProxy
const &a, ErasedProxy
const &b) {
504 return _ErasedProxyEqualityImpl(a, b, 0);
507#ifdef PXR_PYTHON_SUPPORT_ENABLED
508 VtValue const *val = VtGetErasedProxiedVtValue(obj);
510 return pxr_boost::python::api::object(*val);
515 static std::ostream &
516 StreamOut(ErasedProxy
const &obj, std::ostream &out) {
517 return VtStreamOut(obj, out);
519 static Vt_ShapeData
const *GetShapeData(ErasedProxy
const &obj) {
520 return VtGetErasedProxiedVtValue(obj)->_GetShapeData();
522 static size_t GetNumElements(ErasedProxy
const &obj) {
523 return VtGetErasedProxiedVtValue(obj)->_GetNumElements();
526 return VtGetErasedProxiedVtValue(obj)->IsArrayValued();
528 static std::type_info
const &
GetTypeid(ErasedProxy
const &obj) {
529 return VtGetErasedProxiedVtValue(obj)->GetTypeid();
532 return VtGetErasedProxiedVtValue(obj)->GetElementTypeid();
534 static VtValue GetProxiedAsVtValue(ErasedProxy
const &ep) {
535 return *VtGetErasedProxiedVtValue(ep);
538 HoldsType(ErasedProxy
const &ep, std::type_info
const &query) {
539 return VtErasedProxyHoldsType(ep, query);
541 static TfType GetTfType(ErasedProxy
const &ep) {
542 return VtGetErasedProxiedTfType(ep);
544 static void const *GetObjPtr(ErasedProxy
const &ep) {
545 VtValue const *val = VtGetErasedProxiedVtValue(ep);
546 return val ? val->_GetProxiedObjPtr() :
nullptr;
553 template <
class T,
class Container,
class Derived>
554 struct _TypeInfoImpl :
public _TypeInfo
556 static const bool IsLocal = _UsesLocalStore<T>::value;
557 static const bool HasTrivialCopy = _IsTriviallyCopyable<T>::value;
558 static const bool IsProxy = VtIsValueProxy<T>::value;
560 using ProxyHelper = _ProxyHelper<T>;
562 using This = _TypeInfoImpl;
564 constexpr _TypeInfoImpl()
565 : _TypeInfo(
typeid(T),
566 _ArrayHelper<T>::GetElementTypeid(),
567 Vt_KnownValueTypeDetail::GetIndex<T>(),
585 &This::_IsArrayValued,
586 &This::_GetElementTypeid,
587 &This::_GetShapeData,
588 &This::_GetNumElements,
591 &This::_ProxyHoldsType,
592 &This::_GetProxiedType,
593 &This::_GetProxiedTypeid,
594 &This::_GetProxiedObjPtr,
595 &This::_GetProxiedAsVtValue)
600 static T
const &GetObj(_Storage
const &storage) {
601 return Derived::_GetObj(_Container(storage));
604 static T &GetMutableObj(_Storage &storage) {
605 return Derived::_GetMutableObj(_Container(storage));
608 static void CopyInitObj(T
const &objSrc, _Storage &dst) {
609 Derived::_PlaceCopy(&_Container(dst), objSrc);
613 static_assert(
sizeof(Container) <=
sizeof(_Storage),
614 "Container size cannot exceed storage size.");
618 static void _CopyInit(_Storage
const &src, _Storage &dst) {
619 new (&_Container(dst)) Container(_Container(src));
622 static void _Destroy(_Storage &storage) {
623 _Container(storage).~Container();
626 static bool _CanHash(_Storage
const &storage) {
627 return ProxyHelper::CanHash(GetObj(storage));
630 static size_t _Hash(_Storage
const &storage) {
631 return ProxyHelper::Hash(GetObj(storage));
634 static bool _Equal(_Storage
const &lhs, _Storage
const &rhs) {
638 return ProxyHelper::Equal(GetObj(lhs), GetObj(rhs));
641 static bool _EqualPtr(_Storage
const &lhs,
void const *rhs) {
645 return ProxyHelper::Equal(
646 GetObj(lhs), *
static_cast<T
const *
>(rhs));
649 static void _Move(_Storage &src, _Storage &dst)
noexcept {
650 new (&_Container(dst)) Container(std::move(_Container(src)));
654 static void _MakeMutable(_Storage &storage) {
655 GetMutableObj(storage);
659 return ProxyHelper::GetPyObj(GetObj(storage));
662 static std::ostream &_StreamOut(
663 _Storage
const &storage, std::ostream &out) {
664 return ProxyHelper::StreamOut(GetObj(storage), out);
667 static std::type_info
const &_GetTypeid(_Storage
const &storage) {
668 return ProxyHelper::GetTypeid(GetObj(storage));
671 static bool _IsArrayValued(_Storage
const &storage) {
672 return ProxyHelper::IsArrayValued(GetObj(storage));
675 static std::type_info
const &
676 _GetElementTypeid(_Storage
const &storage) {
677 return ProxyHelper::GetElementTypeid(GetObj(storage));
680 static const Vt_ShapeData* _GetShapeData(_Storage
const &storage) {
681 return ProxyHelper::GetShapeData(GetObj(storage));
684 static size_t _GetNumElements(_Storage
const &storage) {
685 return ProxyHelper::GetNumElements(GetObj(storage));
689 _ProxyHoldsType(_Storage
const &storage, std::type_info
const &t) {
690 return ProxyHelper::HoldsType(GetObj(storage), t);
694 _GetProxiedType(_Storage
const &storage) {
695 return ProxyHelper::GetTfType(GetObj(storage));
698 static std::type_info
const &
699 _GetProxiedTypeid(_Storage
const &storage) {
700 return ProxyHelper::GetTypeid(GetObj(storage));
704 _GetProxiedObjPtr(_Storage
const &storage) {
705 return ProxyHelper::GetObjPtr(GetObj(storage));
709 _GetProxiedAsVtValue(_Storage
const &storage) {
710 return ProxyHelper::GetProxiedAsVtValue(GetObj(storage));
716 static Container &_Container(_Storage &storage) {
718 return *
reinterpret_cast<Container *
>(&storage);
720 static Container
const &_Container(_Storage
const &storage) {
722 return *
reinterpret_cast<Container
const *
>(&storage);
730 struct _LocalTypeInfo : _TypeInfoImpl<
736 constexpr _LocalTypeInfo()
737 : _TypeInfoImpl<T, T, _LocalTypeInfo<T>>()
741 static T &_GetMutableObj(T &obj) {
return obj; }
742 static T
const &_GetObj(T
const &obj) {
return obj; }
744 static void _PlaceCopy(T *dst, T
const &src) {
new (dst) T(src); }
751 struct _RemoteTypeInfo : _TypeInfoImpl<
753 TfDelegatedCountPtr<_Counted<T>>,
757 constexpr _RemoteTypeInfo()
764 static T &_GetMutableObj(Ptr &ptr) {
765 if (!ptr->IsUnique()) {
766 ptr = TfMakeDelegatedCountPtr<_Counted<T>>(ptr->Get());
768 return ptr->GetMutable();
770 static T
const &_GetObj(Ptr
const &ptr) {
return ptr->Get(); }
772 static void _PlaceCopy(Ptr *dst, T
const &src) {
773 new (dst) Ptr(TfDelegatedCountIncrementTag,
new _Counted<T>(src));
779 struct _TypeInfoFor {
781 typedef std::conditional_t<_UsesLocalStore<T>::value,
783 _RemoteTypeInfo<T>> Type;
788 struct _TypeInfoFor<char[N]> : _TypeInfoFor<std::string> {};
794 typedef typename _TypeInfoFor<T>::Type TI;
796 static constexpr unsigned int flags =
797 (TI::IsLocal ? _LocalFlag : 0) |
798 (TI::HasTrivialCopy ? _TrivialCopyFlag : 0) |
799 (TI::IsProxy ? _ProxyFlag : 0);
809 friend struct _HoldAside;
811 explicit _HoldAside(
VtValue *val)
812 : info((val->
IsEmpty() || val->_IsLocalAndTriviallyCopyable())
813 ?
static_cast<_TypeInfo
const *
>(NULL) : val->_info.
Get()) {
815 info->Move(val->_storage, storage);
819 info->Destroy(storage);
822 _TypeInfo
const *info;
827 std::is_same<T, typename Vt_ValueGetStored<T>::Type>::value>
828 _Init(T
const &obj) {
829 _info = GetTypeInfo<T>();
830 typedef typename _TypeInfoFor<T>::Type TypeInfo;
831 TypeInfo::CopyInitObj(obj, _storage);
836 !std::is_same<T, typename Vt_ValueGetStored<T>::Type>::value>
837 _Init(T
const &obj) {
838 _Init(
typename Vt_ValueGetStored<T>::Type(obj));
897 if (ARCH_LIKELY(
this != &other))
904 if (ARCH_LIKELY(
this != &other))
913 _TypeInfoFor<T>::Type::IsLocal &&
914 _TypeInfoFor<T>::Type::HasTrivialCopy,
931 !_TypeInfoFor<T>::Type::IsLocal ||
932 !_TypeInfoFor<T>::Type::HasTrivialCopy,
935 _HoldAside tmp(
this);
943 std::string tmp(cstr);
951 return *
this =
const_cast<char const *
>(cstr);
957 if (!
IsEmpty() || !rhs.IsEmpty()) {
980 std::is_same<T, typename Vt_ValueGetStored<T>::Type>::value>
999 std::is_same<T, typename Vt_ValueGetStored<T>::Type>::value>
1002 swap(_GetMutable<T>(), rhs);
1034 template <
class T,
class Fn>
1036 std::is_same<T, typename Vt_ValueGetStored<T>::Type>::value,
bool>
1038 if (!IsHolding<T>()) {
1041 UncheckedMutate<T>(std::forward<Fn>(mutateFn));
1048 template <
class T,
class Fn>
1050 std::is_same<T, typename Vt_ValueGetStored<T>::Type>::value>
1055 T &stored =_GetMutable<T>();
1056 T tmp = std::move(stored);
1057 std::forward<Fn>(mutateFn)(tmp);
1058 stored = std::move(tmp);
1093 if (ARCH_UNLIKELY(_IsProxy())) {
1094 return _info->GetProxiedAsVtValue(
1095 _storage).GetKnownValueTypeIndex();
1097 return _info.
GetLiteral() ? _info->knownTypeIndex : -1;
1122 typedef Vt_DefaultValueFactory<T> Factory;
1126 if (ARCH_UNLIKELY(!IsHolding<T>())) {
1127 return *(
static_cast<T
const *
>(
1128 _FailGet(Factory::Invoke,
typeid(T))));
1139 typedef Vt_DefaultValueFactory<T> Factory;
1143 if (ARCH_UNLIKELY(!IsHolding<T>())) {
1144 return *(
static_cast<T
const *
>(
1145 _FailGet(Factory::Invoke,
typeid(T))));
1148 return UncheckedRemove<T>();
1157 return IsHolding<T>() ? UncheckedGet<T>() : def;
1161 template <
typename From,
typename To>
1163 _RegisterCast(
typeid(From),
typeid(To), castFn);
1168 template <
typename From,
typename To>
1170 _RegisterCast(
typeid(From),
typeid(To), _SimpleCast<From, To>);
1175 template <
typename From,
typename To>
1177 RegisterSimpleCast<From, To>();
1178 RegisterSimpleCast<To, From>();
1188 template <
typename T>
1219 std::type_info
const &to) {
1220 return _CanCast(from, to);
1230 template <
typename T>
1234 return *
this = _PerformCast(
typeid(T), *
this);
1257 *
this = _PerformCast(type, *
this);
1265 template <
typename T>
1267 return _CanCast(
GetTypeid(),
typeid(T));
1293 friend inline size_t hash_value(
VtValue const &val) {
1298 template <
typename T>
1300 typedef typename Vt_ValueGetStored<T>::Type Stored;
1303 template <
typename T>
1309 template <
typename T>
1311 return !(lhs == rhs);
1313 template <
typename T>
1315 return !(lhs == rhs);
1321 if (empty || rhsEmpty) {
1323 return empty == rhsEmpty;
1327 return _info.
Get()->Equal(_storage, rhs._storage);
1329 return _EqualityImpl(rhs);
1334 VT_API
friend std::ostream &
1338 VT_API
const Vt_ShapeData* _GetShapeData()
const;
1339 VT_API
size_t _GetNumElements()
const;
1340 friend struct Vt_ValueShapeDataAccess;
1348 _HoldAside tmp(&dst);
1349 dst._info = src._info;
1350 if (src._IsLocalAndTriviallyCopyable()) {
1351 dst._storage = src._storage;
1353 dst._info->CopyInit(src._storage, dst._storage);
1363 _HoldAside tmp(&dst);
1364 dst._info = src._info;
1365 if (src._IsLocalAndTriviallyCopyable()) {
1366 dst._storage = src._storage;
1368 dst._info->Move(src._storage, dst._storage);
1371 src._info.
Set(
nullptr, 0);
1377 if constexpr (VtIsKnownValueType_Workaround<T>::value) {
1378 return _info->knownTypeIndex == VtGetKnownValueTypeIndex<T>() ||
1379 ARCH_UNLIKELY(_IsProxy() && _TypeIsImpl(
typeid(T)));
1381 std::type_info
const &t =
typeid(T);
1383 ARCH_UNLIKELY(_IsProxy() && _TypeIsImpl(t));
1387 VT_API
bool _TypeIsImpl(std::type_info
const &queriedType)
const;
1389 VT_API
bool _EqualityImpl(
VtValue const &rhs)
const;
1391 template <
class Proxy>
1392 std::enable_if_t<VtIsValueProxy<Proxy>::value, Proxy &>
1394 typedef typename _TypeInfoFor<Proxy>::Type TypeInfo;
1395 return TypeInfo::GetMutableObj(_storage);
1399 std::enable_if_t<!VtIsValueProxy<T>::value, T &>
1402 if (ARCH_UNLIKELY(_IsProxy())) {
1403 *
this = _info->GetProxiedAsVtValue(_storage);
1405 typedef typename _TypeInfoFor<T>::Type TypeInfo;
1406 return TypeInfo::GetMutableObj(_storage);
1409 template <
class Proxy>
1410 std::enable_if_t<VtIsValueProxy<Proxy>::value, Proxy
const &>
1412 typedef typename _TypeInfoFor<Proxy>::Type TypeInfo;
1413 return TypeInfo::GetObj(_storage);
1417 std::enable_if_t<!VtIsValueProxy<T>::value, T
const &>
1419 typedef typename _TypeInfoFor<T>::Type TypeInfo;
1420 if (ARCH_UNLIKELY(_IsProxy())) {
1421 return *
static_cast<T
const *
>(_GetProxiedObjPtr());
1423 return TypeInfo::GetObj(_storage);
1426 void const *_GetProxiedObjPtr()
const {
1427 return _info->GetProxiedObjPtr(_storage);
1433 _FailGet(Vt_DefaultValueHolder (*factory)(),
1434 std::type_info
const &queryType)
const;
1436 inline void _Clear() {
1440ARCH_PRAGMA_MAYBE_UNINITIALIZED
1441 if (_info.
GetLiteral() && !_IsLocalAndTriviallyCopyable())
1442 _info.
Get()->Destroy(_storage);
1444 _info.
Set(
nullptr, 0);
1447 inline bool _IsLocalAndTriviallyCopyable()
const {
1448 unsigned int bits = _info.
BitsAs<
unsigned int>();
1449 return (bits & (_LocalFlag | _TrivialCopyFlag)) ==
1450 (_LocalFlag | _TrivialCopyFlag);
1453 inline bool _IsProxy()
const {
1454 return _info.
BitsAs<
unsigned int>() & _ProxyFlag;
1457 VT_API
static void _RegisterCast(std::type_info
const &from,
1458 std::type_info
const &to,
1464 _PerformCast(std::type_info
const &to,
VtValue const &val);
1469 _CanCast(std::type_info
const &from, std::type_info
const &to);
1472 template <
typename From,
typename To>
1482 Vt_GetPythonObjectFromHeldValue(
VtValue const &self);
1492struct Vt_ValueShapeDataAccess {
1493 static const Vt_ShapeData* _GetShapeData(
const VtValue& value) {
1494 return value._GetShapeData();
1497 static size_t _GetNumElements(
const VtValue& value) {
1498 return value._GetNumElements();
1506struct Vt_DefaultValueFactory {
1507 static Vt_DefaultValueHolder Invoke();
1511inline Vt_DefaultValueHolder
1512Vt_DefaultValueFactory<T>::Invoke() {
1513 return Vt_DefaultValueHolder::Create<T>();
1524#define _VT_DECLARE_ZERO_VALUE_FACTORY(unused, elem) \
1526VT_API Vt_DefaultValueHolder Vt_DefaultValueFactory<VT_TYPE(elem)>::Invoke();
1528TF_PP_SEQ_FOR_EACH(_VT_DECLARE_ZERO_VALUE_FACTORY, ~,
1530 VT_MATRIX_VALUE_TYPES
1531 VT_QUATERNION_VALUE_TYPES
1532 VT_DUALQUATERNION_VALUE_TYPES)
1534#undef _VT_DECLARE_ZERO_VALUE_FACTORY
1543VtValue::Get<VtValue>() const & {
1549VtValue::Get<VtValue>() && {
1550 return std::move(*
this);
1555VtValue::UncheckedGet<VtValue>() const & {
1561VtValue::UncheckedGet<VtValue>() && {
1562 return std::move(*
this);
1567VtValue::IsHolding<VtValue>()
const {
1574VtValue::IsHolding<void>()
const {
1582PXR_NAMESPACE_CLOSE_SCOPE
Defines all the types "TYPED" for which Vt creates a VtTYPEDArray typedef.
A simple type-erased container that provides only destruction, moves and immutable,...
Stores a pointer to a ValueType which uses TfDelegatedCountIncrement and TfDelegatedCountDecrement to...
This class stores a T * and a small integer in the space of a T *.
void Set(T *ptr) noexcept
Set the pointer value to ptr.
constexpr uintptr_t GetLiteral() const noexcept
Retrieve the raw underlying value.
constexpr T * Get() const noexcept
Retrieve the pointer.
constexpr Integral BitsAs() const noexcept
Retrieve the stored bits as the integral type Integral.
Convenience class for accessing the Python Global Interpreter Lock.
Boost Python object wrapper.
TfType represents a dynamic runtime type.
Provides a container which may hold any type, and provides introspection and iteration over array typ...
VT_API std::string GetTypeName() const
Return the type name of the held typeid.
bool CanCastToTypeid(std::type_info const &type) const
Return if this can be cast to type.
T UncheckedRemove()
Make this value empty and return the held T instance.
friend bool operator==(VtValue const &lhs, T const &rhs)
Tests for equality.
int GetKnownValueTypeIndex() const
Return VtKnownValueTypeIndex<T> for the held type T.
T UncheckedGet() &&
This is an overloaded member function, provided for convenience. It differs from the above function o...
static VT_API VtValue CastToTypeOf(VtValue const &val, VtValue const &other)
Return a VtValue holding val cast to same type that other is holding.
T Remove()
Make this value empty and return the held T instance.
static VtValue Take(T &obj)
Create a new VtValue, taking its contents from obj.
static void RegisterSimpleCast()
Register a simple cast from VtValue holding From to VtValue.
VtValue & Cast()
Return this holding value type cast to T.
VtValue & CastToTypeOf(VtValue const &other)
Return this holding value type cast to same type that other is holding.
static void RegisterSimpleBidirectionalCast()
Register a two-way cast from VtValue holding From to VtValue holding To.
VtValue(VtValue const &other)
Copy construct with other.
static void RegisterCast(VtValue(*castFn)(VtValue const &))
Register a cast from VtValue holding From to VtValue holding To.
size_t GetArraySize() const
Return the number of elements in the held value if IsArrayValued(), return 0 otherwise.
T Get() &&
This is an overloaded member function, provided for convenience. It differs from the above function o...
VtValue & operator=(char *cstr)
Assigning a char * gives a VtValue holding a std::string.
bool CanCastToTypeOf(VtValue const &other) const
Return if this can be cast to type.
std::enable_if_t< std::is_same< T, typename Vt_ValueGetStored< T >::Type >::value > UncheckedMutate(Fn &&mutateFn)
Invoke mutateFn, it a non-const reference to the held object which must be of type T.
VtValue & operator=(char const *cstr)
Assigning a char const * gives a VtValue holding a std::string.
T GetWithDefault(T const &def=T()) const
Return a copy of the held object if the held object is of type T.
void UncheckedSwap(T &rhs)
Swap the held value with rhs.
void UncheckedSwap(VtValue &rhs)
This is an overloaded member function, provided for convenience. It differs from the above function o...
std::enable_if_t< std::is_same< T, typename Vt_ValueGetStored< T >::Type >::value, bool > Mutate(Fn &&mutateFn)
If this value holds an object of type T, invoke mutateFn, passing it a non-const reference to the hel...
VT_API bool IsArrayValued() const
Returns true iff this is holding an array type (see VtIsArray<>).
bool IsEmpty() const
Returns true iff this value is empty.
VtValue & operator=(VtValue &&other) noexcept
Move assignment from another VtValue.
VtValue & CastToTypeid(std::type_info const &type)
Return this holding value type cast to type.
VT_API TfType GetType() const
Returns the TfType of the type held by this value.
VT_API std::type_info const & GetElementTypeid() const
Return the typeid of elements in a array valued type.
VtValue & operator=(T const &obj)
Assignment operator from any type.
VtValue(T const &obj)
Construct a VtValue holding a copy of obj.
VT_API size_t GetHash() const
Return a hash code for the held object by calling VtHashValue() on it.
VtValue & Swap(VtValue &rhs) noexcept
Swap this with rhs.
friend void swap(VtValue &lhs, VtValue &rhs)
Overloaded swap() for generic code/stl/etc.
static VtValue Cast(VtValue const &val)
Return a VtValue holding val cast to hold T.
bool CanCast() const
Return if this can be cast to T.
T const & Get() const &
Returns a const reference to the held object if the held object is of type T.
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.
friend bool operator!=(VtValue const &lhs, T const &rhs)
Tests for inequality.
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.
bool IsHolding() const
Return true if this value is holding an object of type T, false otherwise.
VtValue(VtValue &&other) noexcept
Move construct with other.
static VT_API VtValue CastToTypeid(VtValue const &val, std::type_info const &type)
Return a VtValue holding val cast to type.
T const & UncheckedGet() const &
Returns a const reference to the held object if the held object is of type T.
VtValue & operator=(VtValue const &other)
Copy assignment from another VtValue.
VT_API bool CanHash() const
Return true if the held object provides a hash implementation.
void Swap(T &rhs)
Swap the held value with rhs. If this value is holding a T,.
VT_API std::type_info const & GetTypeid() const
Returns the typeid of the type held by this value.
Demangle C++ typenames generated by the typeid() facility.
Pragmas for controlling compiler-specific behaviors.
Safely compare C++ RTTI type structures.
bool TfSafeTypeCompare(const std::type_info &t1, const std::type_info &t2)
Safely compare std::type_info structures.
Definitions of basic string utilities in tf.
Array concept. By default, types are not arrays.
A file containing basic constants and definitions.