70f6220fa3
`vtkm::List` is meant to replace `vtkm::ListTag`. Rather than subclassing a base class with a variadic template, all lists expose the list of types. `vtkm::ListTag` was originally created before we required C++11 so supporting variadic templates was problematic. To hide the issue we had, we made list tags subclass other lists rather than be the list themselves. It makes for nicer types in the compiler, but hides important details about what is actually in the type. It also creates lots of unnecessary new types. The new `vtkm::List` is in some ways simpler. All lists have to be a `vtkm::List`. Subclasses are not supported (or rather, they will not work as expected). All manipulations (such as `vtkm::ListAppend`) resolve directly back to a `vtkm::List`. Although the types reported by the compiler will be longer, they will be more specific to the types being used. Also, the new implimentation should ultimately use fewer types.
258 lines
9.3 KiB
C++
258 lines
9.3 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
|
|
{
|
|
};
|
|
|
|
} // 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 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>>;
|
|
|
|
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 << "ListTagEmpty" << std::endl;
|
|
CheckList(vtkm::List<>{}, vtkm::ListEmpty{});
|
|
|
|
std::cout << "ListTagAppend" << 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 << "ListTagIntersect" << 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 << "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);
|
|
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<32>, TestClass<11>>,
|
|
vtkm::List<TestClass<33>, TestClass<11>>>{},
|
|
vtkm::ListCross<vtkm::List<TestClass<31>, TestClass<32>, TestClass<33>>,
|
|
vtkm::List<TestClass<11>>>{});
|
|
|
|
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);
|
|
|
|
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);
|
|
}
|
|
|
|
} // anonymous namespace
|
|
|
|
int UnitTestList(int argc, char* argv[])
|
|
{
|
|
return vtkm::testing::Testing::Run(TestLists, argc, argv);
|
|
}
|