mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-16 17:22:55 +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, )); \
|
f(BOOST_PP_ENUM_SHIFTED(NumParamsPlusOne, VTK_M_DO_INVOKE_TPARAM, )); \
|
||||||
}
|
}
|
||||||
#define VTK_M_DO_INVOKE_REPEAT(z, NumParams, data) \
|
#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_NAME DoInvokeCont
|
||||||
#define VTK_M_DO_INVOKE_EXPORT VTKM_CONT_EXPORT
|
#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,
|
template<typename OriginalFunction,
|
||||||
typename NewFunction,
|
typename NewFunction,
|
||||||
typename TransformFunctor,
|
typename TransformFunctor,
|
||||||
@ -559,6 +622,79 @@ public:
|
|||||||
return replacedFuncInterface;
|
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.
|
/// \brief Transforms the \c FunctionInterface based on run-time information.
|
||||||
///
|
///
|
||||||
/// The \c DynamicTransform method transforms all the parameters of this \c
|
/// The \c DynamicTransform method transforms all the parameters of this \c
|
||||||
@ -655,6 +791,46 @@ private:
|
|||||||
|
|
||||||
namespace detail {
|
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,
|
template<typename OriginalFunction,
|
||||||
typename NewFunction,
|
typename NewFunction,
|
||||||
typename TransformFunctor,
|
typename TransformFunctor,
|
||||||
|
@ -135,10 +135,22 @@ struct GetReferenceFunctor
|
|||||||
const T *operator()(const T &x) const { return &x; }
|
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 {
|
struct ThreePointerArgFunctor {
|
||||||
void operator()(const Type1 *a1, const Type2 *a2, const Type3 *a3) const
|
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(*a1 == Arg1, "Arg 1 incorrect.");
|
||||||
VTKM_TEST_ASSERT(*a2 == Arg2, "Arg 2 incorrect.");
|
VTKM_TEST_ASSERT(*a2 == Arg2, "Arg 2 incorrect.");
|
||||||
@ -409,6 +421,35 @@ void TestTransformInvoke()
|
|||||||
"Got bad result from invoke.");
|
"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()
|
void TestDynamicTransform()
|
||||||
{
|
{
|
||||||
std::cout << "Trying dynamic transform." << std::endl;
|
std::cout << "Trying dynamic transform." << std::endl;
|
||||||
@ -487,6 +528,7 @@ void TestFunctionInterface()
|
|||||||
TestInvokeResult();
|
TestInvokeResult();
|
||||||
TestAppend();
|
TestAppend();
|
||||||
TestTransformInvoke();
|
TestTransformInvoke();
|
||||||
|
TestStaticTransform();
|
||||||
TestDynamicTransform();
|
TestDynamicTransform();
|
||||||
TestInvokeTime();
|
TestInvokeTime();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user