stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork
This commit is contained in:
@@ -0,0 +1,329 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// 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
|
||||
@@ -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
|
||||
@@ -0,0 +1,148 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// Copyright (c) 2013-2014 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_GET_HPP
|
||||
#define BOOST_COMPUTE_LAMBDA_GET_HPP
|
||||
|
||||
#include <boost/preprocessor/repetition.hpp>
|
||||
|
||||
#include <boost/compute/config.hpp>
|
||||
#include <boost/compute/functional/get.hpp>
|
||||
#include <boost/compute/lambda/placeholder.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
namespace lambda {
|
||||
namespace detail {
|
||||
|
||||
// function wrapper for get<N>() in lambda expressions
|
||||
template<size_t N>
|
||||
struct get_func
|
||||
{
|
||||
template<class Expr, class Args>
|
||||
struct lambda_result
|
||||
{
|
||||
typedef typename proto::result_of::child_c<Expr, 1>::type Arg;
|
||||
typedef typename ::boost::compute::lambda::result_of<Arg, Args>::type T;
|
||||
typedef typename ::boost::compute::detail::get_result_type<N, T>::type type;
|
||||
};
|
||||
|
||||
template<class Context, class Arg>
|
||||
struct make_get_result_type
|
||||
{
|
||||
typedef typename boost::remove_cv<
|
||||
typename boost::compute::lambda::result_of<
|
||||
Arg, typename Context::args_tuple
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
// returns the suffix string for get<N>() in lambda expressions
|
||||
// (e.g. ".x" for get<0>() with float4)
|
||||
template<class T>
|
||||
struct make_get_suffix
|
||||
{
|
||||
static std::string value()
|
||||
{
|
||||
BOOST_STATIC_ASSERT(N < 16);
|
||||
|
||||
std::stringstream stream;
|
||||
|
||||
if(N < 10){
|
||||
stream << ".s" << uint_(N);
|
||||
}
|
||||
else if(N < 16){
|
||||
stream << ".s" << char('a' + (N - 10));
|
||||
}
|
||||
|
||||
return stream.str();
|
||||
}
|
||||
};
|
||||
|
||||
// get<N>() specialization for std::pair<T1, T2>
|
||||
template<class T1, class T2>
|
||||
struct make_get_suffix<std::pair<T1, T2> >
|
||||
{
|
||||
static std::string value()
|
||||
{
|
||||
BOOST_STATIC_ASSERT(N < 2);
|
||||
|
||||
if(N == 0){
|
||||
return ".first";
|
||||
}
|
||||
else {
|
||||
return ".second";
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// get<N>() specialization for boost::tuple<T...>
|
||||
#define BOOST_COMPUTE_LAMBDA_GET_MAKE_TUPLE_SUFFIX(z, n, unused) \
|
||||
template<BOOST_PP_ENUM_PARAMS(n, class T)> \
|
||||
struct make_get_suffix<boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> > \
|
||||
{ \
|
||||
static std::string value() \
|
||||
{ \
|
||||
BOOST_STATIC_ASSERT(N < n); \
|
||||
return ".v" + boost::lexical_cast<std::string>(N); \
|
||||
} \
|
||||
};
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_LAMBDA_GET_MAKE_TUPLE_SUFFIX, ~)
|
||||
|
||||
#undef BOOST_COMPUTE_LAMBDA_GET_MAKE_TUPLE_SUFFIX
|
||||
|
||||
template<class Context, class Arg>
|
||||
static void dispatch_apply_terminal(Context &ctx, const Arg &arg)
|
||||
{
|
||||
typedef typename make_get_result_type<Context, Arg>::type T;
|
||||
|
||||
proto::eval(arg, ctx);
|
||||
ctx.stream << make_get_suffix<T>::value();
|
||||
}
|
||||
|
||||
template<class Context, int I>
|
||||
static void dispatch_apply_terminal(Context &ctx, placeholder<I>)
|
||||
{
|
||||
ctx.stream << ::boost::compute::get<N>()(::boost::get<I>(ctx.args));
|
||||
}
|
||||
|
||||
template<class Context, class Arg>
|
||||
static void dispatch_apply(Context &ctx, const Arg &arg, proto::tag::terminal)
|
||||
{
|
||||
dispatch_apply_terminal(ctx, proto::value(arg));
|
||||
}
|
||||
|
||||
template<class Context, class Arg>
|
||||
static void apply(Context &ctx, const Arg &arg)
|
||||
{
|
||||
dispatch_apply(ctx, arg, typename proto::tag_of<Arg>::type());
|
||||
}
|
||||
};
|
||||
|
||||
} // end detail namespace
|
||||
|
||||
// get<N>()
|
||||
template<size_t N, class Arg>
|
||||
inline typename proto::result_of::make_expr<
|
||||
proto::tag::function, detail::get_func<N>, const Arg&
|
||||
>::type const
|
||||
get(const Arg &arg)
|
||||
{
|
||||
return proto::make_expr<proto::tag::function>(
|
||||
detail::get_func<N>(), ::boost::ref(arg)
|
||||
);
|
||||
}
|
||||
|
||||
} // end lambda namespace
|
||||
} // end compute namespace
|
||||
} // end boost namespace
|
||||
|
||||
#endif // BOOST_COMPUTE_LAMBDA_GET_HPP
|
||||
@@ -0,0 +1,70 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// Copyright (c) 2013-2014 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_MAKE_PAIR_HPP
|
||||
#define BOOST_COMPUTE_LAMBDA_MAKE_PAIR_HPP
|
||||
|
||||
#include <boost/compute/types/pair.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
namespace lambda {
|
||||
namespace detail {
|
||||
|
||||
// function wrapper for make_pair() in lambda expressions
|
||||
struct make_pair_func
|
||||
{
|
||||
template<class Expr, class Args>
|
||||
struct lambda_result
|
||||
{
|
||||
typedef typename proto::result_of::child_c<Expr, 1>::type Arg1;
|
||||
typedef typename proto::result_of::child_c<Expr, 2>::type Arg2;
|
||||
|
||||
typedef typename lambda::result_of<Arg1, Args>::type T1;
|
||||
typedef typename lambda::result_of<Arg2, Args>::type T2;
|
||||
|
||||
typedef std::pair<T1, T2> type;
|
||||
};
|
||||
|
||||
template<class Context, class Arg1, class Arg2>
|
||||
static void apply(Context &ctx, const Arg1 &arg1, const Arg2 &arg2)
|
||||
{
|
||||
typedef typename lambda::result_of<Arg1, typename Context::args_tuple>::type T1;
|
||||
typedef typename lambda::result_of<Arg2, typename Context::args_tuple>::type T2;
|
||||
|
||||
ctx.stream << "boost_make_pair(";
|
||||
ctx.stream << type_name<T1>() << ", ";
|
||||
proto::eval(arg1, ctx);
|
||||
ctx.stream << ", ";
|
||||
ctx.stream << type_name<T2>() << ", ";
|
||||
proto::eval(arg2, ctx);
|
||||
ctx.stream << ")";
|
||||
}
|
||||
};
|
||||
|
||||
} // end detail namespace
|
||||
|
||||
// make_pair(first, second)
|
||||
template<class Arg1, class Arg2>
|
||||
inline typename proto::result_of::make_expr<
|
||||
proto::tag::function, detail::make_pair_func, const Arg1&, const Arg2&
|
||||
>::type const
|
||||
make_pair(const Arg1 &first, const Arg2 &second)
|
||||
{
|
||||
return proto::make_expr<proto::tag::function>(
|
||||
detail::make_pair_func(), ::boost::ref(first), ::boost::ref(second)
|
||||
);
|
||||
}
|
||||
|
||||
} // end lambda namespace
|
||||
} // end compute namespace
|
||||
} // end boost namespace
|
||||
|
||||
#endif // BOOST_COMPUTE_LAMBDA_MAKE_PAIR_HPP
|
||||
@@ -0,0 +1,127 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// Copyright (c) 2013-2014 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_MAKE_TUPLE_HPP
|
||||
#define BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_HPP
|
||||
|
||||
#include <boost/preprocessor/repetition.hpp>
|
||||
|
||||
#include <boost/compute/config.hpp>
|
||||
#include <boost/compute/types/tuple.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
namespace lambda {
|
||||
namespace detail {
|
||||
|
||||
// function wrapper for make_tuple() in lambda expressions
|
||||
struct make_tuple_func
|
||||
{
|
||||
template<class Expr, class Args, int N>
|
||||
struct make_tuple_result_type;
|
||||
|
||||
#define BOOST_COMPUTE_MAKE_TUPLE_RESULT_GET_ARG(z, n, unused) \
|
||||
typedef typename proto::result_of::child_c<Expr, BOOST_PP_INC(n)>::type BOOST_PP_CAT(Arg, n);
|
||||
|
||||
#define BOOST_COMPUTE_MAKE_TUPLE_RESULT_GET_ARG_TYPE(z, n, unused) \
|
||||
typedef typename lambda::result_of<BOOST_PP_CAT(Arg, n), Args>::type BOOST_PP_CAT(T, n);
|
||||
|
||||
#define BOOST_COMPUTE_MAKE_TUPLE_RESULT_TYPE(z, n, unused) \
|
||||
template<class Expr, class Args> \
|
||||
struct make_tuple_result_type<Expr, Args, n> \
|
||||
{ \
|
||||
BOOST_PP_REPEAT(n, BOOST_COMPUTE_MAKE_TUPLE_RESULT_GET_ARG, ~) \
|
||||
BOOST_PP_REPEAT(n, BOOST_COMPUTE_MAKE_TUPLE_RESULT_GET_ARG_TYPE, ~) \
|
||||
typedef boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> type; \
|
||||
};
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_MAKE_TUPLE_RESULT_TYPE, ~)
|
||||
|
||||
#undef BOOST_COMPUTE_MAKE_TUPLE_RESULT_GET_ARG
|
||||
#undef BOOST_COMPUTE_MAKE_TUPLE_RESULT_GET_ARG_TYPE
|
||||
#undef BOOST_COMPUTE_MAKE_TUPLE_RESULT_TYPE
|
||||
|
||||
template<class Expr, class Args>
|
||||
struct lambda_result
|
||||
{
|
||||
typedef typename make_tuple_result_type<
|
||||
Expr, Args, proto::arity_of<Expr>::value - 1
|
||||
>::type type;
|
||||
};
|
||||
|
||||
#define BOOST_COMPUTE_MAKE_TUPLE_GET_ARG_TYPE(z, n, unused) \
|
||||
typedef typename lambda::result_of< \
|
||||
BOOST_PP_CAT(Arg, n), typename Context::args_tuple \
|
||||
>::type BOOST_PP_CAT(T, n);
|
||||
|
||||
#define BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_APPLY_ARG(z, n, unused) \
|
||||
BOOST_PP_COMMA_IF(n) BOOST_PP_CAT(const Arg, n) BOOST_PP_CAT(&arg, n)
|
||||
|
||||
#define BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_APPLY_EVAL_ARG(z, n, unused) \
|
||||
BOOST_PP_EXPR_IF(n, ctx.stream << ", ";) proto::eval(BOOST_PP_CAT(arg, n), ctx);
|
||||
|
||||
#define BOOST_COMPUTE_MAKE_TUPLE_APPLY(z, n, unused) \
|
||||
template<class Context, BOOST_PP_ENUM_PARAMS(n, class Arg)> \
|
||||
static void apply(Context &ctx, BOOST_PP_REPEAT(n, BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_APPLY_ARG, ~)) \
|
||||
{ \
|
||||
BOOST_PP_REPEAT(n, BOOST_COMPUTE_MAKE_TUPLE_GET_ARG_TYPE, ~) \
|
||||
typedef typename boost::tuple<BOOST_PP_ENUM_PARAMS(n, T)> tuple_type; \
|
||||
ctx.stream.template inject_type<tuple_type>(); \
|
||||
ctx.stream << "((" << type_name<tuple_type>() << "){"; \
|
||||
BOOST_PP_REPEAT(n, BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_APPLY_EVAL_ARG, ~) \
|
||||
ctx.stream << "})"; \
|
||||
}
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_MAKE_TUPLE_APPLY, ~)
|
||||
|
||||
#undef BOOST_COMPUTE_MAKE_TUPLE_GET_ARG_TYPE
|
||||
#undef BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_APPLY_ARG
|
||||
#undef BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_APPLY_EVAL_ARG
|
||||
#undef BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_APPLY
|
||||
};
|
||||
|
||||
} // end detail namespace
|
||||
|
||||
#define BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_ARG(z, n, unused) \
|
||||
BOOST_PP_COMMA_IF(n) BOOST_PP_CAT(const Arg, n) BOOST_PP_CAT(&arg, n)
|
||||
|
||||
#define BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_ARG_TYPE(z, n, unused) \
|
||||
BOOST_PP_COMMA_IF(n) BOOST_PP_CAT(const Arg, n) &
|
||||
|
||||
#define BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_REF_ARG(z, n, unused) \
|
||||
BOOST_PP_COMMA_IF(n) ::boost::ref(BOOST_PP_CAT(arg, n))
|
||||
|
||||
#define BOOST_COMPUTE_LAMBDA_MAKE_TUPLE(z, n, unused) \
|
||||
template<BOOST_PP_ENUM_PARAMS(n, class Arg)> \
|
||||
inline typename proto::result_of::make_expr< \
|
||||
proto::tag::function, \
|
||||
detail::make_tuple_func, \
|
||||
BOOST_PP_REPEAT(n, BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_ARG_TYPE, ~) \
|
||||
>::type \
|
||||
make_tuple(BOOST_PP_REPEAT(n, BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_ARG, ~)) \
|
||||
{ \
|
||||
return proto::make_expr<proto::tag::function>( \
|
||||
detail::make_tuple_func(), \
|
||||
BOOST_PP_REPEAT(n, BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_REF_ARG, ~) \
|
||||
); \
|
||||
}
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_COMPUTE_MAX_ARITY, BOOST_COMPUTE_LAMBDA_MAKE_TUPLE, ~)
|
||||
|
||||
#undef BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_ARG
|
||||
#undef BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_ARG_TYPE
|
||||
#undef BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_REF_ARG
|
||||
#undef BOOST_COMPUTE_LAMBDA_MAKE_TUPLE
|
||||
|
||||
} // end lambda namespace
|
||||
} // end compute namespace
|
||||
} // end boost namespace
|
||||
|
||||
#endif // BOOST_COMPUTE_LAMBDA_MAKE_TUPLE_HPP
|
||||
@@ -0,0 +1,28 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// Copyright (c) 2013-2014 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_PLACEHOLDER_HPP
|
||||
#define BOOST_COMPUTE_LAMBDA_PLACEHOLDER_HPP
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
namespace lambda {
|
||||
|
||||
// lambda placeholder type
|
||||
template<int I>
|
||||
struct placeholder
|
||||
{
|
||||
};
|
||||
|
||||
} // end lambda namespace
|
||||
} // end compute namespace
|
||||
} // end boost namespace
|
||||
|
||||
#endif // BOOST_COMPUTE_LAMBDA_PLACEHOLDER_HPP
|
||||
@@ -0,0 +1,93 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// 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_PLACEHOLDERS_HPP
|
||||
#define BOOST_COMPUTE_LAMBDA_PLACEHOLDERS_HPP
|
||||
|
||||
#include <boost/mpl/has_xxx.hpp>
|
||||
|
||||
#include <boost/compute/lambda/context.hpp>
|
||||
#include <boost/compute/lambda/result_of.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
namespace lambda {
|
||||
|
||||
namespace mpl = boost::mpl;
|
||||
namespace proto = boost::proto;
|
||||
|
||||
// lambda placeholders
|
||||
expression<proto::terminal<placeholder<0> >::type> const _1;
|
||||
expression<proto::terminal<placeholder<1> >::type> const _2;
|
||||
expression<proto::terminal<placeholder<2> >::type> const _3;
|
||||
|
||||
namespace detail {
|
||||
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type)
|
||||
|
||||
template<class T, bool HasResultType>
|
||||
struct terminal_type_impl;
|
||||
|
||||
template<class T>
|
||||
struct terminal_type_impl<T, true>
|
||||
{
|
||||
typedef typename T::result_type type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct terminal_type_impl<T, false>
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct terminal_type
|
||||
{
|
||||
typedef typename terminal_type_impl<T, has_result_type<T>::value>::type type;
|
||||
};
|
||||
|
||||
} // end detail namespace
|
||||
|
||||
// result_of placeholders
|
||||
template<class Args>
|
||||
struct result_of<expression<proto::terminal<placeholder<0> >::type>, Args, proto::tag::terminal>
|
||||
{
|
||||
typedef typename boost::tuples::element<0, Args>::type arg_type;
|
||||
|
||||
typedef typename detail::terminal_type<arg_type>::type type;
|
||||
};
|
||||
|
||||
template<class Args>
|
||||
struct result_of<expression<proto::terminal<placeholder<1> >::type>, Args, proto::tag::terminal>
|
||||
{
|
||||
typedef typename boost::tuples::element<1, Args>::type arg_type;
|
||||
|
||||
typedef typename detail::terminal_type<arg_type>::type type;
|
||||
};
|
||||
|
||||
template<class Args>
|
||||
struct result_of<expression<proto::terminal<placeholder<2> >::type>, Args, proto::tag::terminal>
|
||||
{
|
||||
typedef typename boost::tuples::element<2, Args>::type arg_type;
|
||||
|
||||
typedef typename detail::terminal_type<arg_type>::type type;
|
||||
};
|
||||
|
||||
} // end lambda namespace
|
||||
|
||||
// lift lambda placeholders up to the boost::compute namespace
|
||||
using lambda::_1;
|
||||
using lambda::_2;
|
||||
using lambda::_3;
|
||||
|
||||
} // end compute namespace
|
||||
} // end boost namespace
|
||||
|
||||
#endif // BOOST_COMPUTE_LAMBDA_PLACEHOLDERS_HPP
|
||||
@@ -0,0 +1,113 @@
|
||||
//---------------------------------------------------------------------------//
|
||||
// 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_RESULT_OF_HPP
|
||||
#define BOOST_COMPUTE_LAMBDA_RESULT_OF_HPP
|
||||
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/proto/proto.hpp>
|
||||
|
||||
#include <boost/compute/type_traits/common_type.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace compute {
|
||||
namespace lambda {
|
||||
|
||||
namespace mpl = boost::mpl;
|
||||
namespace proto = boost::proto;
|
||||
|
||||
// meta-function returning the result type of a lambda expression
|
||||
template<class Expr,
|
||||
class Args = void,
|
||||
class Tags = typename proto::tag_of<Expr>::type>
|
||||
struct result_of
|
||||
{
|
||||
};
|
||||
|
||||
// terminals
|
||||
template<class Expr, class Args>
|
||||
struct result_of<Expr, Args, proto::tag::terminal>
|
||||
{
|
||||
typedef typename proto::result_of::value<Expr>::type type;
|
||||
};
|
||||
|
||||
// binary operators
|
||||
#define BOOST_COMPUTE_LAMBDA_RESULT_OF_BINARY_OPERATOR(tag) \
|
||||
template<class Expr, class Args> \
|
||||
struct result_of<Expr, Args, tag> \
|
||||
{ \
|
||||
typedef typename proto::result_of::child_c<Expr, 0>::type left; \
|
||||
typedef typename proto::result_of::child_c<Expr, 1>::type right; \
|
||||
\
|
||||
typedef typename boost::common_type< \
|
||||
typename ::boost::compute::lambda::result_of< \
|
||||
left, \
|
||||
Args, \
|
||||
typename proto::tag_of<left>::type>::type, \
|
||||
typename ::boost::compute::lambda::result_of< \
|
||||
right, \
|
||||
Args, \
|
||||
typename proto::tag_of<right>::type>::type \
|
||||
>::type type; \
|
||||
};
|
||||
|
||||
BOOST_COMPUTE_LAMBDA_RESULT_OF_BINARY_OPERATOR(proto::tag::plus)
|
||||
BOOST_COMPUTE_LAMBDA_RESULT_OF_BINARY_OPERATOR(proto::tag::minus)
|
||||
BOOST_COMPUTE_LAMBDA_RESULT_OF_BINARY_OPERATOR(proto::tag::multiplies)
|
||||
BOOST_COMPUTE_LAMBDA_RESULT_OF_BINARY_OPERATOR(proto::tag::divides)
|
||||
BOOST_COMPUTE_LAMBDA_RESULT_OF_BINARY_OPERATOR(proto::tag::modulus)
|
||||
BOOST_COMPUTE_LAMBDA_RESULT_OF_BINARY_OPERATOR(proto::tag::bitwise_and)
|
||||
BOOST_COMPUTE_LAMBDA_RESULT_OF_BINARY_OPERATOR(proto::tag::bitwise_or)
|
||||
BOOST_COMPUTE_LAMBDA_RESULT_OF_BINARY_OPERATOR(proto::tag::bitwise_xor)
|
||||
|
||||
// comparision operators
|
||||
#define BOOST_COMPUTE_LAMBDA_RESULT_OF_COMPARISON_OPERATOR(tag) \
|
||||
template<class Expr, class Args> \
|
||||
struct result_of<Expr, Args, tag> \
|
||||
{ \
|
||||
typedef bool type; \
|
||||
};
|
||||
|
||||
BOOST_COMPUTE_LAMBDA_RESULT_OF_COMPARISON_OPERATOR(proto::tag::less)
|
||||
BOOST_COMPUTE_LAMBDA_RESULT_OF_COMPARISON_OPERATOR(proto::tag::greater)
|
||||
BOOST_COMPUTE_LAMBDA_RESULT_OF_COMPARISON_OPERATOR(proto::tag::less_equal)
|
||||
BOOST_COMPUTE_LAMBDA_RESULT_OF_COMPARISON_OPERATOR(proto::tag::greater_equal)
|
||||
BOOST_COMPUTE_LAMBDA_RESULT_OF_COMPARISON_OPERATOR(proto::tag::equal_to)
|
||||
BOOST_COMPUTE_LAMBDA_RESULT_OF_COMPARISON_OPERATOR(proto::tag::not_equal_to)
|
||||
BOOST_COMPUTE_LAMBDA_RESULT_OF_COMPARISON_OPERATOR(proto::tag::logical_and)
|
||||
BOOST_COMPUTE_LAMBDA_RESULT_OF_COMPARISON_OPERATOR(proto::tag::logical_or)
|
||||
|
||||
// assignment operator
|
||||
template<class Expr, class Args>
|
||||
struct result_of<Expr, Args, proto::tag::assign>
|
||||
{
|
||||
typedef typename proto::result_of::child_c<Expr, 0>::type left;
|
||||
typedef typename proto::result_of::child_c<Expr, 1>::type right;
|
||||
|
||||
typedef typename ::boost::compute::lambda::result_of<
|
||||
right, Args, typename proto::tag_of<right>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
// functions
|
||||
template<class Expr, class Args>
|
||||
struct result_of<Expr, Args, proto::tag::function>
|
||||
{
|
||||
typedef typename proto::result_of::child_c<Expr, 0>::type func_expr;
|
||||
typedef typename proto::result_of::value<func_expr>::type func;
|
||||
|
||||
typedef typename func::template lambda_result<Expr, Args>::type type;
|
||||
};
|
||||
|
||||
} // end lambda namespace
|
||||
} // end compute namespace
|
||||
} // end boost namespace
|
||||
|
||||
#endif // BOOST_COMPUTE_LAMBDA_RESULT_OF_HPP
|
||||
Reference in New Issue
Block a user