330 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			330 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 
								 | 
							
								//---------------------------------------------------------------------------//
							 | 
						||
| 
								 | 
							
								// 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_CONTEXT_HPP
							 | 
						||
| 
								 | 
							
								#define BOOST_COMPUTE_LAMBDA_CONTEXT_HPP
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <boost/proto/core.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/proto/context.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/type_traits.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/preprocessor/repetition.hpp>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <boost/compute/config.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/compute/function.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/compute/lambda/result_of.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/compute/lambda/functional.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/compute/type_traits/result_of.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/compute/type_traits/type_name.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/compute/detail/meta_kernel.hpp>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace boost {
							 | 
						||
| 
								 | 
							
								namespace compute {
							 | 
						||
| 
								 | 
							
								namespace lambda {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace mpl = boost::mpl;
							 | 
						||
| 
								 | 
							
								namespace proto = boost::proto;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define BOOST_COMPUTE_LAMBDA_CONTEXT_DEFINE_BINARY_OPERATOR(tag, op) \
							 | 
						||
| 
								 | 
							
								    template<class LHS, class RHS> \
							 | 
						||
| 
								 | 
							
								    void operator()(tag, const LHS &lhs, const RHS &rhs) \
							 | 
						||
| 
								 | 
							
								    { \
							 | 
						||
| 
								 | 
							
								        if(proto::arity_of<LHS>::value > 0){ \
							 | 
						||
| 
								 | 
							
								            stream << '('; \
							 | 
						||
| 
								 | 
							
								            proto::eval(lhs, *this); \
							 | 
						||
| 
								 | 
							
								            stream << ')'; \
							 | 
						||
| 
								 | 
							
								        } \
							 | 
						||
| 
								 | 
							
								        else { \
							 | 
						||
| 
								 | 
							
								            proto::eval(lhs, *this); \
							 | 
						||
| 
								 | 
							
								        } \
							 | 
						||
| 
								 | 
							
								        \
							 | 
						||
| 
								 | 
							
								        stream << op; \
							 | 
						||
| 
								 | 
							
								        \
							 | 
						||
| 
								 | 
							
								        if(proto::arity_of<RHS>::value > 0){ \
							 | 
						||
| 
								 | 
							
								            stream << '('; \
							 | 
						||
| 
								 | 
							
								            proto::eval(rhs, *this); \
							 | 
						||
| 
								 | 
							
								            stream << ')'; \
							 | 
						||
| 
								 | 
							
								        } \
							 | 
						||
| 
								 | 
							
								        else { \
							 | 
						||
| 
								 | 
							
								            proto::eval(rhs, *this); \
							 | 
						||
| 
								 | 
							
								        } \
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// lambda expression context
							 | 
						||
| 
								 | 
							
								template<class Args>
							 | 
						||
| 
								 | 
							
								struct context : proto::callable_context<context<Args> >
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    typedef void result_type;
							 | 
						||
| 
								 | 
							
								    typedef Args args_tuple;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // create a lambda context for kernel with args
							 | 
						||
| 
								 | 
							
								    context(boost::compute::detail::meta_kernel &kernel, const Args &args_)
							 | 
						||
| 
								 | 
							
								        : stream(kernel),
							 | 
						||
| 
								 | 
							
								          args(args_)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // handle terminals
							 | 
						||
| 
								 | 
							
								    template<class T>
							 | 
						||
| 
								 | 
							
								    void operator()(proto::tag::terminal, const T &x)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        // terminal values in lambda expressions are always literals
							 | 
						||
| 
								 | 
							
								        stream << stream.lit(x);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // handle placeholders
							 | 
						||
| 
								 | 
							
								    template<int I>
							 | 
						||
| 
								 | 
							
								    void operator()(proto::tag::terminal, placeholder<I>)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        stream << boost::get<I>(args);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // handle functions
							 | 
						||
| 
								 | 
							
								    #define BOOST_COMPUTE_LAMBDA_CONTEXT_FUNCTION_ARG(z, n, unused) \
							 | 
						||
| 
								 | 
							
								        BOOST_PP_COMMA_IF(n) BOOST_PP_CAT(const Arg, n) BOOST_PP_CAT(&arg, n)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    #define BOOST_COMPUTE_LAMBDA_CONTEXT_FUNCTION(z, n, unused) \
							 | 
						||
| 
								 | 
							
								    template<class F, BOOST_PP_ENUM_PARAMS(n, class Arg)> \
							 | 
						||
| 
								 | 
							
								    void operator()( \
							 | 
						||
| 
								 | 
							
								        proto::tag::function, \
							 | 
						||
| 
								 | 
							
								        const F &function, \
							 | 
						||
| 
								 | 
							
								        BOOST_PP_REPEAT(n, BOOST_COMPUTE_LAMBDA_CONTEXT_FUNCTION_ARG, ~) \
							 | 
						||
| 
								 | 
							
								    ) \
							 | 
						||
| 
								 | 
							
								    { \
							 | 
						||
| 
								 | 
							
								        proto::value(function).apply(*this, BOOST_PP_ENUM_PARAMS(n, arg)); \
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_LAMBDA_CONTEXT_FUNCTION, ~)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    #undef BOOST_COMPUTE_LAMBDA_CONTEXT_FUNCTION
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // operators
							 | 
						||
| 
								 | 
							
								    BOOST_COMPUTE_LAMBDA_CONTEXT_DEFINE_BINARY_OPERATOR(proto::tag::plus, '+')
							 | 
						||
| 
								 | 
							
								    BOOST_COMPUTE_LAMBDA_CONTEXT_DEFINE_BINARY_OPERATOR(proto::tag::minus, '-')
							 | 
						||
| 
								 | 
							
								    BOOST_COMPUTE_LAMBDA_CONTEXT_DEFINE_BINARY_OPERATOR(proto::tag::multiplies, '*')
							 | 
						||
| 
								 | 
							
								    BOOST_COMPUTE_LAMBDA_CONTEXT_DEFINE_BINARY_OPERATOR(proto::tag::divides, '/')
							 | 
						||
| 
								 | 
							
								    BOOST_COMPUTE_LAMBDA_CONTEXT_DEFINE_BINARY_OPERATOR(proto::tag::modulus, '%')
							 | 
						||
| 
								 | 
							
								    BOOST_COMPUTE_LAMBDA_CONTEXT_DEFINE_BINARY_OPERATOR(proto::tag::less, '<')
							 | 
						||
| 
								 | 
							
								    BOOST_COMPUTE_LAMBDA_CONTEXT_DEFINE_BINARY_OPERATOR(proto::tag::greater, '>')
							 | 
						||
| 
								 | 
							
								    BOOST_COMPUTE_LAMBDA_CONTEXT_DEFINE_BINARY_OPERATOR(proto::tag::less_equal, "<=")
							 | 
						||
| 
								 | 
							
								    BOOST_COMPUTE_LAMBDA_CONTEXT_DEFINE_BINARY_OPERATOR(proto::tag::greater_equal, ">=")
							 | 
						||
| 
								 | 
							
								    BOOST_COMPUTE_LAMBDA_CONTEXT_DEFINE_BINARY_OPERATOR(proto::tag::equal_to, "==")
							 | 
						||
| 
								 | 
							
								    BOOST_COMPUTE_LAMBDA_CONTEXT_DEFINE_BINARY_OPERATOR(proto::tag::not_equal_to, "!=")
							 | 
						||
| 
								 | 
							
								    BOOST_COMPUTE_LAMBDA_CONTEXT_DEFINE_BINARY_OPERATOR(proto::tag::logical_and, "&&")
							 | 
						||
| 
								 | 
							
								    BOOST_COMPUTE_LAMBDA_CONTEXT_DEFINE_BINARY_OPERATOR(proto::tag::logical_or, "||")
							 | 
						||
| 
								 | 
							
								    BOOST_COMPUTE_LAMBDA_CONTEXT_DEFINE_BINARY_OPERATOR(proto::tag::bitwise_and, '&')
							 | 
						||
| 
								 | 
							
								    BOOST_COMPUTE_LAMBDA_CONTEXT_DEFINE_BINARY_OPERATOR(proto::tag::bitwise_or, '|')
							 | 
						||
| 
								 | 
							
								    BOOST_COMPUTE_LAMBDA_CONTEXT_DEFINE_BINARY_OPERATOR(proto::tag::bitwise_xor, '^')
							 | 
						||
| 
								 | 
							
								    BOOST_COMPUTE_LAMBDA_CONTEXT_DEFINE_BINARY_OPERATOR(proto::tag::assign, '=')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // subscript operator
							 | 
						||
| 
								 | 
							
								    template<class LHS, class RHS>
							 | 
						||
| 
								 | 
							
								    void operator()(proto::tag::subscript, const LHS &lhs, const RHS &rhs)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        proto::eval(lhs, *this);
							 | 
						||
| 
								 | 
							
								        stream << '[';
							 | 
						||
| 
								 | 
							
								        proto::eval(rhs, *this);
							 | 
						||
| 
								 | 
							
								        stream << ']';
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // ternary conditional operator
							 | 
						||
| 
								 | 
							
								    template<class Pred, class Arg1, class Arg2>
							 | 
						||
| 
								 | 
							
								    void operator()(proto::tag::if_else_, const Pred &p, const Arg1 &x, const Arg2 &y)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        proto::eval(p, *this);
							 | 
						||
| 
								 | 
							
								        stream << '?';
							 | 
						||
| 
								 | 
							
								        proto::eval(x, *this);
							 | 
						||
| 
								 | 
							
								        stream << ':';
							 | 
						||
| 
								 | 
							
								        proto::eval(y, *this);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    boost::compute::detail::meta_kernel &stream;
							 | 
						||
| 
								 | 
							
								    Args args;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace detail {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<class Expr, class Arg>
							 | 
						||
| 
								 | 
							
								struct invoked_unary_expression
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    typedef typename ::boost::compute::result_of<Expr(Arg)>::type result_type;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    invoked_unary_expression(const Expr &expr, const Arg &arg)
							 | 
						||
| 
								 | 
							
								        : m_expr(expr),
							 | 
						||
| 
								 | 
							
								          m_arg(arg)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Expr m_expr;
							 | 
						||
| 
								 | 
							
								    Arg m_arg;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<class Expr, class Arg>
							 | 
						||
| 
								 | 
							
								boost::compute::detail::meta_kernel&
							 | 
						||
| 
								 | 
							
								operator<<(boost::compute::detail::meta_kernel &kernel,
							 | 
						||
| 
								 | 
							
								           const invoked_unary_expression<Expr, Arg> &expr)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    context<boost::tuple<Arg> > ctx(kernel, boost::make_tuple(expr.m_arg));
							 | 
						||
| 
								 | 
							
								    proto::eval(expr.m_expr, ctx);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return kernel;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<class Expr, class Arg1, class Arg2>
							 | 
						||
| 
								 | 
							
								struct invoked_binary_expression
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    typedef typename ::boost::compute::result_of<Expr(Arg1, Arg2)>::type result_type;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    invoked_binary_expression(const Expr &expr,
							 | 
						||
| 
								 | 
							
								                              const Arg1 &arg1,
							 | 
						||
| 
								 | 
							
								                              const Arg2 &arg2)
							 | 
						||
| 
								 | 
							
								        : m_expr(expr),
							 | 
						||
| 
								 | 
							
								          m_arg1(arg1),
							 | 
						||
| 
								 | 
							
								          m_arg2(arg2)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    Expr m_expr;
							 | 
						||
| 
								 | 
							
								    Arg1 m_arg1;
							 | 
						||
| 
								 | 
							
								    Arg2 m_arg2;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								template<class Expr, class Arg1, class Arg2>
							 | 
						||
| 
								 | 
							
								boost::compute::detail::meta_kernel&
							 | 
						||
| 
								 | 
							
								operator<<(boost::compute::detail::meta_kernel &kernel,
							 | 
						||
| 
								 | 
							
								           const invoked_binary_expression<Expr, Arg1, Arg2> &expr)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    context<boost::tuple<Arg1, Arg2> > ctx(
							 | 
						||
| 
								 | 
							
								        kernel,
							 | 
						||
| 
								 | 
							
								        boost::make_tuple(expr.m_arg1, expr.m_arg2)
							 | 
						||
| 
								 | 
							
								    );
							 | 
						||
| 
								 | 
							
								    proto::eval(expr.m_expr, ctx);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return kernel;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								} // end detail namespace
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// forward declare domain
							 | 
						||
| 
								 | 
							
								struct domain;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// lambda expression wrapper
							 | 
						||
| 
								 | 
							
								template<class Expr>
							 | 
						||
| 
								 | 
							
								struct expression : proto::extends<Expr, expression<Expr>, domain>
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    typedef proto::extends<Expr, expression<Expr>, domain> base_type;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    BOOST_PROTO_EXTENDS_USING_ASSIGN(expression)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    expression(const Expr &expr = Expr())
							 | 
						||
| 
								 | 
							
								        : base_type(expr)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // result_of protocol
							 | 
						||
| 
								 | 
							
								    template<class Signature>
							 | 
						||
| 
								 | 
							
								    struct result
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template<class This>
							 | 
						||
| 
								 | 
							
								    struct result<This()>
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        typedef
							 | 
						||
| 
								 | 
							
								            typename ::boost::compute::lambda::result_of<Expr>::type type;
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template<class This, class Arg>
							 | 
						||
| 
								 | 
							
								    struct result<This(Arg)>
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        typedef
							 | 
						||
| 
								 | 
							
								            typename ::boost::compute::lambda::result_of<
							 | 
						||
| 
								 | 
							
								                Expr,
							 | 
						||
| 
								 | 
							
								                typename boost::tuple<Arg>
							 | 
						||
| 
								 | 
							
								            >::type type;
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template<class This, class Arg1, class Arg2>
							 | 
						||
| 
								 | 
							
								    struct result<This(Arg1, Arg2)>
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        typedef typename
							 | 
						||
| 
								 | 
							
								            ::boost::compute::lambda::result_of<
							 | 
						||
| 
								 | 
							
								                Expr,
							 | 
						||
| 
								 | 
							
								                typename boost::tuple<Arg1, Arg2>
							 | 
						||
| 
								 | 
							
								            >::type type;
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template<class Arg>
							 | 
						||
| 
								 | 
							
								    detail::invoked_unary_expression<expression<Expr>, Arg>
							 | 
						||
| 
								 | 
							
								    operator()(const Arg &x) const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return detail::invoked_unary_expression<expression<Expr>, Arg>(*this, x);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template<class Arg1, class Arg2>
							 | 
						||
| 
								 | 
							
								    detail::invoked_binary_expression<expression<Expr>, Arg1, Arg2>
							 | 
						||
| 
								 | 
							
								    operator()(const Arg1 &x, const Arg2 &y) const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return detail::invoked_binary_expression<
							 | 
						||
| 
								 | 
							
								                   expression<Expr>,
							 | 
						||
| 
								 | 
							
								                   Arg1,
							 | 
						||
| 
								 | 
							
								                   Arg2
							 | 
						||
| 
								 | 
							
								                >(*this, x, y);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // function<> conversion operator
							 | 
						||
| 
								 | 
							
								    template<class R, class A1>
							 | 
						||
| 
								 | 
							
								    operator function<R(A1)>() const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        using ::boost::compute::detail::meta_kernel;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        std::stringstream source;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        ::boost::compute::detail::meta_kernel_variable<A1> arg1("x");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        source << "inline " << type_name<R>() << " lambda"
							 | 
						||
| 
								 | 
							
								               << ::boost::compute::detail::generate_argument_list<R(A1)>('x')
							 | 
						||
| 
								 | 
							
								               << "{\n"
							 | 
						||
| 
								 | 
							
								               << "    return " << meta_kernel::expr_to_string((*this)(arg1)) << ";\n"
							 | 
						||
| 
								 | 
							
								               << "}\n";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return make_function_from_source<R(A1)>("lambda", source.str());
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    template<class R, class A1, class A2>
							 | 
						||
| 
								 | 
							
								    operator function<R(A1, A2)>() const
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        using ::boost::compute::detail::meta_kernel;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        std::stringstream source;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        ::boost::compute::detail::meta_kernel_variable<A1> arg1("x");
							 | 
						||
| 
								 | 
							
								        ::boost::compute::detail::meta_kernel_variable<A1> arg2("y");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        source << "inline " << type_name<R>() << " lambda"
							 | 
						||
| 
								 | 
							
								               << ::boost::compute::detail::generate_argument_list<R(A1, A2)>('x')
							 | 
						||
| 
								 | 
							
								               << "{\n"
							 | 
						||
| 
								 | 
							
								               << "    return " << meta_kernel::expr_to_string((*this)(arg1, arg2)) << ";\n"
							 | 
						||
| 
								 | 
							
								               << "}\n";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return make_function_from_source<R(A1, A2)>("lambda", source.str());
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// lambda expression domain
							 | 
						||
| 
								 | 
							
								struct domain : proto::domain<proto::generator<expression> >
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								} // end lambda namespace
							 | 
						||
| 
								 | 
							
								} // end compute namespace
							 | 
						||
| 
								 | 
							
								} // end boost namespace
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif // BOOST_COMPUTE_LAMBDA_CONTEXT_HPP
							 |