24 #ifndef USD_CRATE_VALUE_INLINERS_H
25 #define USD_CRATE_VALUE_INLINERS_H
28 #include "pxr/base/gf/traits.h"
30 #include <type_traits>
35 PXR_NAMESPACE_OPEN_SCOPE
38 namespace Usd_CrateValueInliners
44 template <
class Src,
class Dst>
45 inline bool _IsExactlyRepresented(Src
const &src, Dst *dst) {
46 Src min =
static_cast<Src
>(std::numeric_limits<Dst>::lowest());
47 Src max =
static_cast<Src
>(std::numeric_limits<Dst>::max());
48 if (min <= src && src <= max &&
49 static_cast<Src>(static_cast<Dst>(src)) == src) {
50 *dst =
static_cast<Dst
>(src);
57 template <
class T>
bool _EncodeInline(T, ...) {
return false; }
58 template <
class T>
void _DecodeInline(T *, ...) { }
63 typename std::enable_if<std::is_floating_point<FP>::value,
bool>::type
64 _EncodeInline(FP fp, uint32_t *ival) {
67 if (_IsExactlyRepresented(fp, &f)) {
68 memcpy(ival, &f,
sizeof(f));
74 typename std::enable_if<std::is_floating_point<FP>::value>::type
75 _DecodeInline(FP *fp, uint32_t ival) {
77 memcpy(&f, &ival,
sizeof(f));
78 *fp =
static_cast<FP
>(f);
84 typename std::enable_if<std::is_integral<INT>::value,
bool>::type
85 _EncodeInline(INT i, uint32_t *ival) {
87 using int_t =
typename std::conditional<
88 std::is_signed<INT>::value, int32_t, uint32_t>::type;
90 if (_IsExactlyRepresented(i, &rep)) {
91 memcpy(ival, &rep,
sizeof(rep));
97 typename std::enable_if<std::is_integral<INT>::value>::type
98 _DecodeInline(INT *i, uint32_t ival) {
99 using int_t =
typename std::conditional<
100 std::is_signed<INT>::value, int32_t, uint32_t>::type;
102 memcpy(&tmp, &ival,
sizeof(tmp));
103 *i =
static_cast<INT
>(tmp);
109 typename std::enable_if<GfIsGfVec<T>::value,
bool>::type
110 _EncodeInline(T vec, uint32_t *out) {
113 static_assert(T::dimension <= 4,
"Vec dimension cannot exceed 4.");
114 int8_t ivec[T::dimension];
115 for (
int i = 0; i != T::dimension; ++i) {
116 if (!_IsExactlyRepresented(vec[i], &ivec[i]))
120 memcpy(out, ivec,
sizeof(ivec));
124 typename std::enable_if<GfIsGfVec<T>::value>::type
125 _DecodeInline(T *vec, uint32_t in) {
126 int8_t ivec[T::dimension];
127 memcpy(ivec, &in,
sizeof(ivec));
128 for (
int i = 0; i != T::dimension; ++i) {
129 (*vec)[i] =
static_cast<typename T::ScalarType
>(ivec[i]);
136 template <
class Matrix>
137 typename std::enable_if<GfIsGfMatrix<Matrix>::value,
bool>::type
138 _EncodeInline(Matrix m, uint32_t *out) {
139 static_assert(Matrix::numRows == Matrix::numColumns,
140 "Requires square matrices");
141 static_assert(Matrix::numRows <= 4,
142 "Matrix dimension cannot exceed 4");
144 int8_t diag[Matrix::numRows];
145 for (
int i = 0; i != Matrix::numRows; ++i) {
146 for (
int j = 0; j != Matrix::numColumns; ++j) {
147 if (((i != j) && m[i][j] != 0) ||
148 ((i == j) && !_IsExactlyRepresented(m[i][j], &diag[i]))) {
156 memcpy(out, diag,
sizeof(diag));
159 template <
class Matrix>
160 typename std::enable_if<GfIsGfMatrix<Matrix>::value>::type
161 _DecodeInline(Matrix *m, uint32_t in) {
162 int8_t diag[Matrix::numRows];
163 memcpy(diag, &in,
sizeof(diag));
165 for (
int i = 0; i != Matrix::numRows; ++i) {
166 (*m)[i][i] =
static_cast<typename Matrix::ScalarType
>(diag[i]);
173 _EncodeInline(
VtDictionary const &dict, uint32_t *ival) {
188 PXR_NAMESPACE_CLOSE_SCOPE
190 #endif // USD_CRATE_VALUE_INLINERS_H
A map with string keys and VtValue values.
VT_API bool empty() const
true if the VtDictionary's size is 0.