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/meta.h"
24#include "pxr/base/tf/pointerAndBits.h"
25#include "pxr/base/tf/preprocessorUtilsLite.h"
29#include "pxr/base/tf/type.h"
31#include "pxr/base/vt/api.h"
32#include "pxr/base/vt/hash.h"
33#include "pxr/base/vt/streamOut.h"
36#include "pxr/base/vt/valueCommon.h"
42PXR_NAMESPACE_OPEN_SCOPE
50VtStreamOut(std::vector<VtValue>
const &val, std::ostream &);
91 static const unsigned int _LocalFlag = 1 << 0;
92 static const unsigned int _TrivialCopyFlag = 1 << 1;
93 static const unsigned int _ProxyFlag = 1 << 2;
94 static const unsigned int _AllFlags =
95 _LocalFlag | _TrivialCopyFlag | _ProxyFlag;
99 explicit _Counted(T
const &obj) : _obj(obj) {
102 bool IsUnique()
const {
return _refCount == 1; }
103 T
const &Get()
const {
return _obj; }
104 T &GetMutable() {
return _obj; }
108 mutable std::atomic<int> _refCount;
110 friend inline void TfDelegatedCountIncrement(_Counted
const *d) {
111 d->_refCount.fetch_add(1, std::memory_order_relaxed);
113 friend inline void TfDelegatedCountDecrement(_Counted
const *d)
noexcept {
114 if (d->_refCount.fetch_sub(1, std::memory_order_release) == 1) {
115 std::atomic_thread_fence(std::memory_order_acquire);
124 static const size_t _MaxLocalSize =
sizeof(
void*);
125 typedef std::aligned_storage<
126 _MaxLocalSize, _MaxLocalSize>::type _Storage;
129 using _IsTriviallyCopyable = std::integral_constant<bool,
130 std::is_trivially_default_constructible_v<T> &&
131 std::is_trivially_copyable_v<T> &&
132 std::is_trivially_copy_assignable_v<T> &&
133 std::is_trivially_destructible_v<T>>;
138 using _UsesLocalStore = std::integral_constant<bool,
139 (
sizeof(T) <=
sizeof(_Storage)) &&
140 VtValueTypeHasCheapCopy<T>::value &&
141 std::is_nothrow_move_constructible<T>::value &&
142 std::is_nothrow_move_assignable<T>::value>;
147 struct alignas(8) _TypeInfo {
149 using _CopyInitFunc = void (*)(_Storage
const &, _Storage &);
150 using _DestroyFunc = void (*)(_Storage &);
151 using _MoveFunc = void (*)(_Storage &, _Storage &);
152 using _CanHashFunc = bool (*)(_Storage
const &);
153 using _HashFunc = size_t (*)(_Storage
const &);
154 using _EqualFunc = bool (*)(_Storage
const &, _Storage
const &);
155 using _EqualPtrFunc = bool (*)(_Storage
const &,
void const *);
156 using _MakeMutableFunc = void (*)(_Storage &);
158 using _GetValueRefFunc =
VtValueRef (*)(_Storage
const &, bool);
159 using _StreamOutFunc =
160 std::ostream & (*)(_Storage
const &, std::ostream &);
161 using _GetTypeidFunc = std::type_info
const & (*)(_Storage
const &);
162 using _IsArrayValuedFunc = bool (*)(_Storage
const &);
163 using _GetElementTypeidFunc =
164 std::type_info
const & (*)(_Storage
const &);
165 using _GetShapeDataFunc =
const Vt_ShapeData* (*)(_Storage
const &);
166 using _GetNumElementsFunc = size_t (*)(_Storage
const &);
167 using _ProxyHoldsTypeFunc = bool (*)(_Storage
const &, std::type_info
const &);
168 using _GetProxiedTypeFunc =
TfType (*)(_Storage
const &);
169 using _GetProxiedTypeidFunc =
170 std::type_info
const & (*)(_Storage
const &);
171 using _GetProxiedObjPtrFunc =
void const *(*)(_Storage
const &);
172 using _GetProxiedAsVtValueFunc =
VtValue (*)(_Storage
const &);
175 constexpr _TypeInfo(
const std::type_info &ti,
176 const std::type_info &elementTi,
183 _CopyInitFunc copyInit,
184 _DestroyFunc destroy,
186 _CanHashFunc canHash,
189 _EqualPtrFunc equalPtr,
190 _MakeMutableFunc makeMutable,
191 _GetPyObjFunc getPyObj,
192 _GetValueRefFunc getValueRef,
193 _StreamOutFunc streamOut,
194 _GetTypeidFunc getTypeid,
195 _IsArrayValuedFunc isArrayValued,
196 _GetElementTypeidFunc getElementTypeid,
197 _GetShapeDataFunc getShapeData,
198 _GetNumElementsFunc getNumElements,
199 _ProxyHoldsTypeFunc proxyHoldsType,
200 _GetProxiedTypeFunc getProxiedType,
201 _GetProxiedTypeidFunc getProxiedTypeid,
202 _GetProxiedObjPtrFunc getProxiedObjPtr,
203 _GetProxiedAsVtValueFunc getProxiedAsVtValue)
205 , elementTypeInfo(elementTi)
206 , knownTypeIndex(knownTypeIndex)
209 , isHashable(isHashable)
210 , canComposeOver(canComposeOver)
211 , canTransform(canTransform)
213 , _copyInit(copyInit)
219 , _equalPtr(equalPtr)
220 , _makeMutable(makeMutable)
221 , _getPyObj(getPyObj)
222 , _getValueRef(getValueRef)
223 , _streamOut(streamOut)
224 , _getTypeid(getTypeid)
225 , _isArrayValued(isArrayValued)
226 , _getElementTypeid(getElementTypeid)
227 , _getShapeData(getShapeData)
228 , _getNumElements(getNumElements)
229 , _proxyHoldsType(proxyHoldsType)
230 , _getProxiedType(getProxiedType)
231 , _getProxiedTypeid(getProxiedTypeid)
232 , _getProxiedObjPtr(getProxiedObjPtr)
233 , _getProxiedAsVtValue(getProxiedAsVtValue)
237 void CopyInit(_Storage
const &src, _Storage &dst)
const {
240 void Destroy(_Storage &storage)
const {
243 void Move(_Storage &src, _Storage &dst)
const noexcept {
246 bool CanHash(_Storage
const &storage)
const {
247 return _canHash(storage);
249 size_t Hash(_Storage
const &storage)
const {
250 return _hash(storage);
252 bool Equal(_Storage
const &lhs, _Storage
const &rhs)
const {
253 return _equal(lhs, rhs);
255 bool EqualPtr(_Storage
const &lhs,
void const *rhs)
const {
256 return _equalPtr(lhs, rhs);
258 void MakeMutable(_Storage &storage)
const {
259 _makeMutable(storage);
262 return _getPyObj(storage);
264 inline VtValueRef GetValueRef(_Storage
const &storage,
266 std::ostream &StreamOut(_Storage
const &storage,
267 std::ostream &out)
const {
268 return _streamOut(storage, out);
271 return _isArrayValued(storage);
274 return _getElementTypeid(storage);
276 std::type_info
const &
GetTypeid(_Storage
const &storage)
const {
277 return _getTypeid(storage);
279 const Vt_ShapeData* GetShapeData(_Storage
const &storage)
const {
280 return _getShapeData(storage);
282 size_t GetNumElements(_Storage
const &storage)
const {
283 return _getNumElements(storage);
285 bool ProxyHoldsType(_Storage
const &storage,
286 std::type_info
const &t)
const {
287 return _proxyHoldsType(storage, t);
289 TfType GetProxiedType(_Storage
const &storage)
const {
290 return _getProxiedType(storage);
292 std::type_info
const &GetProxiedTypeid(_Storage
const &storage)
const {
293 return _getProxiedTypeid(storage);
295 VtValue GetProxiedAsVtValue(_Storage
const &storage)
const {
296 return _getProxiedAsVtValue(storage);
298 void const *GetProxiedObjPtr(_Storage
const &storage)
const {
299 return _getProxiedObjPtr(storage);
302 const std::type_info &typeInfo;
303 const std::type_info &elementTypeInfo;
312 _CopyInitFunc _copyInit;
313 _DestroyFunc _destroy;
315 _CanHashFunc _canHash;
318 _EqualPtrFunc _equalPtr;
319 _MakeMutableFunc _makeMutable;
320 _GetPyObjFunc _getPyObj;
321 _GetValueRefFunc _getValueRef;
322 _StreamOutFunc _streamOut;
323 _GetTypeidFunc _getTypeid;
324 _IsArrayValuedFunc _isArrayValued;
325 _GetElementTypeidFunc _getElementTypeid;
326 _GetShapeDataFunc _getShapeData;
327 _GetNumElementsFunc _getNumElements;
328 _ProxyHoldsTypeFunc _proxyHoldsType;
329 _GetProxiedTypeFunc _getProxiedType;
330 _GetProxiedTypeidFunc _getProxiedTypeid;
331 _GetProxiedObjPtrFunc _getProxiedObjPtr;
332 _GetProxiedAsVtValueFunc _getProxiedAsVtValue;
340 struct _NonArrayHelper
342 static const Vt_ShapeData* GetShapeData(T
const &) {
return NULL; }
343 static size_t GetNumElements(T
const &) {
return 0; }
344 constexpr static std::type_info
const &GetElementTypeid() {
349 template <
class Array>
350 struct _IsArrayHelper
352 static const Vt_ShapeData* GetShapeData(Array
const &obj) {
353 return obj._GetShapeData();
355 static size_t GetNumElements(Array
const &obj) {
358 constexpr static std::type_info
const &GetElementTypeid() {
359 return typeid(
typename Array::ElementType);
364 template <
class ArrayEdit>
365 struct _IsArrayEditHelper : _NonArrayHelper<ArrayEdit>
367 constexpr static std::type_info
const &GetElementTypeid() {
368 return typeid(
typename ArrayEdit::ElementType);
376 using _ArrayHelper = TfConditionalType<
378 TfConditionalType<VtIsArrayEdit<T>::value,
379 _IsArrayEditHelper<T>, _NonArrayHelper<T>>
385 _TypedProxyEqualityImpl(T
const &a, T
const &b,
int) ->
decltype(a == b) {
389 template <
class NoEqual>
391 _TypedProxyEqualityImpl(NoEqual
const &a, NoEqual
const &b,
long) {
392 return VtGetProxiedObject(a) == VtGetProxiedObject(b);
397 _ErasedProxyEqualityImpl(T
const &a, T
const &b,
int) ->
decltype(a == b) {
401 template <
class NoEqual>
403 _ErasedProxyEqualityImpl(NoEqual
const &a, NoEqual
const &b,
long) {
404 return *VtGetErasedProxiedVtValue(a) == *VtGetErasedProxiedVtValue(b);
409 struct _TypedProxyHelper
411 using ProxiedType =
typename VtGetProxiedType<T>::type;
413 static bool CanHash(T
const &) {
return VtIsHashable<ProxiedType>(); }
414 static size_t Hash(T
const &obj) {
415 return VtHashValue(VtGetProxiedObject(obj));
417 static bool Equal(T
const &a, T
const &b) {
422 return _TypedProxyEqualityImpl(a, b, 0);
425#ifdef PXR_PYTHON_SUPPORT_ENABLED
426 ProxiedType
const &p = VtGetProxiedObject(obj);
428 return pxr_boost::python::api::object(p);
434 static std::ostream &StreamOut(T
const &obj, std::ostream &out) {
435 return VtStreamOut(VtGetProxiedObject(obj), out);
437 static Vt_ShapeData
const *GetShapeData(T
const &obj) {
438 return _ArrayHelper<ProxiedType>::GetShapeData(
439 VtGetProxiedObject(obj));
441 static size_t GetNumElements(T
const &obj) {
442 return _ArrayHelper<ProxiedType>::GetNumElements(
443 VtGetProxiedObject(obj));
448 static std::type_info
const &
GetTypeid(T
const &) {
449 return typeid(ProxiedType);
452 return _ArrayHelper<ProxiedType>::GetElementTypeid();
454 static VtValue GetProxiedAsVtValue(T
const &obj) {
455 return VtValue(VtGetProxiedObject(obj));
457 static bool HoldsType(T
const &tp, std::type_info
const &query) {
460 static TfType GetTfType(T
const &tp) {
461 return TfType::Find<ProxiedType>();
463 static void const *GetObjPtr(T
const &tp) {
464 return static_cast<void const *
>(&VtGetProxiedObject(tp));
469 template <
class ErasedProxy>
470 struct _ErasedProxyHelper
472 static bool CanHash(ErasedProxy
const &proxy) {
473 return VtGetErasedProxiedVtValue(proxy)->CanHash();
475 static size_t Hash(ErasedProxy
const &proxy) {
476 return VtGetErasedProxiedVtValue(proxy)->GetHash();
478 static bool Equal(ErasedProxy
const &a, ErasedProxy
const &b) {
483 return _ErasedProxyEqualityImpl(a, b, 0);
486#ifdef PXR_PYTHON_SUPPORT_ENABLED
487 VtValue const *val = VtGetErasedProxiedVtValue(obj);
489 return pxr_boost::python::api::object(*val);
494 static VtValueRef GetValueRef(ErasedProxy
const &obj);
495 static std::ostream &
496 StreamOut(ErasedProxy
const &obj, std::ostream &out) {
497 return VtStreamOut(obj, out);
499 static Vt_ShapeData
const *GetShapeData(ErasedProxy
const &obj) {
500 return VtGetErasedProxiedVtValue(obj)->_GetShapeData();
502 static size_t GetNumElements(ErasedProxy
const &obj) {
503 return VtGetErasedProxiedVtValue(obj)->_GetNumElements();
506 return VtGetErasedProxiedVtValue(obj)->IsArrayValued();
508 static std::type_info
const &
GetTypeid(ErasedProxy
const &obj) {
509 return VtGetErasedProxiedVtValue(obj)->GetTypeid();
512 return VtGetErasedProxiedVtValue(obj)->GetElementTypeid();
514 static VtValue GetProxiedAsVtValue(ErasedProxy
const &ep) {
515 return *VtGetErasedProxiedVtValue(ep);
518 HoldsType(ErasedProxy
const &ep, std::type_info
const &query) {
519 return VtErasedProxyHoldsType(ep, query);
521 static TfType GetTfType(ErasedProxy
const &ep) {
522 return VtGetErasedProxiedTfType(ep);
524 static void const *GetObjPtr(ErasedProxy
const &ep) {
525 VtValue const *val = VtGetErasedProxiedVtValue(ep);
526 return val ? val->_GetProxiedObjPtr() :
nullptr;
533 template <
class T,
class Container,
class Derived>
534 struct _TypeInfoImpl :
public _TypeInfo
536 static const bool IsLocal = _UsesLocalStore<T>::value;
537 static const bool HasTrivialCopy = _IsTriviallyCopyable<T>::value;
538 static const bool IsProxy = VtIsValueProxy<T>::value;
540 using ProxyHelper = TfConditionalType<
541 VtIsErasedValueProxy<T>::value,
542 _ErasedProxyHelper<T>, _TypedProxyHelper<T>>;
544 using This = _TypeInfoImpl;
546 constexpr _TypeInfoImpl()
547 : _TypeInfo(
typeid(T),
548 _ArrayHelper<T>::GetElementTypeid(),
549 Vt_KnownValueTypeDetail::GetIndex<T>(),
570 &This::_IsArrayValued,
571 &This::_GetElementTypeid,
572 &This::_GetShapeData,
573 &This::_GetNumElements,
576 &This::_ProxyHoldsType,
577 &This::_GetProxiedType,
578 &This::_GetProxiedTypeid,
579 &This::_GetProxiedObjPtr,
580 &This::_GetProxiedAsVtValue)
585 static T
const &GetObj(_Storage
const &storage) {
586 return Derived::_GetObj(_Container(storage));
589 static T &GetMutableObj(_Storage &storage) {
590 return Derived::_GetMutableObj(_Container(storage));
593 static void CopyInitObj(T
const &objSrc, _Storage &dst) {
594 Derived::_PlaceCopy(&_Container(dst), objSrc);
598 static_assert(
sizeof(Container) <=
sizeof(_Storage),
599 "Container size cannot exceed storage size.");
603 static void _CopyInit(_Storage
const &src, _Storage &dst) {
604 new (&_Container(dst)) Container(_Container(src));
607 static void _Destroy(_Storage &storage) {
608 _Container(storage).~Container();
611 static bool _CanHash(_Storage
const &storage) {
612 return ProxyHelper::CanHash(GetObj(storage));
615 static size_t _Hash(_Storage
const &storage) {
616 return ProxyHelper::Hash(GetObj(storage));
619 static bool _Equal(_Storage
const &lhs, _Storage
const &rhs) {
623 return ProxyHelper::Equal(GetObj(lhs), GetObj(rhs));
626 static bool _EqualPtr(_Storage
const &lhs,
void const *rhs) {
630 return ProxyHelper::Equal(
631 GetObj(lhs), *
static_cast<T
const *
>(rhs));
634 static void _Move(_Storage &src, _Storage &dst)
noexcept {
635 new (&_Container(dst)) Container(std::move(_Container(src)));
639 static void _MakeMutable(_Storage &storage) {
640 GetMutableObj(storage);
644 return ProxyHelper::GetPyObj(GetObj(storage));
647 static VtValueRef _GetValueRef(_Storage
const &storage,
bool rvalue);
649 static std::ostream &_StreamOut(
650 _Storage
const &storage, std::ostream &out) {
651 return ProxyHelper::StreamOut(GetObj(storage), out);
654 static std::type_info
const &_GetTypeid(_Storage
const &storage) {
655 return ProxyHelper::GetTypeid(GetObj(storage));
658 static bool _IsArrayValued(_Storage
const &storage) {
659 return ProxyHelper::IsArrayValued(GetObj(storage));
662 static std::type_info
const &
663 _GetElementTypeid(_Storage
const &storage) {
664 return ProxyHelper::GetElementTypeid(GetObj(storage));
667 static const Vt_ShapeData* _GetShapeData(_Storage
const &storage) {
668 return ProxyHelper::GetShapeData(GetObj(storage));
671 static size_t _GetNumElements(_Storage
const &storage) {
672 return ProxyHelper::GetNumElements(GetObj(storage));
676 _ProxyHoldsType(_Storage
const &storage, std::type_info
const &t) {
677 return ProxyHelper::HoldsType(GetObj(storage), t);
681 _GetProxiedType(_Storage
const &storage) {
682 return ProxyHelper::GetTfType(GetObj(storage));
685 static std::type_info
const &
686 _GetProxiedTypeid(_Storage
const &storage) {
687 return ProxyHelper::GetTypeid(GetObj(storage));
691 _GetProxiedObjPtr(_Storage
const &storage) {
692 return ProxyHelper::GetObjPtr(GetObj(storage));
696 _GetProxiedAsVtValue(_Storage
const &storage) {
697 return ProxyHelper::GetProxiedAsVtValue(GetObj(storage));
703 static Container &_Container(_Storage &storage) {
705 return *
reinterpret_cast<Container *
>(&storage);
707 static Container
const &_Container(_Storage
const &storage) {
709 return *
reinterpret_cast<Container
const *
>(&storage);
717 struct _LocalTypeInfo : _TypeInfoImpl<
723 constexpr _LocalTypeInfo()
724 : _TypeInfoImpl<T, T, _LocalTypeInfo<T>>()
728 static T &_GetMutableObj(T &obj) {
return obj; }
729 static T
const &_GetObj(T
const &obj) {
return obj; }
731 static void _PlaceCopy(T *dst, T
const &src) {
new (dst) T(src); }
738 struct _RemoteTypeInfo : _TypeInfoImpl<
740 TfDelegatedCountPtr<_Counted<T>>,
744 constexpr _RemoteTypeInfo()
751 static T &_GetMutableObj(Ptr &ptr) {
752 if (!ptr->IsUnique()) {
753 ptr = TfMakeDelegatedCountPtr<_Counted<T>>(ptr->Get());
755 return ptr->GetMutable();
757 static T
const &_GetObj(Ptr
const &ptr) {
return ptr->Get(); }
759 static void _PlaceCopy(Ptr *dst, T
const &src) {
760 new (dst) Ptr(TfDelegatedCountIncrementTag,
new _Counted<T>(src));
767 TfConditionalType<_UsesLocalStore<T>::value,
768 _LocalTypeInfo<T>, _RemoteTypeInfo<T>>;
776 friend struct _HoldAside;
778 explicit _HoldAside(
VtValue *val)
779 : info((val->
IsEmpty() || val->_IsLocalAndTriviallyCopyable())
780 ?
static_cast<_TypeInfo
const *
>(NULL) : val->_info.
Get()) {
782 info->Move(val->_storage, storage);
786 info->Destroy(storage);
789 _TypeInfo
const *info;
794 using StoredType =
typename Vt_ValueGetStored<T>::Type;
795 using TypeInfo = _TypeInfoFor<StoredType>;
801 static const TypeInfo ti;
802 static constexpr unsigned int flags =
803 (TypeInfo::IsLocal ? _LocalFlag : 0) |
804 (TypeInfo::HasTrivialCopy ? _TrivialCopyFlag : 0) |
805 (TypeInfo::IsProxy ? _ProxyFlag : 0);
809 static void Init(
VtValue *val, T
const &obj) {
810 val->_info = _GetTypeInfo();
811 if constexpr (std::is_same_v<T, StoredType>) {
812 TypeInfo::CopyInitObj(obj, val->_storage);
815 TypeInfo::CopyInitObj(StoredType {obj}, val->_storage);
842 _Init<T>::Init(
this, obj);
880 if (ARCH_LIKELY(
this != &other))
887 if (ARCH_LIKELY(
this != &other))
903 if (!
IsEmpty() || !rhs.IsEmpty()) {
922 static_assert(std::is_same_v<T, typename Vt_ValueGetStored<T>::Type>,
923 "Can only VtValue::Swap with a type T that stores as T");
936 static_assert(std::is_same_v<T, typename Vt_ValueGetStored<T>::Type>,
937 "Can only VtValue::Swap with a type T that stores as T");
939 swap(_GetMutable<T>(), rhs);
970 template <
class T,
class Fn>
973 static_assert(std::is_same_v<T, typename Vt_ValueGetStored<T>::Type>,
974 "Can only VtValue::Mutate a type T that stores as T");
975 if (!IsHolding<T>()) {
978 UncheckedMutate<T>(std::forward<Fn>(mutateFn));
985 template <
class T,
class Fn>
988 static_assert(std::is_same_v<T, typename Vt_ValueGetStored<T>::Type>,
989 "Can only VtValue::Mutate a type T that stores as T");
993 T &stored =_GetMutable<T>();
994 T tmp = std::move(stored);
995 std::forward<Fn>(mutateFn)(tmp);
996 stored = std::move(tmp);
1035 if (ARCH_UNLIKELY(_IsProxy())) {
1036 return _info->GetProxiedAsVtValue(
1037 _storage).GetKnownValueTypeIndex();
1039 return _info.
GetLiteral() ? _info->knownTypeIndex : -1;
1064 typedef Vt_DefaultValueFactory<T> Factory;
1068 if (ARCH_UNLIKELY(!IsHolding<T>())) {
1069 return *(
static_cast<T
const *
>(
1070 _FailGet(Factory::Invoke,
typeid(T))));
1081 typedef Vt_DefaultValueFactory<T> Factory;
1085 if (ARCH_UNLIKELY(!IsHolding<T>())) {
1086 return *(
static_cast<T
const *
>(
1087 _FailGet(Factory::Invoke,
typeid(T))));
1090 return UncheckedRemove<T>();
1099 return IsHolding<T>() ? UncheckedGet<T>() : def;
1103 template <
typename From,
typename To>
1105 _RegisterCast(
typeid(From),
typeid(To), castFn);
1110 template <
typename From,
typename To>
1112 _RegisterCast(
typeid(From),
typeid(To), _SimpleCast<From, To>);
1117 template <
typename From,
typename To>
1119 RegisterSimpleCast<From, To>();
1120 RegisterSimpleCast<To, From>();
1130 template <
typename T>
1161 std::type_info
const &to) {
1162 return _CanCast(from, to);
1172 template <
typename T>
1176 return *
this = _PerformCast(
typeid(T), *
this);
1199 *
this = _PerformCast(type, *
this);
1207 template <
typename T>
1209 return _CanCast(
GetTypeid(),
typeid(T));
1251 friend inline
size_t hash_value(
VtValue const &val) {
1252 return val.GetHash();
1270 template <
typename T>
1272 typedef typename Vt_ValueGetStored<T>::Type Stored;
1275 template <
typename T>
1281 template <
typename T>
1283 return !(lhs == rhs);
1285 template <
typename T>
1287 return !(lhs == rhs);
1293 if (empty || rhsEmpty) {
1295 return empty == rhsEmpty;
1299 return _info.
Get()->Equal(_storage, rhs._storage);
1301 return _EqualityImpl(rhs);
1306 VT_API
friend std::ostream &
1310 VT_API
const Vt_ShapeData* _GetShapeData()
const;
1311 VT_API
size_t _GetNumElements()
const;
1312 friend struct Vt_ValueShapeDataAccess;
1320 _HoldAside tmp(&dst);
1321 dst._info = src._info;
1322 if (src._IsLocalAndTriviallyCopyable()) {
1323 dst._storage = src._storage;
1325 dst._info->CopyInit(src._storage, dst._storage);
1335 _HoldAside tmp(&dst);
1336 dst._info = src._info;
1337 if (src._IsLocalAndTriviallyCopyable()) {
1338 dst._storage = src._storage;
1340 dst._info->Move(src._storage, dst._storage);
1343 src._info.
Set(
nullptr, 0);
1349 if constexpr (VtIsKnownValueType_Workaround<T>::value) {
1350 return _info->knownTypeIndex == VtGetKnownValueTypeIndex<T>() ||
1351 ARCH_UNLIKELY(_IsProxy() && _TypeIsImpl(
typeid(T)));
1354 std::type_info
const &t =
typeid(T);
1356 ARCH_UNLIKELY(_IsProxy() && _TypeIsImpl(t));
1360 VT_API
bool _TypeIsImpl(std::type_info
const &queriedType)
const;
1362 VT_API
bool _EqualityImpl(
VtValue const &rhs)
const;
1367 using TypeInfo = _TypeInfoFor<T>;
1368 if constexpr (!VtIsValueProxy<T>::value) {
1371 if (ARCH_UNLIKELY(_IsProxy())) {
1372 *
this = _info->GetProxiedAsVtValue(_storage);
1375 return TypeInfo::GetMutableObj(_storage);
1381 using TypeInfo = _TypeInfoFor<T>;
1382 if constexpr (!VtIsValueProxy<T>::value) {
1385 if (ARCH_UNLIKELY(_IsProxy())) {
1386 return *
static_cast<T
const *
>(_GetProxiedObjPtr());
1389 return TypeInfo::GetObj(_storage);
1392 void const *_GetProxiedObjPtr()
const {
1393 return _info->GetProxiedObjPtr(_storage);
1399 _FailGet(Vt_DefaultValueHolder (*factory)(),
1400 std::type_info
const &queryType)
const;
1402 inline void _Clear() {
1406ARCH_PRAGMA_MAYBE_UNINITIALIZED
1407 if (_info.
GetLiteral() && !_IsLocalAndTriviallyCopyable())
1408 _info.
Get()->Destroy(_storage);
1410 _info.
Set(
nullptr, 0);
1413 inline bool _IsLocalAndTriviallyCopyable()
const {
1414 unsigned int bits = _info.
BitsAs<
unsigned int>();
1415 return (bits & (_LocalFlag | _TrivialCopyFlag)) ==
1416 (_LocalFlag | _TrivialCopyFlag);
1419 inline bool _IsProxy()
const {
1420 return _info.
BitsAs<
unsigned int>() & _ProxyFlag;
1423 VT_API
static void _RegisterCast(std::type_info
const &from,
1424 std::type_info
const &to,
1430 _PerformCast(std::type_info
const &to,
VtValue const &val);
1435 _CanCast(std::type_info
const &from, std::type_info
const &to);
1438 template <
typename From,
typename To>
1448 Vt_GetPythonObjectFromHeldValue(
VtValue const &self);
1458struct Vt_ValueShapeDataAccess {
1459 static const Vt_ShapeData* _GetShapeData(
const VtValue& value) {
1460 return value._GetShapeData();
1463 static size_t _GetNumElements(
const VtValue& value) {
1464 return value._GetNumElements();
1475VtValue::Get<VtValue>() const & {
1481VtValue::Get<VtValue>() && {
1482 return std::move(*
this);
1487VtValue::UncheckedGet<VtValue>() const & {
1493VtValue::UncheckedGet<VtValue>() && {
1494 return std::move(*
this);
1499VtValue::IsHolding<VtValue>()
const {
1506VtValue::IsHolding<void>()
const {
1512PXR_NAMESPACE_CLOSE_SCOPE
1522#include "pxr/base/vt/valueRef.h"
1524PXR_NAMESPACE_OPEN_SCOPE
1530 if constexpr (_TypeInfoFor<T>::IsLocal &&
1531 _TypeInfoFor<T>::HasTrivialCopy) {
1533 _Init<T>::Init(
this, obj);
1537 _HoldAside tmp(
this);
1538 _Init<T>::Init(
this, obj);
1548VtValue::_TypeInfo::GetValueRef(_Storage
const &storage,
bool rvalue)
const
1550 return _getValueRef(storage, rvalue);
1555VtValue::_TypedProxyHelper<T>::GetValueRef(T
const &obj)
1557 return VtGetProxiedObject(obj);
1562VtValue::_ErasedProxyHelper<T>::GetValueRef(T
const &obj)
1564 return *VtGetErasedProxiedVtValue(obj);
1567template <
class T,
class C,
class D>
1569VtValue::_TypeInfoImpl<T, C, D>
1570::_GetValueRef(_Storage
const &storage,
bool rvalue)
1572 if constexpr (!IsProxy) {
1577 return std::move(GetMutableObj(
const_cast<_Storage &
>(storage)));
1580 return ProxyHelper::GetValueRef(GetObj(storage));
1583PXR_NAMESPACE_CLOSE_SCOPE
Defines all the types "TYPED" for which Vt creates a VtTYPEDArray typedef.
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.
VT_API VtValue(VtValueRef ref)
Construct with VtValueRef.
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.
void UncheckedMutate(Fn &&mutateFn)
Invoke mutateFn, passing it a non-const reference to the held object which must be of type T.
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.
VT_API VtValueRef Ref() const &
Return a VtValueRef that refers to the current object held by this VtValue.
bool Mutate(Fn &&mutateFn)
If this value holds an object of type T, invoke mutateFn, passing it a non-const reference to the hel...
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...
bool CanCastToTypeOf(VtValue const &other) 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.
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...
VT_API bool IsArrayValued() const
Return true if this holds a VtArray instance, false otherwise.
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
If this value holds a VtArray or VtArrayEdit instance, return the typeid of its element type.
VT_API bool CanComposeOver() const
Return true if this value holds a type that has been declared at compile time to support composing ov...
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.
VT_API VtValue & operator=(VtValueRef ref)
Assignment from VtValueRef.
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.
VT_API bool IsArrayEditValued() const
Return true if this holds a VtArrayEdit instance, false otherwise.
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 CanTransform() const
Return true if this value holds a type that has been declared to support value transforms at compile ...
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.
VT_API std::type_info const & GetTypeid() const
Return the typeid of the type held by this value.
A non-owning type-erased view of a value, interoperating with VtValue.
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.
A trait to detect instantiations of VtArray, specialized in array.h.
A trait indicating whether VtValue compose-over functionality can be registered for a type.
A file containing basic constants and definitions.