56636afc7a
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.
505 lines
16 KiB
C
505 lines
16 KiB
C
//============================================================================
|
|
// 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
|