Skip to content

Commit cd49e6a

Browse files
committed
paramlist.h: ParamValue as_span, as_cspan
Convenience methods that give a bounded span of the data that a PV holds. Signed-off-by: Larry Gritz <[email protected]>
1 parent 8f489e1 commit cd49e6a

File tree

3 files changed

+36
-15
lines changed

3 files changed

+36
-15
lines changed

src/include/OpenImageIO/paramlist.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,26 @@ class OIIO_UTIL_API ParamValue {
215215
b = std::move(tmp);
216216
}
217217

218+
/// Return a `cspan<T>` pointing to the bounded data. If the type `T` is
219+
/// not the actual underlying base type, return an empty span.
220+
template<typename T> cspan<T> as_cspan() const noexcept
221+
{
222+
return BaseTypeFromC<T>::value == m_type.basetype
223+
? make_cspan(reinterpret_cast<const T*>(data()),
224+
size_t(m_nvalues * m_type.basevalues()))
225+
: cspan<T>();
226+
}
227+
228+
/// Return a `span<T>` pointing to the bounded data. If the type `T` is
229+
/// not the actual underlying base type, return an empty span.
230+
template<typename T> span<T> as_span() noexcept
231+
{
232+
return BaseTypeFromC<T>::value == m_type.basetype
233+
? make_span(reinterpret_cast<T*>(const_cast<void*>(data())),
234+
size_t(m_nvalues * m_type.basevalues()))
235+
: span<T>();
236+
}
237+
218238
// Use with extreme caution! This is just doing a cast. You'd better
219239
// be really sure you are asking for the right type. Note that for
220240
// "string" data, you can get<ustring> or get<char*>, but it's not

src/include/OpenImageIO/typedesc.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -395,12 +395,18 @@ OIIO_INLINE_CONSTEXPR TypeDesc TypeUstringhash(TypeDesc::USTRINGHASH);
395395
template<typename T> struct BaseTypeFromC {};
396396
template<> struct BaseTypeFromC<unsigned char> { static const TypeDesc::BASETYPE value = TypeDesc::UINT8; };
397397
template<> struct BaseTypeFromC<char> { static const TypeDesc::BASETYPE value = TypeDesc::INT8; };
398-
template<> struct BaseTypeFromC<unsigned short> { static const TypeDesc::BASETYPE value = TypeDesc::UINT16; };
399-
template<> struct BaseTypeFromC<short> { static const TypeDesc::BASETYPE value = TypeDesc::INT16; };
400-
template<> struct BaseTypeFromC<unsigned int> { static const TypeDesc::BASETYPE value = TypeDesc::UINT; };
401-
template<> struct BaseTypeFromC<int> { static const TypeDesc::BASETYPE value = TypeDesc::INT; };
398+
template<> struct BaseTypeFromC<uint16_t> { static const TypeDesc::BASETYPE value = TypeDesc::UINT16; };
399+
template<> struct BaseTypeFromC<int16_t> { static const TypeDesc::BASETYPE value = TypeDesc::INT16; };
400+
template<> struct BaseTypeFromC<uint32_t> { static const TypeDesc::BASETYPE value = TypeDesc::UINT; };
401+
template<> struct BaseTypeFromC<int32_t> { static const TypeDesc::BASETYPE value = TypeDesc::INT; };
402+
template<> struct BaseTypeFromC<uint64_t> { static const TypeDesc::BASETYPE value = TypeDesc::UINT64; };
403+
template<> struct BaseTypeFromC<int64_t> { static const TypeDesc::BASETYPE value = TypeDesc::INT64; };
404+
#if defined(__GNUC__) && !defined(__apple_build_version__) && __WORDSIZE == 64
405+
// gcc on some platforms consider int64_t and long long to be different
406+
// types, even though they are actually the same size.
402407
template<> struct BaseTypeFromC<unsigned long long> { static const TypeDesc::BASETYPE value = TypeDesc::UINT64; };
403408
template<> struct BaseTypeFromC<long long> { static const TypeDesc::BASETYPE value = TypeDesc::INT64; };
409+
#endif
404410
#if defined(_HALF_H_) || defined(IMATH_HALF_H_)
405411
template<> struct BaseTypeFromC<half> { static const TypeDesc::BASETYPE value = TypeDesc::HALF; };
406412
#endif

src/libutil/paramlist.cpp

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ ParamValue::init_noclear(ustring _name, TypeDesc _type, int _nvalues,
3535
m_type = _type;
3636
m_nvalues = _nvalues;
3737
m_interp = _interp;
38-
size_t n = (size_t)(m_nvalues * m_type.numelements());
3938
size_t size = (size_t)(m_nvalues * m_type.size());
4039
bool small = (size <= sizeof(m_data));
4140

@@ -58,9 +57,9 @@ ParamValue::init_noclear(ustring _name, TypeDesc _type, int _nvalues,
5857
m_nonlocal = true;
5958
}
6059
if (m_type.basetype == TypeDesc::STRING && !_from_ustring) {
61-
if (ustring* u = (ustring*)data())
62-
for (size_t i = 0; i < n; ++i)
63-
u[i] = ustring(u[i].c_str());
60+
// Convert non-ustrings to ustrings
61+
for (ustring& u : as_span<ustring>())
62+
u = ustring(u.c_str());
6463
}
6564
} else {
6665
// Big enough to warrant a malloc, but the caller said don't
@@ -126,17 +125,13 @@ template<class T>
126125
static void
127126
parse_elements(string_view value, ParamValue& p)
128127
{
129-
using namespace Strutil;
130-
TypeDesc type = p.type();
131-
int num_items = type.numelements() * type.aggregate;
132-
T* data = (T*)p.data();
133-
// Erase any leading whitespace
128+
auto data = p.as_span<T>();
134129
value.remove_prefix(value.find_first_not_of(" \t"));
135-
for (int i = 0; i < num_items; ++i) {
130+
for (auto&& d : data) {
136131
// Make a temporary copy so we for sure have a 0-terminated string.
137132
std::string temp = value;
138133
// Grab the first value from it
139-
data[i] = from_string<T>(temp);
134+
d = Strutil::from_string<T>(temp);
140135
// Skip the value (eat until we find a delimiter -- space, comma, tab)
141136
value.remove_prefix(value.find_first_of(" ,\t"));
142137
// Skip the delimiter

0 commit comments

Comments
 (0)