//============================================================================ // 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 #include namespace vtkm { // We are currently limiting the size of a `vtkm::List`. Generally, a compiler will // happily create a list of any size. However, to make sure the compiler does not go // into an infinite loop, you can only iterate on a list so far. As such, it is safer // to limit the size of the lists. #define VTKM_CHECK_LIST_SIZE(size) \ static_assert((size) <= 512, \ "A vtkm::List with more than 512 elements is not supported." \ " A list this long is problematic for compilers." \ " Compilers often have a recursive template instantiation limit of around 1024," \ " so operations on lists this large can lead to confusing and misleading errors.") /// @brief A template used to hold a list of types. /// /// `List` is an empty `struct` that is used to hold a list of types as its template /// arguments. VTK-m provides templated types that allows a `List` to be /// manipulated and used in numerous ways. template struct List { VTKM_CHECK_LIST_SIZE(sizeof...(Ts)); }; 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 /// @brief A convenience type for an empty list. /// using ListEmpty = vtkm::List<>; /// @brief A special type for a list that represents holding all potential values /// /// Note: This list cannot be used with `ForEach` and some list transforms /// for obvious reasons. using ListUniversal = vtkm::List; namespace detail { template struct ListSizeImpl; template struct ListSizeImpl> { using type = std::integral_constant(sizeof...(Ts))>; }; } // namespace detail /// Becomes an std::integral_constant containing the number of types in a list. /// template using ListSize = typename detail::ListSizeImpl::type; namespace detail { template class Target> struct ListApplyImpl; template class Target> struct ListApplyImpl, Target> { using type = Target; }; // Cannot apply the universal list. template