Last active
August 29, 2015 13:57
-
-
Save ddemidov/9891163 to your computer and use it in GitHub Desktop.
Boost.PP parse parameter list
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
run: | |
@g++ -E pp.cpp | tail -n 1 | clang-format | pygmentize -l cpp | |
check: | |
@g++ -E pp.cpp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define BOOST_PP_VARIADICS 1 | |
#include <boost/preprocessor/enum.hpp> | |
#include <boost/preprocessor/enum_params.hpp> | |
#include <boost/preprocessor/seq.hpp> | |
#include <boost/preprocessor/cat.hpp> | |
#include <boost/preprocessor/tuple.hpp> | |
#include <boost/preprocessor/stringize.hpp> | |
#define VEXCL_FUNCTION_PRINT_ARG_REF(z, n, data) const Arg##n & | |
#define VEXCL_FUNCTION_PRINT_PARAM(z, n, data) const Arg##n &arg##n | |
#define VEXCL_FUNCTION_PRINT_BOOST_REF(z, n, data) boost::ref(arg##n) | |
#define VEXCL_FUNCTION_ARG_TYPE(n, args) \ | |
BOOST_PP_TUPLE_ELEM(0, BOOST_PP_SEQ_ELEM(n, args)) | |
#define VEXCL_FUNCTION_ARG_NAME(n, args) \ | |
BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(1, BOOST_PP_SEQ_ELEM(n, args))) | |
#define VEXCL_FUNCTION_DEF_ARG(z, n, args) \ | |
src.parameter<VEXCL_FUNCTION_ARG_TYPE(n, args)>( \ | |
VEXCL_FUNCTION_ARG_NAME(n, args)); | |
#define VEXCL_FUNCTION_DEFINE_DEP(z, data, dep) dep.define(src); | |
#define VEX_FUNCTION_SINK(type, func_name, nargs, args, deps, body) \ | |
struct vex_function_##func_name : vex::user_function { \ | |
typedef type value_type; \ | |
vex_function_##func_name() {} \ | |
template <BOOST_PP_ENUM_PARAMS(nargs, class Arg)> \ | |
typename boost::proto::result_of::make_expr< \ | |
boost::proto::tag::function, vex_function_##func_name, \ | |
BOOST_PP_ENUM(nargs, VEXCL_FUNCTION_PRINT_ARG_REF, ~) \ | |
>::type const \ | |
operator()( BOOST_PP_ENUM(nargs, VEXCL_FUNCTION_PRINT_PARAM, ~) ) const { \ | |
return boost::proto::make_expr<boost::proto::tag::function>( \ | |
vex_function_##func_name, \ | |
BOOST_PP_ENUM(nargs, VEXCL_FUNCTION_PRINT_BOOST_REF, ~) \ | |
); \ | |
} \ | |
static std::string name() { return #func_name; } \ | |
static void define(vex::backend::source_generator &src) { \ | |
define( src, name() ); \ | |
} \ | |
static void define(vex::backend::source_generator &src, \ | |
const std::string &fname) \ | |
{ \ | |
BOOST_PP_SEQ_FOR_EACH(VEXCL_FUNCTION_DEFINE_DEP, ~, deps) \ | |
src.function< type >(fname).open("("); \ | |
BOOST_PP_REPEAT(nargs, VEXCL_FUNCTION_DEF_ARG, args) \ | |
src.close(")").open("{").new_line() << body; \ | |
src.close("}"); \ | |
} \ | |
} const func_name | |
#define VEXCL_FUNCTION_MAKE_SEQ_0(...) ((__VA_ARGS__)) VEXCL_FUNCTION_MAKE_SEQ_1 | |
#define VEXCL_FUNCTION_MAKE_SEQ_1(...) ((__VA_ARGS__)) VEXCL_FUNCTION_MAKE_SEQ_0 | |
#define VEXCL_FUNCTION_MAKE_SEQ_0_END | |
#define VEXCL_FUNCTION_MAKE_SEQ_1_END | |
#define VEXCL_FUNCTION_MAKE_SEQ(args) \ | |
BOOST_PP_CAT(VEXCL_FUNCTION_MAKE_SEQ_0 args,_END) | |
#define VEX_FUNCTION_SD(type, name, args, deps, body) \ | |
VEX_FUNCTION_SINK(type, name, \ | |
BOOST_PP_SEQ_SIZE(VEXCL_FUNCTION_MAKE_SEQ(args)), \ | |
VEXCL_FUNCTION_MAKE_SEQ(args), deps, body) | |
#define VEX_FUNCTION_DS VEX_FUNCTION_SD | |
#define VEX_FUNCTION_S(type, name, args, body) \ | |
VEX_FUNCTION_SD(type, name, args, , body) | |
#define VEX_FUNCTION_D(type, name, args, deps, ...) \ | |
VEX_FUNCTION_SD(type, name, args, deps, BOOST_PP_STRINGIZE(__VA_ARGS__) ) | |
#define VEX_FUNCTION(type, name, args, ...) \ | |
VEX_FUNCTION_S(type, name, args, BOOST_PP_STRINGIZE(__VA_ARGS__)) | |
VEX_FUNCTION_D(int, append, (double, a)(const char *, b), (sum)(min), return a + b;); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment