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>
52#include <boost/type_traits/has_trivial_assign.hpp>
53#include <boost/type_traits/has_trivial_constructor.hpp>
54#include <boost/type_traits/has_trivial_copy.hpp>
55#include <boost/type_traits/has_trivial_destructor.hpp>
61PXR_NAMESPACE_OPEN_SCOPE
67struct Vt_DefaultValueFactory;
71struct Vt_DefaultValueHolder
76 static Vt_DefaultValueHolder Create() {
77 return Vt_DefaultValueHolder(TfAnyUniquePtr::New<T>(),
typeid(T));
83 static Vt_DefaultValueHolder Create(T
const &val) {
84 return Vt_DefaultValueHolder(TfAnyUniquePtr::New(val),
typeid(T));
88 std::type_info
const &GetType()
const {
94 void const *GetPointer()
const {
99 Vt_DefaultValueHolder(
TfAnyUniquePtr &&ptr, std::type_info
const &type)
100 : _ptr(
std::move(ptr)), _type(&type) {}
103 std::type_info
const *_type;
110VT_API std::ostream &VtStreamOut(std::vector<VtValue>
const &val, std::ostream &);
112#define VT_VALUE_SET_STORED_TYPE(SRC, DST) \
113 template <> struct Vt_ValueStoredType<SRC> { typedef DST Type; }
115template <
class T>
struct Vt_ValueStoredType {
typedef T Type; };
116VT_VALUE_SET_STORED_TYPE(
char const *, std::string);
117VT_VALUE_SET_STORED_TYPE(
char *, std::string);
119#ifdef PXR_PYTHON_SUPPORT_ENABLED
123#undef VT_VALUE_SET_STORED_TYPE
127struct Vt_ValueGetStored
128 : Vt_ValueStoredType<std::decay_t<T>> {};
169 static const unsigned int _LocalFlag = 1 << 0;
170 static const unsigned int _TrivialCopyFlag = 1 << 1;
171 static const unsigned int _ProxyFlag = 1 << 2;
175 explicit _Counted(T
const &obj) : _obj(obj) {
178 bool IsUnique()
const {
return _refCount == 1; }
179 T
const &Get()
const {
return _obj; }
180 T &GetMutable() {
return _obj; }
184 mutable std::atomic<int> _refCount;
186 friend inline void intrusive_ptr_add_ref(_Counted
const *d) {
187 d->_refCount.fetch_add(1, std::memory_order_relaxed);
189 friend inline void intrusive_ptr_release(_Counted
const *d) {
190 if (d->_refCount.fetch_sub(1, std::memory_order_release) == 1) {
191 std::atomic_thread_fence(std::memory_order_acquire);
200 static const size_t _MaxLocalSize =
sizeof(
void*);
201 typedef std::aligned_storage<
202 _MaxLocalSize, _MaxLocalSize>::type _Storage;
205 using _IsTriviallyCopyable = std::integral_constant<bool,
206 boost::has_trivial_constructor<T>::value &&
207 boost::has_trivial_copy<T>::value &&
208 boost::has_trivial_assign<T>::value &&
209 boost::has_trivial_destructor<T>::value>;
214 using _UsesLocalStore = std::integral_constant<bool,
215 (
sizeof(T) <=
sizeof(_Storage)) &&
216 VtValueTypeHasCheapCopy<T>::value &&
217 std::is_nothrow_move_constructible<T>::value &&
218 std::is_nothrow_move_assignable<T>::value>;
223 using _CopyInitFunc = void (*)(_Storage
const &, _Storage &);
224 using _DestroyFunc = void (*)(_Storage &);
225 using _MoveFunc = void (*)(_Storage &, _Storage &);
226 using _CanHashFunc = bool (*)(_Storage
const &);
227 using _HashFunc = size_t (*)(_Storage
const &);
228 using _EqualFunc = bool (*)(_Storage
const &, _Storage
const &);
229 using _EqualPtrFunc = bool (*)(_Storage
const &,
void const *);
230 using _MakeMutableFunc = void (*)(_Storage &);
232 using _StreamOutFunc =
233 std::ostream & (*)(_Storage
const &, std::ostream &);
234 using _GetTypeidFunc = std::type_info
const & (*)(_Storage
const &);
235 using _IsArrayValuedFunc = bool (*)(_Storage
const &);
236 using _GetElementTypeidFunc =
237 std::type_info
const & (*)(_Storage
const &);
238 using _GetShapeDataFunc =
const Vt_ShapeData* (*)(_Storage
const &);
239 using _GetNumElementsFunc = size_t (*)(_Storage
const &);
240 using _ProxyHoldsTypeFunc = bool (*)(_Storage
const &, std::type_info
const &);
241 using _GetProxiedTypeFunc =
TfType (*)(_Storage
const &);
242 using _GetProxiedTypeidFunc =
243 std::type_info
const & (*)(_Storage
const &);
244 using _GetProxiedObjPtrFunc =
void const *(*)(_Storage
const &);
245 using _GetProxiedAsVtValueFunc =
VtValue (*)(_Storage
const &);
248 constexpr _TypeInfo(
const std::type_info &ti,
249 const std::type_info &elementTi,
254 _CopyInitFunc copyInit,
255 _DestroyFunc destroy,
257 _CanHashFunc canHash,
260 _EqualPtrFunc equalPtr,
261 _MakeMutableFunc makeMutable,
262 _GetPyObjFunc getPyObj,
263 _StreamOutFunc streamOut,
264 _GetTypeidFunc getTypeid,
265 _IsArrayValuedFunc isArrayValued,
266 _GetElementTypeidFunc getElementTypeid,
267 _GetShapeDataFunc getShapeData,
268 _GetNumElementsFunc getNumElements,
269 _ProxyHoldsTypeFunc proxyHoldsType,
270 _GetProxiedTypeFunc getProxiedType,
271 _GetProxiedTypeidFunc getProxiedTypeid,
272 _GetProxiedObjPtrFunc getProxiedObjPtr,
273 _GetProxiedAsVtValueFunc getProxiedAsVtValue)
275 , elementTypeInfo(elementTi)
276 , knownTypeIndex(knownTypeIndex)
279 , isHashable(isHashable)
281 , _copyInit(copyInit)
287 , _equalPtr(equalPtr)
288 , _makeMutable(makeMutable)
289 , _getPyObj(getPyObj)
290 , _streamOut(streamOut)
291 , _getTypeid(getTypeid)
292 , _isArrayValued(isArrayValued)
293 , _getElementTypeid(getElementTypeid)
294 , _getShapeData(getShapeData)
295 , _getNumElements(getNumElements)
296 , _proxyHoldsType(proxyHoldsType)
297 , _getProxiedType(getProxiedType)
298 , _getProxiedTypeid(getProxiedTypeid)
299 , _getProxiedObjPtr(getProxiedObjPtr)
300 , _getProxiedAsVtValue(getProxiedAsVtValue)
304 void CopyInit(_Storage
const &src, _Storage &dst)
const {
307 void Destroy(_Storage &storage)
const {
310 void Move(_Storage &src, _Storage &dst)
const noexcept {
313 bool CanHash(_Storage
const &storage)
const {
314 return _canHash(storage);
316 size_t Hash(_Storage
const &storage)
const {
317 return _hash(storage);
319 bool Equal(_Storage
const &lhs, _Storage
const &rhs)
const {
320 return _equal(lhs, rhs);
322 bool EqualPtr(_Storage
const &lhs,
void const *rhs)
const {
323 return _equalPtr(lhs, rhs);
325 void MakeMutable(_Storage &storage)
const {
326 _makeMutable(storage);
329 return _getPyObj(storage);
331 std::ostream &StreamOut(_Storage
const &storage,
332 std::ostream &out)
const {
333 return _streamOut(storage, out);
336 return _isArrayValued(storage);
339 return _getElementTypeid(storage);
341 std::type_info
const &
GetTypeid(_Storage
const &storage)
const {
342 return _getTypeid(storage);
344 const Vt_ShapeData* GetShapeData(_Storage
const &storage)
const {
345 return _getShapeData(storage);
347 size_t GetNumElements(_Storage
const &storage)
const {
348 return _getNumElements(storage);
350 bool ProxyHoldsType(_Storage
const &storage,
351 std::type_info
const &t)
const {
352 return _proxyHoldsType(storage, t);
354 TfType GetProxiedType(_Storage
const &storage)
const {
355 return _getProxiedType(storage);
357 std::type_info
const &GetProxiedTypeid(_Storage
const &storage)
const {
358 return _getProxiedTypeid(storage);
360 VtValue GetProxiedAsVtValue(_Storage
const &storage)
const {
361 return _getProxiedAsVtValue(storage);
363 void const *GetProxiedObjPtr(_Storage
const &storage)
const {
364 return _getProxiedObjPtr(storage);
367 const std::type_info &typeInfo;
368 const std::type_info &elementTypeInfo;
375 _CopyInitFunc _copyInit;
376 _DestroyFunc _destroy;
378 _CanHashFunc _canHash;
381 _EqualPtrFunc _equalPtr;
382 _MakeMutableFunc _makeMutable;
383 _GetPyObjFunc _getPyObj;
384 _StreamOutFunc _streamOut;
385 _GetTypeidFunc _getTypeid;
386 _IsArrayValuedFunc _isArrayValued;
387 _GetElementTypeidFunc _getElementTypeid;
388 _GetShapeDataFunc _getShapeData;
389 _GetNumElementsFunc _getNumElements;
390 _ProxyHoldsTypeFunc _proxyHoldsType;
391 _GetProxiedTypeFunc _getProxiedType;
392 _GetProxiedTypeidFunc _getProxiedTypeid;
393 _GetProxiedObjPtrFunc _getProxiedObjPtr;
394 _GetProxiedAsVtValueFunc _getProxiedAsVtValue;
400 template <
class T,
class Enable=
void>
403 static const Vt_ShapeData* GetShapeData(T
const &) {
return NULL; }
404 static size_t GetNumElements(T
const &) {
return 0; }
405 constexpr static std::type_info
const &GetElementTypeid() {
409 template <
class Array>
411 Array, typename
std::enable_if<VtIsArray<Array>::value>::type>
413 static const Vt_ShapeData* GetShapeData(Array
const &obj) {
414 return obj._GetShapeData();
416 static size_t GetNumElements(Array
const &obj) {
419 constexpr static std::type_info
const &GetElementTypeid() {
420 return typeid(
typename Array::ElementType);
427 _TypedProxyEqualityImpl(T
const &a, T
const &b,
int) ->
decltype(a == b) {
431 template <
class NoEqual>
433 _TypedProxyEqualityImpl(NoEqual
const &a, NoEqual
const &b,
long) {
434 return VtGetProxiedObject(a) == VtGetProxiedObject(b);
439 _ErasedProxyEqualityImpl(T
const &a, T
const &b,
int) ->
decltype(a == b) {
443 template <
class NoEqual>
445 _ErasedProxyEqualityImpl(NoEqual
const &a, NoEqual
const &b,
long) {
446 return *VtGetErasedProxiedVtValue(a) == *VtGetErasedProxiedVtValue(b);
450 template <
class T,
class Enable =
void>
453 using ProxiedType =
typename VtGetProxiedType<T>::type;
455 static bool CanHash(T
const &) {
return VtIsHashable<ProxiedType>(); }
456 static size_t Hash(T
const &obj) {
457 return VtHashValue(VtGetProxiedObject(obj));
459 static bool Equal(T
const &a, T
const &b) {
464 return _TypedProxyEqualityImpl(a, b, 0);
467#ifdef PXR_PYTHON_SUPPORT_ENABLED
468 ProxiedType
const &p = VtGetProxiedObject(obj);
470 return boost::python::api::object(p);
475 static std::ostream &StreamOut(T
const &obj, std::ostream &out) {
476 return VtStreamOut(VtGetProxiedObject(obj), out);
478 static Vt_ShapeData
const *GetShapeData(T
const &obj) {
479 return _ArrayHelper<ProxiedType>::GetShapeData(
480 VtGetProxiedObject(obj));
482 static size_t GetNumElements(T
const &obj) {
483 return _ArrayHelper<ProxiedType>::GetNumElements(
484 VtGetProxiedObject(obj));
489 static std::type_info
const &
GetTypeid(T
const &) {
490 return typeid(ProxiedType);
493 return _ArrayHelper<ProxiedType>::GetElementTypeid();
495 static VtValue GetProxiedAsVtValue(T
const &obj) {
496 return VtValue(VtGetProxiedObject(obj));
498 static bool HoldsType(T
const &tp, std::type_info
const &query) {
501 static TfType GetTfType(T
const &tp) {
502 return TfType::Find<ProxiedType>();
504 static void const *GetObjPtr(T
const &tp) {
505 return static_cast<void const *
>(&VtGetProxiedObject(tp));
509 template <
class ErasedProxy>
511 ErasedProxy, typename
std::enable_if<
512 VtIsErasedValueProxy<ErasedProxy>::value>::type>
514 static bool CanHash(ErasedProxy
const &proxy) {
515 return VtGetErasedProxiedVtValue(proxy)->CanHash();
517 static size_t Hash(ErasedProxy
const &proxy) {
518 return VtGetErasedProxiedVtValue(proxy)->GetHash();
520 static bool Equal(ErasedProxy
const &a, ErasedProxy
const &b) {
525 return _ErasedProxyEqualityImpl(a, b, 0);
528#ifdef PXR_PYTHON_SUPPORT_ENABLED
529 VtValue const *val = VtGetErasedProxiedVtValue(obj);
531 return boost::python::api::object(*val);
536 static std::ostream &
537 StreamOut(ErasedProxy
const &obj, std::ostream &out) {
538 return VtStreamOut(obj, out);
540 static Vt_ShapeData
const *GetShapeData(ErasedProxy
const &obj) {
541 return VtGetErasedProxiedVtValue(obj)->_GetShapeData();
543 static size_t GetNumElements(ErasedProxy
const &obj) {
544 return VtGetErasedProxiedVtValue(obj)->_GetNumElements();
547 return VtGetErasedProxiedVtValue(obj)->IsArrayValued();
549 static std::type_info
const &
GetTypeid(ErasedProxy
const &obj) {
550 return VtGetErasedProxiedVtValue(obj)->GetTypeid();
553 return VtGetErasedProxiedVtValue(obj)->GetElementTypeid();
555 static VtValue GetProxiedAsVtValue(ErasedProxy
const &ep) {
556 return *VtGetErasedProxiedVtValue(ep);
559 HoldsType(ErasedProxy
const &ep, std::type_info
const &query) {
560 return VtErasedProxyHoldsType(ep, query);
562 static TfType GetTfType(ErasedProxy
const &ep) {
563 return VtGetErasedProxiedTfType(ep);
565 static void const *GetObjPtr(ErasedProxy
const &ep) {
566 VtValue const *val = VtGetErasedProxiedVtValue(ep);
567 return val ? val->_GetProxiedObjPtr() :
nullptr;
574 template <
class T,
class Container,
class Derived>
575 struct _TypeInfoImpl :
public _TypeInfo
577 static const bool IsLocal = _UsesLocalStore<T>::value;
578 static const bool HasTrivialCopy = _IsTriviallyCopyable<T>::value;
579 static const bool IsProxy = VtIsValueProxy<T>::value;
581 using ProxyHelper = _ProxyHelper<T>;
583 using This = _TypeInfoImpl;
585 constexpr _TypeInfoImpl()
586 : _TypeInfo(
typeid(T),
587 _ArrayHelper<T>::GetElementTypeid(),
588 Vt_KnownValueTypeDetail::GetIndex<T>(),
606 &This::_IsArrayValued,
607 &This::_GetElementTypeid,
608 &This::_GetShapeData,
609 &This::_GetNumElements,
612 &This::_ProxyHoldsType,
613 &This::_GetProxiedType,
614 &This::_GetProxiedTypeid,
615 &This::_GetProxiedObjPtr,
616 &This::_GetProxiedAsVtValue)
621 static T
const &GetObj(_Storage
const &storage) {
622 return Derived::_GetObj(_Container(storage));
625 static T &GetMutableObj(_Storage &storage) {
626 return Derived::_GetMutableObj(_Container(storage));
629 static void CopyInitObj(T
const &objSrc, _Storage &dst) {
630 Derived::_PlaceCopy(&_Container(dst), objSrc);
634 static_assert(
sizeof(Container) <=
sizeof(_Storage),
635 "Container size cannot exceed storage size.");
639 static void _CopyInit(_Storage
const &src, _Storage &dst) {
640 new (&_Container(dst)) Container(_Container(src));
643 static void _Destroy(_Storage &storage) {
644 _Container(storage).~Container();
647 static bool _CanHash(_Storage
const &storage) {
648 return ProxyHelper::CanHash(GetObj(storage));
651 static size_t _Hash(_Storage
const &storage) {
652 return ProxyHelper::Hash(GetObj(storage));
655 static bool _Equal(_Storage
const &lhs, _Storage
const &rhs) {
659 return ProxyHelper::Equal(GetObj(lhs), GetObj(rhs));
662 static bool _EqualPtr(_Storage
const &lhs,
void const *rhs) {
666 return ProxyHelper::Equal(
667 GetObj(lhs), *
static_cast<T
const *
>(rhs));
670 static void _Move(_Storage &src, _Storage &dst)
noexcept {
671 new (&_Container(dst)) Container(std::move(_Container(src)));
675 static void _MakeMutable(_Storage &storage) {
676 GetMutableObj(storage);
680 return ProxyHelper::GetPyObj(GetObj(storage));
683 static std::ostream &_StreamOut(
684 _Storage
const &storage, std::ostream &out) {
685 return ProxyHelper::StreamOut(GetObj(storage), out);
688 static std::type_info
const &_GetTypeid(_Storage
const &storage) {
689 return ProxyHelper::GetTypeid(GetObj(storage));
692 static bool _IsArrayValued(_Storage
const &storage) {
693 return ProxyHelper::IsArrayValued(GetObj(storage));
696 static std::type_info
const &
697 _GetElementTypeid(_Storage
const &storage) {
698 return ProxyHelper::GetElementTypeid(GetObj(storage));
701 static const Vt_ShapeData* _GetShapeData(_Storage
const &storage) {
702 return ProxyHelper::GetShapeData(GetObj(storage));
705 static size_t _GetNumElements(_Storage
const &storage) {
706 return ProxyHelper::GetNumElements(GetObj(storage));
710 _ProxyHoldsType(_Storage
const &storage, std::type_info
const &t) {
711 return ProxyHelper::HoldsType(GetObj(storage), t);
715 _GetProxiedType(_Storage
const &storage) {
716 return ProxyHelper::GetTfType(GetObj(storage));
719 static std::type_info
const &
720 _GetProxiedTypeid(_Storage
const &storage) {
721 return ProxyHelper::GetTypeid(GetObj(storage));
725 _GetProxiedObjPtr(_Storage
const &storage) {
726 return ProxyHelper::GetObjPtr(GetObj(storage));
730 _GetProxiedAsVtValue(_Storage
const &storage) {
731 return ProxyHelper::GetProxiedAsVtValue(GetObj(storage));
737 static Container &_Container(_Storage &storage) {
739 return *
reinterpret_cast<Container *
>(&storage);
741 static Container
const &_Container(_Storage
const &storage) {
743 return *
reinterpret_cast<Container
const *
>(&storage);
751 struct _LocalTypeInfo : _TypeInfoImpl<
757 constexpr _LocalTypeInfo()
758 : _TypeInfoImpl<T, T, _LocalTypeInfo<T>>()
762 static T &_GetMutableObj(T &obj) {
return obj; }
763 static T
const &_GetObj(T
const &obj) {
return obj; }
765 static void _PlaceCopy(T *dst, T
const &src) {
new (dst) T(src); }
772 struct _RemoteTypeInfo : _TypeInfoImpl<
774 boost::intrusive_ptr<_Counted<T> >,
778 constexpr _RemoteTypeInfo()
780 T, boost::intrusive_ptr<_Counted<T>>, _RemoteTypeInfo<T>>()
783 typedef boost::intrusive_ptr<_Counted<T> > Ptr;
785 static T &_GetMutableObj(Ptr &ptr) {
786 if (!ptr->IsUnique())
787 ptr.reset(
new _Counted<T>(ptr->Get()));
788 return ptr->GetMutable();
790 static T
const &_GetObj(Ptr
const &ptr) {
return ptr->Get(); }
792 static void _PlaceCopy(Ptr *dst, T
const &src) {
793 new (dst) Ptr(
new _Counted<T>(src));
799 struct _TypeInfoFor {
801 typedef std::conditional_t<_UsesLocalStore<T>::value,
803 _RemoteTypeInfo<T>> Type;
808 struct _TypeInfoFor<char[N]> : _TypeInfoFor<std::string> {};
814 typedef typename _TypeInfoFor<T>::Type TI;
816 static constexpr unsigned int flags =
817 (TI::IsLocal ? _LocalFlag : 0) |
818 (TI::HasTrivialCopy ? _TrivialCopyFlag : 0) |
819 (TI::IsProxy ? _ProxyFlag : 0);
829 friend struct _HoldAside;
831 explicit _HoldAside(
VtValue *val)
832 : info((val->
IsEmpty() || val->_IsLocalAndTriviallyCopyable())
833 ?
static_cast<_TypeInfo
const *
>(NULL) : val->_info.
Get()) {
835 info->Move(val->_storage, storage);
839 info->Destroy(storage);
842 _TypeInfo
const *info;
847 std::is_same<T, typename Vt_ValueGetStored<T>::Type>::value>
848 _Init(T
const &obj) {
849 _info = GetTypeInfo<T>();
850 typedef typename _TypeInfoFor<T>::Type TypeInfo;
851 TypeInfo::CopyInitObj(obj, _storage);
856 !std::is_same<T, typename Vt_ValueGetStored<T>::Type>::value>
857 _Init(T
const &obj) {
858 _Init(
typename Vt_ValueGetStored<T>::Type(obj));
917 if (ARCH_LIKELY(
this != &other))
924 if (ARCH_LIKELY(
this != &other))
933 _TypeInfoFor<T>::Type::IsLocal &&
934 _TypeInfoFor<T>::Type::HasTrivialCopy,
951 !_TypeInfoFor<T>::Type::IsLocal ||
952 !_TypeInfoFor<T>::Type::HasTrivialCopy,
955 _HoldAside tmp(
this);
963 std::string tmp(cstr);
971 return *
this =
const_cast<char const *
>(cstr);
977 if (!
IsEmpty() || !rhs.IsEmpty()) {
1000 std::is_same<T, typename Vt_ValueGetStored<T>::Type>::value>
1002 if (!IsHolding<T>())
1019 std::is_same<T, typename Vt_ValueGetStored<T>::Type>::value>
1022 swap(_GetMutable<T>(), rhs);
1083 if (ARCH_UNLIKELY(_IsProxy())) {
1084 return _info->GetProxiedAsVtValue(
1085 _storage).GetKnownValueTypeIndex();
1087 return _info.
GetLiteral() ? _info->knownTypeIndex : -1;
1111 typedef Vt_DefaultValueFactory<T> Factory;
1115 if (ARCH_UNLIKELY(!IsHolding<T>())) {
1116 return *(
static_cast<T
const *
>(
1117 _FailGet(Factory::Invoke,
typeid(T))));
1127 typedef Vt_DefaultValueFactory<T> Factory;
1131 if (ARCH_UNLIKELY(!IsHolding<T>())) {
1132 return *(
static_cast<T
const *
>(
1133 _FailGet(Factory::Invoke,
typeid(T))));
1136 return UncheckedRemove<T>();
1145 return IsHolding<T>() ? UncheckedGet<T>() : def;
1149 template <
typename From,
typename To>
1151 _RegisterCast(
typeid(From),
typeid(To), castFn);
1156 template <
typename From,
typename To>
1158 _RegisterCast(
typeid(From),
typeid(To), _SimpleCast<From, To>);
1163 template <
typename From,
typename To>
1165 RegisterSimpleCast<From, To>();
1166 RegisterSimpleCast<To, From>();
1176 template <
typename T>
1179 return ret.
Cast<T>();
1206 std::type_info
const &to) {
1207 return _CanCast(from, to);
1217 template <
typename T>
1221 return *
this = _PerformCast(
typeid(T), *
this);
1244 *
this = _PerformCast(type, *
this);
1252 template <
typename T>
1254 return _CanCast(
GetTypeid(),
typeid(T));
1280 friend inline size_t hash_value(
VtValue const &val) {
1285 template <
typename T>
1287 typedef typename Vt_ValueGetStored<T>::Type Stored;
1290 template <
typename T>
1296 template <
typename T>
1298 return !(lhs == rhs);
1300 template <
typename T>
1302 return !(lhs == rhs);
1308 if (empty || rhsEmpty) {
1310 return empty == rhsEmpty;
1314 return _info.
Get()->Equal(_storage, rhs._storage);
1316 return _EqualityImpl(rhs);
1321 VT_API
friend std::ostream &
1325 VT_API
const Vt_ShapeData* _GetShapeData()
const;
1326 VT_API
size_t _GetNumElements()
const;
1327 friend struct Vt_ValueShapeDataAccess;
1335 _HoldAside tmp(&dst);
1336 dst._info = src._info;
1337 if (src._IsLocalAndTriviallyCopyable()) {
1338 dst._storage = src._storage;
1340 dst._info->CopyInit(src._storage, dst._storage);
1350 _HoldAside tmp(&dst);
1351 dst._info = src._info;
1352 if (src._IsLocalAndTriviallyCopyable()) {
1353 dst._storage = src._storage;
1355 dst._info->Move(src._storage, dst._storage);
1358 src._info.
Set(
nullptr, 0);
1362 inline std::enable_if_t<VtIsKnownValueType_Workaround<T>::value,
bool>
1364 return _info->knownTypeIndex == VtGetKnownValueTypeIndex<T>() ||
1365 ARCH_UNLIKELY(_IsProxy() && _TypeIsImpl(
typeid(T)));
1369 inline std::enable_if_t<!VtIsKnownValueType_Workaround<T>::value,
bool>
1371 std::type_info
const &t =
typeid(T);
1373 ARCH_UNLIKELY(_IsProxy() && _TypeIsImpl(t));
1376 VT_API
bool _TypeIsImpl(std::type_info
const &queriedType)
const;
1378 VT_API
bool _EqualityImpl(
VtValue const &rhs)
const;
1380 template <
class Proxy>
1381 std::enable_if_t<VtIsValueProxy<Proxy>::value, Proxy &>
1383 typedef typename _TypeInfoFor<Proxy>::Type TypeInfo;
1384 return TypeInfo::GetMutableObj(_storage);
1388 std::enable_if_t<!VtIsValueProxy<T>::value, T &>
1391 if (ARCH_UNLIKELY(_IsProxy())) {
1392 *
this = _info->GetProxiedAsVtValue(_storage);
1394 typedef typename _TypeInfoFor<T>::Type TypeInfo;
1395 return TypeInfo::GetMutableObj(_storage);
1398 template <
class Proxy>
1399 std::enable_if_t<VtIsValueProxy<Proxy>::value, Proxy
const &>
1401 typedef typename _TypeInfoFor<Proxy>::Type TypeInfo;
1402 return TypeInfo::GetObj(_storage);
1406 std::enable_if_t<!VtIsValueProxy<T>::value, T
const &>
1408 typedef typename _TypeInfoFor<T>::Type TypeInfo;
1409 if (ARCH_UNLIKELY(_IsProxy())) {
1410 return *
static_cast<T
const *
>(_GetProxiedObjPtr());
1412 return TypeInfo::GetObj(_storage);
1415 void const *_GetProxiedObjPtr()
const {
1416 return _info->GetProxiedObjPtr(_storage);
1422 _FailGet(Vt_DefaultValueHolder (*factory)(),
1423 std::type_info
const &queryType)
const;
1425 inline void _Clear() {
1429ARCH_PRAGMA_MAYBE_UNINITIALIZED
1430 if (_info.
GetLiteral() && !_IsLocalAndTriviallyCopyable())
1431 _info.
Get()->Destroy(_storage);
1433 _info.
Set(
nullptr, 0);
1436 inline bool _IsLocalAndTriviallyCopyable()
const {
1437 unsigned int bits = _info.
BitsAs<
unsigned int>();
1438 return (bits & (_LocalFlag | _TrivialCopyFlag)) ==
1439 (_LocalFlag | _TrivialCopyFlag);
1442 inline bool _IsProxy()
const {
1443 return _info.
BitsAs<
unsigned int>() & _ProxyFlag;
1446 VT_API
static void _RegisterCast(std::type_info
const &from,
1447 std::type_info
const &to,
1453 _PerformCast(std::type_info
const &to,
VtValue const &val);
1458 _CanCast(std::type_info
const &from, std::type_info
const &to);
1461 template <
typename From,
typename To>
1471 Vt_GetPythonObjectFromHeldValue(
VtValue const &self);
1481struct Vt_ValueShapeDataAccess {
1482 static const Vt_ShapeData* _GetShapeData(
const VtValue& value) {
1483 return value._GetShapeData();
1486 static size_t _GetNumElements(
const VtValue& value) {
1487 return value._GetNumElements();
1495struct Vt_DefaultValueFactory {
1496 static Vt_DefaultValueHolder Invoke();
1500inline Vt_DefaultValueHolder
1501Vt_DefaultValueFactory<T>::Invoke() {
1502 return Vt_DefaultValueHolder::Create<T>();
1513#define _VT_DECLARE_ZERO_VALUE_FACTORY(r, unused, elem) \
1515VT_API Vt_DefaultValueHolder Vt_DefaultValueFactory<VT_TYPE(elem)>::Invoke();
1517BOOST_PP_SEQ_FOR_EACH(_VT_DECLARE_ZERO_VALUE_FACTORY,
1520 VT_MATRIX_VALUE_TYPES
1521 VT_QUATERNION_VALUE_TYPES
1522 VT_DUALQUATERNION_VALUE_TYPES)
1524#undef _VT_DECLARE_ZERO_VALUE_FACTORY
1533VtValue::Get<VtValue>() const & {
1539VtValue::Get<VtValue>() && {
1540 return std::move(*
this);
1545VtValue::UncheckedGet<VtValue>() const & {
1551VtValue::UncheckedGet<VtValue>() && {
1552 return std::move(*
this);
1557VtValue::IsHolding<VtValue>()
const {
1564VtValue::IsHolding<void>()
const {
1572PXR_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.
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...
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.