Skip to content

Commit

Permalink
paramlist.h: ParamValue as_span, as_cspan
Browse files Browse the repository at this point in the history
Convenience methods that give a bounded span of the data that a PV holds.

Signed-off-by: Larry Gritz <[email protected]>
  • Loading branch information
lgritz committed Jan 15, 2025
1 parent b888205 commit 7f2e8e6
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 15 deletions.
20 changes: 20 additions & 0 deletions src/include/OpenImageIO/paramlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,26 @@ class OIIO_UTIL_API ParamValue {
b = std::move(tmp);
}

/// Return a `cspan<T>` pointing to the bounded data. If the type `T` is
/// not the actual underlying base type, return an empty span.
template<typename T> cspan<T> as_cspan() const noexcept
{
return BaseTypeFromC<T>::value == m_type.basetype
? make_cspan(reinterpret_cast<const T*>(data()),
size_t(m_nvalues * m_type.basevalues()))
: cspan<T>();
}

/// Return a `span<T>` pointing to the bounded data. If the type `T` is
/// not the actual underlying base type, return an empty span.
template<typename T> span<T> as_span() noexcept
{
return BaseTypeFromC<T>::value == m_type.basetype
? make_span(reinterpret_cast<T*>(const_cast<void*>(data())),
size_t(m_nvalues * m_type.basevalues()))
: span<T>();
}

// Use with extreme caution! This is just doing a cast. You'd better
// be really sure you are asking for the right type. Note that for
// "string" data, you can get<ustring> or get<char*>, but it's not
Expand Down
14 changes: 10 additions & 4 deletions src/include/OpenImageIO/typedesc.h
Original file line number Diff line number Diff line change
Expand Up @@ -395,12 +395,18 @@ OIIO_INLINE_CONSTEXPR TypeDesc TypeUstringhash(TypeDesc::USTRINGHASH);
template<typename T> struct BaseTypeFromC {};
template<> struct BaseTypeFromC<unsigned char> { static const TypeDesc::BASETYPE value = TypeDesc::UINT8; };
template<> struct BaseTypeFromC<char> { static const TypeDesc::BASETYPE value = TypeDesc::INT8; };
template<> struct BaseTypeFromC<unsigned short> { static const TypeDesc::BASETYPE value = TypeDesc::UINT16; };
template<> struct BaseTypeFromC<short> { static const TypeDesc::BASETYPE value = TypeDesc::INT16; };
template<> struct BaseTypeFromC<unsigned int> { static const TypeDesc::BASETYPE value = TypeDesc::UINT; };
template<> struct BaseTypeFromC<int> { static const TypeDesc::BASETYPE value = TypeDesc::INT; };
template<> struct BaseTypeFromC<uint16_t> { static const TypeDesc::BASETYPE value = TypeDesc::UINT16; };
template<> struct BaseTypeFromC<int16_t> { static const TypeDesc::BASETYPE value = TypeDesc::INT16; };
template<> struct BaseTypeFromC<uint32_t> { static const TypeDesc::BASETYPE value = TypeDesc::UINT; };
template<> struct BaseTypeFromC<int32_t> { static const TypeDesc::BASETYPE value = TypeDesc::INT; };
template<> struct BaseTypeFromC<uint64_t> { static const TypeDesc::BASETYPE value = TypeDesc::UINT64; };
template<> struct BaseTypeFromC<int64_t> { static const TypeDesc::BASETYPE value = TypeDesc::INT64; };
#if defined(__GNUC__) && !defined(__apple_build_version__) && __WORDSIZE == 64
// gcc on some platforms consider int64_t and long long to be different
// types, even though they are actually the same size.
template<> struct BaseTypeFromC<unsigned long long> { static const TypeDesc::BASETYPE value = TypeDesc::UINT64; };
template<> struct BaseTypeFromC<long long> { static const TypeDesc::BASETYPE value = TypeDesc::INT64; };
#endif
#if defined(_HALF_H_) || defined(IMATH_HALF_H_)
template<> struct BaseTypeFromC<half> { static const TypeDesc::BASETYPE value = TypeDesc::HALF; };
#endif
Expand Down
17 changes: 6 additions & 11 deletions src/libutil/paramlist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ ParamValue::init_noclear(ustring _name, TypeDesc _type, int _nvalues,
m_type = _type;
m_nvalues = _nvalues;
m_interp = _interp;
size_t n = (size_t)(m_nvalues * m_type.numelements());
size_t size = (size_t)(m_nvalues * m_type.size());
bool small = (size <= sizeof(m_data));

Expand All @@ -58,9 +57,9 @@ ParamValue::init_noclear(ustring _name, TypeDesc _type, int _nvalues,
m_nonlocal = true;
}
if (m_type.basetype == TypeDesc::STRING && !_from_ustring) {
if (ustring* u = (ustring*)data())
for (size_t i = 0; i < n; ++i)
u[i] = ustring(u[i].c_str());
// Convert non-ustrings to ustrings
for (ustring& u : as_span<ustring>())
u = ustring(u.c_str());
}
} else {
// Big enough to warrant a malloc, but the caller said don't
Expand Down Expand Up @@ -126,17 +125,13 @@ template<class T>
static void
parse_elements(string_view value, ParamValue& p)
{
using namespace Strutil;
TypeDesc type = p.type();
int num_items = type.numelements() * type.aggregate;
T* data = (T*)p.data();
// Erase any leading whitespace
auto data = p.as_span<T>();
value.remove_prefix(value.find_first_not_of(" \t"));
for (int i = 0; i < num_items; ++i) {
for (auto&& d : data) {
// Make a temporary copy so we for sure have a 0-terminated string.
std::string temp = value;
// Grab the first value from it
data[i] = from_string<T>(temp);
d = Strutil::from_string<T>(temp);
// Skip the value (eat until we find a delimiter -- space, comma, tab)
value.remove_prefix(value.find_first_of(" ,\t"));
// Skip the delimiter
Expand Down

0 comments on commit 7f2e8e6

Please sign in to comment.