Allow users to pass multiple arguments to CastAndCall

This commit is contained in:
Robert Maynard 2017-11-07 17:43:36 -05:00
parent dd25c5c2eb
commit 2ff14a811f
5 changed files with 51 additions and 41 deletions

@ -224,10 +224,10 @@ public:
virtual void PrintSummary(std::ostream& out) const;
};
template <typename Functor>
void CastAndCall(const vtkm::cont::CoordinateSystem& coords, const Functor& f)
template <typename Functor, typename... Args>
void CastAndCall(const vtkm::cont::CoordinateSystem& coords, const Functor& f, Args&&... args)
{
coords.GetData().CastAndCall(f);
coords.GetData().CastAndCall(f, std::forward<Args>(args)...);
}
namespace internal

@ -357,8 +357,8 @@ public:
/// two lists to VTKM_DEFAULT_TYPE_LIST_TAG and VTK_DEFAULT_STORAGE_LIST_TAG,
/// respectively.
///
template <typename Functor>
VTKM_CONT void CastAndCall(const Functor& f) const;
template <typename Functor, typename... Args>
VTKM_CONT void CastAndCall(const Functor& f, Args&&...) const;
/// \brief Create a new array of the same type as this array.
///
@ -450,8 +450,9 @@ VTKM_CONT_EXPORT void ThrowCastAndCallException(PolymorphicArrayHandleContainerB
} // namespace detail
template <typename TypeList, typename StorageList>
template <typename Functor>
VTKM_CONT void DynamicArrayHandleBase<TypeList, StorageList>::CastAndCall(const Functor& f) const
template <typename Functor, typename... Args>
VTKM_CONT void DynamicArrayHandleBase<TypeList, StorageList>::CastAndCall(const Functor& f,
Args&&... args) const
{
//For optimizations we should compile once the cross product for the default types
//and make it extern
@ -459,7 +460,8 @@ VTKM_CONT void DynamicArrayHandleBase<TypeList, StorageList>::CastAndCall(const
bool called = false;
auto* ptr = this->ArrayContainer.get();
vtkm::ListForEach(detail::DynamicArrayHandleTry(ptr), crossProduct{}, f, called);
vtkm::ListForEach(
detail::DynamicArrayHandleTry(ptr), crossProduct{}, f, called, std::forward<Args>(args)...);
if (!called)
{
// throw an exception

@ -227,8 +227,8 @@ public:
/// DynamicCellSet). You can use \c ResetCellSetList to get different
/// behavior from \c CastAndCall.
///
template <typename Functor>
VTKM_CONT void CastAndCall(const Functor& f) const;
template <typename Functor, typename... Args>
VTKM_CONT void CastAndCall(const Functor& f, Args&&...) const;
/// \brief Create a new cell set of the same type as this cell set.
///
@ -280,8 +280,8 @@ struct DynamicCellSetTry
{
}
template <typename CellSetType, typename Functor>
void operator()(CellSetType, Functor&& f, bool& called) const
template <typename CellSetType, typename Functor, typename... Args>
void operator()(CellSetType, Functor&& f, bool& called, Args&&... args) const
{
using downcastType = const vtkm::cont::internal::SimplePolymorphicContainer<CellSetType>* const;
if (!called)
@ -289,7 +289,7 @@ struct DynamicCellSetTry
downcastType downcastContainer = dynamic_cast<downcastType>(this->Container);
if (downcastContainer)
{
f(downcastContainer->Item);
f(downcastContainer->Item, std::forward<Args>(args)...);
called = true;
}
}
@ -301,12 +301,12 @@ struct DynamicCellSetTry
} // namespace detail
template <typename CellSetList>
template <typename Functor>
VTKM_CONT void DynamicCellSetBase<CellSetList>::CastAndCall(const Functor& f) const
template <typename Functor, typename... Args>
VTKM_CONT void DynamicCellSetBase<CellSetList>::CastAndCall(const Functor& f, Args&&... args) const
{
bool called = false;
detail::DynamicCellSetTry tryCellSet(this->CellSetContainer.get());
vtkm::ListForEach(tryCellSet, CellSetList{}, f, called);
vtkm::ListForEach(tryCellSet, CellSetList{}, f, called, std::forward<Args>(args)...);
if (!called)
{
throw vtkm::cont::ErrorBadValue("Could not find appropriate cast for cell set.");

@ -401,10 +401,10 @@ private:
}
};
template <typename Functor>
void CastAndCall(const vtkm::cont::Field& field, const Functor& f)
template <typename Functor, typename... Args>
void CastAndCall(const vtkm::cont::Field& field, const Functor& f, Args&&... args)
{
field.GetData().CastAndCall(f);
field.GetData().CastAndCall(f, std::forward<Args>(args)...);
}
namespace internal

@ -22,6 +22,8 @@
#include "vtkm/internal/IndexTag.h"
#include <utility>
namespace vtkm
{
namespace cont
@ -45,69 +47,75 @@ class CellSetPermutation;
/// A Generic interface to CastAndCall. The default implementation simply calls
/// DynamicObject's CastAndCall, but specializations of this function exist for
/// other classes (e.g. Field, CoordinateSystem, ArrayHandle).
template <typename DynamicObject, typename Functor>
void CastAndCall(const DynamicObject& dynamicObject, const Functor& f)
template <typename DynamicObject, typename Functor, typename... Args>
void CastAndCall(const DynamicObject& dynamicObject, const Functor& f, Args&&... args)
{
dynamicObject.CastAndCall(f);
dynamicObject.CastAndCall(f, std::forward<Args>(args)...);
}
/// A specialization of CastAndCall for basic CoordinateSystem to make
/// it be treated just like any other dynamic object
// actually implemented in vtkm/cont/CoordinateSystem
template <typename Functor>
void CastAndCall(const CoordinateSystem& coords, const Functor& f);
template <typename Functor, typename... Args>
void CastAndCall(const CoordinateSystem& coords, const Functor& f, Args&&... args);
/// A specialization of CastAndCall for basic Field to make
/// it be treated just like any other dynamic object
// actually implemented in vtkm/cont/Field
template <typename Functor>
void CastAndCall(const vtkm::cont::Field& field, const Functor& f);
template <typename Functor, typename... Args>
void CastAndCall(const vtkm::cont::Field& field, const Functor& f, Args&&... args);
/// A specialization of CastAndCall for basic ArrayHandle types,
/// Since the type is already known no deduction is needed.
/// This specialization is used to simplify numerous worklet algorithms
template <typename T, typename U, typename Functor>
void CastAndCall(const vtkm::cont::ArrayHandle<T, U>& handle, const Functor& f)
template <typename T, typename U, typename Functor, typename... Args>
void CastAndCall(const vtkm::cont::ArrayHandle<T, U>& handle, const Functor& f, Args&&... args)
{
f(handle);
f(handle, std::forward<Args>(args)...);
}
/// A specialization of CastAndCall for basic CellSetStructured types,
/// Since the type is already known no deduction is needed.
/// This specialization is used to simplify numerous worklet algorithms
template <vtkm::IdComponent Dim, typename Functor>
void CastAndCall(const vtkm::cont::CellSetStructured<Dim>& cellset, const Functor& f)
template <vtkm::IdComponent Dim, typename Functor, typename... Args>
void CastAndCall(const vtkm::cont::CellSetStructured<Dim>& cellset,
const Functor& f,
Args&&... args)
{
f(cellset);
f(cellset, std::forward<Args>(args)...);
}
/// A specialization of CastAndCall for basic CellSetSingleType types,
/// Since the type is already known no deduction is needed.
/// This specialization is used to simplify numerous worklet algorithms
template <typename ConnectivityStorageTag, typename Functor>
template <typename ConnectivityStorageTag, typename Functor, typename... Args>
void CastAndCall(const vtkm::cont::CellSetSingleType<ConnectivityStorageTag>& cellset,
const Functor& f)
const Functor& f,
Args&&... args)
{
f(cellset);
f(cellset, std::forward<Args>(args)...);
}
/// A specialization of CastAndCall for basic CellSetExplicit types,
/// Since the type is already known no deduction is needed.
/// This specialization is used to simplify numerous worklet algorithms
template <typename T, typename S, typename U, typename V, typename Functor>
void CastAndCall(const vtkm::cont::CellSetExplicit<T, S, U, V>& cellset, const Functor& f)
template <typename T, typename S, typename U, typename V, typename Functor, typename... Args>
void CastAndCall(const vtkm::cont::CellSetExplicit<T, S, U, V>& cellset,
const Functor& f,
Args&&... args)
{
f(cellset);
f(cellset, std::forward<Args>(args)...);
}
/// A specialization of CastAndCall for basic CellSetPermutation types,
/// Since the type is already known no deduction is needed.
/// This specialization is used to simplify numerous worklet algorithms
template <typename PermutationType, typename CellSetType, typename Functor>
template <typename PermutationType, typename CellSetType, typename Functor, typename... Args>
void CastAndCall(const vtkm::cont::CellSetPermutation<PermutationType, CellSetType>& cellset,
const Functor& f)
const Functor& f,
Args&&... args)
{
f(cellset);
f(cellset, std::forward<Args>(args)...);
}
namespace internal