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