stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork

This commit is contained in:
2026-02-24 18:38:47 +00:00
parent da8c28aaeb
commit 65cb2619a7
13106 changed files with 2484322 additions and 1804 deletions
@@ -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