//============================================================================ // 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_ListTag_h #define vtk_m_ListTag_h #include #include #include #include #include #include namespace vtkm { namespace detail { //----------------------------------------------------------------------------- /// Base class that all ListTag classes inherit from. Helps identify lists /// in macros like VTKM_IS_LIST_TAG. /// struct ListRoot { }; template using ListBase = brigand::list; /// list value that is used to represent a list actually matches all values struct UniversalTag { //We never want this tag constructed, and by deleting the constructor //we get an error when trying to use this class with ForEach. UniversalTag() = delete; }; } // namespace detail //----------------------------------------------------------------------------- /// A basic tag for a list of typenames. This struct can be subclassed /// and still behave like a list tag. /// @cond NONE template struct VTKM_DEPRECATED(1.6, "ListTagBase replace by List. Note that List cannot be subclassed.") ListTagBase : detail::ListRoot { using list = detail::ListBase; }; /// @endcond /// A special tag for a list that represents holding all potential values /// /// Note: Can not be used with ForEach for obvious reasons. /// @cond NONE struct VTKM_DEPRECATED( 1.6, "ListTagUniversal replaced by ListUniversal. Note that ListUniversal cannot be subclassed.") ListTagUniversal : detail::ListRoot { using list = vtkm::detail::ListBase; }; /// @endcond namespace internal { /// @cond NONE template struct ListTagCheck : std::is_base_of { static constexpr bool Valid = std::is_base_of::value; }; /// @endcond } // namespace internal namespace detail { /// @cond NONE template struct VTKM_DEPRECATED(1.6, "VTKM_IS_LIST_TAG replaced with VTKM_IS_LIST.") ListTagAssert : internal::IsList { }; /// @endcond } // namespace detal /// Checks that the argument is a proper list tag. 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_TAG(tag) \ VTKM_STATIC_ASSERT_MSG((::vtkm::detail::ListTagAssert::value), \ "Provided type is not a valid VTK-m list tag.") namespace internal { namespace detail { /// @cond NONE template struct ListTagAsBrigandListImpl { VTKM_DEPRECATED_SUPPRESS_BEGIN VTKM_IS_LIST_TAG(ListTag); using type = typename ListTag::list; VTKM_DEPRECATED_SUPPRESS_END }; /// @endcond } // namespace detail /// Converts a ListTag to a brigand::list. /// template using ListTagAsBrigandList = typename detail::ListTagAsBrigandListImpl::type; VTKM_DEPRECATED_SUPPRESS_BEGIN namespace detail { // Could use ListApply instead, but that causes deprecation warnings. template struct ListAsListTagImpl; template struct ListAsListTagImpl> { using type = vtkm::ListTagBase; }; } // namespace detail template using ListAsListTag = typename detail::ListAsListTagImpl::type; VTKM_DEPRECATED_SUPPRESS_END // This allows the new `List` operations work on `ListTag`s. template struct AsListImpl { VTKM_STATIC_ASSERT_MSG(ListTagCheck::value, "Attempted to use something that is not a List with a List operation."); VTKM_DEPRECATED_SUPPRESS_BEGIN using type = typename std::conditional::value, vtkm::ListUniversal, brigand::wrap, vtkm::List>>::type; VTKM_DEPRECATED_SUPPRESS_END }; } // namespace internal namespace detail { template class Target> struct ListTagApplyImpl; template class Target> struct ListTagApplyImpl, Target> { using type = Target; }; } // namespace detail /// \brief Applies the list of types to a template. /// /// Given a ListTag and a templated class, returns the class instantiated with the types /// represented by the ListTag. /// template class Target> using ListTagApply VTKM_DEPRECATED(1.6, "ListTagApply replaced by ListApply.") = typename detail::ListTagApplyImpl, Target>::type; /// A special tag for an empty list. /// /// @cond NONE struct VTKM_DEPRECATED( 1.6, "ListTagEmpty replaced by ListEmpty. Note that ListEmpty cannot be subclassed.") ListTagEmpty : detail::ListRoot { using list = vtkm::detail::ListBase<>; }; /// @endcond /// A tag that is a construction of two other tags joined together. This struct /// can be subclassed and still behave like a list tag. /// @cond NONE template struct VTKM_DEPRECATED( 1.6, "ListTagJoin replaced by ListAppend. Note that ListAppend cannot be subclassed.") ListTagJoin : vtkm::internal::ListAsListTag> { }; /// @endcond /// A tag that is constructed by appending \c Type to \c ListTag. /// @cond NONE template struct VTKM_DEPRECATED(1.6, "ListTagAppend replaced by ListAppend. " "Note that ListAppend cannot be subclassed.") ListTagAppend : vtkm::internal::ListAsListTag>> { }; /// @endcond /// Append \c Type to \c ListTag only if \c ListTag does not already contain \c Type. /// No checks are performed to see if \c ListTag itself has only unique elements. /// @cond NONE template struct VTKM_DEPRECATED(1.6) ListTagAppendUnique : std::conditional< vtkm::ListHas::value, vtkm::internal::ListAsListTag>, vtkm::internal::ListAsListTag>>>::type { }; /// @endcond /// A tag that consists of elements that are found in both tags. This struct /// can be subclassed and still behave like a list tag. /// @cond NONE template struct VTKM_DEPRECATED( 1.6, "ListTagIntersect replaced by ListIntersect. Note that ListIntersect cannot be subclassed.") ListTagIntersect : vtkm::internal::ListAsListTag> { }; /// @endcond /// A list tag that consists of each item in another list tag fed into a template that takes /// a single parameter. /// @cond NONE template class Transform> struct VTKM_DEPRECATED( 1.6, "ListTagTransform replaced by ListTransform. Note that ListTransform cannot be subclassed.") ListTagTransform : vtkm::internal::ListAsListTag> { }; /// @endcond /// A list tag that takes an existing ListTag and a predicate template that is applied to /// each type in the ListTag. Any type in the ListTag that has a value element equal to true /// (the equivalent of std::true_type), that item will be removed from the list. For example /// the following type /// /// ```cpp /// vtkm::ListTagRemoveIf, std::is_integral> /// ``` /// /// resolves to a ListTag that is equivalent to `vtkm::ListTag` because /// `std::is_integral` and `std::is_integral` resolve to `std::true_type` /// whereas `std::is_integral` and `std::is_integral` resolve to /// `std::false_type`. /// @cond NONE template class Predicate> struct VTKM_DEPRECATED( 1.6, "ListTagRemoveIf replaced by ListRemoveIf. Note that ListRemoveIf cannot be subclassed.") ListTagRemoveIf : vtkm::internal::ListAsListTag> { }; /// @endcond namespace detail { // Old stlye ListCrossProduct expects brigand::list instead of vtkm::List. Transform back template using ListToBrigand = vtkm::ListApply; } // namespace detail /// Generate a tag that is the cross product of two other tags. The resulting /// tag has the form of Tag< brigand::list, brigand::list .... > /// /// @cond NONE template struct VTKM_DEPRECATED( 1.6, "ListCrossProduct replaced by ListCross. Note that LIstCross cannot be subclassed.") ListCrossProduct : vtkm::internal::ListAsListTag< vtkm::ListTransform, detail::ListToBrigand>> { }; /// @endcond /// \brief Checks to see if the given \c Type is in the list pointed to by \c ListTag. /// /// There is a static boolean named \c value that is set to true if the type is /// contained in the list and false otherwise. /// /// @cond NONE template struct VTKM_DEPRECATED(1.6, "ListContains replaced by ListHas.") ListContains : vtkm::ListHas { }; /// @endcond /// \brief Finds the type at the given index. /// /// This struct contains subtype \c type that resolves to the type at the given index. /// template struct VTKM_DEPRECATED(1.6, "ListTypeAt::type replaced by ListAt.") ListTypeAt { VTKM_DEPRECATED_SUPPRESS_BEGIN VTKM_IS_LIST_TAG(ListTag); VTKM_DEPRECATED_SUPPRESS_END using type = brigand::at, std::integral_constant>; }; } // namespace vtkm #endif //vtk_m_ListTag_h