mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-10-05 01:49:02 +00:00
2b64630674
In pretty much any practical circumstance, whenusing `ListAll` or `ListAny`, you have a list of types on which you run some sort of predicate on each item in the list to determine whether any or all of the items match the predicate. To make this easier, add a second argument to `ListAll` and `ListAny` to provide a predicate that will automatically be added. If no predicate is given, then the operation is run directly on the list. This is implemented by just using an identity operation.
324 lines
13 KiB
C++
324 lines
13 KiB
C++
//============================================================================
|
|
// Copyright (c) Kitware, Inc.
|
|
// All rights reserved.
|
|
// See LICENSE.txt for details.
|
|
//
|
|
// This software is distributed WITHOUT ANY WARRANTY; without even
|
|
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
// PURPOSE. See the above copyright notice for more information.
|
|
//============================================================================
|
|
|
|
#include <vtkm/List.h>
|
|
|
|
#include <vtkm/testing/Testing.h>
|
|
|
|
#include <vector>
|
|
|
|
namespace
|
|
{
|
|
|
|
template <int N>
|
|
struct TestClass : std::integral_constant<int, N>
|
|
{
|
|
};
|
|
|
|
} // anonymous namespace
|
|
|
|
namespace vtkm
|
|
{
|
|
namespace testing
|
|
{
|
|
|
|
template <int N>
|
|
struct TypeName<TestClass<N>>
|
|
{
|
|
static std::string Name()
|
|
{
|
|
std::stringstream stream;
|
|
stream << "TestClass<" << N << ">";
|
|
return stream.str();
|
|
}
|
|
};
|
|
}
|
|
} // namespace vtkm::testing
|
|
|
|
namespace
|
|
{
|
|
|
|
template <typename T>
|
|
struct DoubleTransformLazy;
|
|
template <int N>
|
|
struct DoubleTransformLazy<TestClass<N>>
|
|
{
|
|
using type = TestClass<2 * N>;
|
|
};
|
|
|
|
template <typename T>
|
|
using DoubleTransform = typename DoubleTransformLazy<T>::type;
|
|
|
|
template <typename T>
|
|
struct EvenPredicate;
|
|
template <int N>
|
|
struct EvenPredicate<TestClass<N>> : std::integral_constant<bool, (N % 2) == 0>
|
|
{
|
|
};
|
|
|
|
template <typename T>
|
|
using OddPredicate = vtkm::internal::meta::Not<EvenPredicate<T>>;
|
|
|
|
template <typename T1, typename T2>
|
|
struct AddOperator : TestClass<T1::value + T2::value>
|
|
{
|
|
};
|
|
|
|
template <typename T1, typename T2>
|
|
void CheckSame(T1, T2)
|
|
{
|
|
VTKM_STATIC_ASSERT((std::is_same<T1, T2>::value));
|
|
|
|
std::cout << " Got expected type: " << vtkm::testing::TypeName<T1>::Name() << std::endl;
|
|
}
|
|
|
|
template <typename ExpectedList, typename List>
|
|
void CheckList(ExpectedList, List)
|
|
{
|
|
VTKM_IS_LIST(List);
|
|
CheckSame(ExpectedList{}, List{});
|
|
}
|
|
|
|
template <int N>
|
|
int test_number(TestClass<N>)
|
|
{
|
|
return N;
|
|
}
|
|
|
|
template <typename T>
|
|
struct MutableFunctor
|
|
{
|
|
std::vector<T> FoundTypes;
|
|
|
|
template <typename U>
|
|
VTKM_CONT void operator()(U u)
|
|
{
|
|
this->FoundTypes.push_back(test_number(u));
|
|
}
|
|
};
|
|
|
|
template <typename T>
|
|
struct ConstantFunctor
|
|
{
|
|
template <typename U, typename VectorType>
|
|
VTKM_CONT void operator()(U u, VectorType& vector) const
|
|
{
|
|
vector.push_back(test_number(u));
|
|
}
|
|
};
|
|
|
|
void TryForEach()
|
|
{
|
|
using TestList =
|
|
vtkm::List<TestClass<1>, TestClass<1>, TestClass<2>, TestClass<3>, TestClass<5>, TestClass<8>>;
|
|
const std::vector<int> expectedList = { 1, 1, 2, 3, 5, 8 };
|
|
|
|
std::cout << "Check mutable for each" << std::endl;
|
|
MutableFunctor<int> functor;
|
|
vtkm::ListForEach(functor, TestList{});
|
|
VTKM_TEST_ASSERT(expectedList == functor.FoundTypes);
|
|
|
|
std::cout << "Check constant for each" << std::endl;
|
|
std::vector<int> foundTypes;
|
|
vtkm::ListForEach(ConstantFunctor<int>{}, TestList{}, foundTypes);
|
|
VTKM_TEST_ASSERT(expectedList == foundTypes);
|
|
}
|
|
|
|
void TestLists()
|
|
{
|
|
using SimpleCount = vtkm::List<TestClass<1>, TestClass<2>, TestClass<3>, TestClass<4>>;
|
|
using EvenList = vtkm::List<TestClass<2>, TestClass<4>, TestClass<6>, TestClass<8>>;
|
|
using LongList = vtkm::List<TestClass<1>,
|
|
TestClass<2>,
|
|
TestClass<3>,
|
|
TestClass<4>,
|
|
TestClass<5>,
|
|
TestClass<6>,
|
|
TestClass<7>,
|
|
TestClass<8>,
|
|
TestClass<9>,
|
|
TestClass<10>,
|
|
TestClass<11>,
|
|
TestClass<12>,
|
|
TestClass<13>,
|
|
TestClass<14>>;
|
|
using RepeatList = vtkm::List<TestClass<1>,
|
|
TestClass<1>,
|
|
TestClass<1>,
|
|
TestClass<1>,
|
|
TestClass<1>,
|
|
TestClass<1>,
|
|
TestClass<1>,
|
|
TestClass<1>,
|
|
TestClass<1>,
|
|
TestClass<1>,
|
|
TestClass<1>,
|
|
TestClass<1>,
|
|
TestClass<1>,
|
|
TestClass<14>>;
|
|
|
|
TryForEach();
|
|
|
|
std::cout << "Valid List Tag Checks" << std::endl;
|
|
VTKM_TEST_ASSERT(vtkm::internal::IsList<vtkm::List<TestClass<11>>>::value);
|
|
VTKM_TEST_ASSERT(vtkm::internal::IsList<vtkm::List<TestClass<21>, TestClass<22>>>::value);
|
|
VTKM_TEST_ASSERT(vtkm::internal::IsList<vtkm::ListEmpty>::value);
|
|
VTKM_TEST_ASSERT(vtkm::internal::IsList<vtkm::ListUniversal>::value);
|
|
|
|
std::cout << "ListEmpty" << std::endl;
|
|
CheckList(vtkm::List<>{}, vtkm::ListEmpty{});
|
|
|
|
std::cout << "ListAppend" << std::endl;
|
|
CheckList(vtkm::List<TestClass<31>,
|
|
TestClass<32>,
|
|
TestClass<33>,
|
|
TestClass<11>,
|
|
TestClass<21>,
|
|
TestClass<22>>{},
|
|
vtkm::ListAppend<vtkm::List<TestClass<31>, TestClass<32>, TestClass<33>>,
|
|
vtkm::List<TestClass<11>>,
|
|
vtkm::List<TestClass<21>, TestClass<22>>>{});
|
|
|
|
std::cout << "ListFill" << std::endl;
|
|
CheckList(vtkm::List<int, int, int, int, int>{}, vtkm::ListFill<int, 5>{});
|
|
|
|
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<
|
|
vtkm::List<TestClass<1>, TestClass<2>, TestClass<3>, TestClass<4>, TestClass<5>>,
|
|
vtkm::List<TestClass<3>, TestClass<5>, TestClass<6>>>{});
|
|
CheckList(vtkm::List<TestClass<1>, TestClass<2>>{},
|
|
vtkm::ListIntersect<vtkm::List<TestClass<1>, TestClass<2>>, vtkm::ListUniversal>{});
|
|
CheckList(vtkm::List<TestClass<1>, TestClass<2>>{},
|
|
vtkm::ListIntersect<vtkm::ListUniversal, vtkm::List<TestClass<1>, TestClass<2>>>{});
|
|
|
|
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);
|
|
VTKM_TEST_ASSERT(vtkm::ListSize<vtkm::List<TestClass<2>, TestClass<4>>>::value == 2);
|
|
|
|
std::cout << "ListCross" << std::endl;
|
|
CheckList(vtkm::List<vtkm::List<TestClass<31>, TestClass<11>>,
|
|
vtkm::List<TestClass<31>, TestClass<12>>,
|
|
vtkm::List<TestClass<32>, TestClass<11>>,
|
|
vtkm::List<TestClass<32>, TestClass<12>>,
|
|
vtkm::List<TestClass<33>, TestClass<11>>,
|
|
vtkm::List<TestClass<33>, TestClass<12>>>{},
|
|
vtkm::ListCross<vtkm::List<TestClass<31>, TestClass<32>, TestClass<33>>,
|
|
vtkm::List<TestClass<11>, TestClass<12>>>{});
|
|
|
|
std::cout << "ListAt" << std::endl;
|
|
CheckSame(TestClass<2>{}, vtkm::ListAt<EvenList, 0>{});
|
|
CheckSame(TestClass<4>{}, vtkm::ListAt<EvenList, 1>{});
|
|
CheckSame(TestClass<6>{}, vtkm::ListAt<EvenList, 2>{});
|
|
CheckSame(TestClass<8>{}, vtkm::ListAt<EvenList, 3>{});
|
|
|
|
std::cout << "ListIndexOf" << std::endl;
|
|
VTKM_TEST_ASSERT(vtkm::ListIndexOf<EvenList, TestClass<2>>::value == 0);
|
|
VTKM_TEST_ASSERT(vtkm::ListIndexOf<EvenList, TestClass<4>>::value == 1);
|
|
VTKM_TEST_ASSERT(vtkm::ListIndexOf<EvenList, TestClass<6>>::value == 2);
|
|
VTKM_TEST_ASSERT(vtkm::ListIndexOf<EvenList, TestClass<8>>::value == 3);
|
|
VTKM_TEST_ASSERT(vtkm::ListIndexOf<EvenList, TestClass<1>>::value == -1);
|
|
|
|
VTKM_TEST_ASSERT(vtkm::ListIndexOf<LongList, TestClass<1>>::value == 0);
|
|
VTKM_TEST_ASSERT(vtkm::ListIndexOf<LongList, TestClass<2>>::value == 1);
|
|
VTKM_TEST_ASSERT(vtkm::ListIndexOf<LongList, TestClass<3>>::value == 2);
|
|
VTKM_TEST_ASSERT(vtkm::ListIndexOf<LongList, TestClass<4>>::value == 3);
|
|
VTKM_TEST_ASSERT(vtkm::ListIndexOf<LongList, TestClass<5>>::value == 4);
|
|
VTKM_TEST_ASSERT(vtkm::ListIndexOf<LongList, TestClass<6>>::value == 5);
|
|
VTKM_TEST_ASSERT(vtkm::ListIndexOf<LongList, TestClass<7>>::value == 6);
|
|
VTKM_TEST_ASSERT(vtkm::ListIndexOf<LongList, TestClass<8>>::value == 7);
|
|
VTKM_TEST_ASSERT(vtkm::ListIndexOf<LongList, TestClass<9>>::value == 8);
|
|
VTKM_TEST_ASSERT(vtkm::ListIndexOf<LongList, TestClass<10>>::value == 9);
|
|
VTKM_TEST_ASSERT(vtkm::ListIndexOf<LongList, TestClass<11>>::value == 10);
|
|
VTKM_TEST_ASSERT(vtkm::ListIndexOf<LongList, TestClass<12>>::value == 11);
|
|
VTKM_TEST_ASSERT(vtkm::ListIndexOf<LongList, TestClass<13>>::value == 12);
|
|
VTKM_TEST_ASSERT(vtkm::ListIndexOf<LongList, TestClass<14>>::value == 13);
|
|
VTKM_TEST_ASSERT(vtkm::ListIndexOf<LongList, TestClass<15>>::value == -1);
|
|
VTKM_TEST_ASSERT(vtkm::ListIndexOf<LongList, TestClass<0>>::value == -1);
|
|
|
|
VTKM_TEST_ASSERT(vtkm::ListIndexOf<RepeatList, TestClass<0>>::value == -1);
|
|
VTKM_TEST_ASSERT(vtkm::ListIndexOf<RepeatList, TestClass<1>>::value == 0);
|
|
VTKM_TEST_ASSERT(vtkm::ListIndexOf<RepeatList, TestClass<14>>::value == 13);
|
|
|
|
std::cout << "ListHas" << std::endl;
|
|
VTKM_TEST_ASSERT(vtkm::ListHas<EvenList, TestClass<2>>::value);
|
|
VTKM_TEST_ASSERT(vtkm::ListHas<EvenList, TestClass<4>>::value);
|
|
VTKM_TEST_ASSERT(vtkm::ListHas<EvenList, TestClass<6>>::value);
|
|
VTKM_TEST_ASSERT(vtkm::ListHas<EvenList, TestClass<8>>::value);
|
|
VTKM_TEST_ASSERT(!vtkm::ListHas<EvenList, TestClass<1>>::value);
|
|
|
|
VTKM_TEST_ASSERT(vtkm::ListHas<LongList, TestClass<1>>::value);
|
|
VTKM_TEST_ASSERT(vtkm::ListHas<LongList, TestClass<2>>::value);
|
|
VTKM_TEST_ASSERT(vtkm::ListHas<LongList, TestClass<3>>::value);
|
|
VTKM_TEST_ASSERT(vtkm::ListHas<LongList, TestClass<4>>::value);
|
|
VTKM_TEST_ASSERT(vtkm::ListHas<LongList, TestClass<5>>::value);
|
|
VTKM_TEST_ASSERT(vtkm::ListHas<LongList, TestClass<6>>::value);
|
|
VTKM_TEST_ASSERT(vtkm::ListHas<LongList, TestClass<7>>::value);
|
|
VTKM_TEST_ASSERT(vtkm::ListHas<LongList, TestClass<7>>::value);
|
|
VTKM_TEST_ASSERT(vtkm::ListHas<LongList, TestClass<8>>::value);
|
|
VTKM_TEST_ASSERT(vtkm::ListHas<LongList, TestClass<9>>::value);
|
|
VTKM_TEST_ASSERT(vtkm::ListHas<LongList, TestClass<10>>::value);
|
|
VTKM_TEST_ASSERT(vtkm::ListHas<LongList, TestClass<11>>::value);
|
|
VTKM_TEST_ASSERT(vtkm::ListHas<LongList, TestClass<12>>::value);
|
|
VTKM_TEST_ASSERT(vtkm::ListHas<LongList, TestClass<13>>::value);
|
|
VTKM_TEST_ASSERT(vtkm::ListHas<LongList, TestClass<14>>::value);
|
|
VTKM_TEST_ASSERT(!vtkm::ListHas<LongList, TestClass<15>>::value);
|
|
VTKM_TEST_ASSERT(!vtkm::ListHas<LongList, TestClass<0>>::value);
|
|
|
|
VTKM_TEST_ASSERT(!vtkm::ListHas<RepeatList, TestClass<0>>::value);
|
|
VTKM_TEST_ASSERT(vtkm::ListHas<RepeatList, TestClass<1>>::value);
|
|
VTKM_TEST_ASSERT(vtkm::ListHas<RepeatList, TestClass<14>>::value);
|
|
|
|
std::cout << "ListReduce" << std::endl;
|
|
using Zero = std::integral_constant<int, 0>;
|
|
VTKM_TEST_ASSERT((vtkm::ListReduce<SimpleCount, AddOperator, Zero>::value == 10));
|
|
VTKM_TEST_ASSERT((vtkm::ListReduce<EvenList, AddOperator, Zero>::value == 20));
|
|
VTKM_TEST_ASSERT((vtkm::ListReduce<LongList, AddOperator, Zero>::value == 105));
|
|
VTKM_TEST_ASSERT((vtkm::ListReduce<RepeatList, AddOperator, Zero>::value == 27));
|
|
|
|
std::cout << "ListAll" << std::endl;
|
|
VTKM_TEST_ASSERT(
|
|
(vtkm::ListAll<vtkm::ListTransform<SimpleCount, EvenPredicate>>::value == false));
|
|
VTKM_TEST_ASSERT((vtkm::ListAll<vtkm::ListTransform<EvenList, EvenPredicate>>::value == true));
|
|
VTKM_TEST_ASSERT((vtkm::ListAll<vtkm::ListTransform<LongList, EvenPredicate>>::value == false));
|
|
VTKM_TEST_ASSERT((vtkm::ListAll<vtkm::List<>>::value == true));
|
|
VTKM_TEST_ASSERT((vtkm::ListAll<SimpleCount, EvenPredicate>::value == false));
|
|
VTKM_TEST_ASSERT((vtkm::ListAll<EvenList, EvenPredicate>::value == true));
|
|
VTKM_TEST_ASSERT((vtkm::ListAll<LongList, EvenPredicate>::value == false));
|
|
VTKM_TEST_ASSERT((vtkm::ListAll<vtkm::List<>, EvenPredicate>::value == true));
|
|
|
|
std::cout << "ListAny" << std::endl;
|
|
VTKM_TEST_ASSERT((vtkm::ListAny<vtkm::ListTransform<SimpleCount, EvenPredicate>>::value == true));
|
|
VTKM_TEST_ASSERT((vtkm::ListAny<vtkm::ListTransform<EvenList, EvenPredicate>>::value == true));
|
|
VTKM_TEST_ASSERT((vtkm::ListAny<vtkm::ListTransform<EvenList, OddPredicate>>::value == false));
|
|
VTKM_TEST_ASSERT((vtkm::ListAny<vtkm::ListTransform<LongList, EvenPredicate>>::value == true));
|
|
VTKM_TEST_ASSERT((vtkm::ListAny<vtkm::List<>>::value == false));
|
|
VTKM_TEST_ASSERT((vtkm::ListAny<SimpleCount, EvenPredicate>::value == true));
|
|
VTKM_TEST_ASSERT((vtkm::ListAny<EvenList, EvenPredicate>::value == true));
|
|
VTKM_TEST_ASSERT((vtkm::ListAny<EvenList, OddPredicate>::value == false));
|
|
VTKM_TEST_ASSERT((vtkm::ListAny<LongList, EvenPredicate>::value == true));
|
|
VTKM_TEST_ASSERT((vtkm::ListAny<vtkm::List<>, EvenPredicate>::value == false));
|
|
}
|
|
|
|
} // anonymous namespace
|
|
|
|
int UnitTestList(int argc, char* argv[])
|
|
{
|
|
return vtkm::testing::Testing::Run(TestLists, argc, argv);
|
|
}
|