Loading...
Searching...
No Matches
types.h
Go to the documentation of this file.
1//
2// Copyright 2016 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_TYPES_H
8#define PXR_BASE_VT_TYPES_H
9
12
13#include "pxr/pxr.h"
14#include "pxr/base/vt/api.h"
15#include "pxr/base/vt/traits.h"
17#include "pxr/base/gf/declare.h"
18#include "pxr/base/gf/half.h"
20#include "pxr/base/tf/meta.h"
21#include "pxr/base/tf/preprocessorUtilsLite.h"
22#include "pxr/base/tf/token.h"
23
24#include <cstddef>
25#include <cstring>
26#include <string>
27
28PXR_NAMESPACE_OPEN_SCOPE
29
30// Help ensure TfToken is stored in local storage in VtValue by indicating it is
31// cheap to copy (just refcount operations).
32VT_TYPE_IS_CHEAP_TO_COPY(TfToken);
33
34// GfTimeCode supports value transformations.
36
37// Value types.
38
39#define VT_FLOATING_POINT_BUILTIN_VALUE_TYPES \
40(( double, Double )) \
41(( float, Float )) \
42(( GfHalf, Half ))
43
44#define VT_TIMECODE_VALUE_TYPES \
45(( GfTimeCode, TimeCode ))
46
47#define VT_INTEGRAL_BUILTIN_VALUE_TYPES \
48(( bool, Bool )) \
49(( char, Char )) \
50(( unsigned char, UChar )) \
51(( short, Short )) \
52(( unsigned short, UShort )) \
53(( int, Int )) \
54(( unsigned int, UInt )) \
55(( int64_t, Int64 )) \
56(( uint64_t, UInt64 ))
57
58#define VT_VEC_INT_VALUE_TYPES \
59(( GfVec4i, Vec4i )) \
60(( GfVec3i, Vec3i )) \
61(( GfVec2i, Vec2i ))
62
63#define VT_VEC_HALF_VALUE_TYPES \
64(( GfVec4h, Vec4h )) \
65(( GfVec3h, Vec3h )) \
66(( GfVec2h, Vec2h ))
67
68#define VT_VEC_FLOAT_VALUE_TYPES \
69(( GfVec4f, Vec4f )) \
70(( GfVec3f, Vec3f )) \
71(( GfVec2f, Vec2f ))
72
73#define VT_VEC_DOUBLE_VALUE_TYPES \
74(( GfVec4d, Vec4d )) \
75(( GfVec3d, Vec3d )) \
76(( GfVec2d, Vec2d ))
77
78#define VT_VEC_VALUE_TYPES \
79 VT_VEC_INT_VALUE_TYPES \
80 VT_VEC_HALF_VALUE_TYPES \
81 VT_VEC_FLOAT_VALUE_TYPES \
82 VT_VEC_DOUBLE_VALUE_TYPES
83
84#define VT_MATRIX_FLOAT_VALUE_TYPES \
85(( GfMatrix4f, Matrix4f )) \
86(( GfMatrix3f, Matrix3f )) \
87(( GfMatrix2f, Matrix2f )) \
88
89#define VT_MATRIX_DOUBLE_VALUE_TYPES \
90(( GfMatrix4d, Matrix4d )) \
91(( GfMatrix3d, Matrix3d )) \
92(( GfMatrix2d, Matrix2d ))
93
94#define VT_MATRIX_VALUE_TYPES \
95 VT_MATRIX_FLOAT_VALUE_TYPES \
96 VT_MATRIX_DOUBLE_VALUE_TYPES \
97
98#define VT_GFRANGE_VALUE_TYPES \
99(( GfRange3f, Range3f )) \
100(( GfRange3d, Range3d )) \
101(( GfRange2f, Range2f )) \
102(( GfRange2d, Range2d )) \
103(( GfRange1f, Range1f )) \
104(( GfRange1d, Range1d ))
105
106#define VT_RANGE_VALUE_TYPES \
107 VT_GFRANGE_VALUE_TYPES \
108(( GfInterval, Interval )) \
109(( GfRect2i, Rect2i ))
110
111#define VT_STRING_VALUE_TYPES \
112(( std::string, String )) \
113(( TfToken, Token ))
114
115#define VT_QUATERNION_VALUE_TYPES \
116(( GfQuath, Quath )) \
117(( GfQuatf, Quatf )) \
118(( GfQuatd, Quatd )) \
119(( GfQuaternion, Quaternion ))
120
121#define VT_DUALQUATERNION_VALUE_TYPES \
122(( GfDualQuath, DualQuath )) \
123(( GfDualQuatf, DualQuatf )) \
124(( GfDualQuatd, DualQuatd ))
125
126#define VT_NONARRAY_VALUE_TYPES \
127(( GfFrustum, Frustum)) \
128(( GfMultiInterval, MultiInterval))
129
130// Helper macros for extracting bits from a type tuple.
131#define VT_TYPE(elem) \
132TF_PP_TUPLE_ELEM(0, elem)
133#define VT_TYPE_NAME(elem) \
134TF_PP_TUPLE_ELEM(1, elem)
135
136
137// Composite groups of types.
138#define VT_BUILTIN_NUMERIC_VALUE_TYPES \
139VT_INTEGRAL_BUILTIN_VALUE_TYPES VT_FLOATING_POINT_BUILTIN_VALUE_TYPES \
140VT_TIMECODE_VALUE_TYPES
141
142#define VT_BUILTIN_VALUE_TYPES \
143VT_BUILTIN_NUMERIC_VALUE_TYPES VT_STRING_VALUE_TYPES
144
145#define VT_SCALAR_CLASS_VALUE_TYPES \
146VT_VEC_VALUE_TYPES \
147VT_MATRIX_VALUE_TYPES \
148VT_RANGE_VALUE_TYPES \
149VT_QUATERNION_VALUE_TYPES \
150VT_DUALQUATERNION_VALUE_TYPES
151
152#define VT_SCALAR_VALUE_TYPES \
153VT_BUILTIN_VALUE_TYPES VT_SCALAR_CLASS_VALUE_TYPES
154
155// The following preprocessor code produces type aliases for VtArray holding
156// various scalar value types. The produced aliases are of the form:
157//
158// using VtIntArray = VtArray<int>;
159// using VtDoubleArray = VtArray<double>;
160template<typename T> class VtArray;
161#define VT_ARRAY_ALIAS(unused, elem) \
162using TF_PP_CAT( \
163 Vt, TF_PP_CAT(VT_TYPE_NAME(elem), Array)) = VtArray< VT_TYPE(elem) >;
164TF_PP_SEQ_FOR_EACH(VT_ARRAY_ALIAS, ~, VT_SCALAR_VALUE_TYPES)
165
166// The following preprocessor code produces type aliases for VtArrayEdit holding
167// various scalar value types. The produced aliases are of the form:
168//
169// using VtIntArrayEdit = VtArrayEdit<int>;
170// using VtDoubleArrayEdit = VtArrayEdit<double>;
171template<typename T> class VtArrayEdit;
172#define VT_ARRAY_EDIT_ALIAS(unused, elem) \
173using TF_PP_CAT(Vt, TF_PP_CAT(VT_TYPE_NAME(elem), ArrayEdit)) \
174 = VtArrayEdit< VT_TYPE(elem) >;
175TF_PP_SEQ_FOR_EACH(VT_ARRAY_EDIT_ALIAS, ~, VT_SCALAR_VALUE_TYPES)
176
177// The following preprocessor code produces type aliases for VtArrayEditBuilder
178// holding various scalar value types. The produced aliases are of the form:
179//
180// using VtIntArrayEditBuilder = VtArrayEditBuilder<int>;
181// using VtDoubleArrayEditBuilder = VtArrayEditBuilder<double>;
182template<typename T> class VtArrayEditBuilder;
183#define VT_ARRAY_EDIT_BUILDER_ALIAS(unused, elem) \
184using TF_PP_CAT(Vt, TF_PP_CAT(VT_TYPE_NAME(elem), ArrayEditBuilder)) \
185 = VtArrayEditBuilder< VT_TYPE(elem) >;
186TF_PP_SEQ_FOR_EACH(VT_ARRAY_EDIT_BUILDER_ALIAS, ~, VT_SCALAR_VALUE_TYPES)
187
188// The following preprocessor code generates the boost pp sequence for
189// all array value types (VT_ARRAY_VALUE_TYPES)
190#define VT_ARRAY_TYPE_TUPLE(unused, elem) \
191(( TF_PP_CAT(Vt, TF_PP_CAT(VT_TYPE_NAME(elem), Array)) , \
192 TF_PP_CAT(VT_TYPE_NAME(elem), Array) ))
193#define VT_ARRAY_VALUE_TYPES \
194TF_PP_SEQ_FOR_EACH(VT_ARRAY_TYPE_TUPLE, ~, VT_SCALAR_VALUE_TYPES)
195
196// The following preprocessor code generates the boost pp sequence for
197// all array edit value types (VT_ARRAY_EDIT_VALUE_TYPES)
198#define VT_ARRAY_EDIT_TYPE_TUPLE(unused, elem) \
199(( TF_PP_CAT(Vt, TF_PP_CAT(VT_TYPE_NAME(elem), ArrayEdit)) , \
200 TF_PP_CAT(VT_TYPE_NAME(elem), ArrayEdit) ))
201#define VT_ARRAY_EDIT_VALUE_TYPES \
202TF_PP_SEQ_FOR_EACH(VT_ARRAY_EDIT_TYPE_TUPLE, ~, VT_SCALAR_VALUE_TYPES)
203
204// This unfortunately must be two separate PP lists, otherwise we exceed the
205// MSVC macro nesting depth.
206#define VT_VALUE_TYPES_1 \
207 VT_BUILTIN_VALUE_TYPES VT_SCALAR_CLASS_VALUE_TYPES
208#define VT_VALUE_TYPES_2 \
209 VT_ARRAY_VALUE_TYPES VT_ARRAY_EDIT_VALUE_TYPES VT_NONARRAY_VALUE_TYPES
210
211// Expand _macro for each value type tuple in VT_VALUE_TYPES_{1,2}. The _macro
212// must have the same form as for TF_PP_SEQ_FOR_EACH, namely MACRO(unused,
213// elem), where `unused` should be ignored and `elem` is the VT_VALUE_TYPES
214// tuple element.
215#define VT_FOR_EACH_VALUE_TYPE(_macro) \
216 TF_PP_SEQ_FOR_EACH(_macro, ~, VT_VALUE_TYPES_1) \
217 TF_PP_SEQ_FOR_EACH(_macro, ~, VT_VALUE_TYPES_2)
218
219// Populate a type list from the preprocessor sequence. The type `void` is
220// prepended to accommodate the comma-type expansion for the rest of the type
221// list type and then dropped by TfMetaTail.
222#define VT_COMMA_TYPE(unused, elem) , VT_TYPE(elem)
223using Vt_ValueTypeList =
224 TfMetaApply<TfMetaTail, TfMetaList<
225 void VT_FOR_EACH_VALUE_TYPE(VT_COMMA_TYPE)>>;
226#undef VT_COMMA_TYPE
227
228namespace Vt_KnownValueTypeDetail
229{
230
231// Implement compile-time value type indexes.
232// Base case -- unknown types get index -1.
233template <typename T>
234constexpr int
235GetIndexImpl(TfMetaList<>) {
236 return -1;
237}
238
239template <typename T, typename Typelist>
240constexpr int
241GetIndexImpl(Typelist) {
242 if (std::is_same_v<T, TfMetaApply<TfMetaHead, Typelist>>) {
243 return 0;
244 }
245 else if (const int indexOfTail =
246 GetIndexImpl<T>(TfMetaApply<TfMetaTail, Typelist>{});
247 indexOfTail >= 0) {
248 return 1 + indexOfTail;
249 }
250 else {
251 return -1;
252 }
253}
254
255template <typename T>
256constexpr int
257GetIndex() {
258 return GetIndexImpl<T>(Vt_ValueTypeList{});
259}
260
261} // Vt_KnownValueTypeDetail
262
263// Total number of 'known' value types.
264constexpr int
265VtGetNumKnownValueTypes() {
266 return TfMetaApply<TfMetaLength, Vt_ValueTypeList>::value;
267}
268
282template <class T>
283constexpr int
285{
286 constexpr int index = Vt_KnownValueTypeDetail::GetIndex<T>();
287 static_assert(index != -1, "T is not one of the known VT_VALUE_TYPES.");
288 return index;
289}
290
292template <class T>
293constexpr bool
295{
296 return Vt_KnownValueTypeDetail::GetIndex<T>() != -1;
297}
298
299// XXX: Works around an MSVC bug where constexpr functions cannot be used as the
300// condition in enable_if, fixed in MSVC 2022 version 14.33 1933 (version 17.3).
301// https://developercommunity.visualstudio.com/t/function-template-has-already-been-defined-using-s/833543
302template <class T>
303struct VtIsKnownValueType_Workaround
304{
305 static const bool value = VtIsKnownValueType<T>();
306};
307
308// Generally, we want to allow clients to register value-type transforms for
309// their own user-defined types. Registering transforms for built-in (float,
310// double, string) or low-level (GfVec, GfMatrix) types can lead to ODR
311// violations (due to trait differences in different TUs) and added performance
312// costs. So we allow registering transforms for all the types not known to Vt.
313// However there are a couple of low-level types known to Vt that are explicitly
314// allowed to support registered transforms. This private function captures
315// this set of types.
316template <class T>
317constexpr bool
318Vt_IsTypeAllowedToRegisterTransforms()
319{
320 return !VtIsKnownValueType<T>()
321 || std::is_same_v<T, GfTimeCode>
322 // || std::is_same_v<T, GfDuration>
323 ;
324}
325
326// None of the VT_VALUE_TYPES are value proxies. We want to specialize these
327// templates here, since otherwise the VtIsTypedValueProxy will require a
328// complete type to check if it derives VtTypedValueProxyBase.
329#define VT_SPECIALIZE_IS_VALUE_PROXY(unused, elem) \
330 template <> struct \
331 VtIsValueProxy< VT_TYPE(elem) > : std::false_type {}; \
332 template <> struct \
333 VtIsTypedValueProxy< VT_TYPE(elem) > : std::false_type {}; \
334 template <> struct \
335 VtIsErasedValueProxy< VT_TYPE(elem) > : std::false_type {};
336VT_FOR_EACH_VALUE_TYPE(VT_SPECIALIZE_IS_VALUE_PROXY)
337#undef VT_SPECIALIZE_IS_VALUE_PROXY
338
339// Free functions to represent "zero" for various base types. See
340// specializations in Types.cpp
341template<typename T>
342T VtZero();
343
344// Shape representation used in VtArray for legacy code. This is not supported
345// at the pxr level or in usd. Shape is represented by a total size, plus sized
346// dimensions other than the last. The size of the last dimension is computed
347// as totalSize / (product-of-other-dimensions).
348struct Vt_ShapeData {
349 unsigned int GetRank() const {
350 return
351 otherDims[0] == 0 ? 1 :
352 otherDims[1] == 0 ? 2 :
353 otherDims[2] == 0 ? 3 : 4;
354 }
355 bool operator==(Vt_ShapeData const &other) const {
356 if (totalSize != other.totalSize)
357 return false;
358 unsigned int thisRank = GetRank(), otherRank = other.GetRank();
359 if (thisRank != otherRank)
360 return false;
361 return std::equal(otherDims, otherDims + GetRank() - 1,
362 other.otherDims);
363 }
364 bool operator!=(Vt_ShapeData const &other) const {
365 return !(*this == other);
366 }
367 void clear() {
368 memset(this, 0, sizeof(*this));
369 }
370 static const int NumOtherDims = 3;
371 size_t totalSize;
372 unsigned int otherDims[NumOtherDims];
373};
374
375PXR_NAMESPACE_CLOSE_SCOPE
376
377#endif // PXR_BASE_VT_TYPES_H
Declares Gf types.
#define VT_VALUE_TYPE_CAN_TRANSFORM(T)
A helper for specializing the above trait.
Definition traits.h:150
constexpr int VtGetKnownValueTypeIndex()
Provide compile-time value type indexes for types that are "known" to Vt – specifically,...
Definition types.h:284
constexpr bool VtIsKnownValueType()
Returns true if T is a type that appears in VT_VALUE_TYPES.
Definition types.h:294
Value type that represents a time code.
Definition timeCode.h:28
Token for efficient comparison, assignment, and hashing of known strings.
Definition token.h:71
A builder type that produces instances of VtArrayEdit representing sequences of array edit operations...
An array edit represents a sequence of per-element modifications to a VtArray.
Definition arrayEdit.h:52
Represents an arbitrary dimensional rectangular container class.
Definition array.h:213
This header serves to simply bring in the half float datatype and provide a hash_value function.
Define integral types.
TfToken class for efficient string referencing and hashing, plus conversions to and from stl string c...