Remove vtkm::cont::DynamicArrayHandle.
This commit is contained in:
parent
0a40c620ac
commit
7eb1e31b11
@ -74,7 +74,6 @@ set(headers
|
|||||||
DeviceAdapter.h
|
DeviceAdapter.h
|
||||||
DeviceAdapterAlgorithm.h
|
DeviceAdapterAlgorithm.h
|
||||||
DeviceAdapterListTag.h
|
DeviceAdapterListTag.h
|
||||||
DynamicArrayHandle.h
|
|
||||||
DynamicCellSet.h
|
DynamicCellSet.h
|
||||||
EnvironmentTracker.h
|
EnvironmentTracker.h
|
||||||
Error.h
|
Error.h
|
||||||
@ -139,7 +138,6 @@ set(sources
|
|||||||
DataSetBuilderExplicit.cxx
|
DataSetBuilderExplicit.cxx
|
||||||
DataSetBuilderRectilinear.cxx
|
DataSetBuilderRectilinear.cxx
|
||||||
DataSetBuilderUniform.cxx
|
DataSetBuilderUniform.cxx
|
||||||
DynamicArrayHandle.cxx
|
|
||||||
EnvironmentTracker.cxx
|
EnvironmentTracker.cxx
|
||||||
ErrorBadDevice.cxx
|
ErrorBadDevice.cxx
|
||||||
ErrorBadType.cxx
|
ErrorBadType.cxx
|
||||||
|
@ -1,53 +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.
|
|
||||||
//
|
|
||||||
// Copyright 2015 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
|
||||||
// Copyright 2015 UT-Battelle, LLC.
|
|
||||||
// Copyright 2015 Los Alamos National Security.
|
|
||||||
//
|
|
||||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
|
||||||
// the U.S. Government retains certain rights in this software.
|
|
||||||
//
|
|
||||||
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
|
||||||
// Laboratory (LANL), the U.S. Government retains certain rights in
|
|
||||||
// this software.
|
|
||||||
//============================================================================
|
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <typeindex>
|
|
||||||
#include <vtkm/cont/DynamicArrayHandle.h>
|
|
||||||
|
|
||||||
namespace vtkm
|
|
||||||
{
|
|
||||||
namespace cont
|
|
||||||
{
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
|
|
||||||
PolymorphicArrayHandleContainerBase::PolymorphicArrayHandleContainerBase()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
PolymorphicArrayHandleContainerBase::~PolymorphicArrayHandleContainerBase()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThrowCastAndCallException(PolymorphicArrayHandleContainerBase* ptr,
|
|
||||||
const std::type_info* type,
|
|
||||||
const std::type_info* storage)
|
|
||||||
{
|
|
||||||
std::ostringstream out;
|
|
||||||
out << "Could not find appropriate cast for array in CastAndCall1.\n"
|
|
||||||
"Array: ";
|
|
||||||
ptr->PrintSummary(out);
|
|
||||||
out << "TypeList: " << type->name() << "\nStorageList: " << storage->name() << "\n";
|
|
||||||
throw vtkm::cont::ErrorBadValue(out.str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // namespace vtkm::cont::detail
|
|
@ -1,579 +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.
|
|
||||||
//
|
|
||||||
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
|
||||||
// Copyright 2014 UT-Battelle, LLC.
|
|
||||||
// Copyright 2014 Los Alamos National Security.
|
|
||||||
//
|
|
||||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
|
||||||
// the U.S. Government retains certain rights in this software.
|
|
||||||
//
|
|
||||||
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
|
||||||
// Laboratory (LANL), the U.S. Government retains certain rights in
|
|
||||||
// this software.
|
|
||||||
//============================================================================
|
|
||||||
#ifndef vtk_m_cont_DynamicArrayHandle_h
|
|
||||||
#define vtk_m_cont_DynamicArrayHandle_h
|
|
||||||
|
|
||||||
#include <vtkm/cont/vtkm_cont_export.h>
|
|
||||||
|
|
||||||
#include <vtkm/TypeListTag.h>
|
|
||||||
#include <vtkm/VecTraits.h>
|
|
||||||
|
|
||||||
#include <vtkm/cont/ArrayHandle.h>
|
|
||||||
#include <vtkm/cont/ErrorBadType.h>
|
|
||||||
#include <vtkm/cont/Logging.h>
|
|
||||||
#include <vtkm/cont/StorageListTag.h>
|
|
||||||
|
|
||||||
#include <vtkm/cont/ArrayHandlePermutation.h>
|
|
||||||
#include <vtkm/cont/internal/DynamicTransform.h>
|
|
||||||
|
|
||||||
namespace vtkm
|
|
||||||
{
|
|
||||||
|
|
||||||
template struct ListCrossProduct<VTKM_DEFAULT_TYPE_LIST_TAG, VTKM_DEFAULT_STORAGE_LIST_TAG>;
|
|
||||||
|
|
||||||
namespace cont
|
|
||||||
{
|
|
||||||
|
|
||||||
// Forward declaration
|
|
||||||
template <typename TypeList, typename StorageList>
|
|
||||||
class DynamicArrayHandleBase;
|
|
||||||
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
|
|
||||||
/// \brief Base class for PolymorphicArrayHandleContainer
|
|
||||||
///
|
|
||||||
struct VTKM_CONT_EXPORT PolymorphicArrayHandleContainerBase
|
|
||||||
{
|
|
||||||
PolymorphicArrayHandleContainerBase();
|
|
||||||
|
|
||||||
// This must exist so that subclasses are destroyed correctly.
|
|
||||||
virtual ~PolymorphicArrayHandleContainerBase();
|
|
||||||
|
|
||||||
virtual vtkm::IdComponent GetNumberOfComponents() const = 0;
|
|
||||||
virtual vtkm::Id GetNumberOfValues() const = 0;
|
|
||||||
|
|
||||||
virtual void PrintSummary(std::ostream& out) const = 0;
|
|
||||||
|
|
||||||
virtual std::shared_ptr<PolymorphicArrayHandleContainerBase> NewInstance() const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// \brief ArrayHandle container that can use C++ run-time type information.
|
|
||||||
///
|
|
||||||
/// The \c PolymorphicArrayHandleContainer is similar to the
|
|
||||||
/// \c SimplePolymorphicContainer in that it can contain an object of an
|
|
||||||
/// unknown type. However, this class specifically holds ArrayHandle objects
|
|
||||||
/// (with different template parameters) so that it can polymorphically answer
|
|
||||||
/// simple questions about the object.
|
|
||||||
///
|
|
||||||
template <typename T, typename Storage>
|
|
||||||
struct VTKM_ALWAYS_EXPORT PolymorphicArrayHandleContainer
|
|
||||||
: public PolymorphicArrayHandleContainerBase
|
|
||||||
{
|
|
||||||
using ArrayHandleType = vtkm::cont::ArrayHandle<T, Storage>;
|
|
||||||
|
|
||||||
ArrayHandleType Array;
|
|
||||||
|
|
||||||
VTKM_CONT
|
|
||||||
PolymorphicArrayHandleContainer()
|
|
||||||
: Array()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
VTKM_CONT
|
|
||||||
PolymorphicArrayHandleContainer(const ArrayHandleType& array)
|
|
||||||
: Array(array)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual vtkm::IdComponent GetNumberOfComponents() const
|
|
||||||
{
|
|
||||||
return vtkm::VecTraits<T>::NUM_COMPONENTS;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual vtkm::Id GetNumberOfValues() const { return this->Array.GetNumberOfValues(); }
|
|
||||||
|
|
||||||
virtual void PrintSummary(std::ostream& out) const
|
|
||||||
{
|
|
||||||
vtkm::cont::printSummary_ArrayHandle(this->Array, out);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual std::shared_ptr<PolymorphicArrayHandleContainerBase> NewInstance() const
|
|
||||||
{
|
|
||||||
return std::shared_ptr<PolymorphicArrayHandleContainerBase>(
|
|
||||||
new PolymorphicArrayHandleContainer<T, Storage>());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 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 DynamicArrayHandle from another DynamicArrayHandle of any other
|
|
||||||
// type. Since you cannot partially specialize friendship, use this accessor
|
|
||||||
// class to get at the internals for the copy constructor.
|
|
||||||
struct DynamicArrayHandleCopyHelper
|
|
||||||
{
|
|
||||||
template <typename TypeList, typename StorageList>
|
|
||||||
VTKM_CONT static const std::shared_ptr<vtkm::cont::detail::PolymorphicArrayHandleContainerBase>&
|
|
||||||
GetArrayHandleContainer(const vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>& src)
|
|
||||||
{
|
|
||||||
return src.ArrayContainer;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// A simple function to downcast an ArrayHandle encapsulated in a
|
|
||||||
// PolymorphicArrayHandleContainerBase to the given type of ArrayHandle. If the
|
|
||||||
// conversion cannot be done, nullptr is returned.
|
|
||||||
template <typename Type, typename Storage>
|
|
||||||
VTKM_CONT vtkm::cont::ArrayHandle<Type, Storage>* DynamicArrayHandleTryCast(
|
|
||||||
vtkm::cont::detail::PolymorphicArrayHandleContainerBase* arrayContainer)
|
|
||||||
{
|
|
||||||
vtkm::cont::detail::PolymorphicArrayHandleContainer<Type, Storage>* downcastContainer = nullptr;
|
|
||||||
downcastContainer = dynamic_cast<decltype(downcastContainer)>(arrayContainer);
|
|
||||||
if (downcastContainer != nullptr)
|
|
||||||
{
|
|
||||||
return &downcastContainer->Array;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Type, typename Storage>
|
|
||||||
VTKM_CONT vtkm::cont::ArrayHandle<Type, Storage>* DynamicArrayHandleTryCast(
|
|
||||||
const std::shared_ptr<vtkm::cont::detail::PolymorphicArrayHandleContainerBase>& arrayContainer)
|
|
||||||
{
|
|
||||||
return detail::DynamicArrayHandleTryCast<Type, Storage>(arrayContainer.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
/// \brief Holds an array handle without having to specify template parameters.
|
|
||||||
///
|
|
||||||
/// \c DynamicArrayHandle holds an \c ArrayHandle object using runtime
|
|
||||||
/// polymorphism to manage different value types and storage rather than
|
|
||||||
/// compile-time templates. This adds a programming convenience that helps
|
|
||||||
/// avoid a proliferation of templates. It also provides the management
|
|
||||||
/// necessary to interface VTK-m with data sources where types will not be
|
|
||||||
/// known until runtime.
|
|
||||||
///
|
|
||||||
/// To interface between the runtime polymorphism and the templated algorithms
|
|
||||||
/// in VTK-m, \c DynamicArrayHandle contains a method named \c CastAndCall that
|
|
||||||
/// will determine the correct type from some known list of types and storage
|
|
||||||
/// objects. This mechanism is used internally by VTK-m's worklet invocation
|
|
||||||
/// mechanism to determine the type when running algorithms.
|
|
||||||
///
|
|
||||||
/// By default, \c DynamicArrayHandle will assume that the value type in the
|
|
||||||
/// array matches one of the types specified by \c VTKM_DEFAULT_TYPE_LIST_TAG
|
|
||||||
/// and the storage matches one of the tags specified by \c
|
|
||||||
/// VTKM_DEFAULT_STORAGE_LIST_TAG. These lists can be changed by using the \c
|
|
||||||
/// ResetTypeList and \c ResetStorageList methods, respectively. It is
|
|
||||||
/// worthwhile to match these lists closely to the possible types that might be
|
|
||||||
/// used. If a type is missing you will get a runtime error. If there are more
|
|
||||||
/// types than necessary, then the template mechanism will create a lot of
|
|
||||||
/// object code that is never used, and keep in mind that the number of
|
|
||||||
/// combinations grows exponentially when using multiple \c DynamicArrayHandle
|
|
||||||
/// objects.
|
|
||||||
///
|
|
||||||
/// The actual implementation of \c DynamicArrayHandle is in a templated class
|
|
||||||
/// named \c DynamicArrayHandleBase, which is templated on the list of
|
|
||||||
/// component types and storage types. \c DynamicArrayHandle is really just a
|
|
||||||
/// typedef of \c DynamicArrayHandleBase with the default type and storage
|
|
||||||
/// lists.
|
|
||||||
///
|
|
||||||
template <typename TypeList, typename StorageList>
|
|
||||||
class VTKM_ALWAYS_EXPORT DynamicArrayHandleBase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
VTKM_CONT
|
|
||||||
DynamicArrayHandleBase() {}
|
|
||||||
|
|
||||||
template <typename Type, typename Storage>
|
|
||||||
VTKM_CONT DynamicArrayHandleBase(const vtkm::cont::ArrayHandle<Type, Storage>& array)
|
|
||||||
: ArrayContainer(new vtkm::cont::detail::PolymorphicArrayHandleContainer<Type, Storage>(array))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
VTKM_CONT
|
|
||||||
DynamicArrayHandleBase(const DynamicArrayHandleBase<TypeList, StorageList>& src)
|
|
||||||
: ArrayContainer(src.ArrayContainer)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename OtherTypeList, typename OtherStorageList>
|
|
||||||
VTKM_CONT explicit DynamicArrayHandleBase(
|
|
||||||
const DynamicArrayHandleBase<OtherTypeList, OtherStorageList>& src)
|
|
||||||
: ArrayContainer(detail::DynamicArrayHandleCopyHelper::GetArrayHandleContainer(src))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
VTKM_CONT
|
|
||||||
~DynamicArrayHandleBase() {}
|
|
||||||
|
|
||||||
VTKM_CONT
|
|
||||||
vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>& operator=(
|
|
||||||
const vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>& src)
|
|
||||||
{
|
|
||||||
this->ArrayContainer = src.ArrayContainer;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns true if this array is of the provided type and uses the provided
|
|
||||||
/// storage.
|
|
||||||
///
|
|
||||||
template <typename Type, typename Storage>
|
|
||||||
VTKM_CONT bool IsTypeAndStorage() const
|
|
||||||
{
|
|
||||||
return (detail::DynamicArrayHandleTryCast<Type, Storage>(this->ArrayContainer) != nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns true if this array matches the array handle type passed in.
|
|
||||||
///
|
|
||||||
template <typename ArrayHandleType>
|
|
||||||
VTKM_CONT bool IsType()
|
|
||||||
{
|
|
||||||
VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
|
|
||||||
using ValueType = typename ArrayHandleType::ValueType;
|
|
||||||
using StorageTag = typename ArrayHandleType::StorageTag;
|
|
||||||
return this->IsTypeAndStorage<ValueType, StorageTag>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns true if the array held in this object is the same (or equivalent)
|
|
||||||
/// type as the object given.
|
|
||||||
///
|
|
||||||
template <typename ArrayHandleType>
|
|
||||||
VTKM_CONT bool IsSameType(const ArrayHandleType&)
|
|
||||||
{
|
|
||||||
VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
|
|
||||||
return this->IsType<ArrayHandleType>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns this array cast to an ArrayHandle object of the given type and
|
|
||||||
/// storage. Throws \c ErrorBadType if the cast does not work. Use
|
|
||||||
/// \c IsTypeAndStorage to check if the cast can happen.
|
|
||||||
///
|
|
||||||
///
|
|
||||||
template <typename Type, typename Storage>
|
|
||||||
VTKM_CONT vtkm::cont::ArrayHandle<Type, Storage> CastToTypeStorage() const
|
|
||||||
{
|
|
||||||
vtkm::cont::ArrayHandle<Type, Storage>* downcastArray =
|
|
||||||
detail::DynamicArrayHandleTryCast<Type, Storage>(this->ArrayContainer);
|
|
||||||
if (downcastArray == nullptr)
|
|
||||||
{
|
|
||||||
VTKM_LOG_CAST_FAIL(*this, decltype(downcastArray));
|
|
||||||
throw vtkm::cont::ErrorBadType("Bad cast of dynamic array.");
|
|
||||||
}
|
|
||||||
// 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.
|
|
||||||
VTKM_LOG_CAST_SUCC(*this, *downcastArray);
|
|
||||||
return *downcastArray;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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 ValueType = typename ArrayHandleType::ValueType;
|
|
||||||
using StorageTag = typename ArrayHandleType::StorageTag;
|
|
||||||
// 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.
|
|
||||||
return this->CastToTypeStorage<ValueType, StorageTag>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Given a references to an ArrayHandle object, casts this array to the
|
|
||||||
/// ArrayHandle's type and sets the given ArrayHandle to this array. Throws
|
|
||||||
/// \c ErrorBadType if the cast does not work. Use \c
|
|
||||||
/// ArrayHandleType to check if the cast can happen.
|
|
||||||
///
|
|
||||||
/// Note that this is a shallow copy. The data are not copied and a change
|
|
||||||
/// in the data in one array will be reflected in the other.
|
|
||||||
///
|
|
||||||
template <typename ArrayHandleType>
|
|
||||||
VTKM_CONT void CopyTo(ArrayHandleType& array) const
|
|
||||||
{
|
|
||||||
VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
|
|
||||||
array = this->Cast<ArrayHandleType>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Changes the types to try casting to when resolving this dynamic array,
|
|
||||||
/// which is specified with a list tag like those in TypeListTag.h. Since C++
|
|
||||||
/// does not allow you to actually change the template arguments, this method
|
|
||||||
/// returns a new dynamic array object. This method is particularly useful to
|
|
||||||
/// narrow down (or expand) the types when using an array of particular
|
|
||||||
/// constraints.
|
|
||||||
///
|
|
||||||
template <typename NewTypeList>
|
|
||||||
VTKM_CONT DynamicArrayHandleBase<NewTypeList, StorageList> ResetTypeList(
|
|
||||||
NewTypeList = NewTypeList()) const
|
|
||||||
{
|
|
||||||
VTKM_IS_LIST_TAG(NewTypeList);
|
|
||||||
return DynamicArrayHandleBase<NewTypeList, StorageList>(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Changes the array storage types to try casting to when resolving this
|
|
||||||
/// dynamic array, which is specified with a list tag like those in
|
|
||||||
/// StorageListTag.h. Since C++ does not allow you to actually change the
|
|
||||||
/// template arguments, this method returns a new dynamic array object. This
|
|
||||||
/// method is particularly useful to narrow down (or expand) the types when
|
|
||||||
/// using an array of particular constraints.
|
|
||||||
///
|
|
||||||
template <typename NewStorageList>
|
|
||||||
VTKM_CONT DynamicArrayHandleBase<TypeList, NewStorageList> ResetStorageList(
|
|
||||||
NewStorageList = NewStorageList()) const
|
|
||||||
{
|
|
||||||
VTKM_IS_LIST_TAG(NewStorageList);
|
|
||||||
return DynamicArrayHandleBase<TypeList, NewStorageList>(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Changes the value, and array storage types to try casting to when
|
|
||||||
/// resolving this dynamic array. Since C++ does not allow you to actually
|
|
||||||
/// change the template arguments, this method returns a new dynamic array
|
|
||||||
/// object. This method is particularly useful when you have both custom
|
|
||||||
/// types and traits.
|
|
||||||
///
|
|
||||||
template <typename NewTypeList, typename NewStorageList>
|
|
||||||
VTKM_CONT DynamicArrayHandleBase<NewTypeList, NewStorageList> ResetTypeAndStorageLists(
|
|
||||||
NewTypeList = NewTypeList(),
|
|
||||||
NewStorageList = NewStorageList()) const
|
|
||||||
{
|
|
||||||
VTKM_IS_LIST_TAG(NewTypeList);
|
|
||||||
VTKM_IS_LIST_TAG(NewStorageList);
|
|
||||||
return DynamicArrayHandleBase<NewTypeList, NewStorageList>(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Attempts to cast the held array to a specific value type and storage,
|
|
||||||
/// then call the given functor with the cast array. The types and storage
|
|
||||||
/// tried in the cast are those in the lists defined by the TypeList and
|
|
||||||
/// StorageList, respectively. The default \c DynamicArrayHandle sets these
|
|
||||||
/// two lists to VTKM_DEFAULT_TYPE_LIST_TAG and VTK_DEFAULT_STORAGE_LIST_TAG,
|
|
||||||
/// respectively.
|
|
||||||
///
|
|
||||||
template <typename Functor, typename... Args>
|
|
||||||
VTKM_CONT void CastAndCall(Functor&& f, Args&&...) const;
|
|
||||||
|
|
||||||
/// \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
|
|
||||||
/// returns a new dynamic array handle for it. This method is convenient when
|
|
||||||
/// creating output arrays that should be the same type as some input array.
|
|
||||||
///
|
|
||||||
VTKM_CONT
|
|
||||||
DynamicArrayHandleBase<TypeList, StorageList> NewInstance() const
|
|
||||||
{
|
|
||||||
DynamicArrayHandleBase<TypeList, StorageList> newArray;
|
|
||||||
newArray.ArrayContainer = this->ArrayContainer->NewInstance();
|
|
||||||
return newArray;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \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); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::shared_ptr<vtkm::cont::detail::PolymorphicArrayHandleContainerBase> ArrayContainer;
|
|
||||||
|
|
||||||
friend struct detail::DynamicArrayHandleCopyHelper;
|
|
||||||
};
|
|
||||||
|
|
||||||
using DynamicArrayHandle =
|
|
||||||
vtkm::cont::DynamicArrayHandleBase<VTKM_DEFAULT_TYPE_LIST_TAG, VTKM_DEFAULT_STORAGE_LIST_TAG>;
|
|
||||||
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
|
|
||||||
struct DynamicArrayHandleTry
|
|
||||||
{
|
|
||||||
template <typename T, typename U, typename Functor, typename... Args>
|
|
||||||
void operator()(brigand::list<T, U>,
|
|
||||||
Functor&& f,
|
|
||||||
bool& called,
|
|
||||||
const PolymorphicArrayHandleContainerBase* const container,
|
|
||||||
Args&&... args) const
|
|
||||||
{
|
|
||||||
if (!called)
|
|
||||||
{
|
|
||||||
using downcastType = const vtkm::cont::detail::PolymorphicArrayHandleContainer<T, U>* const;
|
|
||||||
downcastType downcastContainer = dynamic_cast<downcastType>(container);
|
|
||||||
if (downcastContainer)
|
|
||||||
{
|
|
||||||
VTKM_LOG_CAST_SUCC(*container, *downcastContainer);
|
|
||||||
f(downcastContainer->Array, std::forward<Args>(args)...);
|
|
||||||
called = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
VTKM_CONT_EXPORT void ThrowCastAndCallException(PolymorphicArrayHandleContainerBase*,
|
|
||||||
const std::type_info*,
|
|
||||||
const std::type_info*);
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
|
|
||||||
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>>;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <typename TypeList, typename StorageList>
|
|
||||||
template <typename Functor, typename... Args>
|
|
||||||
VTKM_CONT void DynamicArrayHandleBase<TypeList, StorageList>::CastAndCall(Functor&& f,
|
|
||||||
Args&&... args) const
|
|
||||||
{
|
|
||||||
//For optimizations we should compile once the cross product for the default types
|
|
||||||
//and make it extern
|
|
||||||
using crossProduct = ListTagDynamicTypes<TypeList, StorageList>;
|
|
||||||
|
|
||||||
bool called = false;
|
|
||||||
auto* ptr = this->ArrayContainer.get();
|
|
||||||
vtkm::ListForEach(detail::DynamicArrayHandleTry{},
|
|
||||||
crossProduct{},
|
|
||||||
std::forward<Functor>(f),
|
|
||||||
called,
|
|
||||||
ptr,
|
|
||||||
std::forward<Args>(args)...);
|
|
||||||
if (!called)
|
|
||||||
{
|
|
||||||
// throw an exception
|
|
||||||
VTKM_LOG_CAST_FAIL(*this, crossProduct);
|
|
||||||
detail::ThrowCastAndCallException(ptr, &typeid(TypeList), &typeid(StorageList));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace internal
|
|
||||||
{
|
|
||||||
|
|
||||||
template <typename TypeList, typename StorageList>
|
|
||||||
struct DynamicTransformTraits<vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>>
|
|
||||||
{
|
|
||||||
using DynamicTag = vtkm::cont::internal::DynamicTransformTagCastAndCall;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace vtkm::cont
|
|
||||||
|
|
||||||
|
|
||||||
//=============================================================================
|
|
||||||
// Specializations of serialization related classes
|
|
||||||
namespace diy
|
|
||||||
{
|
|
||||||
|
|
||||||
namespace internal
|
|
||||||
{
|
|
||||||
|
|
||||||
struct DynamicArrayHandleSerializeFunctor
|
|
||||||
{
|
|
||||||
template <typename ArrayHandleType>
|
|
||||||
void operator()(const ArrayHandleType& ah, BinaryBuffer& bb) const
|
|
||||||
{
|
|
||||||
diy::save(bb, vtkm::cont::TypeString<ArrayHandleType>::Get());
|
|
||||||
diy::save(bb, ah);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename TypeList, typename StorageList>
|
|
||||||
struct DynamicArrayHandleDeserializeFunctor
|
|
||||||
{
|
|
||||||
template <typename T, typename S>
|
|
||||||
void operator()(brigand::list<T, S>,
|
|
||||||
vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>& dh,
|
|
||||||
const std::string& typeString,
|
|
||||||
bool& success,
|
|
||||||
BinaryBuffer& bb) const
|
|
||||||
{
|
|
||||||
using ArrayHandleType = vtkm::cont::ArrayHandle<T, S>;
|
|
||||||
|
|
||||||
if (!success && (typeString == vtkm::cont::TypeString<ArrayHandleType>::Get()))
|
|
||||||
{
|
|
||||||
ArrayHandleType ah;
|
|
||||||
diy::load(bb, ah);
|
|
||||||
dh = vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>(ah);
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // internal
|
|
||||||
|
|
||||||
template <typename TypeList, typename StorageList>
|
|
||||||
struct Serialization<vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
using Type = vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>;
|
|
||||||
|
|
||||||
public:
|
|
||||||
static VTKM_CONT void save(BinaryBuffer& bb, const Type& obj)
|
|
||||||
{
|
|
||||||
obj.CastAndCall(internal::DynamicArrayHandleSerializeFunctor{}, bb);
|
|
||||||
}
|
|
||||||
|
|
||||||
static VTKM_CONT void load(BinaryBuffer& bb, Type& obj)
|
|
||||||
{
|
|
||||||
using CrossProduct = vtkm::cont::ListTagDynamicTypes<TypeList, StorageList>;
|
|
||||||
|
|
||||||
std::string typeString;
|
|
||||||
diy::load(bb, typeString);
|
|
||||||
|
|
||||||
bool success = false;
|
|
||||||
vtkm::ListForEach(internal::DynamicArrayHandleDeserializeFunctor<TypeList, StorageList>{},
|
|
||||||
CrossProduct{},
|
|
||||||
obj,
|
|
||||||
typeString,
|
|
||||||
success,
|
|
||||||
bb);
|
|
||||||
|
|
||||||
if (!success)
|
|
||||||
{
|
|
||||||
throw vtkm::cont::ErrorBadType(
|
|
||||||
"Error deserializing DynamicArrayHandle. Message TypeString: " + typeString);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // diy
|
|
||||||
|
|
||||||
#endif //vtk_m_cont_DynamicArrayHandle_h
|
|
@ -21,8 +21,8 @@
|
|||||||
#include "vtkm/cont/internal/DynamicTransform.h"
|
#include "vtkm/cont/internal/DynamicTransform.h"
|
||||||
|
|
||||||
#include "vtkm/cont/ArrayHandle.h"
|
#include "vtkm/cont/ArrayHandle.h"
|
||||||
#include "vtkm/cont/DynamicArrayHandle.h"
|
|
||||||
#include "vtkm/cont/DynamicCellSet.h"
|
#include "vtkm/cont/DynamicCellSet.h"
|
||||||
|
#include "vtkm/cont/VariantArrayHandle.h"
|
||||||
|
|
||||||
#include "vtkm/internal/FunctionInterface.h"
|
#include "vtkm/internal/FunctionInterface.h"
|
||||||
|
|
||||||
@ -31,7 +31,7 @@
|
|||||||
namespace vtkm
|
namespace vtkm
|
||||||
{
|
{
|
||||||
|
|
||||||
// DynamicArrayHandle requires its value type to have a defined VecTraits
|
// VariantArrayHandle requires its value type to have a defined VecTraits
|
||||||
// class. One of the tests is to use an "unusual" array of std::string
|
// class. One of the tests is to use an "unusual" array of std::string
|
||||||
// (which is pretty pointless but might tease out some assumptions).
|
// (which is pretty pointless but might tease out some assumptions).
|
||||||
// Make an implementation here. Because I am lazy, this is only a partial
|
// Make an implementation here. Because I am lazy, this is only a partial
|
||||||
@ -71,10 +71,15 @@ struct ScalarFunctor
|
|||||||
struct ArrayHandleScalarFunctor
|
struct ArrayHandleScalarFunctor
|
||||||
{
|
{
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void operator()(const vtkm::cont::ArrayHandle<T>&) const
|
void operator()(const vtkm::cont::ArrayHandleVirtual<T>&) const
|
||||||
{
|
{
|
||||||
VTKM_TEST_FAIL("Called wrong form of functor operator.");
|
VTKM_TEST_FAIL("Called wrong form of functor operator.");
|
||||||
}
|
}
|
||||||
|
void operator()(const vtkm::cont::ArrayHandleVirtual<vtkm::FloatDefault>&) const
|
||||||
|
{
|
||||||
|
std::cout << " In ArrayHandleVirtual<Scalar> functor." << std::endl;
|
||||||
|
g_FunctionCalls++;
|
||||||
|
}
|
||||||
void operator()(const vtkm::cont::ArrayHandle<vtkm::FloatDefault>&) const
|
void operator()(const vtkm::cont::ArrayHandle<vtkm::FloatDefault>&) const
|
||||||
{
|
{
|
||||||
std::cout << " In ArrayHandle<Scalar> functor." << std::endl;
|
std::cout << " In ArrayHandle<Scalar> functor." << std::endl;
|
||||||
@ -84,9 +89,9 @@ struct ArrayHandleScalarFunctor
|
|||||||
|
|
||||||
struct ArrayHandleStringFunctor
|
struct ArrayHandleStringFunctor
|
||||||
{
|
{
|
||||||
void operator()(const vtkm::cont::ArrayHandle<std::string>&) const
|
void operator()(const vtkm::cont::ArrayHandleVirtual<std::string>&) const
|
||||||
{
|
{
|
||||||
std::cout << " In ArrayHandle<string> functor." << std::endl;
|
std::cout << " In ArrayHandleVirtual<string> functor." << std::endl;
|
||||||
g_FunctionCalls++;
|
g_FunctionCalls++;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -121,6 +126,16 @@ struct FunctionInterfaceFunctor
|
|||||||
std::cout << " In FunctionInterface<...> functor." << std::endl;
|
std::cout << " In FunctionInterface<...> functor." << std::endl;
|
||||||
g_FunctionCalls++;
|
g_FunctionCalls++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void operator()(
|
||||||
|
const vtkm::internal::FunctionInterface<void(vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
|
||||||
|
vtkm::cont::ArrayHandleVirtual<vtkm::FloatDefault>,
|
||||||
|
vtkm::cont::ArrayHandleVirtual<std::string>,
|
||||||
|
vtkm::cont::CellSetStructured<3>)>&) const
|
||||||
|
{
|
||||||
|
std::cout << " In FunctionInterface<...> functor." << std::endl;
|
||||||
|
g_FunctionCalls++;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void TestBasicTransform()
|
void TestBasicTransform()
|
||||||
@ -138,13 +153,13 @@ void TestBasicTransform()
|
|||||||
TRY_TRANSFORM(transform(concreteArray, ArrayHandleScalarFunctor(), indexTag));
|
TRY_TRANSFORM(transform(concreteArray, ArrayHandleScalarFunctor(), indexTag));
|
||||||
|
|
||||||
std::cout << " Trying scalar dynamic array." << std::endl;
|
std::cout << " Trying scalar dynamic array." << std::endl;
|
||||||
vtkm::cont::DynamicArrayHandle dynamicArray = concreteArray;
|
vtkm::cont::VariantArrayHandle dynamicArray = concreteArray;
|
||||||
TRY_TRANSFORM(transform(dynamicArray, ArrayHandleScalarFunctor(), indexTag));
|
TRY_TRANSFORM(transform(dynamicArray, ArrayHandleScalarFunctor(), indexTag));
|
||||||
|
|
||||||
std::cout << " Trying with unusual (string) dynamic array." << std::endl;
|
std::cout << " Trying with unusual (string) dynamic array." << std::endl;
|
||||||
dynamicArray = vtkm::cont::ArrayHandle<std::string>();
|
dynamicArray = vtkm::cont::ArrayHandle<std::string>();
|
||||||
TRY_TRANSFORM(transform(
|
TRY_TRANSFORM(
|
||||||
dynamicArray.ResetTypeList(TypeListTagString()), ArrayHandleStringFunctor(), indexTag));
|
transform(dynamicArray.ResetTypes(TypeListTagString()), ArrayHandleStringFunctor(), indexTag));
|
||||||
|
|
||||||
std::cout << " Trying with structured cell set." << std::endl;
|
std::cout << " Trying with structured cell set." << std::endl;
|
||||||
vtkm::cont::CellSetStructured<3> concreteCellSet;
|
vtkm::cont::CellSetStructured<3> concreteCellSet;
|
||||||
@ -171,8 +186,8 @@ void TestFunctionTransform()
|
|||||||
TRY_TRANSFORM(
|
TRY_TRANSFORM(
|
||||||
vtkm::internal::make_FunctionInterface<void>(
|
vtkm::internal::make_FunctionInterface<void>(
|
||||||
scalarArray,
|
scalarArray,
|
||||||
vtkm::cont::DynamicArrayHandle(scalarArray),
|
vtkm::cont::VariantArrayHandle(scalarArray),
|
||||||
vtkm::cont::DynamicArrayHandle(stringArray).ResetTypeList(TypeListTagString()),
|
vtkm::cont::VariantArrayHandle(stringArray).ResetTypes(TypeListTagString()),
|
||||||
vtkm::cont::DynamicCellSet(structuredCellSet))
|
vtkm::cont::DynamicCellSet(structuredCellSet))
|
||||||
.DynamicTransformCont(vtkm::cont::internal::DynamicTransform(), FunctionInterfaceFunctor()));
|
.DynamicTransformCont(vtkm::cont::internal::DynamicTransform(), FunctionInterfaceFunctor()));
|
||||||
}
|
}
|
||||||
|
@ -236,7 +236,7 @@ struct TestArrayHandleGroupVecVariable
|
|||||||
vtkm::cont::make_ArrayHandle(comps));
|
vtkm::cont::make_ArrayHandle(comps));
|
||||||
RunTest(array);
|
RunTest(array);
|
||||||
|
|
||||||
// cannot make a DynamicArrayHandle containing ArrayHandleGroupVecVariable
|
// cannot make a VariantArrayHandle containing ArrayHandleGroupVecVariable
|
||||||
// because of the variable number of components of its values.
|
// because of the variable number of components of its values.
|
||||||
// RunTest(MakeTestVariantArrayHandle(array));
|
// RunTest(MakeTestVariantArrayHandle(array));
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
#include <vtkm/cont/ArrayHandleIndex.h>
|
#include <vtkm/cont/ArrayHandleIndex.h>
|
||||||
#include <vtkm/cont/CellSetSingleType.h>
|
#include <vtkm/cont/CellSetSingleType.h>
|
||||||
#include <vtkm/cont/CellSetStructured.h>
|
#include <vtkm/cont/CellSetStructured.h>
|
||||||
#include <vtkm/cont/DynamicArrayHandle.h>
|
|
||||||
#include <vtkm/cont/DynamicCellSet.h>
|
#include <vtkm/cont/DynamicCellSet.h>
|
||||||
#include <vtkm/cont/ErrorFilterExecution.h>
|
#include <vtkm/cont/ErrorFilterExecution.h>
|
||||||
|
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
#include <vtkm/cont/ArrayHandleIndex.h>
|
#include <vtkm/cont/ArrayHandleIndex.h>
|
||||||
#include <vtkm/cont/CellSetSingleType.h>
|
#include <vtkm/cont/CellSetSingleType.h>
|
||||||
#include <vtkm/cont/CellSetStructured.h>
|
#include <vtkm/cont/CellSetStructured.h>
|
||||||
#include <vtkm/cont/DynamicArrayHandle.h>
|
|
||||||
#include <vtkm/cont/DynamicCellSet.h>
|
#include <vtkm/cont/DynamicCellSet.h>
|
||||||
#include <vtkm/cont/ErrorFilterExecution.h>
|
#include <vtkm/cont/ErrorFilterExecution.h>
|
||||||
|
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
#include <vtkm/cont/ArrayHandleIndex.h>
|
#include <vtkm/cont/ArrayHandleIndex.h>
|
||||||
#include <vtkm/cont/CellSetSingleType.h>
|
#include <vtkm/cont/CellSetSingleType.h>
|
||||||
#include <vtkm/cont/CellSetStructured.h>
|
#include <vtkm/cont/CellSetStructured.h>
|
||||||
#include <vtkm/cont/DynamicArrayHandle.h>
|
|
||||||
#include <vtkm/cont/DynamicCellSet.h>
|
#include <vtkm/cont/DynamicCellSet.h>
|
||||||
#include <vtkm/cont/ErrorFilterExecution.h>
|
#include <vtkm/cont/ErrorFilterExecution.h>
|
||||||
|
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
#include <vtkm/cont/ArrayHandleIndex.h>
|
#include <vtkm/cont/ArrayHandleIndex.h>
|
||||||
#include <vtkm/cont/CellSetSingleType.h>
|
#include <vtkm/cont/CellSetSingleType.h>
|
||||||
#include <vtkm/cont/CellSetStructured.h>
|
#include <vtkm/cont/CellSetStructured.h>
|
||||||
#include <vtkm/cont/DynamicArrayHandle.h>
|
|
||||||
#include <vtkm/cont/DynamicCellSet.h>
|
#include <vtkm/cont/DynamicCellSet.h>
|
||||||
#include <vtkm/cont/ErrorFilterExecution.h>
|
#include <vtkm/cont/ErrorFilterExecution.h>
|
||||||
|
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
#include <vtkm/cont/ArrayHandleIndex.h>
|
#include <vtkm/cont/ArrayHandleIndex.h>
|
||||||
#include <vtkm/cont/CellSetSingleType.h>
|
#include <vtkm/cont/CellSetSingleType.h>
|
||||||
#include <vtkm/cont/CellSetStructured.h>
|
#include <vtkm/cont/CellSetStructured.h>
|
||||||
#include <vtkm/cont/DynamicArrayHandle.h>
|
|
||||||
#include <vtkm/cont/DynamicCellSet.h>
|
#include <vtkm/cont/DynamicCellSet.h>
|
||||||
#include <vtkm/cont/ErrorFilterExecution.h>
|
#include <vtkm/cont/ErrorFilterExecution.h>
|
||||||
|
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
#include <vtkm/cont/ArrayHandleIndex.h>
|
#include <vtkm/cont/ArrayHandleIndex.h>
|
||||||
#include <vtkm/cont/CellSetSingleType.h>
|
#include <vtkm/cont/CellSetSingleType.h>
|
||||||
#include <vtkm/cont/CellSetStructured.h>
|
#include <vtkm/cont/CellSetStructured.h>
|
||||||
#include <vtkm/cont/DynamicArrayHandle.h>
|
|
||||||
#include <vtkm/cont/DynamicCellSet.h>
|
#include <vtkm/cont/DynamicCellSet.h>
|
||||||
#include <vtkm/cont/ErrorFilterExecution.h>
|
#include <vtkm/cont/ErrorFilterExecution.h>
|
||||||
|
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
#include <vtkm/cont/DataSet.h>
|
#include <vtkm/cont/DataSet.h>
|
||||||
#include <vtkm/cont/DataSetBuilderUniform.h>
|
#include <vtkm/cont/DataSetBuilderUniform.h>
|
||||||
#include <vtkm/cont/DataSetFieldAdd.h>
|
#include <vtkm/cont/DataSetFieldAdd.h>
|
||||||
#include <vtkm/cont/DynamicArrayHandle.h>
|
|
||||||
#include <vtkm/cont/testing/Testing.h>
|
#include <vtkm/cont/testing/Testing.h>
|
||||||
#include <vtkm/filter/CleanGrid.h>
|
#include <vtkm/filter/CleanGrid.h>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user