From 124f08381bba7a62f7160e72225e7793c15e60eb Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Wed, 9 Feb 2022 11:27:30 -0700 Subject: [PATCH] Added ListReduce, ListAll, and ListAny These new features to VTK-m lists allow you to compute a single value from a list. `ListReduce` allows you to compute a value based on a predicate. `ListAll` and `ListAny` use this feature to determine if all or any of a list of `true_type` or `false_type` objects are true. --- docs/changelog/new-list-features.md | 57 +++++++++++++++++++++ vtkm/List.h | 77 +++++++++++++++++++++++++++++ vtkm/internal/CMakeLists.txt | 1 + vtkm/internal/Meta.h | 73 +++++++++++++++++++++++++++ vtkm/testing/UnitTestList.cxx | 31 +++++++++++- 5 files changed, 238 insertions(+), 1 deletion(-) create mode 100644 docs/changelog/new-list-features.md create mode 100644 vtkm/internal/Meta.h diff --git a/docs/changelog/new-list-features.md b/docs/changelog/new-list-features.md new file mode 100644 index 000000000..a92bbf90d --- /dev/null +++ b/docs/changelog/new-list-features.md @@ -0,0 +1,57 @@ +# New `vtkm::List` features + +New features were added to those available in `vtkm/List.h`. These new +features provide new operations on lists. + +## Reductions + +The new `vtkm::ListReduce` allows a reduction on a list. This template +takes three arguments: a `vtkm::List`, an operation, and an initial value. +The operation is itself a template that has two type arguments. + +`vtkm::ListReduce` applies the initial value and the first item of the list +to the operator. The result of that template is then iteratively applied to +the operator with the next item in the list and so on. + +``` cpp +// Operation to use +template +using Add = std::integral_constant; + +using MyList = vtkm::List, + std::integral_constant, + std::integral_constant, + std::integral_constant>; + +using MySum = vtkm::ListReduce>; +// MySum becomes std::integral_constant (25+60+87+62 = 234) +``` + +## All and Any + +Because they are very common, two reductions that are automatically +supported are `vtkm::ListAll` and `vtkm::ListAny`. These both take a +`vtkm::List` containing either `std::true_type` or `std::false_type` (or +some other "compatible" type that has a constant static `bool` named +`value`). `vtkm::ListAll` will become `std::false_type` if any of the +entries in the list are `std::false_type`. `vtkm::ListAny` becomes +`std::true_type` if any of the entires in the list are `std::true_type`. + +``` cpp +using MyList = vtkm::List, + std::integral_constant, + std::integral_constant, + std::integral_constant>; + +template +using IsEven = std::integral_constant; + +// Note that vtkm::ListTransform becomes +// vtkm::List + +using AllEven = vtkm::ListAll>; +// AllEven becomes std::false_type + +using AnyEven = vtkm::ListAny>; +// AnyEven becomes std::true_type +``` diff --git a/vtkm/List.h b/vtkm/List.h index 7f41f2e4c..0c7bd9b26 100644 --- a/vtkm/List.h +++ b/vtkm/List.h @@ -12,6 +12,8 @@ #include +#include + namespace vtkm { @@ -807,6 +809,81 @@ template using ListCross = typename detail::ListCrossImpl, internal::AsList>::type; +namespace detail +{ + +template class Operator, typename Result> +struct ListReduceImpl; + +template