mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-08 13:23:51 +00:00
Correct IsType and Cast on ArrayHandleVirtual to work on OSX.
This commit is contained in:
parent
7b9fa975f2
commit
acf825b279
@ -51,16 +51,6 @@ public:
|
||||
void ReleaseResources();
|
||||
|
||||
private:
|
||||
// StorageAny is meant to be seamless when it comes to IsType so we will match
|
||||
// when either the type_info is 'StorageAny<T,S>' or 'Storage<T,S>'. That is why
|
||||
// we need to override the default implementation.
|
||||
bool IsSameType(const std::type_info& other) const
|
||||
{
|
||||
//We don't wan to check just 'S' as that just the tag
|
||||
using ST = typename vtkm::cont::internal::Storage<T, S>;
|
||||
return other == typeid(ST) || other == typeid(*this);
|
||||
}
|
||||
|
||||
std::unique_ptr<StorageVirtual> MakeNewInstance() const
|
||||
{
|
||||
return std::unique_ptr<StorageVirtual>(new StorageAny<T, S>{ vtkm::cont::ArrayHandle<T, S>{} });
|
||||
|
@ -115,7 +115,8 @@ private:
|
||||
/// array at that position.
|
||||
///
|
||||
template <class FunctorType>
|
||||
class ArrayHandleImplicit : public detail::ArrayHandleImplicitTraits<FunctorType>::Superclass
|
||||
class VTKM_ALWAYS_EXPORT ArrayHandleImplicit
|
||||
: public detail::ArrayHandleImplicitTraits<FunctorType>::Superclass
|
||||
{
|
||||
private:
|
||||
using ArrayTraits = typename detail::ArrayHandleImplicitTraits<FunctorType>;
|
||||
|
@ -134,7 +134,6 @@ public:
|
||||
return true; // different valuetype and/or storage
|
||||
}
|
||||
|
||||
|
||||
/// Returns true if this array's storage matches the type passed in.
|
||||
///
|
||||
template <typename ArrayHandleType>
|
||||
@ -155,6 +154,28 @@ public:
|
||||
return this->IsSameType<ArrayHandleType>(is_base{});
|
||||
}
|
||||
|
||||
/// Returns this array cast to the given \c ArrayHandle type. Throws \c
|
||||
/// ErrorBadType if the cast does not work. Use \c IsType
|
||||
/// to check if the cast can happen.
|
||||
///
|
||||
template <typename ArrayHandleType>
|
||||
VTKM_CONT ArrayHandleType Cast() const
|
||||
{
|
||||
VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
|
||||
using VT = typename ArrayHandleType::ValueType;
|
||||
static_assert(
|
||||
std::is_same<VT, T>::value,
|
||||
"ArrayHandleVirtual<ValueType> can only be casted to an ArrayHandle of the same ValueType.");
|
||||
|
||||
//We need to determine if we are checking that `ArrayHandleType`
|
||||
//is a virtual array handle since that is an easy check.
|
||||
//Or if we have to go ask the storage if they are holding
|
||||
//
|
||||
using ST = typename ArrayHandleType::StorageTag;
|
||||
using is_base = std::is_same<vtkm::cont::StorageTagVirtual, ST>;
|
||||
return this->CastToType<ArrayHandleType>(is_base{});
|
||||
}
|
||||
|
||||
/// Returns a new instance of an ArrayHandleVirtual with the same storage
|
||||
///
|
||||
VTKM_CONT ArrayHandle<T, ::vtkm::cont::StorageTagVirtual> NewInstance() const
|
||||
@ -285,19 +306,36 @@ private:
|
||||
bool IsSameType(std::true_type vtkmNotUsed(inheritsFromArrayHandleVirtual)) const
|
||||
{
|
||||
//All classes that derive from ArrayHandleVirtual have virtual methods so we can use
|
||||
//typeid directly
|
||||
return typeid(*this) == typeid(ArrayHandleType);
|
||||
//typeid directly.
|
||||
//needs optimizations based on platform. !OSX can use typeid
|
||||
return nullptr != dynamic_cast<const ArrayHandleType*>(this);
|
||||
}
|
||||
|
||||
template <typename ArrayHandleType>
|
||||
bool IsSameType(std::false_type vtkmNotUsed(notFromArrayHandleVirtual)) const
|
||||
bool IsSameType(std::false_type vtkmNotUsed(notFromArrayHandleVirtual)) const;
|
||||
|
||||
template <typename ArrayHandleType>
|
||||
ArrayHandleType CastToType(std::true_type vtkmNotUsed(inheritsFromArrayHandleVirtual)) const
|
||||
{
|
||||
//We need to go long the way to find the StorageType
|
||||
//as StorageType is private on lots of derived ArrayHandles
|
||||
//See Issue #314
|
||||
using ST = typename ArrayHandleType::StorageTag;
|
||||
return this->Storage->IsType(typeid(vtkm::cont::internal::Storage<T, ST>));
|
||||
//All classes that derive from ArrayHandleVirtual have virtual methods so we can use
|
||||
//dynamic_cast directly
|
||||
if (!this->Storage)
|
||||
{
|
||||
VTKM_LOG_CAST_FAIL(*this, ArrayHandleType);
|
||||
throwFailedDynamicCast("ArrayHandleVirtual", vtkm::cont::TypeName<ArrayHandleType>());
|
||||
}
|
||||
const ArrayHandleType* derived = dynamic_cast<const ArrayHandleType*>(this);
|
||||
if (!derived)
|
||||
{
|
||||
VTKM_LOG_CAST_FAIL(*this, ArrayHandleType);
|
||||
throwFailedDynamicCast("ArrayHandleVirtual", vtkm::cont::TypeName<ArrayHandleType>());
|
||||
}
|
||||
VTKM_LOG_CAST_SUCC(*this, derived);
|
||||
return *derived;
|
||||
}
|
||||
|
||||
template <typename ArrayHandleType>
|
||||
ArrayHandleType CastToType(std::false_type vtkmNotUsed(notFromArrayHandleVirtual)) const;
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
@ -306,6 +344,23 @@ template <typename T>
|
||||
using ArrayHandleVirtual = vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagVirtual>;
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// Free function casting helpers
|
||||
|
||||
template <typename ArrayHandleType, typename T>
|
||||
VTKM_CONT inline bool IsType(const vtkm::cont::ArrayHandleVirtual<T>& virtHandle)
|
||||
{
|
||||
return virtHandle.template IsType<ArrayHandleType>();
|
||||
}
|
||||
|
||||
template <typename ArrayHandleType, typename T>
|
||||
VTKM_CONT inline ArrayHandleType Cast(const vtkm::cont::ArrayHandleVirtual<T>& virtHandle)
|
||||
{
|
||||
return virtHandle.template Cast<ArrayHandleType>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// Specializations of serialization related classes
|
||||
template <typename T>
|
||||
|
@ -22,12 +22,43 @@
|
||||
|
||||
#include <vtkm/cont/ArrayHandleVirtual.h>
|
||||
|
||||
#include <vtkm/cont/ArrayHandleAny.h>
|
||||
#include <vtkm/cont/TryExecute.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
template <typename ArrayHandleType>
|
||||
bool ArrayHandle<T, StorageTagVirtual>::IsSameType(
|
||||
std::false_type vtkmNotUsed(notFromArrayHandleVirtual)) const
|
||||
{
|
||||
if (!this->Storage)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
using S = typename ArrayHandleType::StorageTag;
|
||||
return this->Storage->template IsType<vtkm::cont::StorageAny<T, S>>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename ArrayHandleType>
|
||||
ArrayHandleType ArrayHandle<T, StorageTagVirtual>::CastToType(
|
||||
std::false_type vtkmNotUsed(notFromArrayHandleVirtual)) const
|
||||
{
|
||||
if (!this->Storage)
|
||||
{
|
||||
VTKM_LOG_CAST_FAIL(*this, ArrayHandleType);
|
||||
throwFailedDynamicCast("ArrayHandleVirtual", vtkm::cont::TypeName<ArrayHandleType>());
|
||||
}
|
||||
using S = typename ArrayHandleType::StorageTag;
|
||||
const auto* any = this->Storage->template Cast<vtkm::cont::StorageAny<T, S>>();
|
||||
return any->GetHandle();
|
||||
}
|
||||
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <typename DerivedPortal>
|
||||
@ -69,7 +100,6 @@ inline void make_hostPortal(Payload&& payload, Args&&... args)
|
||||
|
||||
|
||||
|
||||
#include <vtkm/cont/ArrayHandleAny.h>
|
||||
//=============================================================================
|
||||
// Specializations of serialization related classes
|
||||
namespace diy
|
||||
|
@ -40,7 +40,7 @@ namespace cont
|
||||
{
|
||||
|
||||
/// ArrayHandleVirtualCoordinates is a specialization of ArrayHandle.
|
||||
class VTKM_CONT_EXPORT ArrayHandleVirtualCoordinates final
|
||||
class VTKM_ALWAYS_EXPORT ArrayHandleVirtualCoordinates final
|
||||
: public vtkm::cont::ArrayHandleVirtual<vtkm::Vec<vtkm::FloatDefault, 3>>
|
||||
{
|
||||
public:
|
||||
@ -77,20 +77,6 @@ public:
|
||||
using ST = typename decltype(castedHandle)::StorageTag;
|
||||
this->Storage = std::make_shared<vtkm::cont::StorageAny<ValueType, ST>>(castedHandle);
|
||||
}
|
||||
|
||||
/// Returns this array cast to the given \c ArrayHandle type. Throws \c
|
||||
/// ErrorBadType if the cast does not work. Use \c IsType
|
||||
/// to check if the cast can happen.
|
||||
///
|
||||
template <typename ArrayHandleType>
|
||||
VTKM_CONT ArrayHandleType Cast() const
|
||||
{
|
||||
using T = typename ArrayHandleType::ValueType;
|
||||
using S = typename ArrayHandleType::StorageTag;
|
||||
const vtkm::cont::StorageVirtual* storage = this->GetStorage();
|
||||
const auto* any = storage->Cast<vtkm::cont::StorageAny<T, S>>();
|
||||
return any->GetHandle();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Functor, typename... Args>
|
||||
@ -111,7 +97,6 @@ void CastAndCall(const vtkm::cont::ArrayHandleVirtualCoordinates& coords,
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <>
|
||||
struct TypeString<vtkm::cont::ArrayHandleVirtualCoordinates>
|
||||
{
|
||||
|
@ -53,7 +53,8 @@ namespace internal
|
||||
{
|
||||
|
||||
template <class ArrayPortalType>
|
||||
class Storage<typename ArrayPortalType::ValueType, StorageTagImplicit<ArrayPortalType>>
|
||||
class VTKM_ALWAYS_EXPORT
|
||||
Storage<typename ArrayPortalType::ValueType, StorageTagImplicit<ArrayPortalType>>
|
||||
{
|
||||
using ClassType =
|
||||
Storage<typename ArrayPortalType::ValueType, StorageTagImplicit<ArrayPortalType>>;
|
||||
|
@ -87,12 +87,6 @@ void Storage<void, ::vtkm::cont::StorageTagVirtual>::ReleaseResources()
|
||||
this->DeviceUpToDate = false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
bool Storage<void, ::vtkm::cont::StorageTagVirtual>::IsSameType(const std::type_info& other) const
|
||||
{
|
||||
return typeid(*this) == other;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
std::unique_ptr<Storage<void, ::vtkm::cont::StorageTagVirtual>>
|
||||
Storage<void, ::vtkm::cont::StorageTagVirtual>::NewInstance() const
|
||||
|
@ -34,7 +34,7 @@ namespace vtkm
|
||||
namespace cont
|
||||
{
|
||||
|
||||
struct StorageTagVirtual
|
||||
struct VTKM_ALWAYS_EXPORT StorageTagVirtual
|
||||
{
|
||||
};
|
||||
|
||||
@ -99,7 +99,11 @@ public:
|
||||
|
||||
/// Determines if storage types matches the type passed in.
|
||||
///
|
||||
bool IsType(const std::type_info& other) const { return this->IsSameType(other); }
|
||||
template <typename DerivedStorage>
|
||||
bool IsType() const
|
||||
{ //needs optimizations based on platform. !OSX can use typeid
|
||||
return nullptr != dynamic_cast<const DerivedStorage*>(this);
|
||||
}
|
||||
|
||||
/// \brief Create a new storage of the same type as this storage.
|
||||
///
|
||||
@ -155,7 +159,6 @@ private:
|
||||
// virtual void DoShrink(vtkm::Id numberOfValues) = 0;
|
||||
|
||||
//RTTI routines
|
||||
virtual bool IsSameType(const std::type_info&) const;
|
||||
virtual std::unique_ptr<Storage<void, ::vtkm::cont::StorageTagVirtual>> MakeNewInstance()
|
||||
const = 0;
|
||||
|
||||
|
@ -89,31 +89,23 @@ struct Transport<vtkm::cont::arg::TransportTagAtomicArray,
|
||||
vtkm::Id,
|
||||
vtkm::Id) const
|
||||
{
|
||||
using S = vtkm::cont::StorageTagBasic;
|
||||
|
||||
const vtkm::cont::StorageVirtual* storage = array.GetStorage();
|
||||
if (!storage)
|
||||
{
|
||||
throw vtkm::cont::ErrorBadValue("ArrayHandleVirtual must not have a nullptr for storage.");
|
||||
}
|
||||
|
||||
if (!storage->IsType(typeid(vtkm::cont::internal::Storage<T, S>)))
|
||||
using ArrayHandleType = vtkm::cont::ArrayHandle<T>;
|
||||
const bool is_type = vtkm::cont::IsType<ArrayHandleType>(array);
|
||||
if (!is_type)
|
||||
{
|
||||
#if defined(VTKM_ENABLE_LOGGING)
|
||||
using AH = vtkm::cont::ArrayHandle<T, S>;
|
||||
VTKM_LOG_CAST_FAIL(array, AH);
|
||||
VTKM_LOG_CAST_FAIL(array, ArrayHandleType);
|
||||
#endif
|
||||
throw vtkm::cont::ErrorBadValue("Arrays being used as atomic's must always have storage that "
|
||||
"is of the type StorageTagBasic.");
|
||||
}
|
||||
|
||||
const auto* any = static_cast<const vtkm::cont::StorageAny<T, S>*>(storage);
|
||||
VTKM_LOG_CAST_SUCC(array, *any);
|
||||
ArrayHandleType handle = vtkm::cont::Cast<ArrayHandleType>(array);
|
||||
|
||||
// Note: we ignore the size of the domain because the randomly accessed
|
||||
// array might not have the same size depending on how the user is using
|
||||
// the array.
|
||||
ExecType obj(any->GetHandle());
|
||||
ExecType obj(handle);
|
||||
return obj.PrepareForExecution(Device());
|
||||
}
|
||||
};
|
||||
|
@ -137,11 +137,11 @@ VTKM_CONT bool IsType(const VariantArrayHandleContainerBase* container)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
using VT = typename ArrayHandleType::ValueType;
|
||||
using ST = typename ArrayHandleType::StorageTag;
|
||||
|
||||
const vtkm::cont::StorageVirtual* storage = container->GetStorage();
|
||||
return storage->IsType(typeid(vtkm::cont::internal::Storage<VT, ST>));
|
||||
return storage->IsType<vtkm::cont::StorageAny<VT, ST>>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -151,7 +151,9 @@ VTKM_CONT bool IsValueType(const VariantArrayHandleContainerBase* container)
|
||||
{ //you can't use typeid on nullptr of polymorphic types
|
||||
return false;
|
||||
}
|
||||
return typeid(VariantArrayHandleContainer<T>) == typeid(*container);
|
||||
|
||||
//needs optimizations based on platform. !OSX can use typeid
|
||||
return (nullptr != dynamic_cast<const VariantArrayHandleContainer<T>*>(container));
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user