Fix ICE in MSVC 2017

This commit is contained in:
Kenneth Moreland 2022-02-03 09:12:56 -07:00
parent 878e56d974
commit ae28519af4
2 changed files with 59 additions and 7 deletions

@ -622,6 +622,56 @@ using ListTransform = typename detail::ListTransformImpl<internal::AsList<List>,
namespace detail
{
#if defined(VTKM_MSVC) && (_MSC_VER < 1920)
// Special (inefficient) implementation for MSVC 2017, which has an ICE for the regular version
template <typename Passed,
typename Next,
bool Remove,
typename Rest,
template <typename>
class Predicate>
struct ListRemoveIfCheckNext;
template <typename Passed, typename Rest, template <typename> class Predicate>
struct ListRemoveIfGetNext;
template <typename Passed, typename Next, typename Rest, template <typename> class Predicate>
struct ListRemoveIfCheckNext<Passed, Next, true, Rest, Predicate>
{
using type = typename ListRemoveIfGetNext<Passed, Rest, Predicate>::type;
};
template <typename... PassedTs, typename Next, typename Rest, template <typename> class Predicate>
struct ListRemoveIfCheckNext<vtkm::List<PassedTs...>, Next, false, Rest, Predicate>
{
using type = typename ListRemoveIfGetNext<vtkm::List<PassedTs..., Next>, Rest, Predicate>::type;
};
template <typename Passed, typename Next, typename... RestTs, template <typename> class Predicate>
struct ListRemoveIfGetNext<Passed, vtkm::List<Next, RestTs...>, Predicate>
{
using type = typename ListRemoveIfCheckNext<Passed,
Next,
Predicate<Next>::value,
vtkm::List<RestTs...>,
Predicate>::type;
};
template <typename Passed, template <typename> class Predicate>
struct ListRemoveIfGetNext<Passed, vtkm::List<>, Predicate>
{
using type = Passed;
};
template <typename L, template <typename> class Predicate>
struct ListRemoveIfImpl
{
using type = typename ListRemoveIfGetNext<vtkm::List<>, L, Predicate>::type;
};
#else
template <typename L, template <typename> class Predicate>
struct ListRemoveIfImpl;
@ -632,6 +682,8 @@ struct ListRemoveIfImpl<vtkm::List<Ts...>, Predicate>
std::conditional_t<Predicate<Ts>::value, vtkm::List<>, vtkm::List<Ts>>...>::type;
};
#endif
} // namespace detail
/// Takes an existing `List` and a predicate template that is applied to each type in the `List`.

@ -178,6 +178,13 @@ void TestLists()
vtkm::List<TestClass<11>>,
vtkm::List<TestClass<21>, TestClass<22>>>{});
std::cout << "ListTransform" << std::endl;
CheckList(EvenList{}, vtkm::ListTransform<SimpleCount, DoubleTransform>{});
std::cout << "ListRemoveIf" << std::endl;
CheckList(vtkm::List<TestClass<1>, TestClass<3>>{},
vtkm::ListRemoveIf<SimpleCount, EvenPredicate>{});
std::cout << "ListIntersect" << std::endl;
CheckList(vtkm::List<TestClass<3>, TestClass<5>>{},
vtkm::ListIntersect<
@ -188,13 +195,6 @@ void TestLists()
CheckList(vtkm::List<TestClass<1>, TestClass<2>>{},
vtkm::ListIntersect<vtkm::ListUniversal, vtkm::List<TestClass<1>, TestClass<2>>>{});
std::cout << "ListTransform" << std::endl;
CheckList(EvenList{}, vtkm::ListTransform<SimpleCount, DoubleTransform>{});
std::cout << "ListRemoveIf" << std::endl;
CheckList(vtkm::List<TestClass<1>, TestClass<3>>{},
vtkm::ListRemoveIf<SimpleCount, EvenPredicate>{});
std::cout << "ListSize" << std::endl;
VTKM_TEST_ASSERT(vtkm::ListSize<vtkm::ListEmpty>::value == 0);
VTKM_TEST_ASSERT(vtkm::ListSize<vtkm::List<TestClass<2>>>::value == 1);