mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-08 13:23:51 +00:00
Implement FunctionInterface::StaticTransform
This will allow a faster conversion than the dynamic transform and will allow you to define compile-time types for transformation unlike dynamic transform or invoke with transform.
This commit is contained in:
parent
defb4f00cf
commit
438fe0ff8d
@ -247,7 +247,7 @@ struct IdentityFunctor {
|
||||
f(BOOST_PP_ENUM_SHIFTED(NumParamsPlusOne, VTK_M_DO_INVOKE_TPARAM, )); \
|
||||
}
|
||||
#define VTK_M_DO_INVOKE_REPEAT(z, NumParams, data) \
|
||||
VTK_M_DO_INVOKE(BOOST_PP_INC(NumParams));
|
||||
VTK_M_DO_INVOKE(BOOST_PP_INC(NumParams))
|
||||
|
||||
#define VTK_M_DO_INVOKE_NAME DoInvokeCont
|
||||
#define VTK_M_DO_INVOKE_EXPORT VTKM_CONT_EXPORT
|
||||
@ -318,6 +318,69 @@ struct FunctionInterfaceCopyParameters<0, ParameterIndex> {
|
||||
}
|
||||
};
|
||||
|
||||
template<typename OriginalSignature, typename Transform>
|
||||
struct FunctionInterfaceStaticTransformType;
|
||||
|
||||
// The following code uses the Boost preprocessor utilities to create
|
||||
// definitions of DoStaticTransform functions for all supported number of
|
||||
// arguments. The created functions are conceptually defined as follows:
|
||||
//
|
||||
// template<typename Transform,
|
||||
// typename OriginalSignature,
|
||||
// typename TransformedSignature>
|
||||
// VTKM_CONT_EXPORT
|
||||
// void DoStaticTransformCont(
|
||||
// const Transform &transform,
|
||||
// const ParameterContainer<OriginalSignature> &originalParameters,
|
||||
// ParameterContainer<TransformedSignature> &transformedParameters)
|
||||
// {
|
||||
// transformedParameters.Parameter1 = transform(originalParameters.Parameter1);
|
||||
// transformedParameters.Parameter2 = transform(originalParameters.Parameter2);
|
||||
// ...
|
||||
// }
|
||||
//
|
||||
// We define multiple DoStaticTransformCont and DoStaticTransformExec that do
|
||||
// identical things with different exports. It is important to have these
|
||||
// separate definitions instead of a single version with VTKM_EXEC_CONT_EXPORT
|
||||
// because the transform to be invoked may only be viable in one or the other.
|
||||
|
||||
#define VTK_M_DO_STATIC_TRANSFORM_ASSIGN(z, count, data) \
|
||||
BOOST_PP_IF(count, \
|
||||
BOOST_PP_CAT(transformedParameters.Parameter, count) = \
|
||||
transform(BOOST_PP_CAT(originalParameters.Parameter, count));,)
|
||||
|
||||
#define VTK_M_DO_STATIC_TRANSFORM(NumParamsPlusOne) \
|
||||
template<typename Transform, \
|
||||
BOOST_PP_ENUM_PARAMS(NumParamsPlusOne, typename OriginalP), \
|
||||
BOOST_PP_ENUM_PARAMS(NumParamsPlusOne, typename TransformedP)> \
|
||||
VTK_M_DO_STATIC_TRANSFORM_EXPORT \
|
||||
void VTK_M_DO_STATIC_TRANSFORM_NAME( \
|
||||
const Transform &transform, \
|
||||
ParameterContainer<OriginalP0(BOOST_PP_ENUM_SHIFTED_PARAMS(NumParamsPlusOne, OriginalP))> &originalParameters, \
|
||||
ParameterContainer<TransformedP0(BOOST_PP_ENUM_SHIFTED_PARAMS(NumParamsPlusOne, TransformedP))> &transformedParameters) \
|
||||
{ \
|
||||
(void)transform; \
|
||||
(void)originalParameters; \
|
||||
(void)transformedParameters; \
|
||||
BOOST_PP_REPEAT(NumParamsPlusOne, VTK_M_DO_STATIC_TRANSFORM_ASSIGN,) \
|
||||
}
|
||||
#define VTK_M_DO_STATIC_TRANSFORM_REPEAT(z, NumParams, data) \
|
||||
VTK_M_DO_STATIC_TRANSFORM(BOOST_PP_INC(NumParams))
|
||||
|
||||
#define VTK_M_DO_STATIC_TRANSFORM_NAME DoStaticTransformCont
|
||||
#define VTK_M_DO_STATIC_TRANSFORM_EXPORT VTKM_CONT_EXPORT
|
||||
BOOST_PP_REPEAT(BOOST_PP_INC(VTKM_MAX_FUNCTION_PARAMETERS),
|
||||
VTK_M_DO_STATIC_TRANSFORM_REPEAT,)
|
||||
#undef VTK_M_DO_STATIC_TRANSFORM_EXPORT
|
||||
#undef VTK_M_DO_STATIC_TRANSFORM_NAME
|
||||
|
||||
#define VTK_M_DO_STATIC_TRANSFORM_NAME DoStaticTransformExec
|
||||
#define VTK_M_DO_STATIC_TRANSFORM_EXPORT VTKM_EXEC_EXPORT
|
||||
BOOST_PP_REPEAT(BOOST_PP_INC(VTKM_MAX_FUNCTION_PARAMETERS),
|
||||
VTK_M_DO_STATIC_TRANSFORM_REPEAT,)
|
||||
#undef VTK_M_DO_STATIC_TRANSFORM_EXPORT
|
||||
#undef VTK_M_DO_STATIC_TRANSFORM_NAME
|
||||
|
||||
template<typename OriginalFunction,
|
||||
typename NewFunction,
|
||||
typename TransformFunctor,
|
||||
@ -559,6 +622,79 @@ public:
|
||||
return replacedFuncInterface;
|
||||
}
|
||||
|
||||
template<typename Transform>
|
||||
struct StaticTransformType {
|
||||
typedef FunctionInterface<
|
||||
typename detail::FunctionInterfaceStaticTransformType<
|
||||
FunctionSignature,Transform>::type> type;
|
||||
};
|
||||
|
||||
/// \brief Transforms the \c FunctionInterface based on compile-time
|
||||
/// information.
|
||||
///
|
||||
/// The \c StaticTransform method transforms all the parameters of this \c
|
||||
/// FunctionInterface to different types and values based on compile-time
|
||||
/// information. It operates by accepting a functor that defines a unary
|
||||
/// function whose argument is the parameter to transform and the return
|
||||
/// value is the transformed value. The functor must also contain a templated
|
||||
/// struct name ReturnType with an internal type named \c type that defines
|
||||
/// the return type of the transform for a given input type.
|
||||
///
|
||||
/// The transformation is only applied to the parameters of the function. The
|
||||
/// return argument is uneffected.
|
||||
///
|
||||
/// The return type can be determined with the \c StaticTransformType
|
||||
/// template.
|
||||
///
|
||||
/// Here is an example of a transformation that converts a \c
|
||||
/// FunctionInterface to another \c FunctionInterface containing pointers to
|
||||
/// all of the parameters.
|
||||
///
|
||||
/// \code
|
||||
/// struct MyTransformFunctor {
|
||||
/// template<typename T>
|
||||
/// struct ReturnType {
|
||||
/// typedef const T *type;
|
||||
/// };
|
||||
///
|
||||
/// template<typename T>
|
||||
/// DAX_CONT_EXPORT
|
||||
/// const T *operator()(const T &x) const {
|
||||
/// return &x;
|
||||
/// }
|
||||
/// };
|
||||
///
|
||||
/// template<typename FunctionSignature>
|
||||
/// typename vtkm::internal::FunctionInterface<FunctionSignature>::template StaticTransformType<MyTransformFunctor>::type
|
||||
/// ImportantStuff(const vtkm::internal::FunctionInterface<FunctionSignature> &funcInterface)
|
||||
/// {
|
||||
/// return funcInterface.StaticTransformCont(MyTransformFunctor());
|
||||
/// }
|
||||
/// \endcode
|
||||
///
|
||||
template<typename Transform>
|
||||
VTKM_CONT_EXPORT
|
||||
typename StaticTransformType<Transform>::type
|
||||
StaticTransformCont(const Transform &transform)
|
||||
{
|
||||
typename StaticTransformType<Transform>::type newFuncInterface;
|
||||
detail::DoStaticTransformCont(transform,
|
||||
this->Parameters,
|
||||
newFuncInterface.Parameters);
|
||||
return newFuncInterface;
|
||||
}
|
||||
template<typename Transform>
|
||||
VTKM_EXEC_EXPORT
|
||||
typename StaticTransformType<Transform>::type
|
||||
StaticTransformExec(const Transform &transform)
|
||||
{
|
||||
typename StaticTransformType<Transform>::type newFuncInterface;
|
||||
detail::DoStaticTransformExec(transform,
|
||||
this->Parameters,
|
||||
newFuncInterface.Parameters);
|
||||
return newFuncInterface;
|
||||
}
|
||||
|
||||
/// \brief Transforms the \c FunctionInterface based on run-time information.
|
||||
///
|
||||
/// The \c DynamicTransform method transforms all the parameters of this \c
|
||||
@ -655,6 +791,46 @@ private:
|
||||
|
||||
namespace detail {
|
||||
|
||||
// The following code uses the Boost preprocessor utilities to create
|
||||
// definitions of FunctionInterfaceStaticTransformType for all supported number
|
||||
// of arguments. The created classes are conceptually defined as follows:
|
||||
//
|
||||
// template<typename Transform,
|
||||
// typename P0, // Return type
|
||||
// typename P1,
|
||||
// typename P2, ...>
|
||||
// struct FunctionInterfaceStaticTransformType<P0(P1,P2,...), Transform> {
|
||||
// typedef P0(type)(typename Transform::template ReturnType<P1>::type,
|
||||
// typename Transform::template ReturnType<P2>::type, ...);
|
||||
// };
|
||||
|
||||
#define VTK_M_STATIC_TRANSFORM_TPARAM(z, ParamIndex, data) \
|
||||
BOOST_PP_IF( \
|
||||
ParamIndex, \
|
||||
typename Transform::template ReturnType<BOOST_PP_CAT(P,ParamIndex)>::type,)
|
||||
|
||||
#define VTK_M_STATIC_TRANSFORM_TYPE(NumParamsPlusOne) \
|
||||
template<typename Transform, \
|
||||
BOOST_PP_ENUM_PARAMS(NumParamsPlusOne, typename P)> \
|
||||
struct FunctionInterfaceStaticTransformType< \
|
||||
P0(BOOST_PP_ENUM_SHIFTED_PARAMS(NumParamsPlusOne, P)), \
|
||||
Transform> \
|
||||
{ \
|
||||
typedef P0(type)( \
|
||||
BOOST_PP_ENUM_SHIFTED(NumParamsPlusOne, VTK_M_STATIC_TRANSFORM_TPARAM,) \
|
||||
); \
|
||||
};
|
||||
#define VTK_M_STATIC_TRANSFORM_TYPE_REPEAT(z, NumParams, data) \
|
||||
VTK_M_STATIC_TRANSFORM_TYPE(BOOST_PP_INC(NumParams))
|
||||
|
||||
BOOST_PP_REPEAT(BOOST_PP_INC(VTKM_MAX_FUNCTION_PARAMETERS),
|
||||
VTK_M_STATIC_TRANSFORM_TYPE_REPEAT,)
|
||||
|
||||
#undef VTK_M_STATIC_TRANSFORM_TYPE_REPEAT
|
||||
#undef VTK_M_STATIC_TRANSFORM_TYPE
|
||||
#undef VTK_M_STATIC_TRANSFORM_TPARAM
|
||||
|
||||
|
||||
template<typename OriginalFunction,
|
||||
typename NewFunction,
|
||||
typename TransformFunctor,
|
||||
|
@ -135,10 +135,22 @@ struct GetReferenceFunctor
|
||||
const T *operator()(const T &x) const { return &x; }
|
||||
};
|
||||
|
||||
struct PointerTransform {
|
||||
template<typename T>
|
||||
struct ReturnType {
|
||||
typedef const T *type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
const T *operator()(const T &x) const {
|
||||
return &x;
|
||||
}
|
||||
};
|
||||
|
||||
struct ThreePointerArgFunctor {
|
||||
void operator()(const Type1 *a1, const Type2 *a2, const Type3 *a3) const
|
||||
{
|
||||
std::cout << "In 3 arg functor." << std::endl;
|
||||
std::cout << "In 3 point arg functor." << std::endl;
|
||||
|
||||
VTKM_TEST_ASSERT(*a1 == Arg1, "Arg 1 incorrect.");
|
||||
VTKM_TEST_ASSERT(*a2 == Arg2, "Arg 2 incorrect.");
|
||||
@ -409,6 +421,35 @@ void TestTransformInvoke()
|
||||
"Got bad result from invoke.");
|
||||
}
|
||||
|
||||
void TestStaticTransform()
|
||||
{
|
||||
std::cout << "Trying static transform." << std::endl;
|
||||
typedef vtkm::internal::FunctionInterface<void(Type1,Type2,Type3)>
|
||||
OriginalType;
|
||||
OriginalType funcInterface =
|
||||
vtkm::internal::make_FunctionInterface<void>(Arg1, Arg2, Arg3);
|
||||
|
||||
std::cout << "Transform with reported type." << std::endl;
|
||||
typedef OriginalType::StaticTransformType<PointerTransform>::type
|
||||
ReportedType;
|
||||
ReportedType funcInterfaceTransform1 =
|
||||
funcInterface.StaticTransformCont(PointerTransform());
|
||||
funcInterfaceTransform1.InvokeCont(ThreePointerArgFunctor());
|
||||
funcInterfaceTransform1 =
|
||||
funcInterface.StaticTransformExec(PointerTransform());
|
||||
funcInterfaceTransform1.InvokeExec(ThreePointerArgFunctor());
|
||||
|
||||
std::cout << "Transform with expected type." << std::endl;
|
||||
typedef vtkm::internal::FunctionInterface<void(Type1*,Type2*,Type3*)>
|
||||
ExpectedType;
|
||||
ReportedType funcInterfaceTransform2 =
|
||||
funcInterface.StaticTransformCont(PointerTransform());
|
||||
funcInterfaceTransform2.InvokeCont(ThreePointerArgFunctor());
|
||||
funcInterfaceTransform2 =
|
||||
funcInterface.StaticTransformExec(PointerTransform());
|
||||
funcInterfaceTransform2.InvokeExec(ThreePointerArgFunctor());
|
||||
}
|
||||
|
||||
void TestDynamicTransform()
|
||||
{
|
||||
std::cout << "Trying dynamic transform." << std::endl;
|
||||
@ -487,6 +528,7 @@ void TestFunctionInterface()
|
||||
TestInvokeResult();
|
||||
TestAppend();
|
||||
TestTransformInvoke();
|
||||
TestStaticTransform();
|
||||
TestDynamicTransform();
|
||||
TestInvokeTime();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user