From 2ff14a811f74ad0bd80acfb4a20d7080bedee1fc Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Tue, 7 Nov 2017 17:43:36 -0500 Subject: [PATCH] Allow users to pass multiple arguments to CastAndCall --- vtkm/cont/CoordinateSystem.h | 6 ++-- vtkm/cont/DynamicArrayHandle.h | 12 ++++--- vtkm/cont/DynamicCellSet.h | 16 ++++----- vtkm/cont/Field.h | 6 ++-- vtkm/cont/internal/DynamicTransform.h | 52 +++++++++++++++------------ 5 files changed, 51 insertions(+), 41 deletions(-) diff --git a/vtkm/cont/CoordinateSystem.h b/vtkm/cont/CoordinateSystem.h index e044e2f81..1504a83bc 100644 --- a/vtkm/cont/CoordinateSystem.h +++ b/vtkm/cont/CoordinateSystem.h @@ -224,10 +224,10 @@ public: virtual void PrintSummary(std::ostream& out) const; }; -template -void CastAndCall(const vtkm::cont::CoordinateSystem& coords, const Functor& f) +template +void CastAndCall(const vtkm::cont::CoordinateSystem& coords, const Functor& f, Args&&... args) { - coords.GetData().CastAndCall(f); + coords.GetData().CastAndCall(f, std::forward(args)...); } namespace internal diff --git a/vtkm/cont/DynamicArrayHandle.h b/vtkm/cont/DynamicArrayHandle.h index 7baa4a813..bc600e648 100644 --- a/vtkm/cont/DynamicArrayHandle.h +++ b/vtkm/cont/DynamicArrayHandle.h @@ -357,8 +357,8 @@ public: /// two lists to VTKM_DEFAULT_TYPE_LIST_TAG and VTK_DEFAULT_STORAGE_LIST_TAG, /// respectively. /// - template - VTKM_CONT void CastAndCall(const Functor& f) const; + template + 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 -template -VTKM_CONT void DynamicArrayHandleBase::CastAndCall(const Functor& f) const +template +VTKM_CONT void DynamicArrayHandleBase::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::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)...); if (!called) { // throw an exception diff --git a/vtkm/cont/DynamicCellSet.h b/vtkm/cont/DynamicCellSet.h index 95b6758dc..3df58eaf3 100644 --- a/vtkm/cont/DynamicCellSet.h +++ b/vtkm/cont/DynamicCellSet.h @@ -227,8 +227,8 @@ public: /// DynamicCellSet). You can use \c ResetCellSetList to get different /// behavior from \c CastAndCall. /// - template - VTKM_CONT void CastAndCall(const Functor& f) const; + template + 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 - void operator()(CellSetType, Functor&& f, bool& called) const + template + void operator()(CellSetType, Functor&& f, bool& called, Args&&... args) const { using downcastType = const vtkm::cont::internal::SimplePolymorphicContainer* const; if (!called) @@ -289,7 +289,7 @@ struct DynamicCellSetTry downcastType downcastContainer = dynamic_cast(this->Container); if (downcastContainer) { - f(downcastContainer->Item); + f(downcastContainer->Item, std::forward(args)...); called = true; } } @@ -301,12 +301,12 @@ struct DynamicCellSetTry } // namespace detail template -template -VTKM_CONT void DynamicCellSetBase::CastAndCall(const Functor& f) const +template +VTKM_CONT void DynamicCellSetBase::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)...); if (!called) { throw vtkm::cont::ErrorBadValue("Could not find appropriate cast for cell set."); diff --git a/vtkm/cont/Field.h b/vtkm/cont/Field.h index 8efced0f6..79e1386ca 100644 --- a/vtkm/cont/Field.h +++ b/vtkm/cont/Field.h @@ -401,10 +401,10 @@ private: } }; -template -void CastAndCall(const vtkm::cont::Field& field, const Functor& f) +template +void CastAndCall(const vtkm::cont::Field& field, const Functor& f, Args&&... args) { - field.GetData().CastAndCall(f); + field.GetData().CastAndCall(f, std::forward(args)...); } namespace internal diff --git a/vtkm/cont/internal/DynamicTransform.h b/vtkm/cont/internal/DynamicTransform.h index 7d6eb7789..1195723c0 100644 --- a/vtkm/cont/internal/DynamicTransform.h +++ b/vtkm/cont/internal/DynamicTransform.h @@ -22,6 +22,8 @@ #include "vtkm/internal/IndexTag.h" +#include + 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 -void CastAndCall(const DynamicObject& dynamicObject, const Functor& f) +template +void CastAndCall(const DynamicObject& dynamicObject, const Functor& f, Args&&... args) { - dynamicObject.CastAndCall(f); + dynamicObject.CastAndCall(f, std::forward(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 -void CastAndCall(const CoordinateSystem& coords, const Functor& f); +template +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 -void CastAndCall(const vtkm::cont::Field& field, const Functor& f); +template +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 -void CastAndCall(const vtkm::cont::ArrayHandle& handle, const Functor& f) +template +void CastAndCall(const vtkm::cont::ArrayHandle& handle, const Functor& f, Args&&... args) { - f(handle); + f(handle, std::forward(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 -void CastAndCall(const vtkm::cont::CellSetStructured& cellset, const Functor& f) +template +void CastAndCall(const vtkm::cont::CellSetStructured& cellset, + const Functor& f, + Args&&... args) { - f(cellset); + f(cellset, std::forward(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 +template void CastAndCall(const vtkm::cont::CellSetSingleType& cellset, - const Functor& f) + const Functor& f, + Args&&... args) { - f(cellset); + f(cellset, std::forward(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 -void CastAndCall(const vtkm::cont::CellSetExplicit& cellset, const Functor& f) +template +void CastAndCall(const vtkm::cont::CellSetExplicit& cellset, + const Functor& f, + Args&&... args) { - f(cellset); + f(cellset, std::forward(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 +template void CastAndCall(const vtkm::cont::CellSetPermutation& cellset, - const Functor& f) + const Functor& f, + Args&&... args) { - f(cellset); + f(cellset, std::forward(args)...); } namespace internal