2014-03-31 21:28:09 +00:00
|
|
|
//============================================================================
|
|
|
|
// Copyright (c) Kitware, Inc.
|
|
|
|
// All rights reserved.
|
|
|
|
// See LICENSE.txt for details.
|
2019-04-15 23:24:21 +00:00
|
|
|
//
|
2014-03-31 21:28:09 +00:00
|
|
|
// 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
|
|
|
|
|
2014-10-08 18:53:01 +00:00
|
|
|
#include <vtkm/internal/ListTagDetail.h>
|
|
|
|
|
2015-09-17 19:45:35 +00:00
|
|
|
#include <vtkm/StaticAssert.h>
|
2014-03-31 21:28:09 +00:00
|
|
|
#include <vtkm/internal/ExportMacros.h>
|
|
|
|
|
2016-08-29 15:13:00 +00:00
|
|
|
#include <type_traits>
|
2014-10-22 13:24:04 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
namespace vtkm
|
|
|
|
{
|
2014-03-31 21:28:09 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
namespace internal
|
|
|
|
{
|
2014-10-22 13:24:04 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename ListTag>
|
|
|
|
struct ListTagCheck : std::is_base_of<vtkm::detail::ListRoot, ListTag>
|
2014-10-22 13:24:04 +00:00
|
|
|
{
|
2018-02-22 16:34:08 +00:00
|
|
|
static constexpr bool Valid = std::is_base_of<vtkm::detail::ListRoot, ListTag>::value;
|
2014-10-22 13:24:04 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
} // 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.)
|
|
|
|
///
|
2017-05-18 14:29:41 +00:00
|
|
|
#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.")
|
2014-10-22 16:35:56 +00:00
|
|
|
|
2016-12-30 20:42:18 +00:00
|
|
|
/// A special tag for a list that represents holding all potential values
|
|
|
|
///
|
|
|
|
/// Note: Can not be used with ForEach for obvious reasons.
|
2017-05-18 14:29:41 +00:00
|
|
|
struct ListTagUniversal : detail::ListRoot
|
|
|
|
{
|
2016-12-30 20:42:18 +00:00
|
|
|
using list = vtkm::detail::ListBase<vtkm::detail::UniversalTag>;
|
|
|
|
};
|
|
|
|
|
2014-05-14 21:05:38 +00:00
|
|
|
/// A special tag for an empty list.
|
|
|
|
///
|
2017-05-18 14:29:41 +00:00
|
|
|
struct ListTagEmpty : detail::ListRoot
|
|
|
|
{
|
2016-03-03 20:58:09 +00:00
|
|
|
using list = vtkm::detail::ListBase<>;
|
2014-03-31 21:28:09 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/// A tag that is a construction of two other tags joined together. This struct
|
|
|
|
/// can be subclassed and still behave like a list tag.
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename ListTag1, typename ListTag2>
|
|
|
|
struct ListTagJoin : detail::ListRoot
|
|
|
|
{
|
|
|
|
using list = typename detail::ListJoin<typename ListTag1::list, typename ListTag2::list>::type;
|
2014-03-31 21:28:09 +00:00
|
|
|
};
|
|
|
|
|
2018-06-21 17:35:57 +00:00
|
|
|
|
|
|
|
/// A tag that is constructed by appending \c Type to \c ListTag.
|
|
|
|
template <typename ListTag, typename Type>
|
|
|
|
struct ListTagAppend : detail::ListRoot
|
|
|
|
{
|
|
|
|
using list = typename detail::ListJoin<typename ListTag::list, detail::ListBase<Type>>::type;
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Append \c Type to \c ListTag only if \c ListTag does not already contain \c Type.
|
2018-08-07 21:50:41 +00:00
|
|
|
/// No checks are performed to see if \c ListTag itself has only unique elements.
|
2018-06-21 17:35:57 +00:00
|
|
|
template <typename ListTag, typename Type>
|
|
|
|
struct ListTagAppendUnique : detail::ListRoot
|
|
|
|
{
|
|
|
|
using list = typename detail::ListAppendUniqueImpl<typename ListTag::list, Type>::type;
|
|
|
|
};
|
|
|
|
|
2017-11-06 15:12:49 +00:00
|
|
|
/// A tag that consists of elements that are found in both tags. This struct
|
2016-12-29 21:00:52 +00:00
|
|
|
/// can be subclassed and still behave like a list tag.
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename ListTag1, typename ListTag2>
|
|
|
|
struct ListTagIntersect : detail::ListRoot
|
|
|
|
{
|
|
|
|
using list =
|
|
|
|
typename detail::ListIntersect<typename ListTag1::list, typename ListTag2::list>::type;
|
2016-12-29 21:00:52 +00:00
|
|
|
};
|
|
|
|
|
2019-07-14 23:38:30 +00:00
|
|
|
/// \brief Determines the number of types in the given list.
|
|
|
|
///
|
|
|
|
/// There is a static member named \c value that is set to the length of the list.
|
|
|
|
///
|
|
|
|
template <typename ListTag>
|
|
|
|
struct ListSize
|
|
|
|
{
|
|
|
|
VTKM_IS_LIST_TAG(ListTag);
|
|
|
|
static constexpr vtkm::IdComponent value = detail::ListSizeImpl<typename ListTag::list>::value;
|
|
|
|
};
|
|
|
|
|
2014-03-31 21:28:09 +00:00
|
|
|
/// For each typename represented by the list tag, call the functor with a
|
|
|
|
/// default instance of that type.
|
|
|
|
///
|
vtkm::ListForEach can handle passing any number of extra arguments
Rather than requiring all the arguments to be placed as member variables to
the functor you can now pass extra arguments that will be added to the functor
call signature.
So for example:
vtkm::ForEach(functor, vtkm::TypeListTagCommon(), double{42.0}, int{42});
will be converted into:
functor(vtkm::Int32, double, int)
functor(vtkm::Int64, double, int)
functor(vtkm::Float32, double, int)
functor(vtkm::Float64, double, int)
...
2017-11-06 22:26:20 +00:00
|
|
|
template <typename Functor, typename ListTag, typename... Args>
|
|
|
|
VTKM_CONT void ListForEach(Functor&& f, ListTag, Args&&... args)
|
2014-03-31 21:28:09 +00:00
|
|
|
{
|
2014-10-22 16:35:56 +00:00
|
|
|
VTKM_IS_LIST_TAG(ListTag);
|
vtkm::ListForEach can handle passing any number of extra arguments
Rather than requiring all the arguments to be placed as member variables to
the functor you can now pass extra arguments that will be added to the functor
call signature.
So for example:
vtkm::ForEach(functor, vtkm::TypeListTagCommon(), double{42.0}, int{42});
will be converted into:
functor(vtkm::Int32, double, int)
functor(vtkm::Int64, double, int)
functor(vtkm::Float32, double, int)
functor(vtkm::Float64, double, int)
...
2017-11-06 22:26:20 +00:00
|
|
|
detail::ListForEachImpl(
|
|
|
|
std::forward<Functor>(f), typename ListTag::list{}, std::forward<Args>(args)...);
|
2014-03-31 21:28:09 +00:00
|
|
|
}
|
|
|
|
|
2017-11-06 15:12:49 +00:00
|
|
|
/// Generate a tag that is the cross product of two other tags. The resulting
|
2017-12-11 18:31:56 +00:00
|
|
|
// a tag has the form of Tag< brigand::list<A1,B1>, brigand::list<A1,B2> .... >
|
2017-11-06 15:12:49 +00:00
|
|
|
///
|
|
|
|
template <typename ListTag1, typename ListTag2>
|
|
|
|
struct ListCrossProduct : detail::ListRoot
|
|
|
|
{
|
|
|
|
using list =
|
|
|
|
typename detail::ListCrossProductImpl<typename ListTag1::list, typename ListTag2::list>::type;
|
|
|
|
};
|
|
|
|
|
2019-07-14 23:38:30 +00:00
|
|
|
/// \brief Checks to see if the given \c Type is in the list pointed to by \c ListTag.
|
|
|
|
///
|
2014-10-22 16:35:56 +00:00
|
|
|
/// There is a static boolean named \c value that is set to true if the type is
|
|
|
|
/// contained in the list and false otherwise.
|
|
|
|
///
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename ListTag, typename Type>
|
2014-10-22 16:35:56 +00:00
|
|
|
struct ListContains
|
|
|
|
{
|
|
|
|
VTKM_IS_LIST_TAG(ListTag);
|
2018-02-22 16:34:08 +00:00
|
|
|
static constexpr bool value = detail::ListContainsImpl<Type, typename ListTag::list>::value;
|
2014-10-22 16:35:56 +00:00
|
|
|
};
|
|
|
|
|
2019-07-14 23:38:30 +00:00
|
|
|
/// \brief Finds the type at the given index.
|
|
|
|
///
|
|
|
|
/// This struct contains subtype \c type that resolves to the type at the given index.
|
|
|
|
///
|
|
|
|
template <typename ListTag, vtkm::IdComponent Index>
|
|
|
|
struct ListTypeAt
|
|
|
|
{
|
|
|
|
VTKM_IS_LIST_TAG(ListTag);
|
|
|
|
using type =
|
|
|
|
brigand::at<typename ListTag::list, std::integral_constant<vtkm::IdComponent, Index>>;
|
|
|
|
};
|
|
|
|
|
|
|
|
/// \brief Finds the index of the given type.
|
|
|
|
///
|
|
|
|
/// There is a static member named \c value that is set to the index of the given type. If the
|
|
|
|
/// given type is not in the list, the value is set to -1.
|
|
|
|
///
|
|
|
|
template <typename ListTag, typename Type>
|
|
|
|
struct ListIndexOf
|
|
|
|
{
|
|
|
|
VTKM_IS_LIST_TAG(ListTag);
|
|
|
|
static constexpr vtkm::IdComponent value =
|
|
|
|
detail::ListIndexOfImpl<Type, typename ListTag::list, 0>::value;
|
|
|
|
};
|
|
|
|
|
2014-03-31 21:28:09 +00:00
|
|
|
} // namespace vtkm
|
|
|
|
|
|
|
|
#endif //vtk_m_ListTag_h
|