Fix type comparison on OSX

`UnknownArrayHandle` compares `std::type_index` objects to check whether a
requested type is the same as that held in the array handle. However, it is
possible that different translation units can create different but
equivalent `std::type_info`/`std::type_index` objects. In this case, the
`==` operator might return false for two equivalent types. This can happen
on OSX.

To get around this problem, `UnknownArrayHandle` now does a more extensive
check for `std::type_info` object. It first uses the `==` operator to
compare them (as before), which usually works but can possibly return
`false` when the correct result is `true`. To check for this case, it then
compares the name for the two types and returns `true` iff the two names
are the same.
This commit is contained in:
Kenneth Moreland 2022-06-30 07:37:27 -06:00
parent 22ee3c3fa5
commit e312c54356
2 changed files with 38 additions and 2 deletions

@ -0,0 +1,15 @@
# Fix type comparison on OSX
`UnknownArrayHandle` compares `std::type_index` objects to check whether a
requested type is the same as that held in the array handle. However, it is
possible that different translation units can create different but
equivalent `std::type_info`/`std::type_index` objects. In this case, the
`==` operator might return false for two equivalent types. This can happen
on OSX.
To get around this problem, `UnknownArrayHandle` now does a more extensive
check for `std::type_info` object. It first uses the `==` operator to
compare them (as before), which usually works but can possibly return
`false` when the correct result is `true`. To check for this case, it then
compares the name for the two types and returns `true` iff the two names
are the same.

@ -26,6 +26,7 @@
#include <vtkm/cont/internal/ArrayCopyUnknown.h>
#include <cstring>
#include <sstream>
namespace
@ -108,7 +109,17 @@ VTKM_CONT bool UnknownArrayHandle::IsValueTypeImpl(std::type_index type) const
}
// Needs optimization based on platform. OSX cannot compare typeid across translation units?
return this->Container->ValueType == type;
bool typesEqual = (this->Container->ValueType == type);
// Could use optimization based on platform. OSX cannot compare typeid across translation
// units, so we have to also check the names. (Why doesn't the == operator above do that?)
// Are there other platforms that behave similarly?
if (!typesEqual)
{
typesEqual = (std::strcmp(this->Container->ValueType.name(), type.name()) == 0);
}
return typesEqual;
}
VTKM_CONT bool UnknownArrayHandle::IsStorageTypeImpl(std::type_index type) const
@ -119,7 +130,17 @@ VTKM_CONT bool UnknownArrayHandle::IsStorageTypeImpl(std::type_index type) const
}
// Needs optimization based on platform. OSX cannot compare typeid across translation units?
return this->Container->StorageType == type;
bool typesEqual = (this->Container->StorageType == type);
// Could use optimization based on platform. OSX cannot compare typeid across translation
// units, so we have to also check the names. (Why doesn't the == operator above do that?)
// Are there other platforms that behave similarly?
if (!typesEqual)
{
typesEqual = (std::strcmp(this->Container->StorageType.name(), type.name()) == 0);
}
return typesEqual;
}
VTKM_CONT bool UnknownArrayHandle::IsBaseComponentTypeImpl(