Commit cc71e8ec authored by Robert Maynard's avatar Robert Maynard

vtkm::ListForEach can handle passing any number of extra arguments

Rather than requiring all the arguments to be placed as member variables to
the functor you can now pass extra arguments that will be added to the functor
call signature.

So for example:

  vtkm::ForEach(functor, vtkm::TypeListTagCommon(), double{42.0}, int{42});

will be converted into:

  functor(vtkm::Int32, double, int)
  functor(vtkm::Int64, double, int)
  functor(vtkm::Float32, double, int)
  functor(vtkm::Float64, double, int)
  ...
parent 55d4b9bb
......@@ -85,17 +85,17 @@ struct ListTagIntersect : detail::ListRoot
/// For each typename represented by the list tag, call the functor with a
/// default instance of that type.
///
template <typename Functor, typename ListTag>
VTKM_CONT void ListForEach(Functor&& f, ListTag)
template <typename Functor, typename ListTag, typename... Args>
VTKM_CONT void ListForEach(Functor&& f, ListTag, Args&&... args)
{
VTKM_IS_LIST_TAG(ListTag);
detail::ListForEachImpl(f, typename ListTag::list());
detail::ListForEachImpl(
std::forward<Functor>(f), typename ListTag::list{}, std::forward<Args>(args)...);
}
/// Generate a tag that is the cross product of two other tags. The resulting
// a tag has the form of Tag< std::pair<A1,B1>, std::pair<A1,B2> .... >
///
///
template <typename ListTag1, typename ListTag2>
struct ListCrossProduct : detail::ListRoot
{
......
......@@ -165,30 +165,30 @@ struct ListIntersect<SameListTag, SameListTag>
using type = SameListTag;
};
template <typename Functor>
VTKM_CONT void ListForEachImpl(Functor&&, brigand::empty_sequence)
template <typename Functor, typename... Args>
VTKM_CONT void ListForEachImpl(Functor&&, brigand::list<>, Args&&...)
{
}
template <typename Functor, typename T1>
VTKM_CONT void ListForEachImpl(Functor&& f, brigand::list<T1>)
template <typename Functor, typename T1, typename... Args>
VTKM_CONT void ListForEachImpl(Functor&& f, brigand::list<T1>, Args&&... args)
{
f(T1{});
f(T1{}, std::forward<Args>(args)...);
}
template <typename Functor, typename T1, typename T2>
VTKM_CONT void ListForEachImpl(Functor&& f, brigand::list<T1, T2>)
template <typename Functor, typename T1, typename T2, typename... Args>
VTKM_CONT void ListForEachImpl(Functor&& f, brigand::list<T1, T2>, Args&&... args)
{
f(T1{});
f(T2{});
f(T1{}, std::forward<Args>(args)...);
f(T2{}, std::forward<Args>(args)...);
}
template <typename Functor, typename T1, typename T2, typename T3>
VTKM_CONT void ListForEachImpl(Functor&& f, brigand::list<T1, T2, T3>)
template <typename Functor, typename T1, typename T2, typename T3, typename... Args>
VTKM_CONT void ListForEachImpl(Functor&& f, brigand::list<T1, T2, T3>, Args&&... args)
{
f(T1{});
f(T2{});
f(T3{});
f(T1{}, std::forward<Args>(args)...);
f(T2{}, std::forward<Args>(args)...);
f(T3{}, std::forward<Args>(args)...);
}
template <typename Functor,
......@@ -196,14 +196,18 @@ template <typename Functor,
typename T2,
typename T3,
typename T4,
typename... ArgTypes>
VTKM_CONT void ListForEachImpl(Functor&& f, brigand::list<T1, T2, T3, T4, ArgTypes...>)
{
f(T1{});
f(T2{});
f(T3{});
f(T4{});
ListForEachImpl(f, brigand::list<ArgTypes...>());
typename... ArgTypes,
typename... Args>
VTKM_CONT void ListForEachImpl(Functor&& f,
brigand::list<T1, T2, T3, T4, ArgTypes...>&&,
Args&&... args)
{
f(T1{}, std::forward<Args>(args)...);
f(T2{}, std::forward<Args>(args)...);
f(T3{}, std::forward<Args>(args)...);
f(T4{}, std::forward<Args>(args)...);
ListForEachImpl(
std::forward<Functor>(f), brigand::list<ArgTypes...>{}, std::forward<Args>(args)...);
}
......
......@@ -94,17 +94,10 @@ struct MutableFunctor
template <typename T>
struct ConstantFunctor
{
std::vector<T>& FoundTypes;
ConstantFunctor(std::vector<T>& values)
: FoundTypes(values)
{
}
template <typename U>
VTKM_CONT void operator()(U u) const
template <typename U, typename VectorType>
VTKM_CONT void operator()(U u, VectorType& vector) const
{
this->FoundTypes.push_back(test_number(u));
vector.push_back(test_number(u));
}
};
......@@ -160,8 +153,8 @@ void TryList(const vtkm::Vec<int, N>& expected, ListTag)
std::cout << " Try constant for each" << std::endl;
std::vector<int> foundTypes;
ConstantFunctor<int> cfunc(foundTypes);
vtkm::ListForEach(cfunc, ListTag());
ConstantFunctor<int> cfunc;
vtkm::ListForEach(cfunc, ListTag(), foundTypes);
CheckSame(expected, foundTypes);
std::cout << " Try checking contents" << std::endl;
......@@ -188,8 +181,8 @@ void TryList(const vtkm::Vec<std::pair<int, int>, N>& expected, ListTag)
std::cout << " Try constant for each" << std::endl;
std::vector<std::pair<int, int>> foundTypes;
ConstantFunctor<std::pair<int, int>> cfunc(foundTypes);
vtkm::ListForEach(cfunc, ListTag());
ConstantFunctor<std::pair<int, int>> cfunc;
vtkm::ListForEach(cfunc, ListTag(), foundTypes);
CheckSame(expected, foundTypes);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment