Merge topic 'replace-variantarrayhandle-impl'
386301719 Test UnknownArrayHandle behavior on special arrays 872da1f8e Suppress unnecessary deprecation warnings on VS bb443bbc2 Replace the implementation of VariantArrayHandle Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: Robert Maynard <robert.maynard@kitware.com> Merge-request: !2255
This commit is contained in:
commit
06579aac8c
@ -183,7 +183,6 @@ set(sources
|
||||
DataSetBuilderExplicit.cxx
|
||||
DataSetBuilderRectilinear.cxx
|
||||
DataSetBuilderUniform.cxx
|
||||
internal/VariantArrayHandleContainer.cxx
|
||||
Field.cxx
|
||||
FieldRangeCompute.cxx
|
||||
FieldRangeGlobalCompute.cxx
|
||||
|
@ -220,6 +220,7 @@ class VTKM_CONT_EXPORT UnknownArrayHandle
|
||||
|
||||
public:
|
||||
VTKM_CONT UnknownArrayHandle() = default;
|
||||
UnknownArrayHandle(const UnknownArrayHandle&) = default;
|
||||
|
||||
template <typename T, typename S>
|
||||
VTKM_CONT UnknownArrayHandle(const vtkm::cont::ArrayHandle<T, S>& array)
|
||||
@ -227,6 +228,8 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
UnknownArrayHandle& operator=(const vtkm::cont::UnknownArrayHandle&) = default;
|
||||
|
||||
/// \brief Create a new array of the same type as this array.
|
||||
///
|
||||
/// This method creates a new array that is the same type as this one and
|
||||
@ -323,6 +326,14 @@ public:
|
||||
template <typename ArrayHandleType>
|
||||
VTKM_CONT bool CanConvert() const;
|
||||
|
||||
// MSVC will issue deprecation warnings here if this template is instantiated with
|
||||
// a deprecated class even if the template is used from a section of code where
|
||||
// deprecation warnings are suppressed. This is annoying behavior since this template
|
||||
// has no control over what class it is used with. To get around it, we have to
|
||||
// suppress all deprecation warnings here.
|
||||
#ifdef VTKM_MSVC
|
||||
VTKM_DEPRECATED_SUPPRESS_BEGIN
|
||||
#endif
|
||||
///@{
|
||||
/// Returns this array cast appropriately and stored in the given `ArrayHandle` type.
|
||||
/// Throws an `ErrorBadType` if the stored array cannot be stored in the given array type.
|
||||
@ -363,6 +374,9 @@ public:
|
||||
return array;
|
||||
}
|
||||
///@}
|
||||
#ifdef VTKM_MSVC
|
||||
VTKM_DEPRECATED_SUPPRESS_END
|
||||
#endif
|
||||
|
||||
/// \brief Call a functor using the underlying array type.
|
||||
///
|
||||
@ -476,8 +490,17 @@ struct UnknownArrayHandleMultplexerCastTry
|
||||
bool& converted) const
|
||||
{
|
||||
using ArrayType = vtkm::cont::ArrayHandle<T, S>;
|
||||
if (!converted && unknownArray.CanConvert<ArrayType>())
|
||||
if (unknownArray.CanConvert<ArrayType>())
|
||||
{
|
||||
if (converted && !unknownArray.IsType<ArrayType>())
|
||||
{
|
||||
// The array has already been converted and pushed in the multiplexer. It is
|
||||
// possible that multiple array types can be put in the ArrayHandleMultiplexer
|
||||
// (for example, and ArrayHandle or an ArrayHandle that has been cast). Exact
|
||||
// matches will override other matches (hence, the second part of the condition),
|
||||
// but at this point we have already found a better array to put inside.
|
||||
return;
|
||||
}
|
||||
outputArray.GetStorage().SetArray(unknownArray.AsArrayHandle<ArrayType>());
|
||||
converted = true;
|
||||
}
|
||||
|
@ -23,14 +23,71 @@
|
||||
#include <vtkm/cont/ErrorBadType.h>
|
||||
#include <vtkm/cont/Logging.h>
|
||||
#include <vtkm/cont/StorageList.h>
|
||||
|
||||
#include <vtkm/cont/internal/VariantArrayHandleContainer.h>
|
||||
#include <vtkm/cont/UncertainArrayHandle.h>
|
||||
#include <vtkm/cont/UnknownArrayHandle.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
namespace internal
|
||||
{
|
||||
namespace variant
|
||||
{
|
||||
|
||||
struct ForceCastToVirtual
|
||||
{
|
||||
template <typename SrcValueType, typename Storage, typename DstValueType>
|
||||
VTKM_CONT typename std::enable_if<std::is_same<SrcValueType, DstValueType>::value>::type
|
||||
operator()(const vtkm::cont::ArrayHandle<SrcValueType, Storage>& input,
|
||||
vtkm::cont::ArrayHandleVirtual<DstValueType>& output) const
|
||||
{ // ValueTypes match
|
||||
output = vtkm::cont::make_ArrayHandleVirtual<DstValueType>(input);
|
||||
}
|
||||
|
||||
template <typename SrcValueType, typename Storage, typename DstValueType>
|
||||
VTKM_CONT typename std::enable_if<!std::is_same<SrcValueType, DstValueType>::value>::type
|
||||
operator()(const vtkm::cont::ArrayHandle<SrcValueType, Storage>& input,
|
||||
vtkm::cont::ArrayHandleVirtual<DstValueType>& output) const
|
||||
{ // ValueTypes do not match
|
||||
this->ValidateWidthAndCast<SrcValueType, DstValueType>(input, output);
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename S,
|
||||
typename D,
|
||||
typename InputType,
|
||||
vtkm::IdComponent SSize = vtkm::VecTraits<S>::NUM_COMPONENTS,
|
||||
vtkm::IdComponent DSize = vtkm::VecTraits<D>::NUM_COMPONENTS>
|
||||
VTKM_CONT typename std::enable_if<SSize == DSize>::type ValidateWidthAndCast(
|
||||
const InputType& input,
|
||||
vtkm::cont::ArrayHandleVirtual<D>& output) const
|
||||
{ // number of components match
|
||||
auto casted = vtkm::cont::make_ArrayHandleCast<D>(input);
|
||||
output = vtkm::cont::make_ArrayHandleVirtual<D>(casted);
|
||||
}
|
||||
|
||||
template <typename S,
|
||||
typename D,
|
||||
vtkm::IdComponent SSize = vtkm::VecTraits<S>::NUM_COMPONENTS,
|
||||
vtkm::IdComponent DSize = vtkm::VecTraits<D>::NUM_COMPONENTS>
|
||||
VTKM_CONT typename std::enable_if<SSize != DSize>::type ValidateWidthAndCast(
|
||||
const ArrayHandleBase&,
|
||||
ArrayHandleBase&) const
|
||||
{ // number of components do not match
|
||||
std::ostringstream str;
|
||||
str << "VariantArrayHandle::AsVirtual: Cannot cast from " << vtkm::cont::TypeToString<S>()
|
||||
<< " to " << vtkm::cont::TypeToString<D>()
|
||||
<< "; "
|
||||
"number of components must match exactly.";
|
||||
throw vtkm::cont::ErrorBadType(str.str());
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace internal::variant
|
||||
|
||||
/// \brief VariantArrayHandle superclass holding common operations.
|
||||
///
|
||||
/// `VariantArrayHandleCommon` is a superclass to all `VariantArrayHandleBase`
|
||||
@ -40,43 +97,28 @@ namespace cont
|
||||
///
|
||||
/// See the documentation of `VariantArrayHandleBase` for more information.
|
||||
///
|
||||
class VTKM_ALWAYS_EXPORT VariantArrayHandleCommon
|
||||
class VTKM_ALWAYS_EXPORT VariantArrayHandleCommon : public vtkm::cont::UnknownArrayHandle
|
||||
{
|
||||
std::shared_ptr<vtkm::cont::internal::VariantArrayHandleContainerBase> ArrayContainer;
|
||||
using Superclass = vtkm::cont::UnknownArrayHandle;
|
||||
|
||||
public:
|
||||
using Superclass::Superclass;
|
||||
|
||||
VTKM_CONT VariantArrayHandleCommon() = default;
|
||||
|
||||
template <typename T, typename Storage>
|
||||
VTKM_CONT VariantArrayHandleCommon(const vtkm::cont::ArrayHandle<T, Storage>& array)
|
||||
: ArrayContainer(std::make_shared<internal::VariantArrayHandleContainer<T>>(
|
||||
vtkm::cont::ArrayHandleVirtual<T>{ array }))
|
||||
VTKM_CONT VariantArrayHandleCommon(const vtkm::cont::UnknownArrayHandle& array)
|
||||
: Superclass(array)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
VTKM_CONT VariantArrayHandleCommon(
|
||||
const vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagVirtual>& array)
|
||||
: ArrayContainer(std::make_shared<internal::VariantArrayHandleContainer<T>>(array))
|
||||
{
|
||||
}
|
||||
|
||||
/// Returns true if this array matches the array handle type passed in.
|
||||
///
|
||||
template <typename ArrayHandleType>
|
||||
VTKM_CONT bool IsType() const
|
||||
{
|
||||
return internal::variant::IsType<ArrayHandleType>(this->ArrayContainer.get());
|
||||
}
|
||||
|
||||
/// Returns true if this array matches the ValueType type passed in.
|
||||
///
|
||||
template <typename T>
|
||||
VTKM_CONT bool IsValueType() const
|
||||
{
|
||||
return internal::variant::IsValueType<T>(this->ArrayContainer.get());
|
||||
}
|
||||
|
||||
// MSVC will issue deprecation warnings here if this template is instantiated with
|
||||
// a deprecated class even if the template is used from a section of code where
|
||||
// deprecation warnings are suppressed. This is annoying behavior since this template
|
||||
// has no control over what class it is used with. To get around it, we have to
|
||||
// suppress all deprecation warnings here.
|
||||
#ifdef VTKM_MSVC
|
||||
VTKM_DEPRECATED_SUPPRESS_BEGIN
|
||||
#endif
|
||||
/// 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.
|
||||
@ -84,19 +126,11 @@ public:
|
||||
template <typename ArrayHandleType>
|
||||
VTKM_CONT ArrayHandleType Cast() const
|
||||
{
|
||||
// MSVC will issue deprecation warnings if this templated method is instantiated with
|
||||
// a deprecated class here even if the method is called from a section of code where
|
||||
// deprecation warnings are suppressed. This is annoying behavior since this templated
|
||||
// method has no control over what class it is used from. To get around it, we have to
|
||||
// suppress all deprecation warnings here.
|
||||
#ifdef VTKM_MSVC
|
||||
VTKM_DEPRECATED_SUPPRESS_BEGIN
|
||||
#endif
|
||||
return internal::variant::Cast<ArrayHandleType>(this->ArrayContainer.get());
|
||||
#ifdef VTKM_MSVC
|
||||
VTKM_DEPRECATED_SUPPRESS_END
|
||||
#endif
|
||||
return this->AsArrayHandle<ArrayHandleType>();
|
||||
}
|
||||
#ifdef VTKM_MSVC
|
||||
VTKM_DEPRECATED_SUPPRESS_END
|
||||
#endif
|
||||
|
||||
/// \brief Call a functor using the underlying array type.
|
||||
///
|
||||
@ -106,7 +140,11 @@ public:
|
||||
/// calling differs from that of the `CastAndCall` methods of subclasses.)
|
||||
///
|
||||
template <typename TypeList, typename StorageList, typename Functor, typename... Args>
|
||||
VTKM_CONT void CastAndCall(Functor&& functor, Args&&... args) const;
|
||||
VTKM_CONT void CastAndCall(Functor&& functor, Args&&... args) const
|
||||
{
|
||||
this->CastAndCallForTypes<TypeList, StorageList>(std::forward<Functor>(functor),
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
/// Returns this array cast to a `ArrayHandleVirtual` of the given type.
|
||||
/// This will perform type conversions as necessary, and will log warnings
|
||||
@ -141,7 +179,10 @@ public:
|
||||
///
|
||||
///@{
|
||||
template <typename... T>
|
||||
VTKM_CONT void AsMultiplexer(vtkm::cont::ArrayHandleMultiplexer<T...>& result) const;
|
||||
VTKM_CONT void AsMultiplexer(vtkm::cont::ArrayHandleMultiplexer<T...>& result) const
|
||||
{
|
||||
this->AsArrayHandle(result);
|
||||
}
|
||||
|
||||
template <typename ArrayHandleMultiplexerType>
|
||||
VTKM_CONT ArrayHandleMultiplexerType AsMultiplexer() const
|
||||
@ -175,40 +216,8 @@ public:
|
||||
///
|
||||
VTKM_CONT VariantArrayHandleCommon NewInstance() const
|
||||
{
|
||||
VariantArrayHandleCommon instance;
|
||||
instance.ArrayContainer = this->ArrayContainer->NewInstance();
|
||||
return instance;
|
||||
return VariantArrayHandleCommon(this->Superclass::NewInstance());
|
||||
}
|
||||
|
||||
/// Releases any resources being used in the execution environment (that are
|
||||
/// not being shared by the control environment).
|
||||
///
|
||||
void ReleaseResourcesExecution() { return this->ArrayContainer->ReleaseResourcesExecution(); }
|
||||
|
||||
|
||||
/// Releases all resources in both the control and execution environments.
|
||||
///
|
||||
void ReleaseResources() { return this->ArrayContainer->ReleaseResources(); }
|
||||
|
||||
/// \brief Get the number of components in each array value.
|
||||
///
|
||||
/// This method will query the array type for the number of components in
|
||||
/// each value of the array. The number of components is determined by
|
||||
/// the \c VecTraits::NUM_COMPONENTS trait class.
|
||||
///
|
||||
VTKM_CONT
|
||||
vtkm::IdComponent GetNumberOfComponents() const
|
||||
{
|
||||
return this->ArrayContainer->GetNumberOfComponents();
|
||||
}
|
||||
|
||||
/// \brief Get the number of values in the array.
|
||||
///
|
||||
VTKM_CONT
|
||||
vtkm::Id GetNumberOfValues() const { return this->ArrayContainer->GetNumberOfValues(); }
|
||||
|
||||
VTKM_CONT
|
||||
void PrintSummary(std::ostream& out) const { this->ArrayContainer->PrintSummary(out); }
|
||||
};
|
||||
|
||||
/// \brief Holds an array handle without having to specify template parameters.
|
||||
@ -263,6 +272,18 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_CONT explicit VariantArrayHandleBase(const vtkm::cont::UnknownArrayHandle& src)
|
||||
: Superclass(src)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename StorageList>
|
||||
VTKM_CONT VariantArrayHandleBase(
|
||||
const vtkm::cont::UncertainArrayHandle<TypeList, StorageList>& src)
|
||||
: Superclass(src)
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_CONT VariantArrayHandleBase(const VariantArrayHandleBase&) = default;
|
||||
VTKM_CONT VariantArrayHandleBase(VariantArrayHandleBase&&) noexcept = default;
|
||||
|
||||
@ -276,6 +297,11 @@ public:
|
||||
VariantArrayHandleBase<TypeList>& operator=(VariantArrayHandleBase<TypeList>&&) noexcept =
|
||||
default;
|
||||
|
||||
VTKM_CONT operator vtkm::cont::UncertainArrayHandle<TypeList, VTKM_DEFAULT_STORAGE_LIST>() const
|
||||
{
|
||||
return vtkm::cont::UncertainArrayHandle<TypeList, VTKM_DEFAULT_STORAGE_LIST>(*this);
|
||||
}
|
||||
|
||||
|
||||
/// Returns this array cast to a \c ArrayHandleVirtual of the given type.
|
||||
/// This will perform type conversions as necessary, and will log warnings
|
||||
@ -392,207 +418,6 @@ VTKM_CONT inline ArrayHandleType Cast(const vtkm::cont::VariantArrayHandleBase<T
|
||||
return variant.template Cast<ArrayHandleType>();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Out of class implementations
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
struct VariantArrayHandleTry
|
||||
{
|
||||
template <typename T, typename Storage, typename Functor, typename... Args>
|
||||
void operator()(vtkm::List<T, Storage>,
|
||||
Functor&& f,
|
||||
bool& called,
|
||||
const vtkm::cont::internal::VariantArrayHandleContainerBase& container,
|
||||
Args&&... args) const
|
||||
{
|
||||
using DerivedArrayType = vtkm::cont::ArrayHandle<T, Storage>;
|
||||
if (!called && vtkm::cont::internal::variant::IsType<DerivedArrayType>(&container))
|
||||
{
|
||||
called = true;
|
||||
const auto* derivedContainer =
|
||||
static_cast<const vtkm::cont::internal::VariantArrayHandleContainer<T>*>(&container);
|
||||
DerivedArrayType derivedArray = derivedContainer->Array.template Cast<DerivedArrayType>();
|
||||
VTKM_LOG_CAST_SUCC(container, derivedArray);
|
||||
|
||||
// If you get a compile error here, it means that you have called CastAndCall for a
|
||||
// vtkm::cont::VariantArrayHandle and the arguments of the functor do not match those
|
||||
// being passed. This is often because it is calling the functor with an ArrayHandle
|
||||
// type that was not expected. Either add overloads to the functor to accept all
|
||||
// possible array types or constrain the types tried for the CastAndCall. Note that
|
||||
// the functor will be called with an array of type vtkm::cont::ArrayHandle<T, S>.
|
||||
// Directly using a subclass of ArrayHandle (e.g. vtkm::cont::ArrayHandleConstant<T>)
|
||||
// might not work.
|
||||
f(derivedArray, std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct IsUndefinedStorage
|
||||
{
|
||||
};
|
||||
template <typename T, typename U>
|
||||
struct IsUndefinedStorage<vtkm::List<T, U>> : vtkm::cont::internal::IsInvalidArrayHandle<T, U>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename TypeList, typename StorageList>
|
||||
using ListDynamicTypes =
|
||||
vtkm::ListRemoveIf<vtkm::ListCross<TypeList, StorageList>, IsUndefinedStorage>;
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
|
||||
template <typename TypeList, typename StorageTagList, typename Functor, typename... Args>
|
||||
VTKM_CONT void VariantArrayHandleCommon::CastAndCall(Functor&& f, Args&&... args) const
|
||||
{
|
||||
using crossProduct = detail::ListDynamicTypes<TypeList, StorageTagList>;
|
||||
|
||||
bool called = false;
|
||||
const auto& ref = *this->ArrayContainer;
|
||||
vtkm::ListForEach(detail::VariantArrayHandleTry{},
|
||||
crossProduct{},
|
||||
std::forward<Functor>(f),
|
||||
called,
|
||||
ref,
|
||||
std::forward<Args>(args)...);
|
||||
if (!called)
|
||||
{
|
||||
// throw an exception
|
||||
VTKM_LOG_CAST_FAIL(*this, TypeList);
|
||||
detail::ThrowCastAndCallException(ref, typeid(TypeList));
|
||||
}
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
struct VariantArrayHandleTryMultiplexer
|
||||
{
|
||||
template <typename T, typename Storage, typename... ArrayTypes>
|
||||
VTKM_CONT void operator()(const vtkm::cont::ArrayHandle<T, Storage>&,
|
||||
const vtkm::cont::VariantArrayHandleCommon& self,
|
||||
vtkm::cont::ArrayHandleMultiplexer<ArrayTypes...>& result) const
|
||||
{
|
||||
vtkm::cont::ArrayHandle<T, Storage> targetArray;
|
||||
bool foundArray = false;
|
||||
this->FetchArray(targetArray, self, foundArray, result.IsValid());
|
||||
if (foundArray)
|
||||
{
|
||||
result.SetArray(targetArray);
|
||||
VTKM_LOG_CAST_SUCC(self, result);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename T, typename Storage>
|
||||
VTKM_CONT void FetchArrayExact(vtkm::cont::ArrayHandle<T, Storage>& targetArray,
|
||||
const vtkm::cont::VariantArrayHandleCommon& self,
|
||||
bool& foundArray) const
|
||||
{
|
||||
using ArrayType = vtkm::cont::ArrayHandle<T, Storage>;
|
||||
if (self.IsType<ArrayType>())
|
||||
{
|
||||
targetArray = self.Cast<ArrayType>();
|
||||
foundArray = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
foundArray = false;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename Storage>
|
||||
VTKM_CONT void FetchArray(vtkm::cont::ArrayHandle<T, Storage>& targetArray,
|
||||
const vtkm::cont::VariantArrayHandleCommon& self,
|
||||
bool& foundArray,
|
||||
bool vtkmNotUsed(foundArrayInPreviousCall)) const
|
||||
{
|
||||
this->FetchArrayExact(targetArray, self, foundArray);
|
||||
}
|
||||
|
||||
// Special condition for transformed arrays. Instead of pulling out the
|
||||
// transform, pull out the array that is being transformed.
|
||||
template <typename T, typename SrcArray, typename ForwardTransform, typename ReverseTransform>
|
||||
VTKM_CONT void FetchArray(
|
||||
vtkm::cont::ArrayHandle<
|
||||
T,
|
||||
vtkm::cont::internal::StorageTagTransform<SrcArray, ForwardTransform, ReverseTransform>>&
|
||||
targetArray,
|
||||
const vtkm::cont::VariantArrayHandleCommon& self,
|
||||
bool& foundArray,
|
||||
bool foundArrayInPreviousCall) const
|
||||
{
|
||||
// Attempt to get the array itself first
|
||||
this->FetchArrayExact(targetArray, self, foundArray);
|
||||
|
||||
// Try to get the array to be transformed first, but only do so if the array was not already
|
||||
// found in another call to this functor. This is to give precedence to getting the array
|
||||
// exactly rather than creating our own transform.
|
||||
if (!foundArray && !foundArrayInPreviousCall)
|
||||
{
|
||||
SrcArray srcArray;
|
||||
this->FetchArray(srcArray, self, foundArray, foundArrayInPreviousCall);
|
||||
if (foundArray)
|
||||
{
|
||||
targetArray =
|
||||
vtkm::cont::ArrayHandleTransform<SrcArray, ForwardTransform, ReverseTransform>(srcArray);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Special condition for cast arrays. Instead of pulling out an ArrayHandleCast, pull out
|
||||
// the array that is being cast.
|
||||
template <typename TargetT, typename SourceT, typename SourceStorage>
|
||||
VTKM_CONT void FetchArray(
|
||||
vtkm::cont::ArrayHandle<TargetT, vtkm::cont::StorageTagCast<SourceT, SourceStorage>>&
|
||||
targetArray,
|
||||
const vtkm::cont::VariantArrayHandleCommon& self,
|
||||
bool& foundArray,
|
||||
bool foundArrayInPreviousCall) const
|
||||
{
|
||||
// Attempt to get the array itself first
|
||||
this->FetchArrayExact(targetArray, self, foundArray);
|
||||
|
||||
// Try to get the array to be transformed first, but only do so if the array was not already
|
||||
// found in another call to this functor. This is to give precedence to getting the array
|
||||
// exactly rather than creating our own transform.
|
||||
if (!foundArray && !foundArrayInPreviousCall)
|
||||
{
|
||||
using SrcArray = vtkm::cont::ArrayHandle<SourceT, SourceStorage>;
|
||||
SrcArray srcArray;
|
||||
this->FetchArray(srcArray, self, foundArray, foundArrayInPreviousCall);
|
||||
if (foundArray)
|
||||
{
|
||||
targetArray =
|
||||
vtkm::cont::ArrayHandleCast<TargetT, vtkm::cont::ArrayHandle<SourceT, SourceStorage>>(
|
||||
srcArray);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename... T>
|
||||
inline VTKM_CONT void VariantArrayHandleCommon::AsMultiplexer(
|
||||
vtkm::cont::ArrayHandleMultiplexer<T...>& result) const
|
||||
{
|
||||
// Make sure IsValid is clear
|
||||
result = vtkm::cont::ArrayHandleMultiplexer<T...>{};
|
||||
vtkm::ListForEach(detail::VariantArrayHandleTryMultiplexer{}, vtkm::List<T...>{}, *this, result);
|
||||
if (!result.IsValid())
|
||||
{
|
||||
// Could not put the class into the multiplexer. Throw an exception.
|
||||
VTKM_LOG_CAST_FAIL(*this, vtkm::List<T...>);
|
||||
detail::ThrowAsMultiplexerException(*this->ArrayContainer, { typeid(T).name()... });
|
||||
}
|
||||
}
|
||||
|
||||
namespace internal
|
||||
{
|
||||
|
||||
@ -612,72 +437,24 @@ struct DynamicTransformTraits<vtkm::cont::VariantArrayHandleBase<TypeList>>
|
||||
namespace mangled_diy_namespace
|
||||
{
|
||||
|
||||
namespace internal
|
||||
{
|
||||
|
||||
struct VariantArrayHandleSerializeFunctor
|
||||
{
|
||||
template <typename ArrayHandleType>
|
||||
void operator()(const ArrayHandleType& ah, BinaryBuffer& bb) const
|
||||
{
|
||||
vtkmdiy::save(bb, vtkm::cont::SerializableTypeString<ArrayHandleType>::Get());
|
||||
vtkmdiy::save(bb, ah);
|
||||
}
|
||||
};
|
||||
|
||||
struct VariantArrayHandleDeserializeFunctor
|
||||
{
|
||||
template <typename T, typename S, typename TypeList>
|
||||
void operator()(vtkm::List<T, S>,
|
||||
vtkm::cont::VariantArrayHandleBase<TypeList>& dh,
|
||||
const std::string& typeString,
|
||||
bool& success,
|
||||
BinaryBuffer& bb) const
|
||||
{
|
||||
using ArrayHandleType = vtkm::cont::ArrayHandle<T, S>;
|
||||
|
||||
if (!success && (typeString == vtkm::cont::SerializableTypeString<ArrayHandleType>::Get()))
|
||||
{
|
||||
ArrayHandleType ah;
|
||||
vtkmdiy::load(bb, ah);
|
||||
dh = vtkm::cont::VariantArrayHandleBase<TypeList>(ah);
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // internal
|
||||
|
||||
template <typename TypeList>
|
||||
struct Serialization<vtkm::cont::VariantArrayHandleBase<TypeList>>
|
||||
{
|
||||
private:
|
||||
using Type = vtkm::cont::VariantArrayHandleBase<TypeList>;
|
||||
using ImplObject = vtkm::cont::UncertainArrayHandle<TypeList, VTKM_DEFAULT_STORAGE_LIST>;
|
||||
|
||||
public:
|
||||
static VTKM_CONT void save(BinaryBuffer& bb, const Type& obj)
|
||||
{
|
||||
obj.CastAndCall(internal::VariantArrayHandleSerializeFunctor{}, bb);
|
||||
vtkmdiy::save(bb, ImplObject(obj));
|
||||
}
|
||||
|
||||
static VTKM_CONT void load(BinaryBuffer& bb, Type& obj)
|
||||
{
|
||||
std::string typeString;
|
||||
vtkmdiy::load(bb, typeString);
|
||||
|
||||
bool success = false;
|
||||
vtkm::ListForEach(internal::VariantArrayHandleDeserializeFunctor{},
|
||||
vtkm::cont::detail::ListDynamicTypes<TypeList, VTKM_DEFAULT_STORAGE_LIST>{},
|
||||
obj,
|
||||
typeString,
|
||||
success,
|
||||
bb);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
throw vtkm::cont::ErrorBadType(
|
||||
"Error deserializing VariantArrayHandle. Message TypeString: " + typeString);
|
||||
}
|
||||
ImplObject implObj;
|
||||
vtkmdiy::load(bb, implObj);
|
||||
obj = implObj;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -33,7 +33,6 @@ set(headers
|
||||
ReverseConnectivityBuilder.h
|
||||
StorageError.h
|
||||
TransferInfo.h
|
||||
VariantArrayHandleContainer.h
|
||||
VirtualObjectTransfer.h
|
||||
VirtualObjectTransferInstantiate.h
|
||||
VirtualObjectTransferShareWithControl.h
|
||||
|
@ -1,68 +0,0 @@
|
||||
//============================================================================
|
||||
// Copyright (c) Kitware, Inc.
|
||||
// All rights reserved.
|
||||
// See LICENSE.txt for details.
|
||||
//
|
||||
// This software is distributed WITHOUT ANY WARRANTY; without even
|
||||
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the above copyright notice for more information.
|
||||
//============================================================================
|
||||
|
||||
#include <sstream>
|
||||
#include <typeindex>
|
||||
|
||||
#include <vtkm/cont/ErrorBadValue.h>
|
||||
#include <vtkm/cont/internal/VariantArrayHandleContainer.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
|
||||
VariantArrayHandleContainerBase::VariantArrayHandleContainerBase()
|
||||
: TypeIndex(typeid(nullptr))
|
||||
{
|
||||
}
|
||||
|
||||
VariantArrayHandleContainerBase::VariantArrayHandleContainerBase(const std::type_info& typeinfo)
|
||||
: TypeIndex(typeinfo)
|
||||
{
|
||||
}
|
||||
|
||||
VariantArrayHandleContainerBase::~VariantArrayHandleContainerBase() {}
|
||||
}
|
||||
|
||||
namespace detail
|
||||
{
|
||||
VTKM_CONT_EXPORT void ThrowCastAndCallException(
|
||||
const vtkm::cont::internal::VariantArrayHandleContainerBase& ref,
|
||||
const std::type_info& type)
|
||||
{
|
||||
std::ostringstream out;
|
||||
out << "Could not find appropriate cast for array in CastAndCall.\n"
|
||||
"Array: ";
|
||||
ref.PrintSummary(out);
|
||||
out << "TypeList: " << type.name() << "\n";
|
||||
throw vtkm::cont::ErrorBadValue(out.str());
|
||||
}
|
||||
|
||||
VTKM_CONT_EXPORT void ThrowAsMultiplexerException(
|
||||
const vtkm::cont::internal::VariantArrayHandleContainerBase& ref,
|
||||
const std::initializer_list<std::string>& arrayTypes)
|
||||
{
|
||||
std::ostringstream out;
|
||||
out << "Could not find appropriate cast for array in AsMultiplexer.\n"
|
||||
"Array: ";
|
||||
ref.PrintSummary(out);
|
||||
out << "Supported arrays:\n";
|
||||
for (auto&& type : arrayTypes)
|
||||
{
|
||||
out << " " << type << "\n";
|
||||
}
|
||||
throw vtkm::cont::ErrorBadValue(out.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace vtkm::cont::detail
|
@ -1,301 +0,0 @@
|
||||
//============================================================================
|
||||
// Copyright (c) Kitware, Inc.
|
||||
// All rights reserved.
|
||||
// See LICENSE.txt for details.
|
||||
//
|
||||
// This software is distributed WITHOUT ANY WARRANTY; without even
|
||||
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the above copyright notice for more information.
|
||||
//============================================================================
|
||||
#ifndef vtk_m_cont_VariantArrayHandleContainer_h
|
||||
#define vtk_m_cont_VariantArrayHandleContainer_h
|
||||
|
||||
#include <vtkm/cont/vtkm_cont_export.h>
|
||||
|
||||
#include <vtkm/cont/ArrayHandleCast.h>
|
||||
#include <vtkm/cont/ArrayHandleVirtual.h>
|
||||
#include <vtkm/cont/ArrayHandleVirtual.hxx>
|
||||
#include <vtkm/cont/ErrorBadType.h>
|
||||
|
||||
#include <vtkm/VecTraits.h>
|
||||
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <typeindex>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
// Forward declaration needed for GetContainer
|
||||
template <typename TypeList>
|
||||
class VariantArrayHandleBase;
|
||||
|
||||
namespace internal
|
||||
{
|
||||
|
||||
/// \brief Base class for VariantArrayHandleContainer
|
||||
///
|
||||
struct VTKM_CONT_EXPORT VariantArrayHandleContainerBase
|
||||
{
|
||||
std::type_index TypeIndex;
|
||||
|
||||
VariantArrayHandleContainerBase();
|
||||
explicit VariantArrayHandleContainerBase(const std::type_info& hash);
|
||||
|
||||
// This must exist so that subclasses are destroyed correctly.
|
||||
virtual ~VariantArrayHandleContainerBase();
|
||||
|
||||
virtual vtkm::Id GetNumberOfValues() const = 0;
|
||||
virtual vtkm::IdComponent GetNumberOfComponents() const = 0;
|
||||
|
||||
virtual void ReleaseResourcesExecution() = 0;
|
||||
virtual void ReleaseResources() = 0;
|
||||
|
||||
virtual void PrintSummary(std::ostream& out) const = 0;
|
||||
|
||||
virtual std::shared_ptr<VariantArrayHandleContainerBase> NewInstance() const = 0;
|
||||
};
|
||||
|
||||
/// \brief ArrayHandle container that can use C++ run-time type information.
|
||||
///
|
||||
/// The \c VariantArrayHandleContainer holds ArrayHandle objects
|
||||
/// (with different template parameters) so that it can polymorphically answer
|
||||
/// simple questions about the object.
|
||||
///
|
||||
template <typename T>
|
||||
struct VTKM_ALWAYS_EXPORT VariantArrayHandleContainer final : public VariantArrayHandleContainerBase
|
||||
{
|
||||
vtkm::cont::ArrayHandleVirtual<T> Array;
|
||||
mutable vtkm::IdComponent NumberOfComponents = 0;
|
||||
|
||||
VariantArrayHandleContainer()
|
||||
: VariantArrayHandleContainerBase(typeid(T))
|
||||
, Array()
|
||||
{
|
||||
}
|
||||
|
||||
VariantArrayHandleContainer(const vtkm::cont::ArrayHandleVirtual<T>& array)
|
||||
: VariantArrayHandleContainerBase(typeid(T))
|
||||
, Array(array)
|
||||
{
|
||||
}
|
||||
|
||||
~VariantArrayHandleContainer<T>() override = default;
|
||||
|
||||
vtkm::Id GetNumberOfValues() const override { return this->Array.GetNumberOfValues(); }
|
||||
|
||||
vtkm::IdComponent GetNumberOfComponents() const override
|
||||
{
|
||||
// Cache number of components to avoid unnecessary device to host transfers of the array.
|
||||
// Also assumes that the number of components is constant accross all elements and
|
||||
// throughout the life of the array.
|
||||
if (this->NumberOfComponents == 0)
|
||||
{
|
||||
this->NumberOfComponents =
|
||||
this->GetNumberOfComponents(typename vtkm::VecTraits<T>::IsSizeStatic{});
|
||||
}
|
||||
return this->NumberOfComponents;
|
||||
}
|
||||
|
||||
void ReleaseResourcesExecution() override { this->Array.ReleaseResourcesExecution(); }
|
||||
void ReleaseResources() override { this->Array.ReleaseResources(); }
|
||||
|
||||
void PrintSummary(std::ostream& out) const override
|
||||
{
|
||||
vtkm::cont::printSummary_ArrayHandle(this->Array, out);
|
||||
}
|
||||
|
||||
std::shared_ptr<VariantArrayHandleContainerBase> NewInstance() const override
|
||||
{
|
||||
return std::make_shared<VariantArrayHandleContainer<T>>(this->Array.NewInstance());
|
||||
}
|
||||
|
||||
private:
|
||||
vtkm::IdComponent GetNumberOfComponents(VecTraitsTagSizeStatic) const
|
||||
{
|
||||
return vtkm::VecTraits<T>::NUM_COMPONENTS;
|
||||
}
|
||||
|
||||
vtkm::IdComponent GetNumberOfComponents(VecTraitsTagSizeVariable) const
|
||||
{
|
||||
return (this->Array.GetNumberOfValues() == 0)
|
||||
? 0
|
||||
: vtkm::VecTraits<T>::GetNumberOfComponents(this->Array.ReadPortal().Get(0));
|
||||
}
|
||||
};
|
||||
|
||||
namespace variant
|
||||
{
|
||||
|
||||
// One instance of a template class cannot access the private members of
|
||||
// another instance of a template class. However, I want to be able to copy
|
||||
// construct a VariantArrayHandle from another VariantArrayHandle of any other
|
||||
// type. Since you cannot partially specialize friendship, use this accessor
|
||||
// class to get at the internals for the copy constructor.
|
||||
struct GetContainer
|
||||
{
|
||||
template <typename TypeList>
|
||||
VTKM_CONT static const std::shared_ptr<VariantArrayHandleContainerBase>& Extract(
|
||||
const vtkm::cont::VariantArrayHandleBase<TypeList>& src)
|
||||
{
|
||||
return src.ArrayContainer;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
VTKM_CONT bool IsValueType(const VariantArrayHandleContainerBase* container)
|
||||
{
|
||||
if (container == nullptr)
|
||||
{ //you can't use typeid on nullptr of polymorphic types
|
||||
return false;
|
||||
}
|
||||
|
||||
//needs optimizations based on platform. !OSX can use typeid
|
||||
return container->TypeIndex == std::type_index(typeid(T));
|
||||
// return (nullptr != dynamic_cast<const VariantArrayHandleContainer<T>*>(container));
|
||||
}
|
||||
|
||||
template <typename ArrayHandleType>
|
||||
VTKM_CONT inline bool IsType(const VariantArrayHandleContainerBase* container)
|
||||
{ //container could be nullptr
|
||||
using T = typename ArrayHandleType::ValueType;
|
||||
if (!IsValueType<T>(container))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto* derived = static_cast<const VariantArrayHandleContainer<T>*>(container);
|
||||
return vtkm::cont::IsType<ArrayHandleType>(derived->Array);
|
||||
}
|
||||
|
||||
template <typename T, typename S>
|
||||
struct VTKM_ALWAYS_EXPORT Caster
|
||||
{
|
||||
vtkm::cont::ArrayHandle<T, S> operator()(const VariantArrayHandleContainerBase* container) const
|
||||
{
|
||||
//This needs to be reworked
|
||||
using ArrayHandleType = vtkm::cont::ArrayHandle<T, S>;
|
||||
if (!IsValueType<T>(container))
|
||||
{
|
||||
VTKM_LOG_CAST_FAIL(container, ArrayHandleType);
|
||||
throwFailedDynamicCast(vtkm::cont::TypeToString(container),
|
||||
vtkm::cont::TypeToString<ArrayHandleType>());
|
||||
}
|
||||
|
||||
const auto* derived = static_cast<const VariantArrayHandleContainer<T>*>(container);
|
||||
return vtkm::cont::Cast<vtkm::cont::ArrayHandle<T, S>>(derived->Array);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct VTKM_ALWAYS_EXPORT Caster<T, vtkm::cont::StorageTagVirtual>
|
||||
{
|
||||
vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagVirtual> operator()(
|
||||
const VariantArrayHandleContainerBase* container) const
|
||||
{
|
||||
if (!IsValueType<T>(container))
|
||||
{
|
||||
VTKM_LOG_CAST_FAIL(container, vtkm::cont::ArrayHandleVirtual<T>);
|
||||
throwFailedDynamicCast(vtkm::cont::TypeToString(container),
|
||||
vtkm::cont::TypeToString<vtkm::cont::ArrayHandleVirtual<T>>());
|
||||
}
|
||||
|
||||
// Technically, this method returns a copy of the \c ArrayHandle. But
|
||||
// because \c ArrayHandle acts like a shared pointer, it is valid to
|
||||
// do the copy.
|
||||
const auto* derived = static_cast<const VariantArrayHandleContainer<T>*>(container);
|
||||
VTKM_LOG_CAST_SUCC(container, derived->Array);
|
||||
return derived->Array;
|
||||
}
|
||||
};
|
||||
|
||||
// MSVC will issue deprecation warnings here if this template is instantiated with
|
||||
// a deprecated class even if the template is used from a section of code where
|
||||
// deprecation warnings are suppressed. This is annoying behavior since this template
|
||||
// has no control over what class it is used with. To get around it, we have to
|
||||
// suppress all deprecation warnings here.
|
||||
#ifdef VTKM_MSVC
|
||||
VTKM_DEPRECATED_SUPPRESS_BEGIN
|
||||
#endif
|
||||
template <typename ArrayHandleType>
|
||||
VTKM_CONT ArrayHandleType Cast(const VariantArrayHandleContainerBase* container)
|
||||
{ //container could be nullptr
|
||||
VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
|
||||
using Type = typename ArrayHandleType::ValueType;
|
||||
using Storage = typename ArrayHandleType::StorageTag;
|
||||
auto ret = Caster<Type, Storage>{}(container);
|
||||
return ArrayHandleType(std::move(ret));
|
||||
}
|
||||
#ifdef VTKM_MSVC
|
||||
VTKM_DEPRECATED_SUPPRESS_END
|
||||
#endif
|
||||
|
||||
struct ForceCastToVirtual
|
||||
{
|
||||
template <typename SrcValueType, typename Storage, typename DstValueType>
|
||||
VTKM_CONT typename std::enable_if<std::is_same<SrcValueType, DstValueType>::value>::type
|
||||
operator()(const vtkm::cont::ArrayHandle<SrcValueType, Storage>& input,
|
||||
vtkm::cont::ArrayHandleVirtual<DstValueType>& output) const
|
||||
{ // ValueTypes match
|
||||
output = vtkm::cont::make_ArrayHandleVirtual<DstValueType>(input);
|
||||
}
|
||||
|
||||
template <typename SrcValueType, typename Storage, typename DstValueType>
|
||||
VTKM_CONT typename std::enable_if<!std::is_same<SrcValueType, DstValueType>::value>::type
|
||||
operator()(const vtkm::cont::ArrayHandle<SrcValueType, Storage>& input,
|
||||
vtkm::cont::ArrayHandleVirtual<DstValueType>& output) const
|
||||
{ // ValueTypes do not match
|
||||
this->ValidateWidthAndCast<SrcValueType, DstValueType>(input, output);
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename S,
|
||||
typename D,
|
||||
typename InputType,
|
||||
vtkm::IdComponent SSize = vtkm::VecTraits<S>::NUM_COMPONENTS,
|
||||
vtkm::IdComponent DSize = vtkm::VecTraits<D>::NUM_COMPONENTS>
|
||||
VTKM_CONT typename std::enable_if<SSize == DSize>::type ValidateWidthAndCast(
|
||||
const InputType& input,
|
||||
vtkm::cont::ArrayHandleVirtual<D>& output) const
|
||||
{ // number of components match
|
||||
auto casted = vtkm::cont::make_ArrayHandleCast<D>(input);
|
||||
output = vtkm::cont::make_ArrayHandleVirtual<D>(casted);
|
||||
}
|
||||
|
||||
template <typename S,
|
||||
typename D,
|
||||
vtkm::IdComponent SSize = vtkm::VecTraits<S>::NUM_COMPONENTS,
|
||||
vtkm::IdComponent DSize = vtkm::VecTraits<D>::NUM_COMPONENTS>
|
||||
VTKM_CONT typename std::enable_if<SSize != DSize>::type ValidateWidthAndCast(
|
||||
const ArrayHandleBase&,
|
||||
ArrayHandleBase&) const
|
||||
{ // number of components do not match
|
||||
std::ostringstream str;
|
||||
str << "VariantArrayHandle::AsVirtual: Cannot cast from " << vtkm::cont::TypeToString<S>()
|
||||
<< " to " << vtkm::cont::TypeToString<D>()
|
||||
<< "; "
|
||||
"number of components must match exactly.";
|
||||
throw vtkm::cont::ErrorBadType(str.str());
|
||||
}
|
||||
};
|
||||
} // namespace variant
|
||||
|
||||
} // namespace internal
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
VTKM_CONT_EXPORT void ThrowCastAndCallException(
|
||||
const vtkm::cont::internal::VariantArrayHandleContainerBase&,
|
||||
const std::type_info&);
|
||||
|
||||
VTKM_CONT_EXPORT void ThrowAsMultiplexerException(
|
||||
const vtkm::cont::internal::VariantArrayHandleContainerBase& ref,
|
||||
const std::initializer_list<std::string>& arrayTypes);
|
||||
} // namespace detail
|
||||
}
|
||||
} //namespace vtkm::cont
|
||||
|
||||
#endif
|
@ -11,6 +11,7 @@
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/ArrayHandleCounting.h>
|
||||
#include <vtkm/cont/ArrayHandleVirtual.h>
|
||||
#include <vtkm/cont/ArrayHandleVirtual.hxx>
|
||||
|
||||
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
|
||||
|
||||
|
@ -157,27 +157,86 @@ vtkm::cont::UnknownArrayHandle CreateArrayUnknown(T t)
|
||||
}
|
||||
|
||||
template <typename ArrayHandleType>
|
||||
void CheckCastToArrayHandle(const ArrayHandleType& array)
|
||||
void CheckAsArrayHandle(const ArrayHandleType& array)
|
||||
{
|
||||
VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
|
||||
using T = typename ArrayHandleType::ValueType;
|
||||
|
||||
vtkm::cont::UnknownArrayHandle arrayUnknown = array;
|
||||
VTKM_TEST_ASSERT(!arrayUnknown.IsType<vtkm::cont::ArrayHandle<UnusualType>>(),
|
||||
"Dynamic array reporting is wrong type.");
|
||||
|
||||
ArrayHandleType castArray1;
|
||||
arrayUnknown.AsArrayHandle(castArray1);
|
||||
VTKM_TEST_ASSERT(arrayUnknown.CanConvert<ArrayHandleType>(), "Did not query handle correctly.");
|
||||
VTKM_TEST_ASSERT(array == castArray1, "Did not get back same array.");
|
||||
{
|
||||
std::cout << " Normal get ArrayHandle" << std::endl;
|
||||
ArrayHandleType retreivedArray1;
|
||||
arrayUnknown.AsArrayHandle(retreivedArray1);
|
||||
VTKM_TEST_ASSERT(arrayUnknown.CanConvert<ArrayHandleType>(), "Did not query handle correctly.");
|
||||
VTKM_TEST_ASSERT(array == retreivedArray1, "Did not get back same array.");
|
||||
|
||||
ArrayHandleType castArray2 = arrayUnknown.AsArrayHandle<ArrayHandleType>();
|
||||
VTKM_TEST_ASSERT(array == castArray2, "Did not get back same array.");
|
||||
ArrayHandleType retreivedArray2 = arrayUnknown.AsArrayHandle<ArrayHandleType>();
|
||||
VTKM_TEST_ASSERT(array == retreivedArray2, "Did not get back same array.");
|
||||
}
|
||||
|
||||
vtkm::cont::UnknownArrayHandle arrayUnknown2 = vtkm::cont::ArrayHandleMultiplexer<
|
||||
ArrayHandleType,
|
||||
vtkm::cont::ArrayHandleConstant<typename ArrayHandleType::ValueType>>(array);
|
||||
VTKM_TEST_ASSERT(arrayUnknown2.IsType<ArrayHandleType>(),
|
||||
"Putting in multiplexer did not pull out array.");
|
||||
{
|
||||
std::cout << " Put in cast array, get actual array" << std::endl;
|
||||
auto castArray = vtkm::cont::make_ArrayHandleCast<vtkm::Float64>(array);
|
||||
vtkm::cont::UnknownArrayHandle arrayUnknown2(castArray);
|
||||
VTKM_TEST_ASSERT(arrayUnknown2.IsType<ArrayHandleType>());
|
||||
ArrayHandleType retrievedArray = arrayUnknown2.AsArrayHandle<ArrayHandleType>();
|
||||
VTKM_TEST_ASSERT(array == retrievedArray);
|
||||
}
|
||||
|
||||
{
|
||||
std::cout << " Get array as cast" << std::endl;
|
||||
vtkm::cont::ArrayHandleCast<vtkm::Float64, ArrayHandleType> castArray;
|
||||
arrayUnknown.AsArrayHandle(castArray);
|
||||
VTKM_TEST_ASSERT(test_equal_portals(array.ReadPortal(), castArray.ReadPortal()));
|
||||
}
|
||||
|
||||
{
|
||||
std::cout << " Put in multiplexer, get actual array" << std::endl;
|
||||
vtkm::cont::UnknownArrayHandle arrayUnknown2 = vtkm::cont::ArrayHandleMultiplexer<
|
||||
ArrayHandleType,
|
||||
vtkm::cont::ArrayHandleConstant<typename ArrayHandleType::ValueType>>(array);
|
||||
VTKM_TEST_ASSERT(arrayUnknown2.IsType<ArrayHandleType>(),
|
||||
"Putting in multiplexer did not pull out array.");
|
||||
}
|
||||
|
||||
{
|
||||
std::cout << " Make sure multiplex array prefers direct array (1st arg)" << std::endl;
|
||||
using MultiplexerType =
|
||||
vtkm::cont::ArrayHandleMultiplexer<ArrayHandleType,
|
||||
vtkm::cont::ArrayHandleCast<T, ArrayHandleType>>;
|
||||
MultiplexerType multiplexArray = arrayUnknown.AsArrayHandle<MultiplexerType>();
|
||||
|
||||
VTKM_TEST_ASSERT(multiplexArray.IsValid());
|
||||
VTKM_TEST_ASSERT(multiplexArray.GetStorage().GetArrayHandleVariant().GetIndex() == 0);
|
||||
VTKM_TEST_ASSERT(test_equal_portals(multiplexArray.ReadPortal(), array.ReadPortal()));
|
||||
}
|
||||
|
||||
{
|
||||
std::cout << " Make sure multiplex array prefers direct array (2nd arg)" << std::endl;
|
||||
using MultiplexerType =
|
||||
vtkm::cont::ArrayHandleMultiplexer<vtkm::cont::ArrayHandleCast<T, vtkm::cont::ArrayHandle<T>>,
|
||||
ArrayHandleType>;
|
||||
MultiplexerType multiplexArray = arrayUnknown.AsArrayHandle<MultiplexerType>();
|
||||
|
||||
VTKM_TEST_ASSERT(multiplexArray.IsValid());
|
||||
VTKM_TEST_ASSERT(multiplexArray.GetStorage().GetArrayHandleVariant().GetIndex() == 1);
|
||||
VTKM_TEST_ASSERT(test_equal_portals(multiplexArray.ReadPortal(), array.ReadPortal()));
|
||||
}
|
||||
|
||||
{
|
||||
std::cout << " Make sure adding arrays follows nesting of special arrays" << std::endl;
|
||||
vtkm::cont::ArrayHandleMultiplexer<vtkm::cont::ArrayHandle<vtkm::Int64>,
|
||||
vtkm::cont::ArrayHandleCast<vtkm::Int64, ArrayHandleType>>
|
||||
multiplexer(vtkm::cont::make_ArrayHandleCast<vtkm::Int64>(array));
|
||||
auto crazyArray = vtkm::cont::make_ArrayHandleCast<vtkm::Float64>(multiplexer);
|
||||
vtkm::cont::UnknownArrayHandle arrayUnknown2(crazyArray);
|
||||
VTKM_TEST_ASSERT(arrayUnknown2.IsType<ArrayHandleType>());
|
||||
ArrayHandleType retrievedArray = arrayUnknown2.AsArrayHandle<ArrayHandleType>();
|
||||
VTKM_TEST_ASSERT(array == retrievedArray);
|
||||
}
|
||||
}
|
||||
|
||||
// A vtkm::Vec if NumComps > 1, otherwise a scalar
|
||||
@ -320,12 +379,12 @@ void TryUnusualType()
|
||||
}
|
||||
|
||||
template <typename ArrayHandleType>
|
||||
void TryCastToArrayHandle(const ArrayHandleType& array)
|
||||
void TryAsArrayHandle(const ArrayHandleType& array)
|
||||
{
|
||||
CheckCastToArrayHandle(array);
|
||||
CheckAsArrayHandle(array);
|
||||
}
|
||||
|
||||
void TryCastToArrayHandle()
|
||||
void TryAsArrayHandle()
|
||||
{
|
||||
std::cout << " Normal array handle." << std::endl;
|
||||
vtkm::Id buffer[ARRAY_SIZE];
|
||||
@ -336,10 +395,10 @@ void TryCastToArrayHandle()
|
||||
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> array =
|
||||
vtkm::cont::make_ArrayHandle(buffer, ARRAY_SIZE, vtkm::CopyFlag::On);
|
||||
TryCastToArrayHandle(array);
|
||||
TryAsArrayHandle(array);
|
||||
|
||||
std::cout << " Constant array handle." << std::endl;
|
||||
TryCastToArrayHandle(vtkm::cont::make_ArrayHandleConstant(5, ARRAY_SIZE));
|
||||
TryAsArrayHandle(vtkm::cont::make_ArrayHandleConstant(5, ARRAY_SIZE));
|
||||
}
|
||||
|
||||
void TrySetCastArray()
|
||||
@ -386,8 +445,8 @@ void TestUnknownArrayHandle()
|
||||
std::cout << "Try unusual type." << std::endl;
|
||||
TryUnusualType();
|
||||
|
||||
std::cout << "Try CastToArrayHandle" << std::endl;
|
||||
TryCastToArrayHandle();
|
||||
std::cout << "Try AsArrayHandle" << std::endl;
|
||||
TryAsArrayHandle();
|
||||
|
||||
std::cout << "Try setting ArrayHandleCast" << std::endl;
|
||||
TrySetCastArray();
|
||||
|
@ -230,11 +230,16 @@ void CheckCastToArrayHandle(const ArrayHandleType& array)
|
||||
|
||||
ArrayHandleType castArray1;
|
||||
arrayVariant.CopyTo(castArray1);
|
||||
VTKM_TEST_ASSERT(arrayVariant.IsType<ArrayHandleType>(), "Did not query handle correctly.");
|
||||
VTKM_TEST_ASSERT(array == castArray1, "Did not get back same array.");
|
||||
VTKM_TEST_ASSERT(arrayVariant.CanConvert<ArrayHandleType>(), "Did not query handle correctly.");
|
||||
//VTKM_TEST_ASSERT(array == castArray1, "Did not get back same array.");
|
||||
auto result = vtkm::cont::testing::test_equal_ArrayHandles(array, castArray1);
|
||||
VTKM_TEST_ASSERT(result, result.GetMergedMessage());
|
||||
|
||||
|
||||
ArrayHandleType castArray2 = arrayVariant.Cast<ArrayHandleType>();
|
||||
VTKM_TEST_ASSERT(array == castArray2, "Did not get back same array.");
|
||||
//VTKM_TEST_ASSERT(array == castArray2, "Did not get back same array.");
|
||||
result = vtkm::cont::testing::test_equal_ArrayHandles(array, castArray2);
|
||||
VTKM_TEST_ASSERT(result, result.GetMergedMessage());
|
||||
}
|
||||
|
||||
// A vtkm::Vec if NumComps > 1, otherwise a scalar
|
||||
|
Loading…
Reference in New Issue
Block a user