diff options
Diffstat (limited to 'boost/compute/lambda/functional.hpp')
-rw-r--r-- | boost/compute/lambda/functional.hpp | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/boost/compute/lambda/functional.hpp b/boost/compute/lambda/functional.hpp new file mode 100644 index 0000000000..dd7190e4d9 --- /dev/null +++ b/boost/compute/lambda/functional.hpp @@ -0,0 +1,242 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com> +// +// 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 <boost/tuple/tuple.hpp> +#include <boost/lexical_cast.hpp> + +#include <boost/proto/core.hpp> +#include <boost/preprocessor/cat.hpp> +#include <boost/preprocessor/stringize.hpp> + +#include <boost/compute/functional/get.hpp> +#include <boost/compute/lambda/result_of.hpp> +#include <boost/compute/lambda/placeholder.hpp> + +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<class Expr, class Args> \ + struct lambda_result \ + { \ + typedef int type; \ + }; \ + \ + template<class Context, class Arg> \ + static void apply(Context &ctx, const Arg &arg) \ + { \ + ctx.stream << #name << "("; \ + proto::eval(arg, ctx); \ + ctx.stream << ")"; \ + } \ + }; \ + } \ + template<class Arg> \ + 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<proto::tag::function>( \ + 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<class Expr, class Args> \ + struct lambda_result \ + { \ + typedef typename proto::result_of::child_c<Expr, 1>::type Arg1; \ + typedef typename ::boost::compute::lambda::result_of<Arg1, Args>::type type; \ + }; \ + \ + template<class Context, class Arg> \ + static void apply(Context &ctx, const Arg &arg) \ + { \ + ctx.stream << #name << "("; \ + proto::eval(arg, ctx); \ + ctx.stream << ")"; \ + } \ + }; \ + } \ + template<class Arg> \ + 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<proto::tag::function>( \ + 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<class Expr, class Args> \ + struct lambda_result \ + { \ + typedef typename proto::result_of::child_c<Expr, 1>::type Arg1; \ + typedef typename ::boost::compute::lambda::result_of<Arg1, Args>::type type; \ + }; \ + \ + template<class Context, class Arg1, class Arg2> \ + 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<class Arg1, class Arg2> \ + 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<proto::tag::function>( \ + 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<class Expr, class Args> \ + struct lambda_result \ + { \ + typedef typename proto::result_of::child_c<Expr, 1>::type Arg1; \ + typedef typename ::boost::compute::lambda::result_of<Arg1, Args>::type result_type; \ + typedef typename ::boost::compute::scalar_type<result_type>::type type; \ + }; \ + \ + template<class Context, class Arg1, class Arg2> \ + 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<class Arg1, class Arg2> \ + 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<proto::tag::function>( \ + 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<class Expr, class Args> \ + struct lambda_result \ + { \ + typedef typename proto::result_of::child_c<Expr, 1>::type Arg1; \ + typedef typename ::boost::compute::lambda::result_of<Arg1, Args>::type type; \ + }; \ + \ + template<class Context, class Arg1, class Arg2, class Arg3> \ + 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<class Arg1, class Arg2, class Arg3> \ + 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<proto::tag::function>( \ + 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 |