Improve type reporting in UnknownArrayHandle

Added features with reporting types with `UnknownArrayHandle`. First,
added a method named `GetArrayTypeName` that returns a string containing
the type of the contained array. There were already methods
`GetValueType` and `GetStorageType`, but this provides a convenience to
get the whole name in one go.

Also improved the reporting when an `AsArrayHandle` call failed. Before,
the thrown method just reported that the `UnknownArrayHandle` could not
be converted to the given type. Now, it also reports the type actually
held by the `UnknownArrayHandle` so the user can better understand why
the conversion failed.
This commit is contained in:
Kenneth Moreland 2021-08-04 07:59:48 -06:00
parent 6f5455d0d6
commit 1ec4e5d62c
6 changed files with 47 additions and 7 deletions

@ -0,0 +1,14 @@
# Improve type reporting in `UnknownArrayHandle`
Added features with reporting types with `UnknownArrayHandle`. First, added
a method named `GetArrayTypeName` that returns a string containing the type
of the contained array. There were already methods `GetValueType` and
`GetStorageType`, but this provides a convenience to get the whole name in
one go.
Also improved the reporting when an `AsArrayHandle` call failed. Before,
the thrown method just reported that the `UnknownArrayHandle` could not be
converted to the given type. Now, it also reports the type actually held by
the `UnknownArrayHandle` so the user can better understand why the
conversion failed.

@ -237,7 +237,7 @@ vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(const vtkm::cont::Unknown
return ArrayRangeCompute(array.AsArrayHandle<vtkm::cont::ArrayHandleIndex>(), device);
}
}
catch (vtkm::cont::ErrorBadValue&)
catch (vtkm::cont::ErrorBadType&)
{
// If a cast/call failed, try falling back to a more general implementation.
}

@ -201,6 +201,19 @@ VTKM_CONT std::string UnknownArrayHandle::GetStorageTypeName() const
}
}
VTKM_CONT std::string UnknownArrayHandle::GetArrayTypeName() const
{
if (this->Container)
{
return "vtkm::cont::ArrayHandle<" + this->GetValueTypeName() + ", " +
this->GetStorageTypeName() + ">";
}
else
{
return "";
}
}
VTKM_CONT vtkm::Id UnknownArrayHandle::GetNumberOfValues() const
{
if (this->Container)
@ -297,7 +310,7 @@ VTKM_CONT_EXPORT void ThrowCastAndCallException(const vtkm::cont::UnknownArrayHa
"Array: ";
ref.PrintSummary(out);
out << "TypeList: " << vtkm::cont::TypeToString(type) << "\n";
throw vtkm::cont::ErrorBadValue(out.str());
throw vtkm::cont::ErrorBadType(out.str());
}
} // namespace detail

@ -447,6 +447,13 @@ public:
/// Returns an empty string if no array is stored.
VTKM_CONT std::string GetStorageTypeName() const;
/// \brief Returns a string representation of the underlying data type.
///
/// The returned string will be of the form `vtkm::cont::ArrayHandle<T, S>` rather than the name
/// of an actual subclass. If no array is stored, an empty string is returned.
///
VTKM_CONT std::string GetArrayTypeName() const;
/// Returns true if this array matches the ValueType template argument.
///
template <typename ValueType>
@ -580,7 +587,7 @@ public:
if (!this->IsType<ArrayType>())
{
VTKM_LOG_CAST_FAIL(*this, decltype(array));
throwFailedDynamicCast(vtkm::cont::TypeToString(*this), vtkm::cont::TypeToString(array));
throwFailedDynamicCast(this->GetArrayTypeName(), vtkm::cont::TypeToString(array));
}
array = *reinterpret_cast<ArrayType*>(this->Container->ArrayHandlePointer);

@ -90,8 +90,8 @@ struct CheckFunctor
void operator()(const vtkm::cont::ArrayHandle<T, S>& array, bool& called) const
{
called = true;
std::cout << " Checking for array type " << typeid(T).name() << " with storage "
<< typeid(S).name() << std::endl;
std::cout << " Checking for array type " << vtkm::cont::TypeToString<T>() << " with storage "
<< vtkm::cont::TypeToString<S>() << std::endl;
CheckArray(array);
}
@ -100,6 +100,8 @@ struct CheckFunctor
void BasicUnknownArrayChecks(const vtkm::cont::UnknownArrayHandle& array,
vtkm::IdComponent numComponents)
{
std::cout << " Checking an UnknownArrayHandle containing " << array.GetArrayTypeName()
<< std::endl;
VTKM_TEST_ASSERT(array.GetNumberOfValues() == ARRAY_SIZE,
"Dynamic array reports unexpected size.");
VTKM_TEST_ASSERT(array.GetNumberOfComponentsFlat() == numComponents,
@ -388,6 +390,10 @@ struct TryBasicVTKmType
{
vtkm::cont::UnknownArrayHandle array = CreateArrayUnknown(T());
VTKM_TEST_ASSERT(array.GetValueTypeName() == vtkm::cont::TypeToString<T>());
VTKM_TEST_ASSERT(array.GetStorageTypeName() ==
vtkm::cont::TypeToString<vtkm::cont::StorageTagBasic>());
CheckUnknownArray<vtkm::TypeListAll, VTKM_DEFAULT_STORAGE_LIST>(
array, vtkm::VecTraits<T>::NUM_COMPONENTS);
@ -405,7 +411,7 @@ void TryUnusualType()
CheckUnknownArray<VTKM_DEFAULT_TYPE_LIST, VTKM_DEFAULT_STORAGE_LIST>(array, 1);
VTKM_TEST_FAIL("CastAndCall failed to error for unrecognized type.");
}
catch (vtkm::cont::ErrorBadValue&)
catch (vtkm::cont::ErrorBadType&)
{
std::cout << " Caught exception for unrecognized type." << std::endl;
}

@ -457,7 +457,7 @@ void TryUnusualType()
CheckArrayVariant(array, 1, true);
VTKM_TEST_FAIL("CastAndCall failed to error for unrecognized type.");
}
catch (vtkm::cont::ErrorBadValue&)
catch (vtkm::cont::ErrorBadType&)
{
std::cout << " Caught exception for unrecognized type." << std::endl;
}