summaryrefslogtreecommitdiff
path: root/boost/compute/lambda/functional.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/compute/lambda/functional.hpp')
-rw-r--r--boost/compute/lambda/functional.hpp242
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