Correctly forward rvalue functors when passed to CastAndCall

This commit is contained in:
Robert Maynard 2017-12-08 11:40:52 -05:00
parent 3ad106f179
commit 7b1b9e445a
5 changed files with 28 additions and 26 deletions

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

@ -358,7 +358,7 @@ public:
/// respectively.
///
template <typename Functor, typename... Args>
VTKM_CONT void CastAndCall(const Functor& f, Args&&...) const;
VTKM_CONT void CastAndCall(Functor&& f, Args&&...) const;
/// \brief Create a new array of the same type as this array.
///
@ -414,15 +414,15 @@ struct DynamicArrayHandleTry
}
template <typename T, typename U, typename... Args>
void operator()(std::pair<T, U>&& p, Args&&... args) const
void operator()(std::pair<T, U>, Args&&... args) const
{
using storage = vtkm::cont::internal::Storage<T, U>;
using invalid = typename std::is_base_of<vtkm::cont::internal::UndefinedStorage, storage>::type;
this->run(std::forward<decltype(p)>(p), invalid{}, args...);
this->run<T, U>(invalid{}, args...);
}
template <typename T, typename U, typename Functor, typename... Args>
void run(std::pair<T, U>&&, std::false_type, Functor&& f, bool& called, Args&&... args) const
void run(std::false_type, Functor&& f, bool& called, Args&&... args) const
{
if (!called)
{
@ -437,7 +437,7 @@ struct DynamicArrayHandleTry
}
template <typename T, typename U, typename... Args>
void run(std::pair<T, U>&&, std::true_type, Args&&...) const
void run(std::true_type, Args&&...) const
{
}
@ -451,7 +451,7 @@ VTKM_CONT_EXPORT void ThrowCastAndCallException(PolymorphicArrayHandleContainerB
template <typename TypeList, typename StorageList>
template <typename Functor, typename... Args>
VTKM_CONT void DynamicArrayHandleBase<TypeList, StorageList>::CastAndCall(const Functor& f,
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
@ -460,8 +460,11 @@ VTKM_CONT void DynamicArrayHandleBase<TypeList, StorageList>::CastAndCall(const
bool called = false;
auto* ptr = this->ArrayContainer.get();
vtkm::ListForEach(
detail::DynamicArrayHandleTry(ptr), crossProduct{}, f, called, std::forward<Args>(args)...);
vtkm::ListForEach(detail::DynamicArrayHandleTry(ptr),
crossProduct{},
std::forward<Functor>(f),
called,
std::forward<Args>(args)...);
if (!called)
{
// throw an exception

@ -228,7 +228,7 @@ public:
/// behavior from \c CastAndCall.
///
template <typename Functor, typename... Args>
VTKM_CONT void CastAndCall(const Functor& f, Args&&...) const;
VTKM_CONT void CastAndCall(Functor&& f, Args&&...) const;
/// \brief Create a new cell set of the same type as this cell set.
///
@ -302,11 +302,12 @@ struct DynamicCellSetTry
template <typename CellSetList>
template <typename Functor, typename... Args>
VTKM_CONT void DynamicCellSetBase<CellSetList>::CastAndCall(const Functor& f, Args&&... args) const
VTKM_CONT void DynamicCellSetBase<CellSetList>::CastAndCall(Functor&& f, Args&&... args) const
{
bool called = false;
detail::DynamicCellSetTry tryCellSet(this->CellSetContainer.get());
vtkm::ListForEach(tryCellSet, CellSetList{}, f, called, std::forward<Args>(args)...);
vtkm::ListForEach(
tryCellSet, CellSetList{}, std::forward<Functor>(f), called, std::forward<Args>(args)...);
if (!called)
{
throw vtkm::cont::ErrorBadValue("Could not find appropriate cast for cell set.");

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

@ -48,28 +48,28 @@ class CellSetPermutation;
/// DynamicObject's CastAndCall, but specializations of this function exist for
/// other classes (e.g. Field, CoordinateSystem, ArrayHandle).
template <typename DynamicObject, typename Functor, typename... Args>
void CastAndCall(const DynamicObject& dynamicObject, const Functor& f, Args&&... args)
void CastAndCall(const DynamicObject& dynamicObject, Functor&& f, Args&&... args)
{
dynamicObject.CastAndCall(f, std::forward<Args>(args)...);
dynamicObject.CastAndCall(std::forward<Functor>(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, typename... Args>
void CastAndCall(const CoordinateSystem& coords, const Functor& f, Args&&... args);
void CastAndCall(const CoordinateSystem& coords, 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, typename... Args>
void CastAndCall(const vtkm::cont::Field& field, const Functor& f, Args&&... args);
void CastAndCall(const vtkm::cont::Field& field, 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, typename... Args>
void CastAndCall(const vtkm::cont::ArrayHandle<T, U>& handle, const Functor& f, Args&&... args)
void CastAndCall(const vtkm::cont::ArrayHandle<T, U>& handle, Functor&& f, Args&&... args)
{
f(handle, std::forward<Args>(args)...);
}
@ -78,9 +78,7 @@ void CastAndCall(const vtkm::cont::ArrayHandle<T, U>& handle, const Functor& f,
/// 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, typename... Args>
void CastAndCall(const vtkm::cont::CellSetStructured<Dim>& cellset,
const Functor& f,
Args&&... args)
void CastAndCall(const vtkm::cont::CellSetStructured<Dim>& cellset, Functor&& f, Args&&... args)
{
f(cellset, std::forward<Args>(args)...);
}
@ -90,7 +88,7 @@ void CastAndCall(const vtkm::cont::CellSetStructured<Dim>& cellset,
/// This specialization is used to simplify numerous worklet algorithms
template <typename ConnectivityStorageTag, typename Functor, typename... Args>
void CastAndCall(const vtkm::cont::CellSetSingleType<ConnectivityStorageTag>& cellset,
const Functor& f,
Functor&& f,
Args&&... args)
{
f(cellset, std::forward<Args>(args)...);
@ -101,7 +99,7 @@ void CastAndCall(const vtkm::cont::CellSetSingleType<ConnectivityStorageTag>& ce
/// This specialization is used to simplify numerous worklet algorithms
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,
Functor&& f,
Args&&... args)
{
f(cellset, std::forward<Args>(args)...);
@ -112,7 +110,7 @@ void CastAndCall(const vtkm::cont::CellSetExplicit<T, S, U, V>& cellset,
/// This specialization is used to simplify numerous worklet algorithms
template <typename PermutationType, typename CellSetType, typename Functor, typename... Args>
void CastAndCall(const vtkm::cont::CellSetPermutation<PermutationType, CellSetType>& cellset,
const Functor& f,
Functor&& f,
Args&&... args)
{
f(cellset, std::forward<Args>(args)...);