//============================================================================ // 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 #include #include $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 class Tuple; /// \brief Get the size of a tuple. /// /// Given a `vtkm::Tuple` type, because a `std::integral_constant` of the type. /// template using TupleSize = std::integral_constant; /// \brief Compatible with `std::tuple_size` for `vtkm::Tuple`. /// template using tuple_size = std::integral_constant(TupleType::Size)>; namespace detail { template struct TupleElementImpl { using type = decltype(TupleType::ElementTypeI(vtkm::internal::IndexTag{})); }; } // namespace detail /// \brief Becomes the type of the given index for the given `vtkm::Tuple`. /// template using TupleElement = typename detail::TupleElementImpl::type; /// \brief Compatible with `std::tuple_element` for `vtkm::Tuple`. /// template struct tuple_element { using type = TupleElement(Index), TupleType>; }; /// \brief Compatible with `std::tuple_element_t` for `vtkm::Tuple`. /// template using tuple_element_t = typename tuple_element::type; ///@{ /// \brief Retrieve the object from a `vtkm::Tuple` at the given index. /// VTKM_SUPPRESS_EXEC_WARNINGS template VTKM_EXEC_CONT auto Get(const vtkm::Tuple& tuple) -> decltype(tuple.template Get()) { return tuple.template Get(); } VTKM_SUPPRESS_EXEC_WARNINGS template VTKM_EXEC_CONT auto Get(vtkm::Tuple& tuple) -> decltype(tuple.template Get()) { return tuple.template Get(); } ///@} ///@{ /// \brief Compatible with `std::get` for `vtkm::Tuple`. /// VTKM_SUPPRESS_EXEC_WARNINGS template VTKM_EXEC_CONT auto get(const vtkm::Tuple& tuple) -> decltype(vtkm::Get(Index)>(tuple)) { return vtkm::Get(Index)>(tuple); } VTKM_SUPPRESS_EXEC_WARNINGS template VTKM_EXEC_CONT auto get(vtkm::Tuple& tuple) -> decltype(vtkm::Get(Index)>(tuple)) { return vtkm::Get(Index)>(tuple); } ///@} /// \brief Creates a new `vtkm::Tuple` with the given types. /// VTKM_SUPPRESS_EXEC_WARNINGS template VTKM_EXEC_CONT auto MakeTuple(Ts&&... args) -> vtkm::Tuple::type...> { return vtkm::Tuple::type...>(std::forward(args)...); } /// \brief Compatible with `std::make_tuple` for `vtkm::Tuple`. /// VTKM_SUPPRESS_EXEC_WARNINGS template VTKM_EXEC_CONT auto make_tuple(Ts&&... args) -> decltype(vtkm::MakeTuple(std::forward(args)...)) { return vtkm::MakeTuple(std::forward(args)...); } /// @cond NONE namespace detail { struct TupleTransformFunctor { VTKM_SUPPRESS_EXEC_WARNINGS template VTKM_EXEC_CONT auto operator()(Function&& f, Ts&&... args) -> decltype(vtkm::MakeTuple(f(std::forward(args))...)) { return vtkm::MakeTuple(f(std::forward(args))...); } }; VTKM_SUPPRESS_EXEC_WARNINGS template VTKM_EXEC_CONT auto TupleTransform(TupleType&& tuple, Function&& f) -> decltype(tuple.Apply(TupleTransformFunctor{}, std::forward(f))) { return tuple.Apply(TupleTransformFunctor{}, std::forward(f)); } struct TupleForEachFunctor { VTKM_SUPPRESS_EXEC_WARNINGS template VTKM_EXEC_CONT void operator()(Function&& f, Ts&&... args) { (void)std::initializer_list{ (f(std::forward(args)), false)... }; } }; VTKM_SUPPRESS_EXEC_WARNINGS template VTKM_EXEC_CONT auto TupleForEach(TupleType&& tuple, Function&& f) -> decltype(tuple.Apply(TupleForEachFunctor{}, std::forward(f))) { return tuple.Apply(TupleForEachFunctor{}, std::forward(f)); } } // namespace detail /// @endcond template <> class Tuple<> { public: static constexpr vtkm::IdComponent Size = 0; VTKM_SUPPRESS_EXEC_WARNINGS template VTKM_EXEC_CONT auto Apply(Function&& f, Args&&... args) -> decltype(f(std::forward(args)...)) { return f(std::forward(args)...); } VTKM_SUPPRESS_EXEC_WARNINGS template VTKM_EXEC_CONT auto Apply(Function&& f, Args&&... args) const -> decltype(f(std::forward(args)...)) { return f(std::forward(args)...); } VTKM_SUPPRESS_EXEC_WARNINGS template VTKM_EXEC_CONT void ForEach(Function&&) const { } VTKM_SUPPRESS_EXEC_WARNINGS template 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& GetImpl(vtkm::internal::IndexTag<$(index)>) { return this->Value$(index); } VTKM_EXEC_CONT const vtkm::internal::remove_cvref& GetImpl(vtkm::internal::IndexTag<$(index)>) const { return this->Value$(index); } $endfor\ // Invalid indices template static vtkm::internal::NullType ElementTypeI(vtkm::internal::IndexTag); template friend struct detail::TupleElementImpl; public: static constexpr vtkm::IdComponent Size = $(num_params); template using ElementType = vtkm::TupleElement>; 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)) $for(index in range(1, num_params))\ , Value$(index)(std::forward(a$(index))) $endfor\ { } template VTKM_EXEC_CONT auto Get() -> decltype(this->GetImpl(vtkm::internal::IndexTag{})) { return this->GetImpl(vtkm::internal::IndexTag{}); } template VTKM_EXEC_CONT auto Get() const -> decltype(this->GetImpl(vtkm::internal::IndexTag{})) { return this->GetImpl(vtkm::internal::IndexTag{}); } VTKM_SUPPRESS_EXEC_WARNINGS template VTKM_EXEC_CONT auto Apply(Function&& f, Args&&... args) -> decltype(f(std::forward(args)..., $type_list(num_params, "Value"))) { return f(std::forward(args)..., $type_list(num_params, "Value")); } VTKM_SUPPRESS_EXEC_WARNINGS template VTKM_EXEC_CONT auto Apply(Function&& f, Args&&... args) const -> decltype(f(std::forward(args)..., $type_list(num_params, "Value"))) { return f(std::forward(args)..., $type_list(num_params, "Value")); } VTKM_SUPPRESS_EXEC_WARNINGS template VTKM_EXEC_CONT void ForEach(Function&& f) { detail::TupleForEach(*this, std::forward(f)); } VTKM_SUPPRESS_EXEC_WARNINGS template VTKM_EXEC_CONT void ForEach(Function&& f) const { detail::TupleForEach(*this, std::forward(f)); } VTKM_SUPPRESS_EXEC_WARNINGS template VTKM_EXEC_CONT auto Transform(Function&& f) -> decltype(detail::TupleTransform(*this, std::forward(f))) { return detail::TupleTransform(*this, std::forward(f)); } VTKM_SUPPRESS_EXEC_WARNINGS template VTKM_EXEC_CONT auto Transform(Function&& f) const -> decltype(detail::TupleTransform(*this, std::forward(f))) { return detail::TupleTransform(*this, std::forward(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& GetImpl(vtkm::internal::IndexTag<$(index)>) { return this->Value$(index); } VTKM_EXEC_CONT const vtkm::internal::remove_cvref& GetImpl(vtkm::internal::IndexTag<$(index)>) const { return this->Value$(index); } $endfor\ // Implement the "extra" objects in a sub-Tuple using RemainingValuesType = vtkm::Tuple; RemainingValuesType RemainingValues; template static vtkm::TupleElement ElementTypeI(vtkm::internal::IndexTag); template VTKM_EXEC_CONT const vtkm::internal::remove_cvref>& GetImpl(vtkm::internal::IndexTag) { return vtkm::Get(this->RemainingValues); } template VTKM_EXEC_CONT const vtkm::internal::remove_cvref>& GetImpl(vtkm::internal::IndexTag) const { return vtkm::Get(this->RemainingValues); } template friend struct detail::TupleElementImpl; public: static constexpr vtkm::IdComponent Size = $(max_expanded + 1) + static_cast(sizeof...(Ts)); template using ElementType = vtkm::TupleElement>; 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)) $for(index in range(1, max_expanded))\ , Value$(index)(std::forward(a$(index))) $endfor\ , RemainingValues(std::forward(remainingArgs)...) { } template VTKM_EXEC_CONT auto Get() -> decltype(this->GetImpl(vtkm::internal::IndexTag{})) { return this->GetImpl(vtkm::internal::IndexTag{}); } template VTKM_EXEC_CONT auto Get() const -> decltype(this->GetImpl(vtkm::internal::IndexTag{})) { return this->GetImpl(vtkm::internal::IndexTag{}); } VTKM_SUPPRESS_EXEC_WARNINGS template VTKM_EXEC_CONT auto Apply(Function&& f, Args&&... args) -> decltype(this->RemainingValues.Apply(std::forward(f), std::forward(args)..., $for(index in range(0, max_expanded - 1))\ this->Value$(index), $endfor\ this->Value$(max_expanded - 1))) { return this->RemainingValues.Apply(std::forward(f), std::forward(args)..., $for(index in range(0, max_expanded - 1))\ this->Value$(index), $endfor\ this->Value$(max_expanded - 1)); } VTKM_SUPPRESS_EXEC_WARNINGS template VTKM_EXEC_CONT auto Apply(Function&& f, Args&&... args) const -> decltype(this->RemainingValues.Apply(std::forward(f), std::forward(args)..., $for(index in range(0, max_expanded - 1))\ this->Value$(index), $endfor\ this->Value$(max_expanded - 1))) { return this->RemainingValues.Apply(std::forward(f), std::forward(args)..., $for(index in range(0, max_expanded - 1))\ this->Value$(index), $endfor\ this->Value$(max_expanded - 1)); } VTKM_SUPPRESS_EXEC_WARNINGS template VTKM_EXEC_CONT void ForEach(Function&& f) { detail::TupleForEach(*this, std::forward(f)); } VTKM_SUPPRESS_EXEC_WARNINGS template VTKM_EXEC_CONT void ForEach(Function&& f) const { detail::TupleForEach(*this, std::forward(f)); } VTKM_SUPPRESS_EXEC_WARNINGS template VTKM_EXEC_CONT auto Transform(Function&& f) -> decltype(detail::TupleTransform(*this, std::forward(f))) { return detail::TupleTransform(*this, std::forward(f)); } VTKM_SUPPRESS_EXEC_WARNINGS template VTKM_EXEC_CONT auto Transform(Function&& f) const -> decltype(detail::TupleTransform(*this, std::forward(f))) { return detail::TupleTransform(*this, std::forward(f)); } }; ///@} // clang-format on } // namespace vtkm #endif //vtk_m_Tuple_h