From 70f6220fa32b693be76feecabafe4e5b9a679762 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Wed, 4 Dec 2019 07:30:47 -0700 Subject: [PATCH] Add vtkm::List `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. --- vtkm/CMakeLists.txt | 1 + vtkm/List.h | 422 ++++++++++++++++++++++++++++++++++ vtkm/ListTag.h | 73 +++--- vtkm/internal/ListTagDetail.h | 24 -- vtkm/testing/CMakeLists.txt | 1 + vtkm/testing/Testing.h | 29 +++ vtkm/testing/UnitTestList.cxx | 257 +++++++++++++++++++++ 7 files changed, 738 insertions(+), 69 deletions(-) create mode 100644 vtkm/List.h create mode 100644 vtkm/testing/UnitTestList.cxx diff --git a/vtkm/CMakeLists.txt b/vtkm/CMakeLists.txt index 22986574e..2155d0c33 100644 --- a/vtkm/CMakeLists.txt +++ b/vtkm/CMakeLists.txt @@ -30,6 +30,7 @@ set(headers Geometry.h Hash.h ImplicitFunction.h + List.h ListTag.h Math.h Matrix.h diff --git a/vtkm/List.h b/vtkm/List.h new file mode 100644 index 000000000..7b398591b --- /dev/null +++ b/vtkm/List.h @@ -0,0 +1,422 @@ +//============================================================================ +// 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. +//============================================================================ +#ifndef vtk_m_List_h +#define vtk_m_List_h + +#include + +#include + +namespace vtkm +{ + +template +struct List +{ +}; + +namespace internal +{ + +template +struct IsListImpl +{ + using type = std::false_type; +}; + +template +struct IsListImpl> +{ + using type = std::true_type; +}; + +template +using IsList = typename vtkm::internal::IsListImpl::type; + +} // namespace internal + +/// Checks that the argument is a proper list. This is a handy concept +/// check for functions and classes to make sure that a template argument is +/// actually a device adapter tag. (You can get weird errors elsewhere in the +/// code when a mistake is made.) +/// +#define VTKM_IS_LIST(type) \ + VTKM_STATIC_ASSERT_MSG((::vtkm::internal::IsList::value), \ + "Provided type is not a valid VTK-m list type.") + +namespace detail +{ + +/// list value that is used to represent a list actually matches all values +struct UniversalTypeTag +{ + //We never want this tag constructed, and by deleting the constructor + //we get an error when trying to use this class with ForEach. + UniversalTypeTag() = delete; +}; + +} // namespace detail + +namespace internal +{ + +// This is here so that the old (deprecated) `ListTag`s can convert themselves to the new +// `List` style and be operated on. When that deprecated functionality goes away, we can +// probably remove `AsList` and just operate directly on the `List`s. +template +struct AsListImpl; + +template +struct AsListImpl> +{ + using type = vtkm::List; +}; + +template +using AsList = typename AsListImpl::type; +} + +/// A special tag for an empty list. +/// +using ListEmpty = vtkm::List<>; + +/// A special tag for a list that represents holding all potential values +/// +/// Note: Can not be used with ForEach and some list transforms for obvious reasons. +using ListUniversal = vtkm::List; + +namespace detail +{ + +template class Target> +struct ListApplyImpl; +template class Target> +struct ListApplyImpl, Target> +{ + using type = Target; +}; +// Cannot apply the universal list. +template