Created DynamicCellSet

The DynamicCellSet will be used in place of the pointer to a CellSet
in a DataSet. This will prevent us from having to cast it all the time
and also remove reliance on boost smart_ptr.
This commit is contained in:
Kenneth Moreland 2015-07-27 10:13:27 -06:00
parent 53d669772f
commit 6b68666d0c
12 changed files with 565 additions and 22 deletions

@ -75,7 +75,7 @@ struct ArrayHandleImplicitTraits
{
typedef vtkm::cont::StorageTagImplicit<
vtkm::cont::detail::ArrayPortalImplicit<ValueType,
FunctorType> > Tag;
FunctorType> > StorageTag;
};
} // namespace detail
@ -94,16 +94,16 @@ class ArrayHandleImplicit
: public vtkm::cont::ArrayHandle <
ValueType,
typename detail::ArrayHandleImplicitTraits<ValueType,
FunctorType>::Tag >
FunctorType>::StorageTag >
{
private:
typedef typename detail::ArrayHandleImplicitTraits<ValueType,
FunctorType> ArrayTraits;
typedef typename ArrayTraits::Tag Tag;
public:
typedef vtkm::cont::ArrayHandle<ValueType,Tag> Superclass;
typedef typename ArrayTraits::StorageTag StorageTag;
typedef vtkm::cont::ArrayHandle<ValueType,StorageTag> Superclass;
ArrayHandleImplicit()
: Superclass(typename Superclass::PortalConstControl(FunctorType(),0)) { }

@ -35,6 +35,7 @@ set(headers
Assert.h
CellSet.h
CellSetExplicit.h
CellSetListTag.h
CellSetStructured.h
CoordinateSystem.h
DataSet.h
@ -42,6 +43,7 @@ set(headers
DeviceAdapterAlgorithm.h
DeviceAdapterSerial.h
DynamicArrayHandle.h
DynamicCellSet.h
DynamicPointCoordinates.h
ExplicitConnectivity.h
Error.h

@ -27,22 +27,29 @@ namespace vtkm {
namespace cont {
template<typename ShapeStorageTag = VTKM_DEFAULT_STORAGE_TAG,
typename IndiceStorageTag = VTKM_DEFAULT_STORAGE_TAG,
typename IndexStorageTag = VTKM_DEFAULT_STORAGE_TAG,
typename ConnectivityStorageTag = VTKM_DEFAULT_STORAGE_TAG >
class CellSetExplicit : public CellSet
{
public:
typedef ExplicitConnectivity<ShapeStorageTag,
IndiceStorageTag,
IndexStorageTag,
ConnectivityStorageTag
> ExplicitConnectivityType;
VTKM_CONT_EXPORT
CellSetExplicit(const std::string &name, vtkm::IdComponent dimensionality)
CellSetExplicit(const std::string &name = "",
vtkm::IdComponent dimensionality = 3)
: CellSet(name, dimensionality)
{
}
VTKM_CONT_EXPORT
CellSetExplicit(int dimensionality)
: CellSet("", dimensionality)
{
}
virtual vtkm::Id GetNumCells() const
{
return this->NodesOfCellsConnectivity.GetNumberOfElements();

@ -0,0 +1,66 @@
//============================================================================
// 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 Sandia Corporation.
// Copyright 2015 UT-Battelle, LLC.
// Copyright 2015 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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_CellSetListTag_h
#define vtk_m_cont_CellSetListTag_h
#ifndef VTKM_DEFAULT_CELL_SET_LIST_TAG
#define VTKM_DEFAULT_CELL_SET_LIST_TAG ::vtkm::cont::CellSetListTagCommon
#endif
#include <vtkm/ListTag.h>
#include <vtkm/cont/CellSetExplicit.h>
#include <vtkm/cont/CellSetStructured.h>
namespace vtkm {
namespace cont {
struct CellSetListTagStructured1D
: vtkm::ListTagBase<vtkm::cont::CellSetStructured<1> > { };
struct CellSetListTagStructured2D
: vtkm::ListTagBase<vtkm::cont::CellSetStructured<2> > { };
struct CellSetListTagStructured3D
: vtkm::ListTagBase<vtkm::cont::CellSetStructured<3> > { };
template<typename ShapeStorageTag = VTKM_DEFAULT_STORAGE_TAG,
typename IndexStorageTag = VTKM_DEFAULT_STORAGE_TAG,
typename ConnectivityStorageTag = VTKM_DEFAULT_STORAGE_TAG >
struct CellSetListTagExplicit
: vtkm::ListTagBase<
vtkm::cont::CellSetExplicit<
ShapeStorageTag,
IndexStorageTag,
ConnectivityStorageTag> > { };
struct CellSetListTagExplicitDefault
: CellSetListTagExplicit<> { };
struct CellSetListTagCommon
: vtkm::ListTagBase<
vtkm::cont::CellSetStructured<2>,
vtkm::cont::CellSetStructured<3>,
vtkm::cont::CellSetExplicit<> > { };
}
} // namespace vtkm::cont
#endif //vtk_m_cont_CellSetListTag_h

@ -36,7 +36,7 @@ public:
static const int Dimension=DIMENSION;
VTKM_CONT_EXPORT
CellSetStructured(const std::string &name)
CellSetStructured(const std::string &name = "")
: CellSet(name,Dimension)
{
}

@ -141,7 +141,7 @@ public:
template<typename Type, typename Storage>
VTKM_CONT_EXPORT
DynamicArrayHandle(const vtkm::cont::ArrayHandle<Type,Storage> &array)
: ArrayStorage(new vtkm::cont::detail::PolymorphicArrayHandleContainer<
: ArrayContainer(new vtkm::cont::detail::PolymorphicArrayHandleContainer<
Type,Storage>(array))
{ }
@ -149,7 +149,7 @@ public:
VTKM_CONT_EXPORT
DynamicArrayHandle(
const internal::DynamicArrayHandleCast<TypeList,StorageList> &dynamicArray)
: ArrayStorage(dynamicArray.ArrayStorage) { }
: ArrayContainer(dynamicArray.ArrayContainer) { }
/// Returns true if this array is of the provided type and uses the provided
/// storage.
@ -157,7 +157,7 @@ public:
template<typename Type, typename Storage>
VTKM_CONT_EXPORT
bool IsTypeAndStorage(Type = Type(), Storage = Storage()) const {
return (this->TryCastStorage<Type,Storage>() != NULL);
return (this->TryCastContainer<Type,Storage>() != NULL);
}
/// Returns this array cast to an ArrayHandle object of the given type and
@ -169,7 +169,7 @@ public:
vtkm::cont::ArrayHandle<Type, Storage>
CastToArrayHandle(Type = Type(), Storage = Storage()) const {
vtkm::cont::detail::PolymorphicArrayHandleContainer<Type,Storage> *container
= this->TryCastStorage<Type,Storage>();
= this->TryCastContainer<Type,Storage>();
if (container == NULL)
{
throw vtkm::cont::ErrorControlBadValue("Bad cast of dynamic array.");
@ -241,7 +241,7 @@ public:
DynamicArrayHandle NewInstance() const
{
DynamicArrayHandle newArray;
newArray.ArrayStorage = this->ArrayStorage->NewInstance();
newArray.ArrayContainer = this->ArrayContainer->NewInstance();
return newArray;
}
@ -254,7 +254,7 @@ public:
VTKM_CONT_EXPORT
vtkm::IdComponent GetNumberOfComponents() const
{
return this->ArrayStorage->GetNumberOfComponents();
return this->ArrayContainer->GetNumberOfComponents();
}
/// \brief Get the number of values in the array.
@ -262,21 +262,21 @@ public:
VTKM_CONT_EXPORT
vtkm::Id GetNumberOfValues() const
{
return this->ArrayStorage->GetNumberOfValues();
return this->ArrayContainer->GetNumberOfValues();
}
private:
boost::shared_ptr<vtkm::cont::detail::PolymorphicArrayHandleContainerBase>
ArrayStorage;
ArrayContainer;
template<typename Type, typename Storage>
VTKM_CONT_EXPORT
vtkm::cont::detail::PolymorphicArrayHandleContainer<Type,Storage> *
TryCastStorage() const {
TryCastContainer() const {
return
dynamic_cast<
vtkm::cont::detail::PolymorphicArrayHandleContainer<Type,Storage> *>(
this->ArrayStorage.get());
this->ArrayContainer.get());
}
};

294
vtkm/cont/DynamicCellSet.h Normal file

@ -0,0 +1,294 @@
//============================================================================
// 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 Sandia Corporation.
// Copyright 2015 UT-Battelle, LLC.
// Copyright 2015 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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_DynamicCellSet_h
#define vtk_m_cont_DynamicCellSet_h
#include <vtkm/cont/CellSet.h>
#include <vtkm/cont/CellSetListTag.h>
#include <vtkm/cont/ErrorControlBadValue.h>
#include <vtkm/cont/internal/DynamicTransform.h>
#include <vtkm/cont/internal/SimplePolymorphicContainer.h>
#include <boost/smart_ptr/shared_ptr.hpp>
namespace vtkm {
namespace cont {
// Forward declaration.
template<typename CellSetList>
class DynamicCellSetBase;
namespace detail {
// 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 DynamicCellSet from another DynamicCellSet of any other type.
// Since you cannot partially specialize friendship, use this accessor class to
// get at the internals for the copy constructor.
struct DynamicCellSetCopyHelper {
template<typename CellSetList>
VTKM_CONT_EXPORT
static
boost::shared_ptr<vtkm::cont::internal::SimplePolymorphicContainerBase>
GetCellSetContainer(const vtkm::cont::DynamicCellSetBase<CellSetList> &src)
{
return src.CellSetContainer;
}
};
} // namespace detail
/// \brief Holds a cell set without having to specify concrete type.
///
/// \c DynamicCellSet holds a \c CellSet object using runtime polymorphism to
/// manage different subclass types and template parameters of the subclasses
/// 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 DynamicCellSet contains a method named \c CastAndCall that
/// will determine the correct type from some known list of cell set types.
/// This mechanism is used internally by VTK-m's worklet invocation mechanism
/// to determine the type when running algorithms.
///
/// By default, \c DynamicCellSet will assume that the value type in the array
/// matches one of the types specified by \c VTKM_DEFAULT_CELL_SET_LIST_TAG.
/// This list can be changed by using the \c ResetTypeList method. 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 Dynamic* objects.
///
/// The actual implementation of \c DynamicCellSet is in a templated class
/// names \c DynamicCellSetBase, which is templated on the list of cell set
/// types. \c DynamicCellSet is really just a typedef of \c DynamicCellSetBase
/// with the default cell set list.
///
template<typename CellSetList>
class DynamicCellSetBase
{
VTKM_IS_LIST_TAG(CellSetList);
public:
VTKM_CONT_EXPORT
DynamicCellSetBase() { }
template<typename CellSetType>
VTKM_CONT_EXPORT
DynamicCellSetBase(const CellSetType &cellSet)
: CellSetContainer(
new vtkm::cont::internal::SimplePolymorphicContainer<CellSetType>(
cellSet))
{
// TODO: Would be good to check that CellSetType is really a subclass of
// CellSet.
}
VTKM_CONT_EXPORT
DynamicCellSetBase(const DynamicCellSetBase<CellSetList> &src)
: CellSetContainer(src.CellSetContainer) { }
friend class DynamicCellSetBase;
template<typename OtherCellSetList>
VTKM_CONT_EXPORT
explicit
DynamicCellSetBase(const DynamicCellSetBase<OtherCellSetList> &src)
: CellSetContainer(
detail::DynamicCellSetCopyHelper::GetCellSetContainer(src))
{ }
/// Returns true if this cell set is of the provided type.
///
template<typename CellSetType>
VTKM_CONT_EXPORT
bool IsType(CellSetType = CellSetType()) const {
return (this->TryCast<CellSetType>() != NULL);
}
/// Returns the contained cell set as the abstract \c CellSet type.
///
VTKM_CONT_EXPORT
const vtkm::cont::CellSet &GetCellSet() const {
return *reinterpret_cast<const vtkm::cont::CellSet *>(
this->CellSetContainer->GetVoidPointer());
}
/// Returns this cell set cast to a concrete \c CellSet object of the given
/// type. Throws ErrorControlBadValue if the cast does not work. Use
/// IsTypeAndStorage to check if the cast can happen.
///
template<typename CellSetType>
VTKM_CONT_EXPORT
const CellSetType &CastTo(CellSetType = CellSetType()) const {
const vtkm::cont::internal::SimplePolymorphicContainer<CellSetType> *
container = this->TryCast<CellSetType>();
if (container == NULL)
{
throw vtkm::cont::ErrorControlBadValue("Bad cast of dynamic cell set.");
}
return container->Item;
}
template<typename CellSetType>
VTKM_CONT_EXPORT
CellSetType &CastTo(CellSetType = CellSetType()) {
vtkm::cont::internal::SimplePolymorphicContainer<CellSetType> *
container = this->TryCast<CellSetType>();
if (container == NULL)
{
throw vtkm::cont::ErrorControlBadValue("Bad cast of dynamic cell set.");
}
return container->Item;
}
/// Changes the cell set types to try casting to when resolving this dynamic
/// cell set, which is specified with a list tag like those in
/// CellSetListTag.h. Since C++ does not allow you to actually change the
/// template arguments, this method returns a new dynamic cell setobject.
/// This method is particularly useful to narrow down (or expand) the types
/// when using a cell set of particular constraints.
///
template<typename NewCellSetList>
VTKM_CONT_EXPORT
DynamicCellSetBase<NewCellSetList>
ResetCellSetList(NewCellSetList = NewCellSetList()) const {
VTKM_IS_LIST_TAG(NewCellSetList);
return DynamicCellSetBase<NewCellSetList>(*this);
}
/// Attempts to cast the held cell set to a specific concrete type, then call
/// the given functor with the cast cell set. The cell sets tried in the cast
/// are those in the \c CellSetList template argument of the \c
/// DynamicCellSetBase class (or \c VTKM_DEFAULT_CELL_SET_LIST_TAG for \c
/// DynamicCellSet). You can use \c ResetCellSetList to get different
/// behavior from \c CastAndCall.
///
template<typename Functor>
VTKM_CONT_EXPORT
void CastAndCall(const Functor &f) const;
/// \brief Create a new cell set of the same type as this cell set.
///
/// This method creates a new cell setthat is the same type as this one and
/// returns a new dynamic cell set for it. This method is convenient when
/// creating output data sets that should be the same type as some input cell
/// set.
///
VTKM_CONT_EXPORT
DynamicCellSetBase<CellSetList> NewInstance() const
{
DynamicCellSetBase<CellSetList> newCellSet;
newCellSet.CellSetContainer = this->CellSetContainer->NewInstance();
return newCellSet;
}
private:
boost::shared_ptr<vtkm::cont::internal::SimplePolymorphicContainerBase>
CellSetContainer;
friend struct detail::DynamicCellSetCopyHelper;
template<typename CellSetType>
VTKM_CONT_EXPORT
vtkm::cont::internal::SimplePolymorphicContainer<CellSetType> *
TryCast() const {
return
dynamic_cast<
vtkm::cont::internal::SimplePolymorphicContainer<CellSetType> *>(
this->CellSetContainer.get());
}
};
namespace detail {
template<typename Functor>
struct DynamicCellSetTryCellSet
{
const vtkm::cont::CellSet *AbstractCellSet;
const Functor &Function;
bool FoundCast;
VTKM_CONT_EXPORT
DynamicCellSetTryCellSet(const vtkm::cont::CellSet &cellSet,
const Functor &f)
: AbstractCellSet(&cellSet), Function(f), FoundCast(false) { }
template<typename CellSetType>
VTKM_CONT_EXPORT
void operator()(CellSetType) {
if (!this->FoundCast)
{
const CellSetType *cellSet =
dynamic_cast<const CellSetType *>(this->AbstractCellSet);
if (cellSet != NULL)
{
this->Function(*cellSet);
this->FoundCast = true;
}
}
}
};
template<typename Functor, typename CellSetTypeList>
VTKM_CONT_EXPORT
void CastAndCallCellSet(
const Functor &f,
const vtkm::cont::DynamicCellSetBase<CellSetTypeList> &cellSet)
{
typedef detail::DynamicCellSetTryCellSet<Functor> TryCellSetType;
TryCellSetType tryCellSet = TryCellSetType(cellSet.GetCellSet(), f);
vtkm::ListForEach(tryCellSet, CellSetTypeList());
if (!tryCellSet.FoundCast)
{
throw vtkm::cont::ErrorControlBadValue(
"Could not find appropriate cast for cell set.");
}
}
} // namespace detail
template<typename CellSetList>
template<typename Functor>
VTKM_CONT_EXPORT
void DynamicCellSetBase<CellSetList>::CastAndCall(const Functor &f) const
{
detail::CastAndCallCellSet(f, *this);
}
typedef DynamicCellSetBase<vtkm::cont::CellSetListTagCommon> DynamicCellSet;
namespace internal {
template<typename CellSetList>
struct DynamicTransformTraits<
vtkm::cont::DynamicCellSetBase<CellSetList> >
{
typedef vtkm::cont::internal::DynamicTransformTagCastAndCall DynamicTag;
};
} // namespace internal
}
} // namespace vtkm::cont
#endif //vtk_m_cont_DynamicCellSet_h

@ -17,8 +17,8 @@
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_StorageListTag_h
#define vtk_m_StorageListTag_h
#ifndef vtk_m_cont_StorageListTag_h
#define vtk_m_cont_StorageListTag_h
#ifndef VTKM_DEFAULT_STORAGE_LIST_TAG
#define VTKM_DEFAULT_STORAGE_LIST_TAG ::vtkm::cont::StorageListTagBasic
@ -38,4 +38,4 @@ struct StorageListTagBasic
}
} // namespace vtkm::cont
#endif //vtk_m_StorageListTag_h
#endif //vtk_m_cont_StorageListTag_h

@ -36,6 +36,8 @@ struct SimplePolymorphicContainerBase {
virtual boost::shared_ptr<SimplePolymorphicContainerBase>
NewInstance() const = 0;
virtual const void *GetVoidPointer() const = 0;
};
/// \brief Simple object container that can use C++ run-time type information.
@ -63,6 +65,11 @@ struct SimplePolymorphicContainer : public SimplePolymorphicContainerBase
return boost::shared_ptr<SimplePolymorphicContainerBase>(
new SimplePolymorphicContainer<T>());
}
virtual const void *GetVoidPointer() const
{
return &this->Item;
}
};
}

@ -22,6 +22,7 @@
#include "vtkm/cont/ArrayHandle.h"
#include "vtkm/cont/DynamicArrayHandle.h"
#include "vtkm/cont/DynamicCellSet.h"
#include "vtkm/cont/DynamicPointCoordinates.h"
#include "vtkm/internal/FunctionInterface.h"
@ -79,6 +80,17 @@ struct ArrayHandleStringFunctor {
}
};
struct CellSetStructuredFunctor {
template<typename T>
void operator()(const T &) const {
VTKM_TEST_FAIL("Called wrong form of functor operator.");
}
void operator()(const vtkm::cont::CellSetStructured<3> &) const {
std::cout << " In CellSetStructured<3> functor." << std::endl;
g_FunctionCalls++;
}
};
struct FunctionInterfaceFunctor {
template<typename Signature>
void operator()(const vtkm::internal::FunctionInterface<Signature> &) const {
@ -89,6 +101,7 @@ struct FunctionInterfaceFunctor {
void(vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<std::string>,
vtkm::cont::CellSetStructured<3>,
vtkm::cont::ArrayHandleUniformPointCoordinates)> &) const {
std::cout << " In FunctionInterface<...> functor." << std::endl;
g_FunctionCalls++;
@ -118,6 +131,18 @@ void TestBasicTransform()
TRY_TRANSFORM(transform(dynamicArray.ResetTypeList(TypeListTagString()),
ArrayHandleStringFunctor(),
indexTag));
std::cout << " Trying with structured cell set." << std::endl;
vtkm::cont::CellSetStructured<3> concreteCellSet;
TRY_TRANSFORM(transform(concreteCellSet,
CellSetStructuredFunctor(),
indexTag));
std::cout << " Trying with dynamic cell set." << std::endl;
vtkm::cont::DynamicCellSet dynamicCellSet = concreteCellSet;
TRY_TRANSFORM(transform(dynamicCellSet,
CellSetStructuredFunctor(),
indexTag));
}
void TestFunctionTransform()
@ -126,6 +151,7 @@ void TestFunctionTransform()
vtkm::cont::ArrayHandle<vtkm::FloatDefault> scalarArray;
vtkm::cont::ArrayHandle<std::string> stringArray;
vtkm::cont::CellSetStructured<3> structuredCellSet;
vtkm::cont::ArrayHandleUniformPointCoordinates pointCoordinatesArray;
std::cout << " Trying basic functor call w/o transform (make sure it works)."
@ -135,6 +161,7 @@ void TestFunctionTransform()
scalarArray,
scalarArray,
stringArray,
structuredCellSet,
pointCoordinatesArray)));
std::cout << " Trying dynamic cast" << std::endl;
@ -143,6 +170,7 @@ void TestFunctionTransform()
scalarArray,
vtkm::cont::DynamicArrayHandle(scalarArray),
vtkm::cont::DynamicArrayHandle(stringArray).ResetTypeList(TypeListTagString()),
vtkm::cont::DynamicCellSet(structuredCellSet),
vtkm::cont::DynamicPointCoordinates(vtkm::cont::PointCoordinatesUniform()))
.DynamicTransformCont(vtkm::cont::internal::DynamicTransform(),
FunctionInterfaceFunctor()));

@ -47,6 +47,7 @@ set(unit_tests
UnitTestDeviceAdapterAlgorithmGeneral.cxx
UnitTestDeviceAdapterSerial.cxx
UnitTestDynamicArrayHandle.cxx
UnitTestDynamicCellSet.cxx
UnitTestDynamicPointCoordinates.cxx
UnitTestPointCoordinates.cxx
UnitTestStorageBasic.cxx

@ -0,0 +1,138 @@
//============================================================================
// 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 Sandia Corporation.
// Copyright 2015 UT-Battelle, LLC.
// Copyright 2015 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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 <vtkm/cont/DynamicCellSet.h>
#include <vtkm/cont/ArrayHandleConstant.h>
#include <vtkm/cont/testing/Testing.h>
namespace {
struct NonDefaultCellSetList
: vtkm::ListTagBase<
vtkm::cont::CellSetStructured<1>,
vtkm::cont::CellSetExplicit<vtkm::cont::ArrayHandleConstant<vtkm::Id>::StorageTag > >
{ };
bool CheckCalled;
template<typename ExpectedCellType>
struct CheckFunctor
{
void operator()(const ExpectedCellType &) const
{
CheckCalled = true;
}
template<typename UnexpectedType>
void operator()(const UnexpectedType &) const
{
VTKM_TEST_FAIL("CastAndCall functor called with wrong type.");
}
};
template<typename CellSetType, typename CellSetList>
void CheckDynamicCellSet(
const CellSetType &cellSet,
vtkm::cont::DynamicCellSetBase<CellSetList> dynamicCellSet)
{
VTKM_TEST_ASSERT(dynamicCellSet.IsType(cellSet),
"DynamicCellSet reports wrong type.");
VTKM_TEST_ASSERT(!dynamicCellSet.IsType(vtkm::Id()),
"DynamicCellSet reports wrong type.");
dynamicCellSet.CastTo(cellSet);
CheckCalled = false;
dynamicCellSet.CastAndCall(CheckFunctor<CellSetType>());
VTKM_TEST_ASSERT(CheckCalled,
"The functor was never called (and apparently a bad value exception not thrown).");
}
template<typename CellSetType, typename CellSetList>
void TryNewInstance(
CellSetType, vtkm::cont::DynamicCellSetBase<CellSetList> &originalCellSet)
{
vtkm::cont::DynamicCellSetBase<CellSetList> newCellSet =
originalCellSet.NewInstance();
VTKM_TEST_ASSERT(newCellSet.IsType(CellSetType()),
"New cell set wrong type.");
VTKM_TEST_ASSERT(&originalCellSet.CastTo(CellSetType())
!= &newCellSet.CastTo(CellSetType()),
"NewInstance did not make a copy.");
}
template<typename CellSetType, typename CellSetList>
void TryCellSet(CellSetType cellSet,
vtkm::cont::DynamicCellSetBase<CellSetList> &dynamicCellSet)
{
CheckDynamicCellSet(cellSet, dynamicCellSet);
CheckDynamicCellSet(
cellSet,
dynamicCellSet.ResetCellSetList(vtkm::ListTagBase<CellSetType>()));
TryNewInstance(cellSet, dynamicCellSet);
}
template<typename CellSetType>
void TryDefaultCellSet(CellSetType cellSet)
{
vtkm::cont::DynamicCellSet dynamicCellSet(cellSet);
TryCellSet(cellSet, dynamicCellSet);
}
template<typename CellSetType>
void TryNonDefaultCellSet(CellSetType cellSet)
{
vtkm::cont::DynamicCellSetBase<NonDefaultCellSetList> dynamicCellSet(cellSet);
TryCellSet(cellSet, dynamicCellSet);
}
void TestDynamicCellSet()
{
std::cout << "Try default types with default type lists." << std::endl;
std::cout << "*** 2D Structured Grid ******************" << std::endl;
TryDefaultCellSet(vtkm::cont::CellSetStructured<2>());
std::cout << "*** 3D Structured Grid ******************" << std::endl;
TryDefaultCellSet(vtkm::cont::CellSetStructured<3>());
std::cout << "*** Explicit Grid ***********************" << std::endl;
TryDefaultCellSet(vtkm::cont::CellSetExplicit<>());
std::cout << std::endl << "Try non-default types." << std::endl;
std::cout << "*** 1D Structured Grid ******************" << std::endl;
TryNonDefaultCellSet(vtkm::cont::CellSetStructured<1>());
std::cout << "*** Explicit Grid Constant Shape ********" << std::endl;
TryNonDefaultCellSet(vtkm::cont::CellSetExplicit<
vtkm::cont::ArrayHandleConstant<vtkm::Id>::StorageTag>());
}
} // anonymous namespace
int UnitTestDynamicCellSet(int, char *[])
{
return vtkm::cont::testing::Testing::Run(TestDynamicCellSet);
}