//============================================================================ // 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. // // Copyright 2014 Sandia Corporation. // Copyright 2014 UT-Battelle, LLC. // Copyright 2014 Los Alamos National Security. // // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // 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. //============================================================================ $# 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 FunctionInterfaceDetailPre.h.in > FunctionInterfaceDetailPre.h $# $# Ignore the following comment. It is meant for the generated file. // **** DO NOT EDIT THIS FILE!!! **** // This file is automatically generated by FunctionInterfaceDetailPre.h.in #ifndef vtk_m_internal_FunctionInterfaceDetailPre_h #define vtk_m_internal_FunctionInterfaceDetailPre_h #if !defined(vtk_m_internal_FunctionInterface_h) && !defined(VTKM_TEST_HEADER_BUILD) #error FunctionInterfaceDetailPre.h must be included from FunctionInterface.h #endif #include #include #include #include $py(max_parameters=10)\ #define VTKM_MAX_FUNCTION_PARAMETERS $(max_parameters) $# Python commands used in template expansion. $py( def comma_if(flag): if flag: return ',' else: return ''; def ptype(num, name=""): if num == 0: return '%sR' % name else: return '%sP%d' % (name, num) def template_params(num_params, start=0, name=''): if num_params < start: return '' result = 'typename %s' % ptype(start, name) for param in xrange(start+1, num_params+1): result += ',\n typename %s' % ptype(param, name) return result def signature(num_params, return_type=ptype(0), name=''): result = '%s(' % return_type if num_params > 0: result += ptype(1, name) for param in xrange(2, num_params+1): result += ',%s' % ptype(param, name) result += ')' return result )\ $# $extend(comma_if, ptype, template_params, signature)\ namespace vtkm { namespace internal { /// This struct is used internally by FunctionInterface to store the return /// value of a function. There is a special implementation for a return type of /// void, which stores nothing. /// template struct FunctionInterfaceReturnContainer { T Value; static VTKM_CONSTEXPR bool VALID = true; }; template<> struct FunctionInterfaceReturnContainer { // Nothing to store for void return. static VTKM_CONSTEXPR bool VALID = false; }; namespace detail { //============================================================================ // This templated class contains the state of parameters. If you get a compiler // error stating that this class is not specialized, that probably means that // you are using FunctionInterface with an unsupported number of arguments. template struct ParameterContainer; $for(num_params in range(0, max_parameters+1))\ template<$template_params(num_params)> struct ParameterContainer<$signature(num_params)> { $for(param_index in range(1, num_params+1))\ $ptype(param_index) Parameter$(param_index); $endfor\ }; $endfor\ //============================================================================ template struct FunctionSigInfo; template struct FunctionSigInfo { static VTKM_CONSTEXPR std::size_t Arity = sizeof...(ArgTypes); using ArityType = std::integral_constant; using ResultType = R; using Components = brigand::list; using Parameters = brigand::list; }; template struct AtType; template struct AtType { using type = brigand::at_c< brigand::list, Index>; }; template struct AppendType; template class L, typename T, typename NT, typename... U> struct AppendType, NT> { typedef T type(U...,NT); }; template struct AsSigType; template class L, typename T, typename... U> struct AsSigType< L > { typedef T type(U...); }; template< typename Components, vtkm::IdComponent ParameterIndex, typename NewType > class ReplaceType { typedef std::integral_constant Index; using split = brigand::split_at; using front = brigand::push_back< brigand::front, NewType >; using back = brigand::pop_front< brigand::back >; using replaced = brigand::append< front, back >; public: using type = typename AsSigType< replaced >::type; }; //============================================================================ template struct ParameterContainerAccess; $for(param_index in range(1, max_parameters+1))\ template<> struct ParameterContainerAccess<$(param_index)> { VTKM_SUPPRESS_EXEC_WARNINGS template VTKM_EXEC_CONT const typename AtType<$(param_index), FunctionSignature>::type & Get(const ParameterContainer ¶meters) { return parameters.Parameter$(param_index); } VTKM_SUPPRESS_EXEC_WARNINGS template VTKM_EXEC_CONT void Set(ParameterContainer ¶meters, const typename AtType<$(param_index), FunctionSignature>::type &value) { parameters.Parameter$(param_index) = value; } }; $endfor\ //============================================================================ template struct CopyAllParameters; $for(num_params in range(1, max_parameters+1))\ template<> struct CopyAllParameters<$(num_params)> { VTKM_SUPPRESS_EXEC_WARNINGS template VTKM_EXEC_CONT void Copy(vtkm::internal::detail::ParameterContainer &dest, const vtkm::internal::detail::ParameterContainer &src) { $for(param_index in range(1, num_params+1))\ dest.Parameter$(param_index) = src.Parameter$(param_index); $endfor\ } }; $endfor\ template<> struct CopyAllParameters<0> { VTKM_SUPPRESS_EXEC_WARNINGS template VTKM_EXEC_CONT void Copy(vtkm::internal::detail::ParameterContainer &, const vtkm::internal::detail::ParameterContainer &) { // Nothing to copy. } }; //============================================================================ $for(num_params in range(0, max_parameters+1))\ $# Invoke functions need both control and execution versions $for(environment in ['Cont', 'Exec'])\ $# Invoke functions also need to accept const and non-const versions of the functor $for(functor_const in ['const ', ''])\ VTKM_SUPPRESS_EXEC_WARNINGS template VTKM_$(environment.upper()) void DoInvoke$(environment)( $(functor_const)Functor &f, ParameterContainer<$signature(num_params)> ¶meters, FunctionInterfaceReturnContainer<$ptype(0)> &result, const TransformFunctor &transform) { $if(num_params < 1)\ (void) parameters; result.Value = transform(f()); $else\ result.Value = transform(f( $for(param_index in xrange(1, num_params))\ transform(parameters.Parameter$(param_index)), $endfor\ transform(parameters.Parameter$(num_params)))); $endif\ } VTKM_SUPPRESS_EXEC_WARNINGS template0) $template_params(num_params,1)> VTKM_$(environment.upper()) void DoInvoke$(environment)( $(functor_const)Functor &f, ParameterContainer<$signature(num_params,'void')> ¶meters, FunctionInterfaceReturnContainer &, const TransformFunctor &transform) { $if(num_params < 1)\ (void) parameters; (void) transform; f(); $else\ f( $for(param_index in xrange(1, num_params))\ transform(parameters.Parameter$(param_index)), $endfor\ transform(parameters.Parameter$(num_params))); $endif\ } $endfor\ $endfor\ $endfor\ //============================================================================ template struct FunctionInterfaceStaticTransformType; $for(num_params in xrange(0, max_parameters))\ $# Transform functions need both control and execution versions $for(environment in ['Cont', 'Exec'])\ VTKM_SUPPRESS_EXEC_WARNINGS template VTKM_$(environment.upper()) void DoStaticTransform$(environment)( const Transform &transform, const ParameterContainer<$signature(num_params,ptype(0,'Original'),'Original')> &originalParameters, ParameterContainer<$signature(num_params,ptype(0,'Transformed'),'Transformed')> &transformedParameters) { $if(num_params < 1)\ (void)transform; (void)originalParameters; (void)transformedParameters; $else\ $for(param_index in xrange(1, num_params+1))\ transformedParameters.Parameter$(param_index) = transform(originalParameters.Parameter$(param_index), vtkm::internal::IndexTag<$(param_index)>()); $endfor\ $endif\ } $endfor\ $endfor\ //============================================================================ $for(num_params in xrange(0, max_parameters))\ $# ForEach functions need both control and execution versions $for(environment in ['Cont', 'Exec'])\ $# ForEach functions also need to accept const and non-const versions of the FunctionInterface $for(function_interface_const in ['const ', ''])\ VTKM_SUPPRESS_EXEC_WARNINGS template VTKM_$(environment.upper()) void DoForEach$(environment)( const Functor &f, $(function_interface_const)ParameterContainer<$signature(num_params)> ¶meters) { $if(num_params < 1)\ (void)f; (void)parameters; $else\ $for(param_index in xrange(1, num_params+1))\ f(parameters.Parameter$(param_index), vtkm::internal::IndexTag<$(param_index)>()); $endfor\ $endif\ } $endfor\ $endfor\ $endfor\ } // namespace detail } } // namespace vtkm::internal #endif //vtk_m_internal_FunctionInterfaceDetailPre_h