mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-08 21:33:55 +00:00
Allow VariantArrayHandle CastAndCall to cast to concrete types
When you call VariantArrayHandle::CastAndCall, it now tries both basic storage and virtual storage. You can modify the types of storages tried by giving a type list of storage tags as the first argument.
This commit is contained in:
parent
5cf2a21d3c
commit
d59ce11c00
58
docs/changelog/cast-variant-to-storage.md
Normal file
58
docs/changelog/cast-variant-to-storage.md
Normal file
@ -0,0 +1,58 @@
|
||||
# Allow VariantArrayHandle CastAndCall to cast to concrete types
|
||||
|
||||
Previously, the `VariantArrayHandle::CastAndCall` (and indirect calls through
|
||||
`vtkm::cont::CastAndCall`) attempted to cast to only
|
||||
`vtkm::cont::ArrayHandleVirtual` with different value types. That worked, but
|
||||
it meant that whatever was called had to operate through virtual functions.
|
||||
|
||||
Under most circumstances, it is worthwhile to also check for some common
|
||||
storage types that, when encountered, can be accessed much faster. This
|
||||
change provides the casting to concrete storage types and now uses
|
||||
`vtkm::cont::ArrayHandleVirtual` as a fallback when no concrete storage
|
||||
type is found.
|
||||
|
||||
By default, `CastAndCall` checks all the storage types in
|
||||
`VTKM_DEFAULT_STORAGE_LIST_TAG`, which typically contains only the basic
|
||||
storage. The `ArrayHandleVirtual::CastAndCall` method also allows you to
|
||||
override this behavior by specifying a different type list in the first
|
||||
argument. If the first argument is a list type, `CastAndCall` assumes that
|
||||
all the types in the list are storage tags. If you pass in
|
||||
`vtkm::ListTagEmpty`, then `CastAndCall` will always cast to an
|
||||
`ArrayHandleVirtual` (the previous behavior). Alternately, you can pass in
|
||||
storage tags that might be likely under the current usage.
|
||||
|
||||
As an example, consider the following simple code.
|
||||
|
||||
``` cpp
|
||||
vtkm::cont::VariantArrayHandle array;
|
||||
|
||||
// stuff happens
|
||||
|
||||
array.CastAndCall(myFunctor);
|
||||
```
|
||||
|
||||
Previously, `myFunctor` would be called with
|
||||
`vtkm::cont::ArrayHandleVirtual<T>` with different type `T`s. After this
|
||||
change, `myFunctor` will be called with that and with
|
||||
`vtkm::cont::ArrayHandle<T>` of the same type `T`s.
|
||||
|
||||
If you want to only call `myFunctor` with
|
||||
`vtkm::cont::ArrayHandleVirtual<T>`, then replace the previous line with
|
||||
|
||||
``` cpp
|
||||
array.CastAndCall(vtkm::ListTagEmpty(), myFunctor);
|
||||
```
|
||||
|
||||
Let's say that additionally using `vtkm::cont::ArrayHandleIndex` was also
|
||||
common. If you want to also specialize for that array, you can do so with
|
||||
the following line.
|
||||
|
||||
``` cpp
|
||||
array.CastAndCall(vtkm::ListTagBase<vtkm::cont::StorageBasic,
|
||||
vtkm::cont::ArrayHandleIndex::StorageTag>,
|
||||
myFunctor);
|
||||
```
|
||||
|
||||
Note that `myFunctor` will be called with
|
||||
`vtkm::cont::ArrayHandle<T,vtkm::cont::ArrayHandleIndex::StorageTag>`, not
|
||||
`vtkm::cont::ArrayHandleIndex`.
|
@ -113,11 +113,10 @@ private:
|
||||
template <typename T, class ArrayPortalType, class DeviceAdapterTag>
|
||||
class ArrayTransfer<T, StorageTagImplicit<ArrayPortalType>, DeviceAdapterTag>
|
||||
{
|
||||
private:
|
||||
public:
|
||||
using StorageTag = StorageTagImplicit<ArrayPortalType>;
|
||||
using StorageType = vtkm::cont::internal::Storage<T, StorageTag>;
|
||||
|
||||
public:
|
||||
using ValueType = T;
|
||||
|
||||
using PortalControl = typename StorageType::PortalType;
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
#include <vtkm/cont/ErrorBadType.h>
|
||||
#include <vtkm/cont/Logging.h>
|
||||
#include <vtkm/cont/StorageListTag.h>
|
||||
#include <vtkm/cont/internal/DynamicTransform.h>
|
||||
|
||||
#include <vtkm/cont/internal/VariantArrayHandleContainer.h>
|
||||
@ -173,13 +174,45 @@ public:
|
||||
return VariantArrayHandleBase<NewTypeList>(*this);
|
||||
}
|
||||
|
||||
/// Attempts to cast the held array to a specific value type,
|
||||
//@{
|
||||
/// \brief Call a functor using the underlying array type.
|
||||
///
|
||||
/// \c CastAndCall Attempts to cast the held array to a specific value type,
|
||||
/// then call the given functor with the cast array. The types
|
||||
/// tried in the cast are those in the lists defined by the TypeList.
|
||||
/// By default \c VariantArrayHandle set this to VTKM_DEFAULT_TYPE_LIST_TAG.
|
||||
/// By default \c VariantArrayHandle set this to \c VTKM_DEFAULT_TYPE_LIST_TAG.
|
||||
///
|
||||
template <typename Functor, typename... Args>
|
||||
VTKM_CONT void CastAndCall(Functor&& f, Args&&...) const;
|
||||
/// In addition to the value type, an \c ArrayHandle also requires a storage tag.
|
||||
/// By default, \c CastAndCall attempts to cast the array using the storage tags
|
||||
/// listed in \c VTKM_DEFAULT_STORAGE_LIST_TAG. You can optionally give a custom
|
||||
/// list of storage tags as the second argument. If the storage of the underlying
|
||||
/// array does not match any of the storage tags given, then the array will
|
||||
/// be cast to an \c ArrayHandleVirtual, which can hold any array given the
|
||||
/// appropriate value type. To always use \c ArrayHandleVirtual, pass
|
||||
/// \c vtkm::ListTagEmpty as thefirst argument.
|
||||
///
|
||||
/// As previous stated, if a storage tag list is provided, it is given in the
|
||||
/// first argument. The functor to call with the cast array is given as the next
|
||||
/// argument (or the first argument if a storage tag list is not provided).
|
||||
/// The remaning arguments, if any, are passed to the functor.
|
||||
///
|
||||
/// The functor will be called with the cast array as its first argument. Any
|
||||
/// remaining arguments are passed from the arguments to \c CastAndCall.
|
||||
///
|
||||
template <typename FunctorOrStorageList, typename... Args>
|
||||
VTKM_CONT void CastAndCall(FunctorOrStorageList&& functorOrStorageList, Args&&... args) const
|
||||
{
|
||||
this->CastAndCallImpl(vtkm::internal::ListTagCheck<FunctorOrStorageList>(),
|
||||
std::forward<FunctorOrStorageList>(functorOrStorageList),
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename Functor>
|
||||
VTKM_CONT void CastAndCall(Functor&& f) const
|
||||
{
|
||||
this->CastAndCallImpl(std::false_type(), std::forward<Functor>(f));
|
||||
}
|
||||
//@}
|
||||
|
||||
/// \brief Create a new array of the same type as this array.
|
||||
///
|
||||
@ -228,6 +261,18 @@ public:
|
||||
private:
|
||||
friend struct internal::variant::GetContainer;
|
||||
std::shared_ptr<vtkm::cont::internal::VariantArrayHandleContainerBase> ArrayContainer;
|
||||
|
||||
template <typename Functor, typename... Args>
|
||||
VTKM_CONT void CastAndCallImpl(std::false_type, Functor&& f, Args&&... args) const
|
||||
{
|
||||
this->CastAndCallImpl(std::true_type(),
|
||||
VTKM_DEFAULT_STORAGE_LIST_TAG(),
|
||||
std::forward<Functor>(f),
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename StorageTagList, typename Functor, typename... Args>
|
||||
VTKM_CONT void CastAndCallImpl(std::true_type, StorageTagList, Functor&& f, Args&&...) const;
|
||||
};
|
||||
|
||||
using VariantArrayHandle = vtkm::cont::VariantArrayHandleBase<VTKM_DEFAULT_TYPE_LIST_TAG>;
|
||||
@ -254,6 +299,37 @@ namespace detail
|
||||
{
|
||||
|
||||
struct VariantArrayHandleTry
|
||||
{
|
||||
template <typename T, typename Storage, typename Functor, typename... Args>
|
||||
void operator()(brigand::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)...);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct VariantArrayHandleTryFallback
|
||||
{
|
||||
template <typename T, typename Functor, typename... Args>
|
||||
void operator()(T,
|
||||
@ -268,31 +344,74 @@ struct VariantArrayHandleTry
|
||||
const auto* derived =
|
||||
static_cast<const vtkm::cont::internal::VariantArrayHandleContainer<T>*>(&container);
|
||||
VTKM_LOG_CAST_SUCC(container, derived);
|
||||
|
||||
// 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(derived->Array, std::forward<Args>(args)...);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct IsUndefinedStorage
|
||||
{
|
||||
};
|
||||
template <typename T, typename U>
|
||||
struct IsUndefinedStorage<brigand::list<T, U>> : vtkm::cont::internal::IsInValidArrayHandle<T, U>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename TypeList, typename StorageList>
|
||||
struct ListTagDynamicTypes : vtkm::detail::ListRoot
|
||||
{
|
||||
using crossProduct = typename vtkm::ListCrossProduct<TypeList, StorageList>;
|
||||
// using list = typename crossProduct::list;
|
||||
using list = ::brigand::remove_if<typename crossProduct::list, IsUndefinedStorage<brigand::_1>>;
|
||||
};
|
||||
|
||||
|
||||
VTKM_CONT_EXPORT void ThrowCastAndCallException(
|
||||
const vtkm::cont::internal::VariantArrayHandleContainerBase&,
|
||||
const std::type_info&);
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
|
||||
template <typename TypeList>
|
||||
template <typename Functor, typename... Args>
|
||||
VTKM_CONT void VariantArrayHandleBase<TypeList>::CastAndCall(Functor&& f, Args&&... args) const
|
||||
template <typename StorageTagList, typename Functor, typename... Args>
|
||||
VTKM_CONT void VariantArrayHandleBase<TypeList>::CastAndCallImpl(std::true_type,
|
||||
StorageTagList,
|
||||
Functor&& f,
|
||||
Args&&... args) const
|
||||
{
|
||||
using crossProduct = detail::ListTagDynamicTypes<TypeList, StorageTagList>;
|
||||
|
||||
bool called = false;
|
||||
const auto& ref = *this->ArrayContainer;
|
||||
vtkm::ListForEach(detail::VariantArrayHandleTry{},
|
||||
TypeList{},
|
||||
crossProduct{},
|
||||
std::forward<Functor>(f),
|
||||
called,
|
||||
ref,
|
||||
std::forward<Args>(args)...);
|
||||
if (!called)
|
||||
{
|
||||
// try to fall back to using ArrayHandleVirtual
|
||||
vtkm::ListForEach(detail::VariantArrayHandleTryFallback{},
|
||||
TypeList{},
|
||||
std::forward<Functor>(f),
|
||||
called,
|
||||
ref,
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
if (!called)
|
||||
{
|
||||
// throw an exception
|
||||
VTKM_LOG_CAST_FAIL(*this, TypeList);
|
||||
@ -363,7 +482,7 @@ private:
|
||||
public:
|
||||
static VTKM_CONT void save(BinaryBuffer& bb, const Type& obj)
|
||||
{
|
||||
vtkm::cont::CastAndCall(obj, internal::VariantArrayHandleSerializeFunctor{}, bb);
|
||||
obj.CastAndCall(vtkm::ListTagEmpty(), internal::VariantArrayHandleSerializeFunctor{}, bb);
|
||||
}
|
||||
|
||||
static VTKM_CONT void load(BinaryBuffer& bb, Type& obj)
|
||||
|
@ -70,8 +70,8 @@ struct ScalarFunctor
|
||||
|
||||
struct ArrayHandleScalarFunctor
|
||||
{
|
||||
template <typename T>
|
||||
void operator()(const vtkm::cont::ArrayHandleVirtual<T>&) const
|
||||
template <typename ArrayType>
|
||||
void operator()(const ArrayType&) const
|
||||
{
|
||||
VTKM_TEST_FAIL("Called wrong form of functor operator.");
|
||||
}
|
||||
|
@ -95,12 +95,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
struct StorageListTagUnusual
|
||||
: vtkm::ListTagBase<ArrayHandleWithUnusualStorage<vtkm::Id>::StorageTag,
|
||||
ArrayHandleWithUnusualStorage<std::string>::StorageTag>
|
||||
{
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct TestValueFunctor
|
||||
{
|
||||
@ -110,10 +104,44 @@ struct TestValueFunctor
|
||||
struct CheckFunctor
|
||||
{
|
||||
template <typename T>
|
||||
void operator()(const vtkm::cont::ArrayHandleVirtual<T>& array, bool& called) const
|
||||
void operator()(const vtkm::cont::ArrayHandle<T>& array,
|
||||
bool& calledBasic,
|
||||
bool& vtkmNotUsed(calledUnusual),
|
||||
bool& vtkmNotUsed(calledVirtual)) const
|
||||
{
|
||||
called = true;
|
||||
std::cout << " Checking for type: " << typeid(T).name() << std::endl;
|
||||
calledBasic = true;
|
||||
std::cout << " Checking for basic array type: " << typeid(T).name() << std::endl;
|
||||
|
||||
VTKM_TEST_ASSERT(array.GetNumberOfValues() == ARRAY_SIZE, "Unexpected array size.");
|
||||
|
||||
auto portal = array.GetPortalConstControl();
|
||||
CheckPortal(portal);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void operator()(
|
||||
const vtkm::cont::ArrayHandle<T, typename ArrayHandleWithUnusualStorage<T>::StorageTag>& array,
|
||||
bool& vtkmNotUsed(calledBasic),
|
||||
bool& calledUnusual,
|
||||
bool& vtkmNotUsed(calledVirtual)) const
|
||||
{
|
||||
calledUnusual = true;
|
||||
std::cout << " Checking for unusual array type: " << typeid(T).name() << std::endl;
|
||||
|
||||
VTKM_TEST_ASSERT(array.GetNumberOfValues() == ARRAY_SIZE, "Unexpected array size.");
|
||||
|
||||
auto portal = array.GetPortalConstControl();
|
||||
CheckPortal(portal);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void operator()(const vtkm::cont::ArrayHandleVirtual<T>& array,
|
||||
bool& vtkmNotUsed(calledBasic),
|
||||
bool& vtkmNotUsed(calledUnusual),
|
||||
bool& calledVirtual) const
|
||||
{
|
||||
calledVirtual = true;
|
||||
std::cout << " Checking for virtual array type: " << typeid(T).name() << std::endl;
|
||||
|
||||
VTKM_TEST_ASSERT(array.GetNumberOfValues() == ARRAY_SIZE, "Unexpected array size.");
|
||||
|
||||
@ -132,28 +160,78 @@ void BasicArrayVariantChecks(const vtkm::cont::VariantArrayHandleBase<TypeList>&
|
||||
"Dynamic array reports unexpected number of components.");
|
||||
}
|
||||
|
||||
void CheckArrayVariant(vtkm::cont::VariantArrayHandle array, vtkm::IdComponent numComponents)
|
||||
{
|
||||
BasicArrayVariantChecks(array, numComponents);
|
||||
|
||||
bool called = false;
|
||||
array.CastAndCall(CheckFunctor(), called);
|
||||
|
||||
VTKM_TEST_ASSERT(
|
||||
called, "The functor was never called (and apparently a bad value exception not thrown).");
|
||||
}
|
||||
|
||||
template <typename TypeList>
|
||||
void CheckArrayVariant(const vtkm::cont::VariantArrayHandleBase<TypeList>& array,
|
||||
vtkm::IdComponent numComponents)
|
||||
vtkm::IdComponent numComponents,
|
||||
bool isBasicArray,
|
||||
bool isUnusualArray)
|
||||
{
|
||||
BasicArrayVariantChecks(array, numComponents);
|
||||
|
||||
bool called = false;
|
||||
CastAndCall(array, CheckFunctor(), called);
|
||||
std::cout << " CastAndCall with default storage" << std::endl;
|
||||
bool calledBasic = false;
|
||||
bool calledUnusual = false;
|
||||
bool calledVirtual = false;
|
||||
CastAndCall(array, CheckFunctor(), calledBasic, calledUnusual, calledVirtual);
|
||||
|
||||
VTKM_TEST_ASSERT(
|
||||
called, "The functor was never called (and apparently a bad value exception not thrown).");
|
||||
calledBasic || calledUnusual || calledVirtual,
|
||||
"The functor was never called (and apparently a bad value exception not thrown).");
|
||||
if (isBasicArray)
|
||||
{
|
||||
VTKM_TEST_ASSERT(calledBasic, "The functor was never called with the basic array fast path");
|
||||
VTKM_TEST_ASSERT(!calledUnusual, "The functor was somehow called with the unusual fast path");
|
||||
VTKM_TEST_ASSERT(!calledVirtual, "The functor was somehow called with the virtual path");
|
||||
}
|
||||
else
|
||||
{
|
||||
VTKM_TEST_ASSERT(!calledBasic, "The array somehow got cast to a basic storage.");
|
||||
VTKM_TEST_ASSERT(!calledUnusual, "The array somehow got cast to an unusual storage.");
|
||||
}
|
||||
|
||||
std::cout << " CastAndCall with no storage" << std::endl;
|
||||
calledBasic = false;
|
||||
calledUnusual = false;
|
||||
calledVirtual = false;
|
||||
array.CastAndCall(
|
||||
vtkm::ListTagEmpty(), CheckFunctor(), calledBasic, calledUnusual, calledVirtual);
|
||||
VTKM_TEST_ASSERT(
|
||||
calledBasic || calledUnusual || calledVirtual,
|
||||
"The functor was never called (and apparently a bad value exception not thrown).");
|
||||
VTKM_TEST_ASSERT(!calledBasic, "The array somehow got cast to a basic storage.");
|
||||
VTKM_TEST_ASSERT(!calledUnusual, "The array somehow got cast to an unusual storage.");
|
||||
|
||||
std::cout << " CastAndCall with extra storage" << std::endl;
|
||||
calledBasic = false;
|
||||
calledUnusual = false;
|
||||
calledVirtual = false;
|
||||
array.CastAndCall(vtkm::ListTagBase<vtkm::cont::StorageTagBasic,
|
||||
ArrayHandleWithUnusualStorage<vtkm::Id>::StorageTag,
|
||||
ArrayHandleWithUnusualStorage<std::string>::StorageTag>(),
|
||||
CheckFunctor(),
|
||||
calledBasic,
|
||||
calledUnusual,
|
||||
calledVirtual);
|
||||
VTKM_TEST_ASSERT(
|
||||
calledBasic || calledUnusual || calledVirtual,
|
||||
"The functor was never called (and apparently a bad value exception not thrown).");
|
||||
if (isBasicArray)
|
||||
{
|
||||
VTKM_TEST_ASSERT(calledBasic, "The functor was never called with the basic array fast path");
|
||||
VTKM_TEST_ASSERT(!calledUnusual, "The functor was somehow called with the unusual fast path");
|
||||
VTKM_TEST_ASSERT(!calledVirtual, "The functor was somehow called with the virtual path");
|
||||
}
|
||||
else if (isUnusualArray)
|
||||
{
|
||||
VTKM_TEST_ASSERT(calledUnusual, "The functor was never called with the unusual fast path");
|
||||
VTKM_TEST_ASSERT(!calledBasic, "The functor was somehow called with the basic fast path");
|
||||
VTKM_TEST_ASSERT(!calledVirtual, "The functor was somehow called with the virtual path");
|
||||
}
|
||||
else
|
||||
{
|
||||
VTKM_TEST_ASSERT(!calledBasic, "The array somehow got cast to a basic storage.");
|
||||
VTKM_TEST_ASSERT(!calledUnusual, "The array somehow got cast to an unusual storage.");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -196,7 +274,7 @@ template <typename T, typename ArrayVariantType>
|
||||
void TryNewInstance(T, ArrayVariantType originalArray)
|
||||
{
|
||||
// This check should already have been performed by caller, but just in case.
|
||||
CheckArrayVariant(originalArray, vtkm::VecTraits<T>::NUM_COMPONENTS);
|
||||
CheckArrayVariant(originalArray, vtkm::VecTraits<T>::NUM_COMPONENTS, true, false);
|
||||
|
||||
std::cout << "Create new instance of array." << std::endl;
|
||||
ArrayVariantType newArray = originalArray.NewInstance();
|
||||
@ -212,7 +290,7 @@ void TryNewInstance(T, ArrayVariantType originalArray)
|
||||
{
|
||||
staticArray.GetPortalControl().Set(index, TestValue(index + 100, T()));
|
||||
}
|
||||
CheckArrayVariant(originalArray, vtkm::VecTraits<T>::NUM_COMPONENTS);
|
||||
CheckArrayVariant(originalArray, vtkm::VecTraits<T>::NUM_COMPONENTS, true, false);
|
||||
|
||||
std::cout << "Set the new static array to expected values and make sure the new" << std::endl
|
||||
<< "dynamic array points to the same new values." << std::endl;
|
||||
@ -220,7 +298,7 @@ void TryNewInstance(T, ArrayVariantType originalArray)
|
||||
{
|
||||
staticArray.GetPortalControl().Set(index, TestValue(index, T()));
|
||||
}
|
||||
CheckArrayVariant(newArray, vtkm::VecTraits<T>::NUM_COMPONENTS);
|
||||
CheckArrayVariant(newArray, vtkm::VecTraits<T>::NUM_COMPONENTS, true, false);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -228,7 +306,7 @@ void TryDefaultType(T)
|
||||
{
|
||||
vtkm::cont::VariantArrayHandle array = CreateArrayVariant(T());
|
||||
|
||||
CheckArrayVariant(array, vtkm::VecTraits<T>::NUM_COMPONENTS);
|
||||
CheckArrayVariant(array, vtkm::VecTraits<T>::NUM_COMPONENTS, true, false);
|
||||
|
||||
TryNewInstance(T(), array);
|
||||
}
|
||||
@ -240,7 +318,8 @@ struct TryBasicVTKmType
|
||||
{
|
||||
vtkm::cont::VariantArrayHandle array = CreateArrayVariant(T());
|
||||
|
||||
CheckArrayVariant(array.ResetTypes(vtkm::TypeListTagAll()), vtkm::VecTraits<T>::NUM_COMPONENTS);
|
||||
CheckArrayVariant(
|
||||
array.ResetTypes(vtkm::TypeListTagAll()), vtkm::VecTraits<T>::NUM_COMPONENTS, true, false);
|
||||
|
||||
TryNewInstance(T(), array.ResetTypes(vtkm::TypeListTagAll()));
|
||||
}
|
||||
@ -253,7 +332,7 @@ void TryUnusualType()
|
||||
|
||||
try
|
||||
{
|
||||
CheckArrayVariant(array, 1);
|
||||
CheckArrayVariant(array, 1, true, false);
|
||||
VTKM_TEST_FAIL("CastAndCall failed to error for unrecognized type.");
|
||||
}
|
||||
catch (vtkm::cont::ErrorBadValue&)
|
||||
@ -261,7 +340,7 @@ void TryUnusualType()
|
||||
std::cout << " Caught exception for unrecognized type." << std::endl;
|
||||
}
|
||||
|
||||
CheckArrayVariant(array.ResetTypes(TypeListTagString()), 1);
|
||||
CheckArrayVariant(array.ResetTypes(TypeListTagString()), 1, true, false);
|
||||
std::cout << " Found type when type list was reset." << std::endl;
|
||||
}
|
||||
|
||||
@ -271,7 +350,7 @@ void TryUnusualStorage()
|
||||
|
||||
try
|
||||
{
|
||||
CheckArrayVariant(array, 1);
|
||||
CheckArrayVariant(array, 1, false, true);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
@ -285,7 +364,7 @@ void TryUnusualTypeAndStorage()
|
||||
|
||||
try
|
||||
{
|
||||
CheckArrayVariant(array, 1);
|
||||
CheckArrayVariant(array, 1, false, true);
|
||||
VTKM_TEST_FAIL("CastAndCall failed to error for unrecognized type/storage.");
|
||||
}
|
||||
catch (vtkm::cont::ErrorBadValue&)
|
||||
@ -295,7 +374,7 @@ void TryUnusualTypeAndStorage()
|
||||
|
||||
try
|
||||
{
|
||||
CheckArrayVariant(array.ResetTypes(TypeListTagString()), 1);
|
||||
CheckArrayVariant(array.ResetTypes(TypeListTagString()), 1, false, true);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
@ -852,11 +852,16 @@ private:
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void operator()(const vtkm::cont::ArrayHandleVirtual<T>& handle) const
|
||||
template <typename ArrayHandleType>
|
||||
void operator()(const ArrayHandleType& handle) const
|
||||
{
|
||||
VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
|
||||
using T = typename ArrayHandleType::ValueType;
|
||||
|
||||
if (this->Permutation.GetNumberOfValues() < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
vtkm::cont::ArrayHandle<T> out;
|
||||
out.Allocate(this->Permutation.GetNumberOfValues());
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user