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