Skip to content

Commit 6e60347

Browse files
authored
api: extend TypeDesc and ParamType to represent ustringhash (#3915)
I think it will be handy to be able to have ParamValue contain ustringhashes and have a TypeDesc that can describe it explicitly. Signed-off-by: Larry Gritz <[email protected]>
1 parent 353e022 commit 6e60347

File tree

6 files changed

+71
-92
lines changed

6 files changed

+71
-92
lines changed

src/include/OpenImageIO/paramlist.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,11 @@ class OIIO_UTIL_API ParamValue {
110110
: ParamValue(_name, ustring(value))
111111
{
112112
}
113+
ParamValue(string_view _name, ustringhash value) noexcept
114+
{
115+
init_noclear(ustring(_name), TypeDesc::USTRINGHASH, 1, &value,
116+
Copy(true));
117+
}
113118

114119
// Set from string -- parse
115120
ParamValue(string_view _name, TypeDesc type, string_view value);

src/include/OpenImageIO/typedesc.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ struct OIIO_UTIL_API TypeDesc {
8383
DOUBLE, ///< 64-bit IEEE floating point values, (C/C++ `double`).
8484
STRING, ///< Character string.
8585
PTR, ///< A pointer value.
86+
USTRINGHASH, ///< The hash of a ustring
8687
LASTBASE
8788
};
8889

@@ -404,6 +405,7 @@ OIIO_INLINE_CONSTEXPR TypeDesc TypeTimeCode (TypeDesc::UINT, TypeDesc::SCALAR, T
404405
OIIO_INLINE_CONSTEXPR TypeDesc TypeKeyCode (TypeDesc::INT, TypeDesc::SCALAR, TypeDesc::KEYCODE, 7);
405406
OIIO_INLINE_CONSTEXPR TypeDesc TypeRational(TypeDesc::INT, TypeDesc::VEC2, TypeDesc::RATIONAL);
406407
OIIO_INLINE_CONSTEXPR TypeDesc TypePointer(TypeDesc::PTR);
408+
OIIO_INLINE_CONSTEXPR TypeDesc TypeUstringhash(TypeDesc::USTRINGHASH);
407409

408410

409411

@@ -485,6 +487,10 @@ template<> struct TypeDescFromC<Imath::Box3i> { static const constexpr TypeDesc
485487
#endif
486488

487489

490+
class ustringhash; // forward declaration
491+
492+
493+
488494
/// A template mechanism for getting C type of TypeDesc::BASETYPE.
489495
///
490496
template<int b> struct CType {};
@@ -501,6 +507,7 @@ template<> struct CType<(int)TypeDesc::HALF> { typedef half type; };
501507
#endif
502508
template<> struct CType<(int)TypeDesc::FLOAT> { typedef float type; };
503509
template<> struct CType<(int)TypeDesc::DOUBLE> { typedef double type; };
510+
template<> struct CType<(int)TypeDesc::USTRINGHASH> { typedef ustringhash type; };
504511

505512

506513

src/libutil/paramlist.cpp

Lines changed: 9 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,9 @@ ParamValue::ParamValue(string_view name, TypeDesc type, string_view value)
171171
} else if (type == TypeDesc::STRING) {
172172
ustring s(value);
173173
init(name, type, 1, &s);
174+
} else if (type == TypeDesc::USTRINGHASH) {
175+
ustringhash s(value);
176+
init(name, type, 1, &s);
174177
}
175178
}
176179

@@ -187,40 +190,11 @@ ParamValue::get_int(int defaultval) const
187190
int
188191
ParamValue::get_int_indexed(int index, int defaultval) const
189192
{
190-
#if 1 && OIIO_VERSION >= 20101
191193
int val = defaultval;
192194
convert_type(type().elementtype(),
193195
(const char*)data() + index * type().basesize(), TypeInt,
194196
&val);
195197
return val;
196-
#else
197-
int base = type().basetype;
198-
if (base == TypeDesc::INT)
199-
return get<int>(index);
200-
if (base == TypeDesc::UINT)
201-
return (int)get<unsigned int>(index);
202-
if (base == TypeDesc::INT16)
203-
return get<short>(index);
204-
if (base == TypeDesc::UINT16)
205-
return get<unsigned short>(index);
206-
if (base == TypeDesc::INT8)
207-
return get<char>(index);
208-
if (base == TypeDesc::UINT8)
209-
return get<unsigned char>(index);
210-
if (base == TypeDesc::INT64)
211-
return get<long long>(index);
212-
if (base == TypeDesc::UINT64)
213-
return get<unsigned long long>(index);
214-
if (base == TypeDesc::STRING) {
215-
// Only succeed for a string if it exactly holds something that
216-
// exactly parses to an int value.
217-
string_view str = get<ustring>(index);
218-
int val = defaultval;
219-
if (Strutil::parse_int(str, val) && str.empty())
220-
return val;
221-
}
222-
return defaultval; // Some nonstandard type, fail
223-
#endif
224198
}
225199

226200

@@ -236,54 +210,11 @@ ParamValue::get_float(float defaultval) const
236210
float
237211
ParamValue::get_float_indexed(int index, float defaultval) const
238212
{
239-
#if 1 && OIIO_VERSION >= 20101
240213
float val = defaultval;
241214
convert_type(type().elementtype(),
242215
(const char*)data() + index * type().basesize(), TypeFloat,
243216
&val);
244217
return val;
245-
#else
246-
int base = type().basetype;
247-
if (base == TypeDesc::FLOAT)
248-
return get<float>(index);
249-
if (base == TypeDesc::HALF)
250-
return get<half>(index);
251-
if (base == TypeDesc::DOUBLE)
252-
return get<double>(index);
253-
if (base == TypeDesc::INT) {
254-
if (type().aggregate == TypeDesc::VEC2
255-
&& type().vecsemantics == TypeDesc::RATIONAL) {
256-
int num = get<int>(2 * index + 0);
257-
int den = get<int>(2 * index + 1);
258-
return den ? float(num) / float(den) : 0.0f;
259-
}
260-
return get<int>(index);
261-
}
262-
if (base == TypeDesc::UINT)
263-
return get<unsigned int>(index);
264-
if (base == TypeDesc::INT16)
265-
return get<short>(index);
266-
if (base == TypeDesc::UINT16)
267-
return get<unsigned short>(index);
268-
if (base == TypeDesc::INT8)
269-
return get<char>(index);
270-
if (base == TypeDesc::UINT8)
271-
return get<unsigned char>(index);
272-
if (base == TypeDesc::INT64)
273-
return get<long long>(index);
274-
if (base == TypeDesc::UINT64)
275-
return get<unsigned long long>(index);
276-
if (base == TypeDesc::STRING) {
277-
// Only succeed for a string if it exactly holds something
278-
// that exactly parses to a float value.
279-
string_view str = get<ustring>(index);
280-
float val = defaultval;
281-
if (Strutil::parse_float(str, val) && str.empty())
282-
return val;
283-
}
284-
285-
return defaultval;
286-
#endif
287218
}
288219

289220

@@ -400,6 +331,8 @@ ParamValue::get_string_indexed(int index) const
400331
} else if (element.basetype == TypeDesc::PTR) {
401332
out += "ptr ";
402333
formatType<void*>(*this, index, index + 1, "{:p}", out);
334+
} else if (element.basetype == TypeDesc::USTRINGHASH) {
335+
return get<ustringhash>(index).string();
403336
} else {
404337
out += Strutil::fmt::format(
405338
"<unknown data type> (base {:d}, agg {:d} vec {:d})",
@@ -417,6 +350,8 @@ ParamValue::get_ustring(int maxsize) const
417350
// super inexpensive.
418351
if (type() == TypeDesc::STRING)
419352
return get<ustring>();
353+
if (type() == TypeDesc::USTRINGHASH)
354+
return ustring(get<ustringhash>());
420355
return ustring(get_string(maxsize));
421356
}
422357

@@ -429,6 +364,8 @@ ParamValue::get_ustring_indexed(int index) const
429364
// super inexpensive.
430365
if (type() == TypeDesc::STRING)
431366
return get<ustring>(index);
367+
if (type() == TypeDesc::USTRINGHASH)
368+
return ustring(get<ustringhash>());
432369
return ustring(get_string_indexed(index));
433370
}
434371

src/libutil/paramlist_test.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,18 @@ test_value_types()
104104
const char* val = "hello";
105105
ParamValue p("name", val);
106106
OIIO_CHECK_EQUAL(p.get<ustring>(), "hello");
107+
OIIO_CHECK_EQUAL(p.get_ustring(), "hello");
107108
OIIO_CHECK_EQUAL(p.get_string(), "hello");
108109
}
109110

111+
{
112+
ustringhash val("hello");
113+
ParamValue p("name", val);
114+
OIIO_CHECK_EQUAL(p.get_string(), "hello");
115+
OIIO_CHECK_EQUAL(p.get_ustring(), "hello");
116+
OIIO_CHECK_EQUAL(p.get<ustringhash>(), val);
117+
}
118+
110119
{
111120
const void* ptr = reinterpret_cast<const void*>(size_t(0xdeadbeef));
112121
ParamValue p("name", TypeDesc::PTR, 1, &ptr);

src/libutil/typedesc.cpp

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ static int basetype_size[TypeDesc::LASTBASE] = {
4747
sizeof(float), // FLOAT
4848
sizeof(double), // DOUBLE
4949
sizeof(char*), // STRING
50-
sizeof(void*) // PTR
50+
sizeof(void*), // PTR
51+
sizeof(ustringhash), // USTRINGHASH
5152
};
5253

5354
}
@@ -81,7 +82,8 @@ TypeDesc::is_floating_point() const noexcept
8182
1, // FLOAT
8283
1, // DOUBLE
8384
0, // STRING
84-
0 // PTR
85+
0, // PTR
86+
0, // USTRINGHASH
8587
};
8688
OIIO_DASSERT(basetype < TypeDesc::LASTBASE);
8789
return isfloat[basetype];
@@ -107,7 +109,8 @@ TypeDesc::is_signed() const noexcept
107109
1, // FLOAT
108110
1, // DOUBLE
109111
0, // STRING
110-
0 // PTR
112+
0, // PTR
113+
0, // USTRINGHASH
111114
};
112115
OIIO_DASSERT(basetype < TypeDesc::LASTBASE);
113116
return issigned[basetype];
@@ -118,21 +121,22 @@ TypeDesc::is_signed() const noexcept
118121
namespace {
119122

120123
static const char* basetype_name[] = {
121-
"unknown", // UNKNOWN
122-
"void", // VOID/NONE
123-
"uint8", // UCHAR
124-
"int8", // CHAR
125-
"uint16", // USHORT
126-
"int16", // SHORT
127-
"uint", // UINT
128-
"int", // INT
129-
"uint64", // ULONGLONG
130-
"int64", // LONGLONG
131-
"half", // HALF
132-
"float", // FLOAT
133-
"double", // DOUBLE
134-
"string", // STRING
135-
"pointer" // PTR
124+
"unknown", // UNKNOWN
125+
"void", // VOID/NONE
126+
"uint8", // UCHAR
127+
"int8", // CHAR
128+
"uint16", // USHORT
129+
"int16", // SHORT
130+
"uint", // UINT
131+
"int", // INT
132+
"uint64", // ULONGLONG
133+
"int64", // LONGLONG
134+
"half", // HALF
135+
"float", // FLOAT
136+
"double", // DOUBLE
137+
"string", // STRING
138+
"pointer", // PTR
139+
"ustringhash", // USTRINGHASH
136140
};
137141

138142
static const char* basetype_code[] = {
@@ -150,7 +154,8 @@ static const char* basetype_code[] = {
150154
"f", // FLOAT
151155
"d", // DOUBLE
152156
"str", // STRING
153-
"ptr" // PTR
157+
"ptr", // PTR
158+
"uh", // USTRINGHASH
154159
};
155160

156161
} // namespace
@@ -318,6 +323,8 @@ TypeDesc::fromstring(string_view typestring)
318323
t = TypeKeyCode;
319324
else if (type == "pointer")
320325
t = TypePointer;
326+
else if (type == "ustringhash")
327+
t = TypeUstringhash;
321328
else {
322329
return 0; // unknown
323330
}
@@ -625,6 +632,14 @@ tostring(TypeDesc type, const void* data, const tostring_formatting& fmt)
625632
return fmt.use_sprintf
626633
? sprint_type(type, fmt.ptr_fmt, fmt, (void**)data)
627634
: format_type(type, fmt.ptr_fmt, fmt, (void**)data);
635+
case TypeDesc::USTRINGHASH: {
636+
const char* v = ((const ustringhash*)data)->c_str();
637+
if (!type.is_array()
638+
&& !(fmt.flags & tostring_formatting::quote_single_string))
639+
return v ? v : "";
640+
return fmt.use_sprintf ? sprint_type(type, fmt.string_fmt, fmt, &v)
641+
: format_type(type, fmt.string_fmt, fmt, &v);
642+
}
628643
default:
629644
#ifndef NDEBUG
630645
return Strutil::sprintf("<unknown data type> (base %d, agg %d vec %d)",
@@ -780,7 +795,10 @@ convert_type(TypeDesc srctype, const void* src, TypeDesc dsttype, void* dst,
780795
}
781796

782797
if (dsttype == TypeString) {
783-
(*(ustring*)dst) = ustring(tostring(srctype, src));
798+
if (srctype == TypeUstringhash)
799+
(*(ustring*)dst) = ustring::from_hash(*(const ustring::hash_t*)src);
800+
else
801+
(*(ustring*)dst) = ustring(tostring(srctype, src));
784802
return true;
785803
}
786804

src/libutil/typedesc_test.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include <OpenImageIO/typedesc.h>
2020
#include <OpenImageIO/unittest.h>
21+
#include <OpenImageIO/ustring.h>
2122

2223

2324
using namespace OIIO;
@@ -144,6 +145,8 @@ main(int /*argc*/, char* /*argv*/[])
144145
TypeFloat4, {});
145146
test_type<const char*>("string", TypeDesc(TypeDesc::STRING), TypeString,
146147
"hello", "hello");
148+
test_type<ustringhash>("ustringhash", TypeDesc(TypeDesc::USTRINGHASH),
149+
TypeUstringhash, ustringhash("hello"), "hello");
147150
int i2[2] = { 1, 2 };
148151
test_type<int[2]>("rational",
149152
TypeDesc(TypeDesc::INT, TypeDesc::VEC2,

0 commit comments

Comments
 (0)