ListTag.h 4.07 KB
Newer Older
1 2 3 4 5 6 7 8
//============================================================================
//  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.
//
Kenneth Moreland's avatar
Kenneth Moreland committed
9
//  Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
10
//  Copyright 2014 UT-Battelle, LLC.
11
//  Copyright 2014 Los Alamos National Security.
12
//
Kenneth Moreland's avatar
Kenneth Moreland committed
13
//  Under the terms of Contract DE-NA0003525 with NTESS,
14 15 16 17 18 19 20 21 22
//  the U.S. Government retains certain rights in this software.
//
//  Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
//  Laboratory (LANL), the U.S. Government retains certain rights in
//  this software.
//============================================================================
#ifndef vtk_m_ListTag_h
#define vtk_m_ListTag_h

Kenneth Moreland's avatar
Kenneth Moreland committed
23 24
#include <vtkm/internal/ListTagDetail.h>

25
#include <vtkm/StaticAssert.h>
26 27
#include <vtkm/internal/ExportMacros.h>

28
#include <type_traits>
Kenneth Moreland's avatar
Kenneth Moreland committed
29

30 31
namespace vtkm
{
32

33 34
namespace internal
{
Kenneth Moreland's avatar
Kenneth Moreland committed
35

36 37
template <typename ListTag>
struct ListTagCheck : std::is_base_of<vtkm::detail::ListRoot, ListTag>
Kenneth Moreland's avatar
Kenneth Moreland committed
38
{
39
  static constexpr bool Valid = std::is_base_of<vtkm::detail::ListRoot, ListTag>::value;
Kenneth Moreland's avatar
Kenneth Moreland committed
40 41 42 43 44 45 46 47 48
};

} // namespace internal

/// 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.)
///
49 50 51
#define VTKM_IS_LIST_TAG(tag)                                                                      \
  VTKM_STATIC_ASSERT_MSG((::vtkm::internal::ListTagCheck<tag>::value),                             \
                         "Provided type is not a valid VTK-m list tag.")
52

53 54 55
/// A special tag for a list that represents holding all potential values
///
/// Note: Can not be used with ForEach for obvious reasons.
56 57
struct ListTagUniversal : detail::ListRoot
{
58 59 60
  using list = vtkm::detail::ListBase<vtkm::detail::UniversalTag>;
};

61 62
/// A special tag for an empty list.
///
63 64
struct ListTagEmpty : detail::ListRoot
{
65
  using list = vtkm::detail::ListBase<>;
66 67 68 69
};

/// A tag that is a construction of two other tags joined together. This struct
/// can be subclassed and still behave like a list tag.
70 71 72 73
template <typename ListTag1, typename ListTag2>
struct ListTagJoin : detail::ListRoot
{
  using list = typename detail::ListJoin<typename ListTag1::list, typename ListTag2::list>::type;
74 75
};

76
/// A tag that consists of elements that are found in both tags. This struct
77
/// can be subclassed and still behave like a list tag.
78 79 80 81 82
template <typename ListTag1, typename ListTag2>
struct ListTagIntersect : detail::ListRoot
{
  using list =
    typename detail::ListIntersect<typename ListTag1::list, typename ListTag2::list>::type;
83 84
};

85 86 87
/// For each typename represented by the list tag, call the functor with a
/// default instance of that type.
///
88 89
template <typename Functor, typename ListTag, typename... Args>
VTKM_CONT void ListForEach(Functor&& f, ListTag, Args&&... args)
90
{
91
  VTKM_IS_LIST_TAG(ListTag);
92 93
  detail::ListForEachImpl(
    std::forward<Functor>(f), typename ListTag::list{}, std::forward<Args>(args)...);
94 95
}

96
/// Generate a tag that is the cross product of two other tags. The resulting
97
// a tag has the form of Tag< brigand::list<A1,B1>, brigand::list<A1,B2> .... >
98 99 100 101 102 103 104 105
///
template <typename ListTag1, typename ListTag2>
struct ListCrossProduct : detail::ListRoot
{
  using list =
    typename detail::ListCrossProductImpl<typename ListTag1::list, typename ListTag2::list>::type;
};

106 107 108 109
/// 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.
///
110
template <typename ListTag, typename Type>
111 112 113
struct ListContains
{
  VTKM_IS_LIST_TAG(ListTag);
114
  static constexpr bool value = detail::ListContainsImpl<Type, typename ListTag::list>::value;
115 116
};

117 118 119
} // namespace vtkm

#endif //vtk_m_ListTag_h