//---------------------------------------------------------------------------// // Copyright (c) 2013 Kyle Lutz // // Distributed under the Boost Software License, Version 1.0 // See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt // // See http://boostorg.github.com/compute for more information. //---------------------------------------------------------------------------// #ifndef BOOST_COMPUTE_LAMBDA_FUNCTIONAL_HPP #define BOOST_COMPUTE_LAMBDA_FUNCTIONAL_HPP #include #include #include #include #include #include #include #include namespace boost { namespace compute { namespace lambda { namespace mpl = boost::mpl; namespace proto = boost::proto; // wraps a unary boolean function #define BOOST_COMPUTE_LAMBDA_WRAP_BOOLEAN_UNARY_FUNCTION(name) \ namespace detail { \ struct BOOST_PP_CAT(name, _func) \ { \ template \ struct lambda_result \ { \ typedef int type; \ }; \ \ template \ static void apply(Context &ctx, const Arg &arg) \ { \ ctx.stream << #name << "("; \ proto::eval(arg, ctx); \ ctx.stream << ")"; \ } \ }; \ } \ template \ inline typename proto::result_of::make_expr< \ proto::tag::function, BOOST_PP_CAT(detail::name, _func), const Arg& \ >::type const \ name(const Arg &arg) \ { \ return proto::make_expr( \ BOOST_PP_CAT(detail::name, _func)(), ::boost::ref(arg) \ ); \ } // wraps a unary function who's return type is the same as the argument type #define BOOST_COMPUTE_LAMBDA_WRAP_UNARY_FUNCTION_T(name) \ namespace detail { \ struct BOOST_PP_CAT(name, _func) \ { \ template \ struct lambda_result \ { \ typedef typename proto::result_of::child_c::type Arg1; \ typedef typename ::boost::compute::lambda::result_of::type type; \ }; \ \ template \ static void apply(Context &ctx, const Arg &arg) \ { \ ctx.stream << #name << "("; \ proto::eval(arg, ctx); \ ctx.stream << ")"; \ } \ }; \ } \ template \ inline typename proto::result_of::make_expr< \ proto::tag::function, BOOST_PP_CAT(detail::name, _func), const Arg& \ >::type const \ name(const Arg &arg) \ { \ return proto::make_expr( \ BOOST_PP_CAT(detail::name, _func)(), ::boost::ref(arg) \ ); \ } // wraps a binary function #define BOOST_COMPUTE_LAMBDA_WRAP_BINARY_FUNCTION(name) \ namespace detail { \ struct BOOST_PP_CAT(name, _func) \ { \ template \ struct lambda_result \ { \ typedef typename proto::result_of::child_c::type Arg1; \ typedef typename ::boost::compute::lambda::result_of::type type; \ }; \ \ template \ static void apply(Context &ctx, const Arg1 &arg1, const Arg2 &arg2) \ { \ ctx.stream << #name << "("; \ proto::eval(arg1, ctx); \ ctx.stream << ", "; \ proto::eval(arg2, ctx); \ ctx.stream << ")"; \ } \ }; \ } \ template \ inline typename proto::result_of::make_expr< \ proto::tag::function, BOOST_PP_CAT(detail::name, _func), const Arg1&, const Arg2& \ >::type const \ name(const Arg1 &arg1, const Arg2 &arg2) \ { \ return proto::make_expr( \ BOOST_PP_CAT(detail::name, _func)(), ::boost::ref(arg1), ::boost::ref(arg2) \ ); \ } // wraps a binary function who's result type is the scalar type of the first argument #define BOOST_COMPUTE_LAMBDA_WRAP_BINARY_FUNCTION_ST(name) \ namespace detail { \ struct BOOST_PP_CAT(name, _func) \ { \ template \ struct lambda_result \ { \ typedef typename proto::result_of::child_c::type Arg1; \ typedef typename ::boost::compute::lambda::result_of::type result_type; \ typedef typename ::boost::compute::scalar_type::type type; \ }; \ \ template \ static void apply(Context &ctx, const Arg1 &arg1, const Arg2 &arg2) \ { \ ctx.stream << #name << "("; \ proto::eval(arg1, ctx); \ ctx.stream << ", "; \ proto::eval(arg2, ctx); \ ctx.stream << ")"; \ } \ }; \ } \ template \ inline typename proto::result_of::make_expr< \ proto::tag::function, BOOST_PP_CAT(detail::name, _func), const Arg1&, const Arg2& \ >::type const \ name(const Arg1 &arg1, const Arg2 &arg2) \ { \ return proto::make_expr( \ BOOST_PP_CAT(detail::name, _func)(), ::boost::ref(arg1), ::boost::ref(arg2) \ ); \ } // wraps a ternary function #define BOOST_COMPUTE_LAMBDA_WRAP_TERNARY_FUNCTION(name) \ namespace detail { \ struct BOOST_PP_CAT(name, _func) \ { \ template \ struct lambda_result \ { \ typedef typename proto::result_of::child_c::type Arg1; \ typedef typename ::boost::compute::lambda::result_of::type type; \ }; \ \ template \ static void apply(Context &ctx, const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3) \ { \ ctx.stream << #name << "("; \ proto::eval(arg1, ctx); \ ctx.stream << ", "; \ proto::eval(arg2, ctx); \ ctx.stream << ", "; \ proto::eval(arg3, ctx); \ ctx.stream << ")"; \ } \ }; \ } \ template \ inline typename proto::result_of::make_expr< \ proto::tag::function, BOOST_PP_CAT(detail::name, _func), const Arg1&, const Arg2&, const Arg3& \ >::type const \ name(const Arg1 &arg1, const Arg2 &arg2, const Arg3 &arg3) \ { \ return proto::make_expr( \ BOOST_PP_CAT(detail::name, _func)(), ::boost::ref(arg1), ::boost::ref(arg2), ::boost::ref(arg3) \ ); \ } BOOST_COMPUTE_LAMBDA_WRAP_BOOLEAN_UNARY_FUNCTION(all) BOOST_COMPUTE_LAMBDA_WRAP_BOOLEAN_UNARY_FUNCTION(any) BOOST_COMPUTE_LAMBDA_WRAP_BOOLEAN_UNARY_FUNCTION(isinf) BOOST_COMPUTE_LAMBDA_WRAP_BOOLEAN_UNARY_FUNCTION(isnan) BOOST_COMPUTE_LAMBDA_WRAP_BOOLEAN_UNARY_FUNCTION(isfinite) BOOST_COMPUTE_LAMBDA_WRAP_UNARY_FUNCTION_T(abs) BOOST_COMPUTE_LAMBDA_WRAP_UNARY_FUNCTION_T(cos) BOOST_COMPUTE_LAMBDA_WRAP_UNARY_FUNCTION_T(acos) BOOST_COMPUTE_LAMBDA_WRAP_UNARY_FUNCTION_T(sin) BOOST_COMPUTE_LAMBDA_WRAP_UNARY_FUNCTION_T(asin) BOOST_COMPUTE_LAMBDA_WRAP_UNARY_FUNCTION_T(tan) BOOST_COMPUTE_LAMBDA_WRAP_UNARY_FUNCTION_T(atan) BOOST_COMPUTE_LAMBDA_WRAP_UNARY_FUNCTION_T(sqrt) BOOST_COMPUTE_LAMBDA_WRAP_UNARY_FUNCTION_T(rsqrt) BOOST_COMPUTE_LAMBDA_WRAP_UNARY_FUNCTION_T(exp) BOOST_COMPUTE_LAMBDA_WRAP_UNARY_FUNCTION_T(exp2) BOOST_COMPUTE_LAMBDA_WRAP_UNARY_FUNCTION_T(exp10) BOOST_COMPUTE_LAMBDA_WRAP_UNARY_FUNCTION_T(log) BOOST_COMPUTE_LAMBDA_WRAP_UNARY_FUNCTION_T(log2) BOOST_COMPUTE_LAMBDA_WRAP_UNARY_FUNCTION_T(log10) BOOST_COMPUTE_LAMBDA_WRAP_UNARY_FUNCTION_T(round) BOOST_COMPUTE_LAMBDA_WRAP_UNARY_FUNCTION_T(length) BOOST_COMPUTE_LAMBDA_WRAP_BINARY_FUNCTION(cross) BOOST_COMPUTE_LAMBDA_WRAP_BINARY_FUNCTION(pow) BOOST_COMPUTE_LAMBDA_WRAP_BINARY_FUNCTION(pown) BOOST_COMPUTE_LAMBDA_WRAP_BINARY_FUNCTION(powr) BOOST_COMPUTE_LAMBDA_WRAP_BINARY_FUNCTION_ST(dot) BOOST_COMPUTE_LAMBDA_WRAP_BINARY_FUNCTION_ST(distance) BOOST_COMPUTE_LAMBDA_WRAP_TERNARY_FUNCTION(clamp) BOOST_COMPUTE_LAMBDA_WRAP_TERNARY_FUNCTION(fma) BOOST_COMPUTE_LAMBDA_WRAP_TERNARY_FUNCTION(mad) BOOST_COMPUTE_LAMBDA_WRAP_TERNARY_FUNCTION(smoothstep) } // end lambda namespace } // end compute namespace } // end boost namespace #endif // BOOST_COMPUTE_LAMBDA_FUNCTIONAL_HPP