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"
38#include "pxr/base/tf/anyUniquePtr.h"
39#include "pxr/base/tf/pointerAndBits.h"
43#include "pxr/base/tf/type.h"
45#include "pxr/base/vt/api.h"
46#include "pxr/base/vt/hash.h"
47#include "pxr/base/vt/streamOut.h"
51#include <boost/intrusive_ptr.hpp>
57PXR_NAMESPACE_OPEN_SCOPE
63struct Vt_DefaultValueFactory;
67struct Vt_DefaultValueHolder
72 static Vt_DefaultValueHolder Create() {
73 return Vt_DefaultValueHolder(TfAnyUniquePtr::New<T>(),
typeid(T));
79 static Vt_DefaultValueHolder Create(T
const &val) {
80 return Vt_DefaultValueHolder(TfAnyUniquePtr::New(val),
typeid(T));
84 std::type_info
const &GetType()
const {
90 void const *GetPointer()
const {
95 Vt_DefaultValueHolder(
TfAnyUniquePtr &&ptr, std::type_info
const &type)
96 : _ptr(
std::move(ptr)), _type(&type) {}
99 std::type_info
const *_type;
106VT_API std::ostream &VtStreamOut(std::vector<VtValue>
const &val, std::ostream &);
108#define VT_VALUE_SET_STORED_TYPE(SRC, DST) \
109 template <> struct Vt_ValueStoredType<SRC> { typedef DST Type; }
111template <
class T>
struct Vt_ValueStoredType {
typedef T Type; };
112VT_VALUE_SET_STORED_TYPE(
char const *, std::string);
113VT_VALUE_SET_STORED_TYPE(
char *, std::string);
115#ifdef PXR_PYTHON_SUPPORT_ENABLED
119#undef VT_VALUE_SET_STORED_TYPE
123struct Vt_ValueGetStored
124 : Vt_ValueStoredType<std::decay_t<T>> {};
165 static const unsigned int _LocalFlag = 1 << 0;
166 static const unsigned int _TrivialCopyFlag = 1 << 1;
167 static const unsigned int _ProxyFlag = 1 << 2;
171 explicit _Counted(T
const &obj) : _obj(obj) {
174 bool IsUnique()
const {
return _refCount == 1; }
175 T
const &Get()
const {
return _obj; }
176 T &GetMutable() {
return _obj; }
180 mutable std::atomic<int> _refCount;
182 friend inline void intrusive_ptr_add_ref(_Counted
const *d) {
183 d->_refCount.fetch_add(1, std::memory_order_relaxed);
185 friend inline void intrusive_ptr_release(_Counted
const *d) {
186 if (d->_refCount.fetch_sub(1, std::memory_order_release) == 1) {
187 std::atomic_thread_fence(std::memory_order_acquire);
196 static const size_t _MaxLocalSize =
sizeof(
void*);
197 typedef std::aligned_storage<
198 _MaxLocalSize, _MaxLocalSize>::type _Storage;
201 using _IsTriviallyCopyable = std::integral_constant<bool,
202 std::is_trivially_default_constructible_v<T> &&
203 std::is_trivially_copyable_v<T> &&
204 std::is_trivially_copy_assignable_v<T> &&
205 std::is_trivially_destructible_v<T>>;
210 using _UsesLocalStore = std::integral_constant<bool,
211 (
sizeof(T) <=
sizeof(_Storage)) &&
212 VtValueTypeHasCheapCopy<T>::value &&
213 std::is_nothrow_move_constructible<T>::value &&
214 std::is_nothrow_move_assignable<T>::value>;
219 using _CopyInitFunc = void (*)(_Storage
const &, _Storage &);
220 using _DestroyFunc = void (*)(_Storage &);
221 using _MoveFunc = void (*)(_Storage &, _Storage &);
222 using _CanHashFunc = bool (*)(_Storage
const &);
223 using _HashFunc = size_t (*)(_Storage
const &);
224 using _EqualFunc = bool (*)(_Storage
const &, _Storage
const &);
225 using _EqualPtrFunc = bool (*)(_Storage
const &,
void const *);
226 using _MakeMutableFunc = void (*)(_Storage &);
228 using _StreamOutFunc =
229 std::ostream & (*)(_Storage
const &, std::ostream &);
230 using _GetTypeidFunc = std::type_info
const & (*)(_Storage
const &);
231 using _IsArrayValuedFunc = bool (*)(_Storage
const &);
232 using _GetElementTypeidFunc =
233 std::type_info
const & (*)(_Storage
const &);
234 using _GetShapeDataFunc =
const Vt_ShapeData* (*)(_Storage
const &);
235 using _GetNumElementsFunc = size_t (*)(_Storage
const &);
236 using _ProxyHoldsTypeFunc = bool (*)(_Storage
const &, std::type_info
const &);
237 using _GetProxiedTypeFunc =
TfType (*)(_Storage
const &);
238 using _GetProxiedTypeidFunc =
239 std::type_info
const & (*)(_Storage
const &);
240 using _GetProxiedObjPtrFunc =
void const *(*)(_Storage
const &);
241 using _GetProxiedAsVtValueFunc =
VtValue (*)(_Storage
const &);
244 constexpr _TypeInfo(
const std::type_info &ti,
245 const std::type_info &elementTi,
250 _CopyInitFunc copyInit,
251 _DestroyFunc destroy,
253 _CanHashFunc canHash,
256 _EqualPtrFunc equalPtr,
257 _MakeMutableFunc makeMutable,
258 _GetPyObjFunc getPyObj,
259 _StreamOutFunc streamOut,
260 _GetTypeidFunc getTypeid,
261 _IsArrayValuedFunc isArrayValued,
262 _GetElementTypeidFunc getElementTypeid,
263 _GetShapeDataFunc getShapeData,
264 _GetNumElementsFunc getNumElements,
265 _ProxyHoldsTypeFunc proxyHoldsType,
266 _GetProxiedTypeFunc getProxiedType,
267 _GetProxiedTypeidFunc getProxiedTypeid,
268 _GetProxiedObjPtrFunc getProxiedObjPtr,
269 _GetProxiedAsVtValueFunc getProxiedAsVtValue)
271 , elementTypeInfo(elementTi)
272 , knownTypeIndex(knownTypeIndex)
275 , isHashable(isHashable)
277 , _copyInit(copyInit)
283 , _equalPtr(equalPtr)
284 , _makeMutable(makeMutable)
285 , _getPyObj(getPyObj)
286 , _streamOut(streamOut)
287 , _getTypeid(getTypeid)
288 , _isArrayValued(isArrayValued)
289 , _getElementTypeid(getElementTypeid)
290 , _getShapeData(getShapeData)
291 , _getNumElements(getNumElements)
292 , _proxyHoldsType(proxyHoldsType)
293 , _getProxiedType(getProxiedType)
294 , _getProxiedTypeid(getProxiedTypeid)
295 , _getProxiedObjPtr(getProxiedObjPtr)
296 , _getProxiedAsVtValue(getProxiedAsVtValue)
300 void CopyInit(_Storage
const &src, _Storage &dst)
const {
303 void Destroy(_Storage &storage)
const {
306 void Move(_Storage &src, _Storage &dst)
const noexcept {
309 bool CanHash(_Storage
const &storage)
const {
310 return _canHash(storage);
312 size_t Hash(_Storage
const &storage)
const {
313 return _hash(storage);
315 bool Equal(_Storage
const &lhs, _Storage
const &rhs)
const {
316 return _equal(lhs, rhs);
318 bool EqualPtr(_Storage
const &lhs,
void const *rhs)
const {
319 return _equalPtr(lhs, rhs);
321 void MakeMutable(_Storage &storage)
const {
322 _makeMutable(storage);
325 return _getPyObj(storage);
327 std::ostream &StreamOut(_Storage
const &storage,
328 std::ostream &out)
const {
329 return _streamOut(storage, out);
332 return _isArrayValued(storage);
335 return _getElementTypeid(storage);
337 std::type_info
const &
GetTypeid(_Storage
const &storage)
const {
338 return _getTypeid(storage);
340 const Vt_ShapeData* GetShapeData(_Storage
const &storage)
const {
341 return _getShapeData(storage);
343 size_t GetNumElements(_Storage
const &storage)
const {
344 return _getNumElements(storage);
346 bool ProxyHoldsType(_Storage
const &storage,
347 std::type_info
const &t)
const {
348 return _proxyHoldsType(storage, t);
350 TfType GetProxiedType(_Storage
const &storage)
const {
351 return _getProxiedType(storage);
353 std::type_info
const &GetProxiedTypeid(_Storage
const &storage)
const {
354 return _getProxiedTypeid(storage);
356 VtValue GetProxiedAsVtValue(_Storage
const &storage)
const {
357 return _getProxiedAsVtValue(storage);
359 void const *GetProxiedObjPtr(_Storage
const &storage)
const {
360 return _getProxiedObjPtr(storage);
363 const std::type_info &typeInfo;
364 const std::type_info &elementTypeInfo;
371 _CopyInitFunc _copyInit;
372 _DestroyFunc _destroy;
374 _CanHashFunc _canHash;
377 _EqualPtrFunc _equalPtr;
378 _MakeMutableFunc _makeMutable;
379 _GetPyObjFunc _getPyObj;
380 _StreamOutFunc _streamOut;
381 _GetTypeidFunc _getTypeid;
382 _IsArrayValuedFunc _isArrayValued;
383 _GetElementTypeidFunc _getElementTypeid;
384 _GetShapeDataFunc _getShapeData;
385 _GetNumElementsFunc _getNumElements;
386 _ProxyHoldsTypeFunc _proxyHoldsType;
387 _GetProxiedTypeFunc _getProxiedType;
388 _GetProxiedTypeidFunc _getProxiedTypeid;
389 _GetProxiedObjPtrFunc _getProxiedObjPtr;
390 _GetProxiedAsVtValueFunc _getProxiedAsVtValue;
396 template <
class T,
class Enable=
void>
399 static const Vt_ShapeData* GetShapeData(T
const &) {
return NULL; }
400 static size_t GetNumElements(T
const &) {
return 0; }
401 constexpr static std::type_info
const &GetElementTypeid() {
405 template <
class Array>
407 Array, typename
std::enable_if<VtIsArray<Array>::value>::type>
409 static const Vt_ShapeData* GetShapeData(Array
const &obj) {
410 return obj._GetShapeData();
412 static size_t GetNumElements(Array
const &obj) {
415 constexpr static std::type_info
const &GetElementTypeid() {
416 return typeid(
typename Array::ElementType);
423 _TypedProxyEqualityImpl(T
const &a, T
const &b,
int) ->
decltype(a == b) {
427 template <
class NoEqual>
429 _TypedProxyEqualityImpl(NoEqual
const &a, NoEqual
const &b,
long) {
430 return VtGetProxiedObject(a) == VtGetProxiedObject(b);
435 _ErasedProxyEqualityImpl(T
const &a, T
const &b,
int) ->
decltype(a == b) {
439 template <
class NoEqual>
441 _ErasedProxyEqualityImpl(NoEqual
const &a, NoEqual
const &b,
long) {
442 return *VtGetErasedProxiedVtValue(a) == *VtGetErasedProxiedVtValue(b);
446 template <
class T,
class Enable =
void>
449 using ProxiedType =
typename VtGetProxiedType<T>::type;
451 static bool CanHash(T
const &) {
return VtIsHashable<ProxiedType>(); }
452 static size_t Hash(T
const &obj) {
453 return VtHashValue(VtGetProxiedObject(obj));
455 static bool Equal(T
const &a, T
const &b) {
460 return _TypedProxyEqualityImpl(a, b, 0);
463#ifdef PXR_PYTHON_SUPPORT_ENABLED
464 ProxiedType
const &p = VtGetProxiedObject(obj);
466 return boost::python::api::object(p);
471 static std::ostream &StreamOut(T
const &obj, std::ostream &out) {
472 return VtStreamOut(VtGetProxiedObject(obj), out);
474 static Vt_ShapeData
const *GetShapeData(T
const &obj) {
475 return _ArrayHelper<ProxiedType>::GetShapeData(
476 VtGetProxiedObject(obj));
478 static size_t GetNumElements(T
const &obj) {
479 return _ArrayHelper<ProxiedType>::GetNumElements(
480 VtGetProxiedObject(obj));
485 static std::type_info
const &
GetTypeid(T
const &) {
486 return typeid(ProxiedType);
489 return _ArrayHelper<ProxiedType>::GetElementTypeid();
491 static VtValue GetProxiedAsVtValue(T
const &obj) {
492 return VtValue(VtGetProxiedObject(obj));
494 static bool HoldsType(T
const &tp, std::type_info
const &query) {
497 static TfType GetTfType(T
const &tp) {
498 return TfType::Find<ProxiedType>();
500 static void const *GetObjPtr(T
const &tp) {
501 return static_cast<void const *
>(&VtGetProxiedObject(tp));
505 template <
class ErasedProxy>
507 ErasedProxy, typename
std::enable_if<
508 VtIsErasedValueProxy<ErasedProxy>::value>::type>
510 static bool CanHash(ErasedProxy
const &proxy) {
511 return VtGetErasedProxiedVtValue(proxy)->CanHash();
513 static size_t Hash(ErasedProxy
const &proxy) {
514 return VtGetErasedProxiedVtValue(proxy)->GetHash();
516 static bool Equal(ErasedProxy
const &a, ErasedProxy
const &b) {
521 return _ErasedProxyEqualityImpl(a, b, 0);
524#ifdef PXR_PYTHON_SUPPORT_ENABLED
525 VtValue const *val = VtGetErasedProxiedVtValue(obj);
527 return boost::python::api::object(*val);
532 static std::ostream &
533 StreamOut(ErasedProxy
const &obj, std::ostream &out) {
534 return VtStreamOut(obj, out);
536 static Vt_ShapeData
const *GetShapeData(ErasedProxy
const &obj) {
537 return VtGetErasedProxiedVtValue(obj)->_GetShapeData();
539 static size_t GetNumElements(ErasedProxy
const &obj) {
540 return VtGetErasedProxiedVtValue(obj)->_GetNumElements();
543 return VtGetErasedProxiedVtValue(obj)->IsArrayValued();
545 static std::type_info
const &
GetTypeid(ErasedProxy
const &obj) {
546 return VtGetErasedProxiedVtValue(obj)->GetTypeid();
549 return VtGetErasedProxiedVtValue(obj)->GetElementTypeid();
551 static VtValue GetProxiedAsVtValue(ErasedProxy
const &ep) {
552 return *VtGetErasedProxiedVtValue(ep);
555 HoldsType(ErasedProxy
const &ep, std::type_info
const &query) {
556 return VtErasedProxyHoldsType(ep, query);
558 static TfType GetTfType(ErasedProxy
const &ep) {
559 return VtGetErasedProxiedTfType(ep);
561 static void const *GetObjPtr(ErasedProxy
const &ep) {
562 VtValue const *val = VtGetErasedProxiedVtValue(ep);
563 return val ? val->_GetProxiedObjPtr() :
nullptr;
570 template <
class T,
class Container,
class Derived>
571 struct _TypeInfoImpl :
public _TypeInfo
573 static const bool IsLocal = _UsesLocalStore<T>::value;
574 static const bool HasTrivialCopy = _IsTriviallyCopyable<T>::value;
575 static const bool IsProxy = VtIsValueProxy<T>::value;
577 using ProxyHelper = _ProxyHelper<T>;
579 using This = _TypeInfoImpl;
581 constexpr _TypeInfoImpl()
582 : _TypeInfo(
typeid(T),
583 _ArrayHelper<T>::GetElementTypeid(),
584 Vt_KnownValueTypeDetail::GetIndex<T>(),
602 &This::_IsArrayValued,
603 &This::_GetElementTypeid,
604 &This::_GetShapeData,
605 &This::_GetNumElements,
608 &This::_ProxyHoldsType,
609 &This::_GetProxiedType,
610 &This::_GetProxiedTypeid,
611 &This::_GetProxiedObjPtr,
612 &This::_GetProxiedAsVtValue)
617 static T
const &GetObj(_Storage
const &storage) {
618 return Derived::_GetObj(_Container(storage));
621 static T &GetMutableObj(_Storage &storage) {
622 return Derived::_GetMutableObj(_Container(storage));
625 static void CopyInitObj(T
const &objSrc, _Storage &dst) {
626 Derived::_PlaceCopy(&_Container(dst), objSrc);
630 static_assert(
sizeof(Container) <=
sizeof(_Storage),
631 "Container size cannot exceed storage size.");
635 static void _CopyInit(_Storage
const &src, _Storage &dst) {
636 new (&_Container(dst)) Container(_Container(src));
639 static void _Destroy(_Storage &storage) {
640 _Container(storage).~Container();
643 static bool _CanHash(_Storage
const &storage) {
644 return ProxyHelper::CanHash(GetObj(storage));
647 static size_t _Hash(_Storage
const &storage) {
648 return ProxyHelper::Hash(GetObj(storage));
651 static bool _Equal(_Storage
const &lhs, _Storage
const &rhs) {
655 return ProxyHelper::Equal(GetObj(lhs), GetObj(rhs));
658 static bool _EqualPtr(_Storage
const &lhs,
void const *rhs) {
662 return ProxyHelper::Equal(
663 GetObj(lhs), *
static_cast<T
const *
>(rhs));
666 static void _Move(_Storage &src, _Storage &dst)
noexcept {
667 new (&_Container(dst)) Container(std::move(_Container(src)));
671 static void _MakeMutable(_Storage &storage) {
672 GetMutableObj(storage);
676 return ProxyHelper::GetPyObj(GetObj(storage));
679 static std::ostream &_StreamOut(
680 _Storage
const &storage, std::ostream &out) {
681 return ProxyHelper::StreamOut(GetObj(storage), out);
684 static std::type_info
const &_GetTypeid(_Storage
const &storage) {
685 return ProxyHelper::GetTypeid(GetObj(storage));
688 static bool _IsArrayValued(_Storage
const &storage) {
689 return ProxyHelper::IsArrayValued(GetObj(storage));
692 static std::type_info
const &
693 _GetElementTypeid(_Storage
const &storage) {
694 return ProxyHelper::GetElementTypeid(GetObj(storage));
697 static const Vt_ShapeData* _GetShapeData(_Storage
const &storage) {
698 return ProxyHelper::GetShapeData(GetObj(storage));
701 static size_t _GetNumElements(_Storage
const &storage) {
702 return ProxyHelper::GetNumElements(GetObj(storage));
706 _ProxyHoldsType(_Storage
const &storage, std::type_info
const &t) {
707 return ProxyHelper::HoldsType(GetObj(storage), t);
711 _GetProxiedType(_Storage
const &storage) {
712 return ProxyHelper::GetTfType(GetObj(storage));
715 static std::type_info
const &
716 _GetProxiedTypeid(_Storage
const &storage) {
717 return ProxyHelper::GetTypeid(GetObj(storage));
721 _GetProxiedObjPtr(_Storage
const &storage) {
722 return ProxyHelper::GetObjPtr(GetObj(storage));
726 _GetProxiedAsVtValue(_Storage
const &storage) {
727 return ProxyHelper::GetProxiedAsVtValue(GetObj(storage));
733 static Container &_Container(_Storage &storage) {
735 return *
reinterpret_cast<Container *
>(&storage);
737 static Container
const &_Container(_Storage
const &storage) {
739 return *
reinterpret_cast<Container
const *
>(&storage);
747 struct _LocalTypeInfo : _TypeInfoImpl<
753 constexpr _LocalTypeInfo()
754 : _TypeInfoImpl<T, T, _LocalTypeInfo<T>>()
758 static T &_GetMutableObj(T &obj) {
return obj; }
759 static T
const &_GetObj(T
const &obj) {
return obj; }
761 static void _PlaceCopy(T *dst, T
const &src) {
new (dst) T(src); }
768 struct _RemoteTypeInfo : _TypeInfoImpl<
770 boost::intrusive_ptr<_Counted<T> >,
774 constexpr _RemoteTypeInfo()
776 T, boost::intrusive_ptr<_Counted<T>>, _RemoteTypeInfo<T>>()
779 typedef boost::intrusive_ptr<_Counted<T> > Ptr;
781 static T &_GetMutableObj(Ptr &ptr) {
782 if (!ptr->IsUnique())
783 ptr.reset(
new _Counted<T>(ptr->Get()));
784 return ptr->GetMutable();
786 static T
const &_GetObj(Ptr
const &ptr) {
return ptr->Get(); }
788 static void _PlaceCopy(Ptr *dst, T
const &src) {
789 new (dst) Ptr(
new _Counted<T>(src));
795 struct _TypeInfoFor {
797 typedef std::conditional_t<_UsesLocalStore<T>::value,
799 _RemoteTypeInfo<T>> Type;
804 struct _TypeInfoFor<char[N]> : _TypeInfoFor<std::string> {};
810 typedef typename _TypeInfoFor<T>::Type TI;
812 static constexpr unsigned int flags =
813 (TI::IsLocal ? _LocalFlag : 0) |
814 (TI::HasTrivialCopy ? _TrivialCopyFlag : 0) |
815 (TI::IsProxy ? _ProxyFlag : 0);
825 friend struct _HoldAside;
827 explicit _HoldAside(
VtValue *val)
828 : info((val->
IsEmpty() || val->_IsLocalAndTriviallyCopyable())
829 ?
static_cast<_TypeInfo
const *
>(NULL) : val->_info.
Get()) {
831 info->Move(val->_storage, storage);
835 info->Destroy(storage);
838 _TypeInfo
const *info;
843 std::is_same<T, typename Vt_ValueGetStored<T>::Type>::value>
844 _Init(T
const &obj) {
845 _info = GetTypeInfo<T>();
846 typedef typename _TypeInfoFor<T>::Type TypeInfo;
847 TypeInfo::CopyInitObj(obj, _storage);
852 !std::is_same<T, typename Vt_ValueGetStored<T>::Type>::value>
853 _Init(T
const &obj) {
854 _Init(
typename Vt_ValueGetStored<T>::Type(obj));
913 if (ARCH_LIKELY(
this != &other))
920 if (ARCH_LIKELY(
this != &other))
929 _TypeInfoFor<T>::Type::IsLocal &&
930 _TypeInfoFor<T>::Type::HasTrivialCopy,
947 !_TypeInfoFor<T>::Type::IsLocal ||
948 !_TypeInfoFor<T>::Type::HasTrivialCopy,
951 _HoldAside tmp(
this);
959 std::string tmp(cstr);
967 return *
this =
const_cast<char const *
>(cstr);
973 if (!
IsEmpty() || !rhs.IsEmpty()) {
996 std::is_same<T, typename Vt_ValueGetStored<T>::Type>::value>
1015 std::is_same<T, typename Vt_ValueGetStored<T>::Type>::value>
1018 swap(_GetMutable<T>(), rhs);
1050 template <
class T,
class Fn>
1052 std::is_same<T, typename Vt_ValueGetStored<T>::Type>::value,
bool>
1054 if (!IsHolding<T>()) {
1057 UncheckedMutate<T>(std::forward<Fn>(mutateFn));
1064 template <
class T,
class Fn>
1066 std::is_same<T, typename Vt_ValueGetStored<T>::Type>::value>
1071 T &stored =_GetMutable<T>();
1072 T tmp = std::move(stored);
1073 std::forward<Fn>(mutateFn)(tmp);
1074 stored = std::move(tmp);
1109 if (ARCH_UNLIKELY(_IsProxy())) {
1110 return _info->GetProxiedAsVtValue(
1111 _storage).GetKnownValueTypeIndex();
1113 return _info.
GetLiteral() ? _info->knownTypeIndex : -1;
1137 typedef Vt_DefaultValueFactory<T> Factory;
1141 if (ARCH_UNLIKELY(!IsHolding<T>())) {
1142 return *(
static_cast<T
const *
>(
1143 _FailGet(Factory::Invoke,
typeid(T))));
1153 typedef Vt_DefaultValueFactory<T> Factory;
1157 if (ARCH_UNLIKELY(!IsHolding<T>())) {
1158 return *(
static_cast<T
const *
>(
1159 _FailGet(Factory::Invoke,
typeid(T))));
1162 return UncheckedRemove<T>();
1171 return IsHolding<T>() ? UncheckedGet<T>() : def;
1175 template <
typename From,
typename To>
1177 _RegisterCast(
typeid(From),
typeid(To), castFn);
1182 template <
typename From,
typename To>
1184 _RegisterCast(
typeid(From),
typeid(To), _SimpleCast<From, To>);
1189 template <
typename From,
typename To>
1191 RegisterSimpleCast<From, To>();
1192 RegisterSimpleCast<To, From>();
1202 template <
typename T>
1205 return ret.
Cast<T>();
1232 std::type_info
const &to) {
1233 return _CanCast(from, to);
1243 template <
typename T>
1247 return *
this = _PerformCast(
typeid(T), *
this);
1270 *
this = _PerformCast(type, *
this);
1278 template <
typename T>
1280 return _CanCast(
GetTypeid(),
typeid(T));
1306 friend inline size_t hash_value(
VtValue const &val) {
1311 template <
typename T>
1313 typedef typename Vt_ValueGetStored<T>::Type Stored;
1316 template <
typename T>
1322 template <
typename T>
1324 return !(lhs == rhs);
1326 template <
typename T>
1328 return !(lhs == rhs);
1334 if (empty || rhsEmpty) {
1336 return empty == rhsEmpty;
1340 return _info.
Get()->Equal(_storage, rhs._storage);
1342 return _EqualityImpl(rhs);
1347 VT_API
friend std::ostream &
1351 VT_API
const Vt_ShapeData* _GetShapeData()
const;
1352 VT_API
size_t _GetNumElements()
const;
1353 friend struct Vt_ValueShapeDataAccess;
1361 _HoldAside tmp(&dst);
1362 dst._info = src._info;
1363 if (src._IsLocalAndTriviallyCopyable()) {
1364 dst._storage = src._storage;
1366 dst._info->CopyInit(src._storage, dst._storage);
1376 _HoldAside tmp(&dst);
1377 dst._info = src._info;
1378 if (src._IsLocalAndTriviallyCopyable()) {
1379 dst._storage = src._storage;
1381 dst._info->Move(src._storage, dst._storage);
1384 src._info.
Set(
nullptr, 0);
1388 inline std::enable_if_t<VtIsKnownValueType_Workaround<T>::value,
bool>
1390 return _info->knownTypeIndex == VtGetKnownValueTypeIndex<T>() ||
1391 ARCH_UNLIKELY(_IsProxy() && _TypeIsImpl(
typeid(T)));
1395 inline std::enable_if_t<!VtIsKnownValueType_Workaround<T>::value,
bool>
1397 std::type_info
const &t =
typeid(T);
1399 ARCH_UNLIKELY(_IsProxy() && _TypeIsImpl(t));
1402 VT_API
bool _TypeIsImpl(std::type_info
const &queriedType)
const;
1404 VT_API
bool _EqualityImpl(
VtValue const &rhs)
const;
1406 template <
class Proxy>
1407 std::enable_if_t<VtIsValueProxy<Proxy>::value, Proxy &>
1409 typedef typename _TypeInfoFor<Proxy>::Type TypeInfo;
1410 return TypeInfo::GetMutableObj(_storage);
1414 std::enable_if_t<!VtIsValueProxy<T>::value, T &>
1417 if (ARCH_UNLIKELY(_IsProxy())) {
1418 *
this = _info->GetProxiedAsVtValue(_storage);
1420 typedef typename _TypeInfoFor<T>::Type TypeInfo;
1421 return TypeInfo::GetMutableObj(_storage);
1424 template <
class Proxy>
1425 std::enable_if_t<VtIsValueProxy<Proxy>::value, Proxy
const &>
1427 typedef typename _TypeInfoFor<Proxy>::Type TypeInfo;
1428 return TypeInfo::GetObj(_storage);
1432 std::enable_if_t<!VtIsValueProxy<T>::value, T
const &>
1434 typedef typename _TypeInfoFor<T>::Type TypeInfo;
1435 if (ARCH_UNLIKELY(_IsProxy())) {
1436 return *
static_cast<T
const *
>(_GetProxiedObjPtr());
1438 return TypeInfo::GetObj(_storage);
1441 void const *_GetProxiedObjPtr()
const {
1442 return _info->GetProxiedObjPtr(_storage);
1448 _FailGet(Vt_DefaultValueHolder (*factory)(),
1449 std::type_info
const &queryType)
const;
1451 inline void _Clear() {
1455ARCH_PRAGMA_MAYBE_UNINITIALIZED
1456 if (_info.
GetLiteral() && !_IsLocalAndTriviallyCopyable())
1457 _info.
Get()->Destroy(_storage);
1459 _info.
Set(
nullptr, 0);
1462 inline bool _IsLocalAndTriviallyCopyable()
const {
1463 unsigned int bits = _info.
BitsAs<
unsigned int>();
1464 return (bits & (_LocalFlag | _TrivialCopyFlag)) ==
1465 (_LocalFlag | _TrivialCopyFlag);
1468 inline bool _IsProxy()
const {
1469 return _info.
BitsAs<
unsigned int>() & _ProxyFlag;
1472 VT_API
static void _RegisterCast(std::type_info
const &from,
1473 std::type_info
const &to,
1479 _PerformCast(std::type_info
const &to,
VtValue const &val);
1484 _CanCast(std::type_info
const &from, std::type_info
const &to);
1487 template <
typename From,
typename To>
1497 Vt_GetPythonObjectFromHeldValue(
VtValue const &self);
1507struct Vt_ValueShapeDataAccess {
1508 static const Vt_ShapeData* _GetShapeData(
const VtValue& value) {
1509 return value._GetShapeData();
1512 static size_t _GetNumElements(
const VtValue& value) {
1513 return value._GetNumElements();
1521struct Vt_DefaultValueFactory {
1522 static Vt_DefaultValueHolder Invoke();
1526inline Vt_DefaultValueHolder
1527Vt_DefaultValueFactory<T>::Invoke() {
1528 return Vt_DefaultValueHolder::Create<T>();
1539#define _VT_DECLARE_ZERO_VALUE_FACTORY(r, unused, elem) \
1541VT_API Vt_DefaultValueHolder Vt_DefaultValueFactory<VT_TYPE(elem)>::Invoke();
1543BOOST_PP_SEQ_FOR_EACH(_VT_DECLARE_ZERO_VALUE_FACTORY,
1546 VT_MATRIX_VALUE_TYPES
1547 VT_QUATERNION_VALUE_TYPES
1548 VT_DUALQUATERNION_VALUE_TYPES)
1550#undef _VT_DECLARE_ZERO_VALUE_FACTORY
1559VtValue::Get<VtValue>() const & {
1565VtValue::Get<VtValue>() && {
1566 return std::move(*
this);
1571VtValue::UncheckedGet<VtValue>() const & {
1577VtValue::UncheckedGet<VtValue>() && {
1578 return std::move(*
this);
1583VtValue::IsHolding<VtValue>()
const {
1590VtValue::IsHolding<void>()
const {
1598PXR_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,...
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.
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.
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.