Make Tuple class

Made a new vtkm::Tuple class to replace tao tuple.

This version of Tuple should hopefully compile faster. Having our own
implementation should also make it easier to port to new devices.
This commit is contained in:
Kenneth Moreland 2020-02-23 16:37:15 -07:00
parent d0d1f750c2
commit 56636afc7a
12 changed files with 5667 additions and 20 deletions

@ -47,6 +47,7 @@ set(headers
Swap.h Swap.h
TopologyElementTag.h TopologyElementTag.h
Transform3D.h Transform3D.h
Tuple.h
TypeList.h TypeList.h
TypeListTag.h TypeListTag.h
Types.h Types.h
@ -67,6 +68,7 @@ set(template_sources
) )
vtkm_pyexpander_generated_file(Math.h) vtkm_pyexpander_generated_file(Math.h)
vtkm_pyexpander_generated_file(Tuple.h)
vtkm_declare_headers( vtkm_declare_headers(
${headers} ${headers}

4904
vtkm/Tuple.h Normal file

File diff suppressed because it is too large Load Diff

504
vtkm/Tuple.h.in Normal file

@ -0,0 +1,504 @@
//============================================================================
// 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.
//============================================================================
$# This file uses the pyexpander macro processing utility to build the
$# FunctionInterface facilities that use a variable number of arguments.
$# Information, documentation, and downloads for pyexpander can be found at:
$#
$# http://pyexpander.sourceforge.net/
$#
$# To build the source code, execute the following (after installing
$# pyexpander, of course):
$#
$# expander.py VariantDetail.h.in > VariantDetail.h
$#
$# Ignore the following comment. It is meant for the generated file.
// **** DO NOT EDIT THIS FILE!!! ****
// This file is automatically generated by Tuple.h.in
#ifndef vtk_m_Tuple_h
#define vtk_m_Tuple_h
#include <vtkm/Types.h>
#include <vtkm/internal/DecayHelpers.h>
#include <vtkm/internal/IndexTag.h>
$py(max_expanded=20)\
$# Python commands used in template expansion.
$py(
def type_list(num_params, name='T'):
if num_params < 1:
return ''
result = '%s0' % name
for param in range(1, num_params):
result += ', %s%d' % (name, param)
return result
def typename_list(num_params, name='T'):
if num_params < 1:
return ''
result = 'typename %s0' % name
for param in range(1, num_params):
result += ', typename %s%d' % (name, param)
return result
def perfect_param_list(num_params, classname='A', argname='a'):
if num_params < 1:
return ''
result = '%s0&& %s0' % (classname, argname)
for param in range(1, num_params):
result += ', %s%d&& %s%d' % (classname, param, argname, param)
return result
)\
$#
$extend(type_list, typename_list, perfect_param_list)\
namespace vtkm
{
///@{
/// \brief VTK-m replacement for std::tuple
///
/// This function serves the same function as `std::tuple` and behaves similarly. However, this
/// version of `Tuple` works on devices that VTK-m supports. There are also some implementation
/// details that makes compiling faster for VTK-m use. We also provide some methods like `Apply`
/// and `ForEach` that are helpful for several VTK-m operations.
///
template <typename... Ts>
class Tuple;
/// \brief Get the size of a tuple.
///
/// Given a `vtkm::Tuple` type, because a `std::integral_constant` of the type.
///
template <typename TupleType>
using TupleSize = std::integral_constant<vtkm::IdComponent, TupleType::Size>;
/// \brief Compatible with `std::tuple_size` for `vtkm::Tuple`.
///
template <typename TupleType>
using tuple_size = std::integral_constant<std::size_t, static_cast<std::size_t>(TupleType::Size)>;
namespace detail
{
template <vtkm::IdComponent Index, typename TupleType>
struct TupleElementImpl
{
using type = decltype(TupleType::ElementTypeI(vtkm::internal::IndexTag<Index>{}));
};
} // namespace detail
/// \brief Becomes the type of the given index for the given `vtkm::Tuple`.
///
template <vtkm::IdComponent Index, typename TupleType>
using TupleElement = typename detail::TupleElementImpl<Index, TupleType>::type;
/// \brief Compatible with `std::tuple_element` for `vtkm::Tuple`.
///
template <std::size_t Index, typename TupleType>
struct tuple_element
{
using type = TupleElement<static_cast<vtkm::IdComponent>(Index), TupleType>;
};
/// \brief Compatible with `std::tuple_element_t` for `vtkm::Tuple`.
///
template <std::size_t Index, typename TupleType>
using tuple_element_t = typename tuple_element<Index, TupleType>::type;
///@{
/// \brief Retrieve the object from a `vtkm::Tuple` at the given index.
///
VTKM_SUPPRESS_EXEC_WARNINGS
template <vtkm::IdComponent Index, typename... Ts>
VTKM_EXEC_CONT auto Get(const vtkm::Tuple<Ts...>& tuple) -> decltype(tuple.template Get<Index>())
{
return tuple.template Get<Index>();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <vtkm::IdComponent Index, typename... Ts>
VTKM_EXEC_CONT auto Get(vtkm::Tuple<Ts...>& tuple) -> decltype(tuple.template Get<Index>())
{
return tuple.template Get<Index>();
}
///@}
///@{
/// \brief Compatible with `std::get` for `vtkm::Tuple`.
///
VTKM_SUPPRESS_EXEC_WARNINGS
template <std::size_t Index, typename... Ts>
VTKM_EXEC_CONT auto get(const vtkm::Tuple<Ts...>& tuple)
-> decltype(vtkm::Get<static_cast<vtkm::IdComponent>(Index)>(tuple))
{
return vtkm::Get<static_cast<vtkm::IdComponent>(Index)>(tuple);
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <std::size_t Index, typename... Ts>
VTKM_EXEC_CONT auto get(vtkm::Tuple<Ts...>& tuple)
-> decltype(vtkm::Get<static_cast<vtkm::IdComponent>(Index)>(tuple))
{
return vtkm::Get<static_cast<vtkm::IdComponent>(Index)>(tuple);
}
///@}
/// \brief Creates a new `vtkm::Tuple` with the given types.
///
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename... Ts>
VTKM_EXEC_CONT auto MakeTuple(Ts&&... args) -> vtkm::Tuple<typename std::decay<Ts>::type...>
{
return vtkm::Tuple<typename std::decay<Ts>::type...>(std::forward<Ts>(args)...);
}
/// \brief Compatible with `std::make_tuple` for `vtkm::Tuple`.
///
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename... Ts>
VTKM_EXEC_CONT auto make_tuple(Ts&&... args) -> decltype(vtkm::MakeTuple(std::forward<Ts>(args)...))
{
return vtkm::MakeTuple(std::forward<Ts>(args)...);
}
namespace detail
{
struct TupleTransformFunctor
{
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename Function, typename... Ts>
VTKM_EXEC_CONT auto operator()(Function&& f, Ts&&... args)
-> decltype(vtkm::MakeTuple(f(std::forward<Ts>(args))...))
{
return vtkm::MakeTuple(f(std::forward<Ts>(args))...);
}
};
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename TupleType, typename Function>
VTKM_EXEC_CONT auto TupleTransform(TupleType&& tuple, Function&& f)
-> decltype(tuple.Apply(TupleTransformFunctor{}, std::forward<Function>(f)))
{
return tuple.Apply(TupleTransformFunctor{}, std::forward<Function>(f));
}
struct TupleForEachFunctor
{
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename Function, typename... Ts>
VTKM_EXEC_CONT void operator()(Function&& f, Ts&&... args)
{
(void)std::initializer_list<bool>{ (f(std::forward<Ts>(args)), false)... };
}
};
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename TupleType, typename Function>
VTKM_EXEC_CONT auto TupleForEach(TupleType&& tuple, Function&& f)
-> decltype(tuple.Apply(TupleForEachFunctor{}, std::forward<Function>(f)))
{
return tuple.Apply(TupleForEachFunctor{}, std::forward<Function>(f));
}
} // namespace detail
template <>
class Tuple<>
{
public:
static constexpr vtkm::IdComponent Size = 0;
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename Function, typename... Args>
VTKM_EXEC_CONT auto Apply(Function&& f, Args&&... args)
-> decltype(f(std::forward<Args>(args)...))
{
return f(std::forward<Args>(args)...);
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename Function, typename... Args>
VTKM_EXEC_CONT auto Apply(Function&& f, Args&&... args) const
-> decltype(f(std::forward<Args>(args)...))
{
return f(std::forward<Args>(args)...);
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename Function>
VTKM_EXEC_CONT void ForEach(Function&&) const
{
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename Function>
VTKM_EXEC_CONT vtkm::Tuple<> Transform(Function&&) const
{
return vtkm::Tuple<>{};
}
};
// clang-format off
$for(num_params in range(1, max_expanded + 1))\
template<$typename_list(num_params)>
class Tuple<$type_list(num_params)>
{
$for(index in range(0, num_params))\
T$(index) Value$(index);
static T$(index) ElementTypeI(vtkm::internal::IndexTag<$(index)>);
VTKM_EXEC_CONT vtkm::internal::remove_cvref<T$(index)>& GetImpl(vtkm::internal::IndexTag<$(index)>)
{
return this->Value$(index);
}
VTKM_EXEC_CONT const vtkm::internal::remove_cvref<T$(index)>& GetImpl(vtkm::internal::IndexTag<$(index)>) const
{
return this->Value$(index);
}
$endfor\
// Invalid indices
template <vtkm::IdComponent Index>
static vtkm::internal::NullType ElementTypeI(vtkm::internal::IndexTag<Index>);
template <vtkm::IdComponent, typename>
friend struct detail::TupleElementImpl;
public:
static constexpr vtkm::IdComponent Size = $(num_params);
template <vtkm::IdComponent Index>
using ElementType = vtkm::TupleElement<Index, Tuple<$type_list(num_params)>>;
Tuple() = default;
Tuple(Tuple&&) = default;
Tuple(const Tuple&) = default;
~Tuple() = default;
Tuple& operator=(Tuple&&) = default;
Tuple& operator=(const Tuple&) = default;
VTKM_SUPPRESS_EXEC_WARNINGS
template <$typename_list(num_params, 'A')>
VTKM_EXEC_CONT Tuple($perfect_param_list(num_params, 'A', 'a'))
: Value0(std::forward<A0>(a0))
$for(index in range(1, num_params))\
, Value$(index)(std::forward<A$(index)>(a$(index)))
$endfor\
{
}
template <vtkm::IdComponent Index>
VTKM_EXEC_CONT auto Get() -> decltype(this->GetImpl(vtkm::internal::IndexTag<Index>{}))
{
return this->GetImpl(vtkm::internal::IndexTag<Index>{});
}
template <vtkm::IdComponent Index>
VTKM_EXEC_CONT auto Get() const -> decltype(this->GetImpl(vtkm::internal::IndexTag<Index>{}))
{
return this->GetImpl(vtkm::internal::IndexTag<Index>{});
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename Function, typename... Args>
VTKM_EXEC_CONT
auto Apply(Function&& f, Args&&... args)
-> decltype(f(std::forward<Args>(args)..., $type_list(num_params, "Value")))
{
return f(std::forward<Args>(args)..., $type_list(num_params, "Value"));
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename Function, typename... Args>
VTKM_EXEC_CONT
auto Apply(Function&& f, Args&&... args) const
-> decltype(f(std::forward<Args>(args)..., $type_list(num_params, "Value")))
{
return f(std::forward<Args>(args)..., $type_list(num_params, "Value"));
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename Function>
VTKM_EXEC_CONT void ForEach(Function&& f)
{
detail::TupleForEach(*this, std::forward<Function>(f));
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename Function>
VTKM_EXEC_CONT void ForEach(Function&& f) const
{
detail::TupleForEach(*this, std::forward<Function>(f));
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename Function>
VTKM_EXEC_CONT auto Transform(Function&& f)
-> decltype(detail::TupleTransform(*this, std::forward<Function>(f)))
{
return detail::TupleTransform(*this, std::forward<Function>(f));
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename Function>
VTKM_EXEC_CONT auto Transform(Function&& f) const
-> decltype(detail::TupleTransform(*this, std::forward<Function>(f)))
{
return detail::TupleTransform(*this, std::forward<Function>(f));
}
};
$endfor\
// Fallback case for tuples with > $(max_expanded) items.
template<$typename_list(max_expanded + 1), typename... Ts>
class Tuple<$type_list(max_expanded + 1), Ts...>
{
$for(index in range(0, max_expanded))\
T$(index) Value$(index);
static T$(index) ElementTypeI(vtkm::internal::IndexTag<$(index)>);
VTKM_EXEC_CONT vtkm::internal::remove_cvref<T$(index)>& GetImpl(vtkm::internal::IndexTag<$(index)>)
{
return this->Value$(index);
}
VTKM_EXEC_CONT const vtkm::internal::remove_cvref<T$(index)>& GetImpl(vtkm::internal::IndexTag<$(index)>) const
{
return this->Value$(index);
}
$endfor\
// Implement the "extra" objects in a sub-Tuple
using RemainingValuesType = vtkm::Tuple<T$(max_expanded), Ts...>;
RemainingValuesType RemainingValues;
template <vtkm::IdComponent Index>
static vtkm::TupleElement<Index - $(max_expanded), RemainingValuesType>
ElementTypeI(vtkm::internal::IndexTag<Index>);
template <typename vtkm::IdComponent Index>
VTKM_EXEC_CONT const vtkm::internal::remove_cvref<vtkm::TupleElement<Index - $(max_expanded), RemainingValuesType>>&
GetImpl(vtkm::internal::IndexTag<Index>) { return vtkm::Get<Index - $(max_expanded)>(this->RemainingValues); }
template <typename vtkm::IdComponent Index>
VTKM_EXEC_CONT const vtkm::internal::remove_cvref<vtkm::TupleElement<Index - $(max_expanded), RemainingValuesType>>&
GetImpl(vtkm::internal::IndexTag<Index>) const { return vtkm::Get<Index - $(max_expanded)>(this->RemainingValues); }
template <vtkm::IdComponent, typename>
friend struct detail::TupleElementImpl;
public:
static constexpr vtkm::IdComponent Size =
$(max_expanded + 1) + static_cast<vtkm::IdComponent>(sizeof...(Ts));
template <vtkm::IdComponent Index>
using ElementType = vtkm::TupleElement<Index, Tuple<$type_list(max_expanded + 1), Ts...>>;
Tuple() = default;
Tuple(Tuple&&) = default;
Tuple(const Tuple&) = default;
~Tuple() = default;
Tuple& operator=(Tuple&&) = default;
Tuple& operator=(const Tuple&) = default;
VTKM_SUPPRESS_EXEC_WARNINGS
template <$typename_list(max_expanded, 'A'), typename... As>
VTKM_EXEC_CONT Tuple($perfect_param_list(max_expanded, 'A', 'a'), As&&... remainingArgs)
: Value0(std::forward<A0>(a0))
$for(index in range(1, max_expanded))\
, Value$(index)(std::forward<A$(index)>(a$(index)))
$endfor\
, RemainingValues(std::forward<As>(remainingArgs)...)
{
}
template <vtkm::IdComponent Index>
VTKM_EXEC_CONT auto Get() -> decltype(this->GetImpl(vtkm::internal::IndexTag<Index>{}))
{
return this->GetImpl(vtkm::internal::IndexTag<Index>{});
}
template <vtkm::IdComponent Index>
VTKM_EXEC_CONT auto Get() const -> decltype(this->GetImpl(vtkm::internal::IndexTag<Index>{}))
{
return this->GetImpl(vtkm::internal::IndexTag<Index>{});
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename Function, typename... Args>
VTKM_EXEC_CONT
auto Apply(Function&& f, Args&&... args)
-> decltype(this->RemainingValues.Apply(std::forward<Function>(f),
std::forward<Args>(args)...,
$for(index in range(0, max_expanded - 1))\
this->Value$(index),
$endfor\
this->Value$(max_expanded - 1)))
{
return this->RemainingValues.Apply(std::forward<Function>(f),
std::forward<Args>(args)...,
$for(index in range(0, max_expanded - 1))\
this->Value$(index),
$endfor\
this->Value$(max_expanded - 1));
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename Function, typename... Args>
VTKM_EXEC_CONT
auto Apply(Function&& f, Args&&... args) const
-> decltype(this->RemainingValues.Apply(std::forward<Function>(f),
std::forward<Args>(args)...,
$for(index in range(0, max_expanded - 1))\
this->Value$(index),
$endfor\
this->Value$(max_expanded - 1)))
{
return this->RemainingValues.Apply(std::forward<Function>(f),
std::forward<Args>(args)...,
$for(index in range(0, max_expanded - 1))\
this->Value$(index),
$endfor\
this->Value$(max_expanded - 1));
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename Function>
VTKM_EXEC_CONT void ForEach(Function&& f)
{
detail::TupleForEach(*this, std::forward<Function>(f));
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename Function>
VTKM_EXEC_CONT void ForEach(Function&& f) const
{
detail::TupleForEach(*this, std::forward<Function>(f));
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename Function>
VTKM_EXEC_CONT auto Transform(Function&& f)
-> decltype(detail::TupleTransform(*this, std::forward<Function>(f)))
{
return detail::TupleTransform(*this, std::forward<Function>(f));
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename Function>
VTKM_EXEC_CONT auto Transform(Function&& f) const
-> decltype(detail::TupleTransform(*this, std::forward<Function>(f)))
{
return detail::TupleTransform(*this, std::forward<Function>(f));
}
};
///@}
// clang-format on
} // namespace vtkm
#endif //vtk_m_Tuple_h

@ -69,7 +69,7 @@ struct Invoker
typename std::enable_if<detail::scatter_or_mask<T>::value, int>::type* = nullptr> typename std::enable_if<detail::scatter_or_mask<T>::value, int>::type* = nullptr>
inline void operator()(Worklet&& worklet, T&& scatterOrMask, Args&&... args) const inline void operator()(Worklet&& worklet, T&& scatterOrMask, Args&&... args) const
{ {
using WorkletType = worklet::internal::remove_cvref<Worklet>; using WorkletType = vtkm::internal::remove_cvref<Worklet>;
using DispatcherType = typename WorkletType::template Dispatcher<WorkletType>; using DispatcherType = typename WorkletType::template Dispatcher<WorkletType>;
DispatcherType dispatcher(worklet, scatterOrMask); DispatcherType dispatcher(worklet, scatterOrMask);
@ -94,7 +94,7 @@ struct Invoker
U&& scatterOrMaskB, U&& scatterOrMaskB,
Args&&... args) const Args&&... args) const
{ {
using WorkletType = worklet::internal::remove_cvref<Worklet>; using WorkletType = vtkm::internal::remove_cvref<Worklet>;
using DispatcherType = typename WorkletType::template Dispatcher<WorkletType>; using DispatcherType = typename WorkletType::template Dispatcher<WorkletType>;
DispatcherType dispatcher(worklet, scatterOrMaskA, scatterOrMaskB); DispatcherType dispatcher(worklet, scatterOrMaskA, scatterOrMaskB);
@ -112,7 +112,7 @@ struct Invoker
typename std::enable_if<!detail::scatter_or_mask<T>::value, int>::type* = nullptr> typename std::enable_if<!detail::scatter_or_mask<T>::value, int>::type* = nullptr>
inline void operator()(Worklet&& worklet, T&& t, Args&&... args) const inline void operator()(Worklet&& worklet, T&& t, Args&&... args) const
{ {
using WorkletType = worklet::internal::remove_cvref<Worklet>; using WorkletType = vtkm::internal::remove_cvref<Worklet>;
using DispatcherType = typename WorkletType::template Dispatcher<WorkletType>; using DispatcherType = typename WorkletType::template Dispatcher<WorkletType>;
DispatcherType dispatcher(worklet); DispatcherType dispatcher(worklet);

@ -56,6 +56,7 @@ set(headers
ConfigureFor32.h ConfigureFor32.h
ConfigureFor64.h ConfigureFor64.h
ConnectivityStructuredInternals.h ConnectivityStructuredInternals.h
DecayHelpers.h
ExportMacros.h ExportMacros.h
FunctionInterface.h FunctionInterface.h
FunctionInterfaceDetailPost.h FunctionInterfaceDetailPost.h

@ -14,8 +14,6 @@
namespace vtkm namespace vtkm
{ {
namespace worklet
{
namespace internal namespace internal
{ {
@ -25,6 +23,5 @@ using remove_pointer_and_decay = typename std::remove_pointer<typename std::deca
template <typename T> template <typename T>
using remove_cvref = typename std::remove_cv<typename std::remove_reference<T>::type>::type; using remove_cvref = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
} }
} } // namespace vtkm::internal
}
#endif #endif

@ -37,6 +37,7 @@ set(unit_tests
UnitTestRange.cxx UnitTestRange.cxx
UnitTestTesting.cxx UnitTestTesting.cxx
UnitTestTransform3D.cxx UnitTestTransform3D.cxx
UnitTestTuple.cxx
UnitTestTypeList.cxx UnitTestTypeList.cxx
UnitTestTypeListTag.cxx UnitTestTypeListTag.cxx
UnitTestTypes.cxx UnitTestTypes.cxx

@ -0,0 +1,235 @@
//============================================================================
// 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.
//============================================================================
#include <vtkm/Tuple.h>
#include <vtkm/testing/Testing.h>
namespace
{
template <vtkm::IdComponent Index>
struct TypePlaceholder
{
vtkm::Id X;
TypePlaceholder(vtkm::Id x)
: X(x)
{
}
};
void Check2(TypePlaceholder<0> a0, TypePlaceholder<1> a1)
{
VTKM_TEST_ASSERT(a0.X == TestValue(0, vtkm::Id{}));
VTKM_TEST_ASSERT(a1.X == TestValue(1, vtkm::Id{}));
}
void Check22(TypePlaceholder<0> a0,
TypePlaceholder<1> a1,
TypePlaceholder<2> a2,
TypePlaceholder<3> a3,
TypePlaceholder<4> a4,
TypePlaceholder<5> a5,
TypePlaceholder<6> a6,
TypePlaceholder<7> a7,
TypePlaceholder<8> a8,
TypePlaceholder<9> a9,
TypePlaceholder<10> a10,
TypePlaceholder<11> a11,
TypePlaceholder<12> a12,
TypePlaceholder<13> a13,
TypePlaceholder<14> a14,
TypePlaceholder<15> a15,
TypePlaceholder<16> a16,
TypePlaceholder<17> a17,
TypePlaceholder<18> a18,
TypePlaceholder<19> a19,
TypePlaceholder<20> a20,
TypePlaceholder<21> a21)
{
VTKM_TEST_ASSERT(a0.X == TestValue(0, vtkm::Id{}));
VTKM_TEST_ASSERT(a1.X == TestValue(1, vtkm::Id{}));
VTKM_TEST_ASSERT(a2.X == TestValue(2, vtkm::Id{}));
VTKM_TEST_ASSERT(a3.X == TestValue(3, vtkm::Id{}));
VTKM_TEST_ASSERT(a4.X == TestValue(4, vtkm::Id{}));
VTKM_TEST_ASSERT(a5.X == TestValue(5, vtkm::Id{}));
VTKM_TEST_ASSERT(a6.X == TestValue(6, vtkm::Id{}));
VTKM_TEST_ASSERT(a7.X == TestValue(7, vtkm::Id{}));
VTKM_TEST_ASSERT(a8.X == TestValue(8, vtkm::Id{}));
VTKM_TEST_ASSERT(a9.X == TestValue(9, vtkm::Id{}));
VTKM_TEST_ASSERT(a10.X == TestValue(10, vtkm::Id{}));
VTKM_TEST_ASSERT(a11.X == TestValue(11, vtkm::Id{}));
VTKM_TEST_ASSERT(a12.X == TestValue(12, vtkm::Id{}));
VTKM_TEST_ASSERT(a13.X == TestValue(13, vtkm::Id{}));
VTKM_TEST_ASSERT(a14.X == TestValue(14, vtkm::Id{}));
VTKM_TEST_ASSERT(a15.X == TestValue(15, vtkm::Id{}));
VTKM_TEST_ASSERT(a16.X == TestValue(16, vtkm::Id{}));
VTKM_TEST_ASSERT(a17.X == TestValue(17, vtkm::Id{}));
VTKM_TEST_ASSERT(a18.X == TestValue(18, vtkm::Id{}));
VTKM_TEST_ASSERT(a19.X == TestValue(19, vtkm::Id{}));
VTKM_TEST_ASSERT(a20.X == TestValue(20, vtkm::Id{}));
VTKM_TEST_ASSERT(a21.X == TestValue(21, vtkm::Id{}));
}
struct CheckReturn
{
template <typename Function, typename... Ts>
vtkm::Id operator()(Function f, Ts... args)
{
f(args...);
return vtkm::Id(sizeof...(Ts));
}
};
struct CheckValues
{
vtkm::IdComponent NumChecked = 0;
template <vtkm::IdComponent Index>
void operator()(TypePlaceholder<Index> x)
{
VTKM_TEST_ASSERT(x.X == TestValue(Index, vtkm::Id{}));
this->NumChecked++;
}
};
struct TransformValues
{
vtkm::Id AddValue;
TransformValues(vtkm::Id addValue)
: AddValue(addValue)
{
}
template <vtkm::IdComponent Index>
vtkm::Id operator()(TypePlaceholder<Index> x) const
{
return x.X + this->AddValue;
}
};
void TestTuple2()
{
using TupleType = vtkm::Tuple<TypePlaceholder<0>, TypePlaceholder<1>>;
VTKM_STATIC_ASSERT(vtkm::TupleSize<TupleType>::value == 2);
VTKM_STATIC_ASSERT((std::is_same<TypePlaceholder<0>, vtkm::TupleElement<0, TupleType>>::value));
VTKM_STATIC_ASSERT((std::is_same<TypePlaceholder<1>, vtkm::TupleElement<1, TupleType>>::value));
TupleType tuple(TestValue(0, vtkm::Id()), TestValue(1, vtkm::Id()));
tuple.Apply(Check2);
vtkm::Id result = tuple.Apply(CheckReturn{}, Check2);
VTKM_TEST_ASSERT(result == 2);
CheckValues checkFunctor;
VTKM_TEST_ASSERT(checkFunctor.NumChecked == 0);
tuple.ForEach(checkFunctor);
VTKM_TEST_ASSERT(checkFunctor.NumChecked == 2);
auto transformedTuple = tuple.Transform(TransformValues{ 10 });
using TransformedTupleType = decltype(transformedTuple);
VTKM_STATIC_ASSERT((std::is_same<vtkm::TupleElement<0, TransformedTupleType>, vtkm::Id>::value));
VTKM_STATIC_ASSERT((std::is_same<vtkm::TupleElement<1, TransformedTupleType>, vtkm::Id>::value));
VTKM_TEST_ASSERT(vtkm::Get<0>(transformedTuple) == TestValue(0, vtkm::Id{}) + 10);
VTKM_TEST_ASSERT(vtkm::Get<1>(transformedTuple) == TestValue(1, vtkm::Id{}) + 10);
}
void TestTuple22()
{
using TupleType = vtkm::Tuple<TypePlaceholder<0>,
TypePlaceholder<1>,
TypePlaceholder<2>,
TypePlaceholder<3>,
TypePlaceholder<4>,
TypePlaceholder<5>,
TypePlaceholder<6>,
TypePlaceholder<7>,
TypePlaceholder<8>,
TypePlaceholder<9>,
TypePlaceholder<10>,
TypePlaceholder<11>,
TypePlaceholder<12>,
TypePlaceholder<13>,
TypePlaceholder<14>,
TypePlaceholder<15>,
TypePlaceholder<16>,
TypePlaceholder<17>,
TypePlaceholder<18>,
TypePlaceholder<19>,
TypePlaceholder<20>,
TypePlaceholder<21>>;
VTKM_STATIC_ASSERT(vtkm::TupleSize<TupleType>::value == 22);
VTKM_STATIC_ASSERT((std::is_same<TypePlaceholder<0>, vtkm::TupleElement<0, TupleType>>::value));
VTKM_STATIC_ASSERT((std::is_same<TypePlaceholder<1>, vtkm::TupleElement<1, TupleType>>::value));
VTKM_STATIC_ASSERT((std::is_same<TypePlaceholder<20>, vtkm::TupleElement<20, TupleType>>::value));
VTKM_STATIC_ASSERT((std::is_same<TypePlaceholder<21>, vtkm::TupleElement<21, TupleType>>::value));
TupleType tuple(TestValue(0, vtkm::Id()),
TestValue(1, vtkm::Id()),
TestValue(2, vtkm::Id()),
TestValue(3, vtkm::Id()),
TestValue(4, vtkm::Id()),
TestValue(5, vtkm::Id()),
TestValue(6, vtkm::Id()),
TestValue(7, vtkm::Id()),
TestValue(8, vtkm::Id()),
TestValue(9, vtkm::Id()),
TestValue(10, vtkm::Id()),
TestValue(11, vtkm::Id()),
TestValue(12, vtkm::Id()),
TestValue(13, vtkm::Id()),
TestValue(14, vtkm::Id()),
TestValue(15, vtkm::Id()),
TestValue(16, vtkm::Id()),
TestValue(17, vtkm::Id()),
TestValue(18, vtkm::Id()),
TestValue(19, vtkm::Id()),
TestValue(20, vtkm::Id()),
TestValue(21, vtkm::Id()));
tuple.Apply(Check22);
vtkm::Id result = tuple.Apply(CheckReturn{}, Check22);
VTKM_TEST_ASSERT(result == 22);
CheckValues checkFunctor;
VTKM_TEST_ASSERT(checkFunctor.NumChecked == 0);
tuple.ForEach(checkFunctor);
VTKM_TEST_ASSERT(checkFunctor.NumChecked == 22);
auto transformedTuple = tuple.Transform(TransformValues{ 10 });
using TransformedTupleType = decltype(transformedTuple);
VTKM_STATIC_ASSERT((std::is_same<vtkm::TupleElement<0, TransformedTupleType>, vtkm::Id>::value));
VTKM_STATIC_ASSERT((std::is_same<vtkm::TupleElement<1, TransformedTupleType>, vtkm::Id>::value));
VTKM_STATIC_ASSERT((std::is_same<vtkm::TupleElement<20, TransformedTupleType>, vtkm::Id>::value));
VTKM_STATIC_ASSERT((std::is_same<vtkm::TupleElement<21, TransformedTupleType>, vtkm::Id>::value));
VTKM_TEST_ASSERT(vtkm::Get<0>(transformedTuple) == TestValue(0, vtkm::Id{}) + 10);
VTKM_TEST_ASSERT(vtkm::Get<1>(transformedTuple) == TestValue(1, vtkm::Id{}) + 10);
VTKM_TEST_ASSERT(vtkm::Get<20>(transformedTuple) == TestValue(20, vtkm::Id{}) + 10);
VTKM_TEST_ASSERT(vtkm::Get<21>(transformedTuple) == TestValue(21, vtkm::Id{}) + 10);
}
void TestTuple()
{
TestTuple2();
TestTuple22();
}
} // anonymous namespace
int UnitTestTuple(int argc, char* argv[])
{
return vtkm::testing::Testing::Run(TestTuple, argc, argv);
}

@ -9,7 +9,6 @@
##============================================================================ ##============================================================================
set(headers set(headers
DecayHelpers.h
DispatcherBase.h DispatcherBase.h
MaskBase.h MaskBase.h
Placeholders.h Placeholders.h

@ -28,7 +28,8 @@
#include <vtkm/internal/brigand.hpp> #include <vtkm/internal/brigand.hpp>
#include <vtkm/worklet/internal/DecayHelpers.h> #include <vtkm/internal/DecayHelpers.h>
#include <vtkm/worklet/internal/WorkletBase.h> #include <vtkm/worklet/internal/WorkletBase.h>
#include <sstream> #include <sstream>
@ -156,7 +157,7 @@ struct ReportValueOnError<Value, true> : std::true_type
template <typename Type, typename State> template <typename Type, typename State>
struct DetermineIfHasDynamicParameter struct DetermineIfHasDynamicParameter
{ {
using T = remove_pointer_and_decay<Type>; using T = vtkm::internal::remove_pointer_and_decay<Type>;
using DynamicTag = typename vtkm::cont::internal::DynamicTransformTraits<T>::DynamicTag; using DynamicTag = typename vtkm::cont::internal::DynamicTransformTraits<T>::DynamicTag;
using isDynamic = using isDynamic =
typename std::is_same<DynamicTag, vtkm::cont::internal::DynamicTransformTagCastAndCall>::type; typename std::is_same<DynamicTag, vtkm::cont::internal::DynamicTransformTagCastAndCall>::type;
@ -312,7 +313,7 @@ struct DispatcherBaseTransportFunctor
{ {
using TransportTag = using TransportTag =
typename DispatcherBaseTransportInvokeTypes<ControlInterface, Index>::TransportTag; typename DispatcherBaseTransportInvokeTypes<ControlInterface, Index>::TransportTag;
using T = remove_pointer_and_decay<ControlParameter>; using T = vtkm::internal::remove_pointer_and_decay<ControlParameter>;
using TransportType = typename vtkm::cont::arg::Transport<TransportTag, T, Device>; using TransportType = typename vtkm::cont::arg::Transport<TransportTag, T, Device>;
using type = typename TransportType::ExecObjectType; using type = typename TransportType::ExecObjectType;
}; };
@ -324,7 +325,7 @@ struct DispatcherBaseTransportFunctor
{ {
using TransportTag = using TransportTag =
typename DispatcherBaseTransportInvokeTypes<ControlInterface, Index>::TransportTag; typename DispatcherBaseTransportInvokeTypes<ControlInterface, Index>::TransportTag;
using T = remove_pointer_and_decay<ControlParameter>; using T = vtkm::internal::remove_pointer_and_decay<ControlParameter>;
vtkm::cont::arg::Transport<TransportTag, T, Device> transport; vtkm::cont::arg::Transport<TransportTag, T, Device> transport;
not_nullptr(invokeData, Index); not_nullptr(invokeData, Index);
@ -413,7 +414,7 @@ struct for_each_dynamic_arg
void operator()(const Trampoline& trampoline, ContParams&& sig, T&& t, Args&&... args) const void operator()(const Trampoline& trampoline, ContParams&& sig, T&& t, Args&&... args) const
{ {
//Determine that state of T when it is either a `cons&` or a `* const&` //Determine that state of T when it is either a `cons&` or a `* const&`
using Type = remove_pointer_and_decay<T>; using Type = vtkm::internal::remove_pointer_and_decay<T>;
using tag = typename vtkm::cont::internal::DynamicTransformTraits<Type>::DynamicTag; using tag = typename vtkm::cont::internal::DynamicTransformTraits<Type>::DynamicTag;
//convert the first item to a known type //convert the first item to a known type
convert_arg<LeftToProcess>( convert_arg<LeftToProcess>(
@ -498,7 +499,8 @@ private:
template <typename... Args> template <typename... Args>
VTKM_CONT void StartInvoke(Args&&... args) const VTKM_CONT void StartInvoke(Args&&... args) const
{ {
using ParameterInterface = vtkm::internal::FunctionInterface<void(remove_cvref<Args>...)>; using ParameterInterface =
vtkm::internal::FunctionInterface<void(vtkm::internal::remove_cvref<Args>...)>;
VTKM_STATIC_ASSERT_MSG(ParameterInterface::ARITY == NUM_INVOKE_PARAMS, VTKM_STATIC_ASSERT_MSG(ParameterInterface::ARITY == NUM_INVOKE_PARAMS,
"Dispatcher Invoke called with wrong number of arguments."); "Dispatcher Invoke called with wrong number of arguments.");
@ -543,7 +545,8 @@ private:
template <typename... Args> template <typename... Args>
VTKM_CONT void StartInvokeDynamic(std::false_type, Args&&... args) const VTKM_CONT void StartInvokeDynamic(std::false_type, Args&&... args) const
{ {
using ParameterInterface = vtkm::internal::FunctionInterface<void(remove_cvref<Args>...)>; using ParameterInterface =
vtkm::internal::FunctionInterface<void(vtkm::internal::remove_cvref<Args>...)>;
//Nothing requires a conversion from dynamic to static types, so //Nothing requires a conversion from dynamic to static types, so
//next we need to verify that each argument's type is correct. If not //next we need to verify that each argument's type is correct. If not
@ -564,7 +567,8 @@ private:
static_assert(isAllValid::value == expectedLen::value, static_assert(isAllValid::value == expectedLen::value,
"All arguments failed the TypeCheck pass"); "All arguments failed the TypeCheck pass");
auto fi = vtkm::internal::make_FunctionInterface<void, remove_cvref<Args>...>(args...); auto fi =
vtkm::internal::make_FunctionInterface<void, vtkm::internal::remove_cvref<Args>...>(args...);
auto ivc = vtkm::internal::Invocation<ParameterInterface, auto ivc = vtkm::internal::Invocation<ParameterInterface,
ControlInterface, ControlInterface,
ExecutionInterface, ExecutionInterface,

@ -10,8 +10,8 @@
#ifndef vtk_m_worklet_internal_MaskBase_h #ifndef vtk_m_worklet_internal_MaskBase_h
#define vtk_m_worklet_internal_MaskBase_h #define vtk_m_worklet_internal_MaskBase_h
#include <vtkm/internal/DecayHelpers.h>
#include <vtkm/internal/ExportMacros.h> #include <vtkm/internal/ExportMacros.h>
#include <vtkm/worklet/internal/DecayHelpers.h>
namespace vtkm namespace vtkm
{ {
@ -30,7 +30,7 @@ struct VTKM_ALWAYS_EXPORT MaskBase
}; };
template <typename T> template <typename T>
using is_mask = std::is_base_of<MaskBase, remove_cvref<T>>; using is_mask = std::is_base_of<MaskBase, vtkm::internal::remove_cvref<T>>;
} }
} }
} }

@ -10,8 +10,8 @@
#ifndef vtk_m_worklet_internal_ScatterBase_h #ifndef vtk_m_worklet_internal_ScatterBase_h
#define vtk_m_worklet_internal_ScatterBase_h #define vtk_m_worklet_internal_ScatterBase_h
#include <vtkm/internal/DecayHelpers.h>
#include <vtkm/internal/ExportMacros.h> #include <vtkm/internal/ExportMacros.h>
#include <vtkm/worklet/internal/DecayHelpers.h>
namespace vtkm namespace vtkm
{ {
@ -29,7 +29,7 @@ struct VTKM_ALWAYS_EXPORT ScatterBase
}; };
template <typename T> template <typename T>
using is_scatter = std::is_base_of<ScatterBase, remove_cvref<T>>; using is_scatter = std::is_base_of<ScatterBase, vtkm::internal::remove_cvref<T>>;
} }
} }
} }