Loading...
Searching...
No Matches
valueRef.h
1//
2// Copyright 2025 Pixar
3//
4// Licensed under the terms set forth in the LICENSE.txt file available at
5// https://openusd.org/license.
6//
7#ifndef PXR_BASE_VT_VALUEREF_H
8#define PXR_BASE_VT_VALUEREF_H
9
10#include "pxr/pxr.h"
11
12// XXX: Include pyLock.h after pyObjWrapper.h to work around
13// Python include ordering issues.
14#include "pxr/base/tf/pyObjWrapper.h"
15
16#include "pxr/base/tf/pyLock.h"
17
19#include "pxr/base/arch/hints.h"
21#include "pxr/base/tf/anyUniquePtr.h"
22#include "pxr/base/tf/preprocessorUtilsLite.h"
25#include "pxr/base/tf/tf.h"
26#include "pxr/base/tf/type.h"
27
28#include "pxr/base/vt/api.h"
29#include "pxr/base/vt/hash.h"
30#include "pxr/base/vt/streamOut.h"
31#include "pxr/base/vt/traits.h"
32#include "pxr/base/vt/types.h"
33#include "pxr/base/vt/valueCommon.h"
34
35#include <iosfwd>
36#include <typeinfo>
37#include <type_traits>
38
39PXR_NAMESPACE_OPEN_SCOPE
40
41class VtValue;
42class VtValueRef;
43
44// Overload VtStreamOut for vector<VtValueRef>. Produces output like [value1,
45// value2, ... valueN].
46VT_API std::ostream &
47VtStreamOut(std::vector<VtValueRef> const &val, std::ostream &);
48
65{
66protected:
67
68 // This unfortunately needs to be a union since there are some callers that
69 // place function pointers in VtValue. The specific _TypeInfo
70 // instantiations know which union member to use at based on their type
71 // parameter.
72 union _RefdObjPtr {
73 void const *objPtr;
74 void (*fnPtr)();
75 };
76
77 // Type information base class.
78 // We force alignment here in order to ensure that TfPointerAndBits has
79 // enough room to store all TypeInfo related flags.
80 struct alignas(8) _TypeInfo {
81 private:
82 using _CanHashFunc = bool (*)(_RefdObjPtr);
83 using _HashFunc = size_t (*)(_RefdObjPtr);
84 using _EqualFunc = bool (*)(_RefdObjPtr, _RefdObjPtr);
85 using _GetPyObjFunc = TfPyObjWrapper (*)(_RefdObjPtr);
86 using _GetVtValueFunc = VtValue (*)(_RefdObjPtr);
87 using _StreamOutFunc = std::ostream & (*)(_RefdObjPtr, std::ostream &);
88 using _IsArrayValuedFunc = bool (*)(_RefdObjPtr);
89 using _GetNumElementsFunc = size_t (*)(_RefdObjPtr);
90
91 protected:
92 constexpr _TypeInfo(const std::type_info &ti,
93 const std::type_info &elementTi,
94 int knownTypeIndex,
95 bool isArray,
96 bool isHashable,
97 bool canComposeOver,
98 bool canTransform,
99 bool isMutable,
100 _CanHashFunc canHash,
101 _HashFunc hash,
102 _EqualFunc equal,
103 _GetPyObjFunc getPyObj,
104 _GetVtValueFunc getVtValue,
105 _StreamOutFunc streamOut,
106 _IsArrayValuedFunc isArrayValued,
107 _GetNumElementsFunc getNumElements)
108 : typeInfo(ti)
109 , elementTypeInfo(elementTi)
110 , knownTypeIndex(knownTypeIndex)
111 , isArray(isArray)
112 , isHashable(isHashable)
113 , canComposeOver(canComposeOver)
114 , canTransform(canTransform)
115 , isMutable(isMutable)
116 // Function table
117 , _canHash(canHash)
118 , _hash(hash)
119 , _equal(equal)
120 , _getPyObj(getPyObj)
121 , _getVtValue(getVtValue)
122 , _streamOut(streamOut)
123 , _isArrayValued(isArrayValued)
124 , _getNumElements(getNumElements)
125 {}
126
127 public:
128 bool CanHash(_RefdObjPtr storage) const {
129 return _canHash(storage);
130 }
131 size_t Hash(_RefdObjPtr storage) const {
132 return _hash(storage);
133 }
134 bool Equal(_RefdObjPtr lhs, _RefdObjPtr rhs) const {
135 return _equal(lhs, rhs);
136 }
137 TfPyObjWrapper GetPyObj(_RefdObjPtr storage) const {
138 return _getPyObj(storage);
139 }
140 // Defined below due to circular VtValue <-> VtValueRef includes.
141 inline VtValue GetVtValue(_RefdObjPtr storage) const;
142 std::ostream &StreamOut(_RefdObjPtr storage,
143 std::ostream &out) const {
144 return _streamOut(storage, out);
145 }
146 bool IsArrayValued(_RefdObjPtr storage) const {
147 return _isArrayValued(storage);
148 }
149 size_t GetNumElements(_RefdObjPtr storage) const {
150 return _getNumElements(storage);
151 }
152
153 const std::type_info &typeInfo;
154 const std::type_info &elementTypeInfo;
155 const int knownTypeIndex;
156 const bool isArray;
157 const bool isHashable;
158 const bool canComposeOver;
159 const bool canTransform;
160 const bool isMutable;
161
162 private:
163 _CanHashFunc _canHash;
164 _HashFunc _hash;
165 _EqualFunc _equal;
166 _GetPyObjFunc _getPyObj;
167 _GetVtValueFunc _getVtValue;
168 _StreamOutFunc _streamOut;
169 _IsArrayValuedFunc _isArrayValued;
170 _GetNumElementsFunc _getNumElements;
171 };
172
173 // Type-dispatching overloads.
174
175 // Array type helpers. Non-array types have no shape data, no elements and
176 // report `void` for their element types.
177 template <class T>
178 struct _NonArrayHelper
179 {
180 template <class U>
181 static size_t GetNumElements(U &&) { return 0; }
182 constexpr static std::type_info const &GetElementTypeid() {
183 return typeid(void);
184 }
185 };
186 // VtArray types report their qualities.
187 template <class Array>
188 struct _IsArrayHelper
189 {
190 static size_t GetNumElements(Array const &obj) {
191 return obj.size();
192 }
193 constexpr static std::type_info const &GetElementTypeid() {
194 return typeid(typename Array::ElementType);
195 }
196 };
197 // VtArrayEdit types are identical to non-array types except that they do
198 // report their underlying element type.
199 template <class ArrayEdit>
200 struct _IsArrayEditHelper : _NonArrayHelper<ArrayEdit>
201 {
202 constexpr static std::type_info const &GetElementTypeid() {
203 return typeid(typename ArrayEdit::ElementType);
204 }
205 };
206
207 // Select which flavor of array helper to use -- VtArray uses
208 // _IsArrayHelper, VtArrayEdit uses _IsArrayEditHelper, all other types use
209 // _NonArrayHelper.
210 template <class T>
211 using _ArrayHelper = TfConditionalType<
212 VtIsArray<T>::value, _IsArrayHelper<T>,
213 TfConditionalType<VtIsArrayEdit<T>::value,
214 _IsArrayEditHelper<T>, _NonArrayHelper<T>>
215 >;
216
217 // _TypeInfo implementation.
218 template <class T, bool IsMutable>
219 struct _TypeInfoImpl : public _TypeInfo
220 {
221 using Type = T;
222 using This = _TypeInfoImpl;
223
224 static constexpr bool IsPointer = std::is_pointer_v<Type>;
225 static constexpr bool IsFunctionPointer =
226 IsPointer && std::is_function_v<std::remove_pointer_t<Type>>;
227
228 using ConstType = std::conditional_t<
229 IsPointer,
230 const std::remove_pointer_t<Type> *,
231 const Type>;
232
233 using GetObjResultType = std::conditional_t<
234 IsPointer, ConstType, ConstType &>;
235
236 using GetMutableObjResultType = std::conditional_t<
237 IsPointer, Type, Type &>;
238
239 //using RefType = Type &;
240 // using ObjType = std::conditional_t<
241 // std::is_pointer_v<Type>, Type, Type &>;
242 //using ConstRefType = ConstType const &;
243
244 constexpr _TypeInfoImpl()
245 : _TypeInfo(typeid(T),
246 _ArrayHelper<T>::GetElementTypeid(),
247 Vt_KnownValueTypeDetail::GetIndex<T>(),
249 VtIsHashable<T>(),
252 IsMutable,
253 &This::_CanHash,
254 &This::_Hash,
255 &This::_Equal,
256 &This::_GetPyObj,
257 &This::_GetVtValue,
258 &This::_StreamOut,
259
260 // Array support.
261 &This::_IsArrayValued,
262 &This::_GetNumElements)
263
264 {}
265
267 // Typed API for client use.
268 static GetObjResultType
269 GetObj(_RefdObjPtr const &storage) {
270 if constexpr (IsFunctionPointer) {
271 return reinterpret_cast<GetObjResultType>(storage.fnPtr);
272 }
273 else if constexpr (IsPointer) {
274 return reinterpret_cast<GetObjResultType>(storage.objPtr);
275 }
276 else {
277 return *static_cast<ConstType *>(storage.objPtr);
278 }
279 }
280
281 static GetMutableObjResultType
282 GetMutableObj(_RefdObjPtr &storage) {
283 // This const cast is safe since the original VtValueRef must've
284 // been constructed with a mutable object.
285 if constexpr (IsFunctionPointer) {
286 return reinterpret_cast<GetMutableObjResultType>(storage.fnPtr);
287 }
288 else if constexpr (IsPointer) {
289 return reinterpret_cast<
290 GetMutableObjResultType>(storage.objPtr);
291 }
292 else {
293 return *static_cast<Type *>(const_cast<void *>(storage.objPtr));
294 }
295 }
296
297 static void SetObj(T const &obj, _RefdObjPtr &storage) {
298 if constexpr (IsFunctionPointer) {
299 storage.fnPtr = reinterpret_cast<void (*)()>(obj);
300 }
301 else if constexpr (IsPointer) {
302 storage.objPtr = static_cast<void const *>(obj);
303 }
304 else {
305 storage.objPtr = static_cast<void const *>(std::addressof(obj));
306 }
307 }
308
309 private:
310 static bool _CanHash(_RefdObjPtr) {
311 return VtIsHashable<T>();
312 }
313
314 static size_t _Hash(_RefdObjPtr ptr) {
315 return VtHashValue(GetObj(ptr));
316 }
317
318 static bool _Equal(_RefdObjPtr lhs, _RefdObjPtr rhs) {
319 return GetObj(lhs) == GetObj(rhs);
320 }
321
322 static TfPyObjWrapper _GetPyObj(_RefdObjPtr storage) {
323#ifdef PXR_PYTHON_SUPPORT_ENABLED
324 TfPyLock lock;
325 return pxr_boost::python::api::object(GetObj(storage));
326#else
327 return {};
328#endif
329 }
330
331 // Defined below.
332 static VtValue _GetVtValue(_RefdObjPtr storage);
333
334 static std::ostream &_StreamOut(
335 _RefdObjPtr storage, std::ostream &out) {
336 return VtStreamOut(GetObj(storage), out);
337 }
338
339 static bool _IsArrayValued(_RefdObjPtr storage) {
340 return VtIsArray<T>::value;
341 }
342
343 static std::type_info const &
344 _GetElementTypeid(_RefdObjPtr ptr) {
345 return _ArrayHelper<T>::GetElementTypeid();
346 }
347
348 static size_t _GetNumElements(_RefdObjPtr ptr) {
349 return _ArrayHelper<T>::GetNumElements(GetObj(ptr));
350 }
351
352 };
353
354 // Metafunction that returns the specific _TypeInfo subclass for T or T&.
355 // The passed `T` should be as-if deduced by a forwarding reference, so a
356 // reference type if the referenced object is mutable, otherwise a
357 // non-reference type.
358 template <class T>
359 using _TypeInfoFor = _TypeInfoImpl<
360 std::decay_t<T>,
361 std::is_reference_v<T> && std::is_const_v<T>>;
362
363public:
364
366 VtValueRef() : _info(nullptr) {}
367
368 VtValueRef(VtValueRef const &) = default;
369 VtValueRef(VtValueRef &&) = default;
370
373 template <class T>
374 VtValueRef(T &&obj, std::enable_if_t<
375 !std::is_same_v<std::decay_t<T>, VtValueRef> &&
376 !std::is_same_v<std::decay_t<T>, VtValue>> * = 0) {
377 using TypeInfo = _TypeInfoFor<T>;
378 using TypeInfoType = typename TypeInfo::Type;
379 static_assert(!VtIsValueProxy<TypeInfoType>::value,
380 "VtValueRef does not support proxies");
381 static const TypeInfo ti;
382 ti.SetObj(obj, _ptr);
383 _info = std::addressof(ti);
384 }
385
387 VtValueRef &operator=(VtValueRef const &ref) = default;
388 VtValueRef &operator=(VtValueRef &&ref) = default;
389
390 // Disallow implicit conversion assignments.
391 template <class T>
392 VtValueRef &operator=(T &&) = delete;
393
395 friend void swap(VtValueRef &lhs, VtValueRef &rhs) {
396 std::swap(lhs._ptr, rhs._ptr);
397 std::swap(lhs._info, rhs._info);
398 }
399
402 template <class T>
403 bool IsHolding() const {
404 return _info && _TypeIs<T>();
405 }
406
409 bool IsRValue() const {
410 return _info && _info->isMutable;
411 }
412
414 VT_API bool IsArrayValued() const;
415
417 VT_API bool IsArrayEditValued() const;
418
421 size_t GetArraySize() const { return _GetNumElements(); }
422
424 std::type_info const &GetTypeid() const {
425 return _info ? _info->typeInfo : typeid(void);
426 }
427
431 std::type_info const &GetElementTypeid() const {
432 return _info ? _info->elementTypeInfo : typeid(void);
433 }
434
436 VT_API TfType GetType() const;
437
439 VT_API std::string GetTypeName() const;
440
444 return _info ? _info->knownTypeIndex : -1;
445 }
446
450 template <class T>
451 typename _TypeInfoFor<T>::GetObjResultType
452 UncheckedGet() const { return _Get<T>(); }
453
462 template <class T>
463 typename _TypeInfoFor<T>::GetObjResultType
464 Get() const {
465 using Factory = Vt_DefaultValueFactory<T>;
466
467 // In the unlikely case that the types don't match, we obtain a default
468 // value to return and issue an error via _FailGet.
469 if (ARCH_UNLIKELY(!IsHolding<T>())) {
470 return *(static_cast<T const *>(
471 _FailGet(Factory::Invoke, typeid(T))));
472 }
473
474 return _Get<T>();
475 }
476
481 template <class T>
482 T GetWithDefault(T const &def = T()) const {
483 return IsHolding<T>() ? UncheckedGet<T>() : def;
484 }
485
491 template <class T>
492 T Remove() {
493 if (IsHolding<T>()) {
494 return UncheckedRemove<T>();
495 }
496 else {
497 _FailRemove(typeid(T));
498 }
499 return {};
500 }
501
506 template <class T>
508 if (IsRValue()) {
509 return std::move(_GetMutable<T>());
510 }
511 return _Get<T>();
512 }
513
515 bool IsEmpty() const { return !_info; }
516
518 VT_API operator VtValue() const;
519
521 VT_API bool CanHash() const;
522
524 VT_API size_t GetHash() const;
525
526 friend inline size_t hash_value(VtValueRef const &val) {
527 return val.GetHash();
528 }
529
535 bool CanComposeOver() const {
536 return !_info || _info->canComposeOver;
537 }
538
544 bool CanTransform() const {
545 return _info && _info->canTransform;
546 }
547
549 bool operator == (const VtValueRef &rhs) const {
550 bool empty = IsEmpty(), rhsEmpty = rhs.IsEmpty();
551 if (empty || rhsEmpty) {
552 // Either one or both empty -- only equal if both empty.
553 return empty == rhsEmpty;
554 }
555 if (_info == rhs._info) {
556 // Holding identical types -- compare directly.
557 return _info->Equal(_ptr, rhs._ptr);
558 }
559 return false;
560 }
561 bool operator != (const VtValueRef &rhs) const { return !(*this == rhs); }
562
564 VT_API friend std::ostream &
565 operator << (std::ostream &out, const VtValueRef &self);
566
567protected:
568 VT_API size_t _GetNumElements() const;
569
570 template <class T>
571 inline bool
572 _TypeIs() const {
573 if constexpr (VtIsKnownValueType_Workaround<T>::value) {
574 return _info->knownTypeIndex == VtGetKnownValueTypeIndex<T>();
575 }
576 else {
577 std::type_info const &t = typeid(T);
578 return TfSafeTypeCompare(_info->typeInfo, t);
579 }
580 }
581
582 template <class T>
583 typename _TypeInfoFor<T>::GetMutableObjResultType
584 _GetMutable() {
585 using TypeInfo = _TypeInfoFor<T>;
586 return TypeInfo::GetMutableObj(_ptr);
587 }
588
589 template <class T>
590 typename _TypeInfoFor<T>::GetObjResultType
591 _Get() const {
592 using TypeInfo = _TypeInfoFor<T>;
593 return TypeInfo::GetObj(_ptr);
594 }
595
596 // Helper invoked in case Get fails. Reports an error and returns a default
597 // value for \a queryType.
598 VT_API void const *
599 _FailGet(Vt_DefaultValueHolder (*factory)(),
600 std::type_info const &queryType) const;
601
602 VT_API void _FailRemove(std::type_info const &);
603
604 // This grants friend access to a function in the wrapper file for this
605 // class. This lets the wrapper reach down into a value to get a
606 // pxr_boost::python wrapped object corresponding to the viewed type. This
607 // facility is necessary to get the python API we want.
608 friend TfPyObjWrapper
609 Vt_GetPythonObjectFromHeldValue(VtValueRef const &self);
610
611 VT_API TfPyObjWrapper _GetPythonObject() const;
612
613 _RefdObjPtr _ptr;
614 _TypeInfo const *_info;
615};
616
617#ifndef doxygen
618
619//
620// The Get()/IsHolding routines needs to be special-cased to handle getting a
621// VtValueRef *as* a VtValueRef.
622//
623
624template <>
625inline VtValueRef const &
626VtValueRef::Get<VtValueRef>() const {
627 return *this;
628}
629
630template <>
631inline VtValueRef const &
632VtValueRef::UncheckedGet<VtValueRef>() const {
633 return *this;
634}
635
636template <>
637inline bool
638VtValueRef::IsHolding<VtValueRef>() const {
639 return true;
640}
641
642// Specialize VtValueRef::IsHolding<void>() to always return false.
643template <>
644inline bool
645VtValueRef::IsHolding<void>() const {
646 return false;
647}
648
649#endif // !doxygen
650
662{
663public:
665 VtMutableValueRef() = default;
666
667 template <class T>
668 VtMutableValueRef(T &obj) : VtValueRef(obj) {}
669
671 template <class T>
673 static_assert(std::is_same_v<T, typename Vt_ValueGetStored<T>::Type>,
674 "Can only assign to VtMutableValueRef with a type T "
675 "that stores as T");
676 if (IsHolding<T>()) {
677 _GetMutable<T>() = std::forward<T>(obj);
678 }
679 else {
680 _FailAssign(typeid(T));
681 }
682 return *this;
683 }
684
685 template <class T>
686 VtMutableValueRef &UncheckedAssign(T &&obj) {
687 static_assert(std::is_same_v<T, typename Vt_ValueGetStored<T>::Type>,
688 "Can only assign to VtMutableValueRef with a type T "
689 "that stores as T");
690 _GetMutable<T>() = std::forward<T>(obj);
691 return *this;
692 }
693
698 template <class T>
699 void
700 Swap(T &rhs) {
701 static_assert(std::is_same_v<T, typename Vt_ValueGetStored<T>::Type>,
702 "Can only VtValueRef::Swap with a type T "
703 "that stores as T");
704 if (IsHolding<T>()) {
705 UncheckedSwap(rhs);
706 }
707 else {
708 _FailSwap(typeid(T));
709 }
710 }
711
716 template <class T>
717 void
719 static_assert(std::is_same_v<T, typename Vt_ValueGetStored<T>::Type>,
720 "Can only VtValueRef::Swap with a type T "
721 "that stores as T");
722 using std::swap;
723 swap(_GetMutable<T>(), rhs);
724 }
725
729 template <class T, class Fn>
730 bool
731 Mutate(Fn &&mutateFn) {
732 static_assert(std::is_same_v<T, typename Vt_ValueGetStored<T>::Type>,
733 "Can only VtValueRef::Mutate a type T that stores as T");
734 if (!IsHolding<T>()) {
735 return false;
736 }
737 UncheckedMutate<T>(std::forward<Fn>(mutateFn));
738 return true;
739 }
740
744 template <class T, class Fn>
745 void
746 UncheckedMutate(Fn &&mutateFn) {
747 static_assert(std::is_same_v<T, typename Vt_ValueGetStored<T>::Type>,
748 "Can only VtValueRef::Mutate a type T that stores as T");
749 // We move to a temporary, mutate the temporary, then move back. This
750 // prevents callers from escaping a mutable reference to the viewed
751 // object via a side-effect of mutateFn.
752 T &stored = _GetMutable<T>();
753 T tmp = std::move(stored);
754 std::forward<Fn>(mutateFn)(tmp);
755 stored = std::move(tmp);
756 }
757
758private:
759 VT_API void _FailAssign(std::type_info const &);
760 VT_API void _FailSwap(std::type_info const &);
761
762};
763
764PXR_NAMESPACE_CLOSE_SCOPE
765
766// This unusual arrangement of closing the namespace, including value.h, then
767// reopening the namespace exists because valueRef.h and value.h are
768// interdependent. A similar symmetric construct exists in value.h. If
769// valueRef.h is included first, then value.h will be included here. Otherwise
770// if value.h is included first then it will have included valueRef.h. Either
771// way all the necessary declarations from both types are present prior to the
772// appearance of the following defintions.
773
774#include "pxr/base/vt/value.h"
775
776PXR_NAMESPACE_OPEN_SCOPE
777
778// Defined here due to circular dependencies.
780VtValueRef::_TypeInfo::GetVtValue(_RefdObjPtr storage) const {
781 return _getVtValue(storage);
782}
783
784template <class T, bool B>
786VtValueRef::_TypeInfoImpl<T, B>::_GetVtValue(_RefdObjPtr storage) {
787 return VtValue { GetObj(storage) };
788}
789
790PXR_NAMESPACE_CLOSE_SCOPE
791
792#ifdef PXR_PYTHON_SUPPORT_ENABLED
793
794#include "pxr/external/boost/python/converter/arg_from_python.hpp"
795#include <optional>
796
797namespace PXR_BOOST_NAMESPACE::python::converter {
798
799// We specialize arg_rvalue_from_python<VtValueRef> to derive
800// arg_rvalue_from_python<VtValue>. This way we get storage for both -- an
801// `rvalue_from_python_data<VtValue &> m_data` in the base and a VtValueRef in
802// this class. There's no other way afaict to "add space" in an rvalue
803// converter to support a "view" type where we need to also conjure a temporary
804// for that view. This way we can create the `VtValue` in the base as usual and
805// let the `VtValueRef` here refer to it for the lifetime of the arg.
806template <>
807struct arg_rvalue_from_python<PXR_NS::VtValueRef>
808 : public arg_rvalue_from_python<PXR_NS::VtValue>
809{
810 using base_type = arg_rvalue_from_python<PXR_NS::VtValue>;
811 using base_type::convertible;
812 using result_type = PXR_NS::VtValueRef &; // boost.python convention.
813
814 VT_API arg_rvalue_from_python(PyObject* obj);
815
816 VT_API result_type operator()();
817
818 std::optional<PXR_NS::VtValueRef> optValueRef;
819};
820
821} // namespace PXR_BOOST_NAMESPACE::python::converter
822
823#endif // PXR_PYTHON_SUPPORT_ENABLED
824
825#endif // PXR_BASE_VT_VALUEREF_H
826
Defines all the types "TYPED" for which Vt creates a VtTYPEDArray typedef.
Convenience class for accessing the Python Global Interpreter Lock.
Definition: pyLock.h:105
Boost Python object wrapper.
Definition: pyObjWrapper.h:79
TfType represents a dynamic runtime type.
Definition: type.h:48
A non-owning type-erased view of a mutable lvalue, interoperating with VtValue.
Definition: valueRef.h:662
void UncheckedMutate(Fn &&mutateFn)
Invoke mutateFn, passing it a non-const reference to the viewed object which must be of type T.
Definition: valueRef.h:746
VtMutableValueRef()=default
Default ctor gives empty VtMutableValueRef.
bool Mutate(Fn &&mutateFn)
If this value holds an object of type T, invoke mutateFn, passing it a non-const reference to the vie...
Definition: valueRef.h:731
VtMutableValueRef & operator=(T &&obj)
Assign to the viewed value.
Definition: valueRef.h:672
void UncheckedSwap(T &rhs)
Swap the viewed value with rhs.
Definition: valueRef.h:718
void Swap(T &rhs)
Swap the viewed value with rhs.
Definition: valueRef.h:700
Provides a container which may hold any type, and provides introspection and iteration over array typ...
Definition: value.h:90
A non-owning type-erased view of a value, interoperating with VtValue.
Definition: valueRef.h:65
VT_API std::string GetTypeName() const
Return the type name of the viewed typeid.
T UncheckedRemove()
Return a move-constructed (if the viewed object is an rvalue) or copy-constructed T instance from the...
Definition: valueRef.h:507
std::type_info const & GetElementTypeid() const
If this value views a VtArray or VtArrayEdit instance, return the typeid of its element type.
Definition: valueRef.h:431
bool operator==(const VtValueRef &rhs) const
Test two values for equality.
Definition: valueRef.h:549
int GetKnownValueTypeIndex() const
Return VtKnownValueTypeIndex<T> for the viewed type T.
Definition: valueRef.h:443
bool IsRValue() const
Return true if this refers to an rvalue, and thus can be Remove()d by a move construction operation i...
Definition: valueRef.h:409
VtValueRef(T &&obj, std::enable_if_t< !std::is_same_v< std::decay_t< T >, VtValueRef > &&!std::is_same_v< std::decay_t< T >, VtValue > > *=0)
Implicitly convert or construct a VtValueRef referring to obj.
Definition: valueRef.h:374
T Remove()
Return a move-constructed (if the viewed object is an rvalue) or copy-constructed T instance from the...
Definition: valueRef.h:492
VtValueRef()
Default ctor gives empty VtValueRef.
Definition: valueRef.h:366
size_t GetArraySize() const
Return the number of elements in the viewed value if IsArrayValued(), return 0 otherwise.
Definition: valueRef.h:421
VtValueRef & operator=(VtValueRef const &ref)=default
Rebind to view the same object as another VtValueRef.
T GetWithDefault(T const &def=T()) const
Return a copy of the viewed object if the viewed object is of type T.
Definition: valueRef.h:482
friend void swap(VtValueRef &lhs, VtValueRef &rhs)
Overloaded swap() for generic code/stl/etc. Swaps the viewed objects.
Definition: valueRef.h:395
VT_API bool IsArrayValued() const
Return true if this views a VtArray instance, false otherwise.
bool IsEmpty() const
Returns true iff this value is empty.
Definition: valueRef.h:515
VT_API TfType GetType() const
Returns the TfType of the type viewed by this value.
bool CanComposeOver() const
Return true if this value holds a type that has been declared at compile time to support composing ov...
Definition: valueRef.h:535
VT_API size_t GetHash() const
Return a hash code for the viewed object by calling VtHashValue() on it.
std::type_info const & GetTypeid() const
Return the typeid of the type viewed by this value.
Definition: valueRef.h:424
bool CanTransform() const
Return true if this value holds a type that has been declared to support value transforms at compile ...
Definition: valueRef.h:544
_TypeInfoFor< T >::GetObjResultType UncheckedGet() const
Return a const reference to the viewed object if the viewed object is of type T.
Definition: valueRef.h:452
VT_API bool IsArrayEditValued() const
Return true if this views a VtArrayEdit instance, false otherwise.
bool IsHolding() const
Return true if this value is viewing an object of type T, false otherwise.
Definition: valueRef.h:403
VT_API bool CanHash() const
Return true if the viewed object provides a hash implementation.
VT_API friend std::ostream & operator<<(std::ostream &out, const VtValueRef &self)
Calls through to operator << on the viewed object.
_TypeInfoFor< T >::GetObjResultType Get() const
Return a const reference to the viewed object if the viewed object is of type T.
Definition: valueRef.h:464
Demangle C++ typenames generated by the typeid() facility.
Compiler hints.
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.
Definition: traits.h:22
A trait indicating whether VtValue compose-over functionality can be registered for a type.
Definition: traits.h:137
A trait indicating whether VtValue transform functionality can be registered for a type.
Definition: traits.h:147
A file containing basic constants and definitions.