2
0
mirror of https://github.com/boostorg/yap.git synced 2026-02-23 16:22:09 +00:00

Add remaining binary operators.

This commit is contained in:
Zach Laine
2016-11-08 08:38:01 -06:00
parent 2ab89e9851
commit 7cc60e87d4
4 changed files with 295 additions and 48 deletions

View File

@@ -23,19 +23,63 @@ namespace boost::proto17 {
} else if constexpr (Kind == expr_kind::placeholder) {
static_assert(sizeof...(T) == 1);
return args[expr.elements[0_c]];
} else if constexpr (Kind == expr_kind::plus) {
return
eval_plus(
default_eval_expr(expr.elements[0_c], static_cast<Tuple &&>(args)),
default_eval_expr(expr.elements[1_c], static_cast<Tuple &&>(args))
);
} else if constexpr (Kind == expr_kind::minus) {
return
eval_minus(
default_eval_expr(expr.elements[0_c], static_cast<Tuple &&>(args)),
default_eval_expr(expr.elements[1_c], static_cast<Tuple &&>(args))
);
} else if constexpr (Kind == expr_kind::call) {
}
// TODO: Unary ops.
#define BOOST_PROTO17_BINARY_OPERATOR_CASE(op_name) \
else if constexpr (Kind == expr_kind:: op_name) { \
return \
eval_## op_name( \
default_eval_expr(expr.elements[0_c], static_cast<Tuple &&>(args)), \
default_eval_expr(expr.elements[1_c], static_cast<Tuple &&>(args)) \
); \
}
BOOST_PROTO17_BINARY_OPERATOR_CASE(shift_left) // <<
BOOST_PROTO17_BINARY_OPERATOR_CASE(shift_right) // >>
BOOST_PROTO17_BINARY_OPERATOR_CASE(multiplies) // *
BOOST_PROTO17_BINARY_OPERATOR_CASE(divides) // /
BOOST_PROTO17_BINARY_OPERATOR_CASE(modulus) // %
BOOST_PROTO17_BINARY_OPERATOR_CASE(plus) // +
BOOST_PROTO17_BINARY_OPERATOR_CASE(minus) // -
BOOST_PROTO17_BINARY_OPERATOR_CASE(less) // <
BOOST_PROTO17_BINARY_OPERATOR_CASE(greater) // >
BOOST_PROTO17_BINARY_OPERATOR_CASE(less_equal) // <=
BOOST_PROTO17_BINARY_OPERATOR_CASE(greater_equal) // >=
BOOST_PROTO17_BINARY_OPERATOR_CASE(equal_to) // ==
BOOST_PROTO17_BINARY_OPERATOR_CASE(not_equal_to) // !=
BOOST_PROTO17_BINARY_OPERATOR_CASE(logical_or) // ||
BOOST_PROTO17_BINARY_OPERATOR_CASE(logical_and) // &&
BOOST_PROTO17_BINARY_OPERATOR_CASE(bitwise_and) // &
BOOST_PROTO17_BINARY_OPERATOR_CASE(bitwise_or) // |
BOOST_PROTO17_BINARY_OPERATOR_CASE(bitwise_xor) // ^
else if constexpr (Kind == expr_kind::comma) {
return
eval_comma(
default_eval_expr(expr.elements[0_c], static_cast<Tuple &&>(args)),
default_eval_expr(expr.elements[1_c], static_cast<Tuple &&>(args))
);
}
BOOST_PROTO17_BINARY_OPERATOR_CASE(mem_ptr) // ->*
BOOST_PROTO17_BINARY_OPERATOR_CASE(assign) // =
BOOST_PROTO17_BINARY_OPERATOR_CASE(shift_left_assign) // <<=
BOOST_PROTO17_BINARY_OPERATOR_CASE(shift_right_assign) // >>=
BOOST_PROTO17_BINARY_OPERATOR_CASE(multiplies_assign) // *=
BOOST_PROTO17_BINARY_OPERATOR_CASE(divides_assign) // /=
BOOST_PROTO17_BINARY_OPERATOR_CASE(modulus_assign) // %=
BOOST_PROTO17_BINARY_OPERATOR_CASE(plus_assign) // +=
BOOST_PROTO17_BINARY_OPERATOR_CASE(minus_assign) // -=
BOOST_PROTO17_BINARY_OPERATOR_CASE(bitwise_and_assign) // &=
BOOST_PROTO17_BINARY_OPERATOR_CASE(bitwise_or_assign) // |=
BOOST_PROTO17_BINARY_OPERATOR_CASE(bitwise_xor_assign) // ^=
BOOST_PROTO17_BINARY_OPERATOR_CASE(bitwise_xor_assign) // []
#undef BOOST_PROTO17_BINARY_OPERATOR_CASE
else if constexpr (Kind == expr_kind::call) {
return hana::unpack(
hana::transform(expr.elements, [&args] (auto && element) {
return default_eval_expr(element, static_cast<Tuple &&>(args));

View File

@@ -75,39 +75,81 @@ namespace boost::proto17 {
operator R ()
{ return eval_expression_as(*this, hana::basic_type<R>{}); }
// TODO: Unary ops.
#define BOOST_PROTO17_BINARY_MEMBER_OPERATOR(op, op_name) \
template <typename U> \
decltype(auto) operator op (U && rhs) const & \
{ \
using rhs_type = typename detail::rhs_type<U>::type; \
return expression<expr_kind::op_name, this_type, rhs_type>{ \
hana::tuple<this_type, rhs_type>{ \
*this, \
static_cast<U &&>(rhs) \
} \
}; \
} \
template <typename U> \
decltype(auto) operator op (U && rhs) && \
{ \
using rhs_type = typename detail::rhs_type<U>::type; \
return expression<expr_kind::op_name, this_type, rhs_type>{ \
hana::tuple<this_type, rhs_type>{ \
std::move(*this), \
static_cast<U &&>(rhs) \
} \
}; \
}
BOOST_PROTO17_BINARY_MEMBER_OPERATOR(<<, shift_left) // <<
BOOST_PROTO17_BINARY_MEMBER_OPERATOR(>>, shift_right) // >>
BOOST_PROTO17_BINARY_MEMBER_OPERATOR(*, multiplies) // *
BOOST_PROTO17_BINARY_MEMBER_OPERATOR(/, divides) // /
BOOST_PROTO17_BINARY_MEMBER_OPERATOR(%, modulus) // %
BOOST_PROTO17_BINARY_MEMBER_OPERATOR(+, plus) // +
BOOST_PROTO17_BINARY_MEMBER_OPERATOR(-, minus) // -
BOOST_PROTO17_BINARY_MEMBER_OPERATOR(<, less) // <
BOOST_PROTO17_BINARY_MEMBER_OPERATOR(>, greater) // >
BOOST_PROTO17_BINARY_MEMBER_OPERATOR(<=, less_equal) // <=
BOOST_PROTO17_BINARY_MEMBER_OPERATOR(>=, greater_equal) // >=
BOOST_PROTO17_BINARY_MEMBER_OPERATOR(==, equal_to) // ==
BOOST_PROTO17_BINARY_MEMBER_OPERATOR(!=, not_equal_to) // !=
BOOST_PROTO17_BINARY_MEMBER_OPERATOR(||, logical_or) // ||
BOOST_PROTO17_BINARY_MEMBER_OPERATOR(&&, logical_and) // &&
BOOST_PROTO17_BINARY_MEMBER_OPERATOR(&, bitwise_and) // &
BOOST_PROTO17_BINARY_MEMBER_OPERATOR(|, bitwise_or) // |
BOOST_PROTO17_BINARY_MEMBER_OPERATOR(^, bitwise_xor) // ^
template <typename U>
decltype(auto) operator+ (U && rhs) const &
decltype(auto) operator, (U && rhs) const &
{
using rhs_type = typename detail::rhs_type<U>::type;
return expression<expr_kind::plus, this_type, rhs_type>{
return expression<expr_kind::comma, this_type, rhs_type>{
hana::tuple<this_type, rhs_type>{*this, static_cast<U &&>(rhs)}
};
}
template <typename U>
decltype(auto) operator+ (U && rhs) &&
decltype(auto) operator, (U && rhs) &&
{
using rhs_type = typename detail::rhs_type<U>::type;
return expression<expr_kind::plus, this_type, rhs_type>{
return expression<expr_kind::comma, this_type, rhs_type>{
hana::tuple<this_type, rhs_type>{std::move(*this), static_cast<U &&>(rhs)}
};
}
template <typename U>
decltype(auto) operator- (U && rhs) const &
{
using rhs_type = typename detail::rhs_type<U>::type;
return expression<expr_kind::minus, this_type, rhs_type>{
hana::tuple<this_type, rhs_type>{*this, static_cast<U &&>(rhs)}
};
}
template <typename U>
decltype(auto) operator- (U && rhs) &&
{
using rhs_type = typename detail::rhs_type<U>::type;
return expression<expr_kind::minus, this_type, rhs_type>{
hana::tuple<this_type, rhs_type>{std::move(*this), static_cast<U &&>(rhs)}
};
}
BOOST_PROTO17_BINARY_MEMBER_OPERATOR(->*, mem_ptr) // ->*
BOOST_PROTO17_BINARY_MEMBER_OPERATOR(=, assign) // =
BOOST_PROTO17_BINARY_MEMBER_OPERATOR(<<=, shift_left_assign) // <<=
BOOST_PROTO17_BINARY_MEMBER_OPERATOR(>>=, shift_right_assign) // >>=
BOOST_PROTO17_BINARY_MEMBER_OPERATOR(*=, multiplies_assign) // *=
BOOST_PROTO17_BINARY_MEMBER_OPERATOR(/=, divides_assign) // /=
BOOST_PROTO17_BINARY_MEMBER_OPERATOR(%=, modulus_assign) // %=
BOOST_PROTO17_BINARY_MEMBER_OPERATOR(+=, plus_assign) // +=
BOOST_PROTO17_BINARY_MEMBER_OPERATOR(-=, minus_assign) // -=
BOOST_PROTO17_BINARY_MEMBER_OPERATOR(&=, bitwise_and_assign) // &=
BOOST_PROTO17_BINARY_MEMBER_OPERATOR(|=, bitwise_or_assign) // |=
BOOST_PROTO17_BINARY_MEMBER_OPERATOR(^=, bitwise_xor_assign) // ^=
BOOST_PROTO17_BINARY_MEMBER_OPERATOR([], subscript) // []
template <typename ...U>
decltype(auto) operator() (U && ...u) const &

View File

@@ -9,30 +9,79 @@ namespace boost::proto17 {
namespace adl_detail {
// TODO: Unary ops.
#define BOOST_PROTO17_BINARY_OPERATOR(op, op_name) \
template <typename T, typename U> \
constexpr auto eval_ ## op_name (T && t, U && u) BOOST_PROTO17_NOEXCEPT_DECLTYPE_RETURN( \
static_cast<T &&>(t) op static_cast<U &&>(u) \
) \
struct eval_ ## op_name ## _fn \
{ \
template <typename T, typename U> \
constexpr auto operator() (T && t, U && u) const BOOST_PROTO17_NOEXCEPT_DECLTYPE_RETURN( \
eval_ ## op_name(static_cast<T &&>(t), static_cast<U &&>(u)) \
) \
};
BOOST_PROTO17_BINARY_OPERATOR(<<, shift_left) // <<
BOOST_PROTO17_BINARY_OPERATOR(>>, shift_right) // >>
BOOST_PROTO17_BINARY_OPERATOR(*, multiplies) // *
BOOST_PROTO17_BINARY_OPERATOR(/, divides) // /
BOOST_PROTO17_BINARY_OPERATOR(%, modulus) // %
BOOST_PROTO17_BINARY_OPERATOR(+, plus) // +
BOOST_PROTO17_BINARY_OPERATOR(-, minus) // -
BOOST_PROTO17_BINARY_OPERATOR(<, less) // <
BOOST_PROTO17_BINARY_OPERATOR(>, greater) // >
BOOST_PROTO17_BINARY_OPERATOR(<=, less_equal) // <=
BOOST_PROTO17_BINARY_OPERATOR(>=, greater_equal) // >=
BOOST_PROTO17_BINARY_OPERATOR(==, equal_to) // ==
BOOST_PROTO17_BINARY_OPERATOR(!=, not_equal_to) // !=
BOOST_PROTO17_BINARY_OPERATOR(||, logical_or) // ||
BOOST_PROTO17_BINARY_OPERATOR(&&, logical_and) // &&
BOOST_PROTO17_BINARY_OPERATOR(&, bitwise_and) // &
BOOST_PROTO17_BINARY_OPERATOR(|, bitwise_or) // |
BOOST_PROTO17_BINARY_OPERATOR(^, bitwise_xor) // ^
template <typename T, typename U>
constexpr auto eval_plus (T && t, U && u) BOOST_PROTO17_NOEXCEPT_DECLTYPE_RETURN(
static_cast<T &&>(t) + static_cast<U &&>(u)
constexpr auto eval_comma (T && t, U && u) BOOST_PROTO17_NOEXCEPT_DECLTYPE_RETURN(
(static_cast<T &&>(t) , static_cast<U &&>(u))
)
struct eval_plus_fn
struct eval_comma_fn
{
template <typename T, typename U>
constexpr auto operator() (T && t, U && u) const BOOST_PROTO17_NOEXCEPT_DECLTYPE_RETURN(
eval_plus(static_cast<T &&>(t), static_cast<U &&>(u))
eval_comma(static_cast<T &&>(t), static_cast<U &&>(u))
)
};
BOOST_PROTO17_BINARY_OPERATOR(->*, mem_ptr) // ->*
BOOST_PROTO17_BINARY_OPERATOR(=, assign) // =
BOOST_PROTO17_BINARY_OPERATOR(<<=, shift_left_assign) // <<=
BOOST_PROTO17_BINARY_OPERATOR(>>=, shift_right_assign) // >>=
BOOST_PROTO17_BINARY_OPERATOR(*=, multiplies_assign) // *=
BOOST_PROTO17_BINARY_OPERATOR(/=, divides_assign) // /=
BOOST_PROTO17_BINARY_OPERATOR(%=, modulus_assign) // %=
BOOST_PROTO17_BINARY_OPERATOR(+=, plus_assign) // +=
BOOST_PROTO17_BINARY_OPERATOR(-=, minus_assign) // -=
BOOST_PROTO17_BINARY_OPERATOR(&=, bitwise_and_assign) // &=
BOOST_PROTO17_BINARY_OPERATOR(|=, bitwise_or_assign) // |=
BOOST_PROTO17_BINARY_OPERATOR(^=, bitwise_xor_assign) // ^=
template <typename T, typename U>
constexpr auto eval_minus (T && t, U && u) BOOST_PROTO17_NOEXCEPT_DECLTYPE_RETURN(
static_cast<T &&>(t) - static_cast<U &&>(u)
constexpr auto eval_subscript (T && t, U && u) BOOST_PROTO17_NOEXCEPT_DECLTYPE_RETURN(
static_cast<T &&>(t)[static_cast<U &&>(u)]
)
struct eval_minus_fn
struct eval_subscript_fn
{
template <typename T, typename U>
constexpr auto operator() (T && t, U && u) const BOOST_PROTO17_NOEXCEPT_DECLTYPE_RETURN(
eval_minus(static_cast<T &&>(t), static_cast<U &&>(u))
eval_subscript(static_cast<T &&>(t), static_cast<U &&>(u))
)
};
#undef BOOST_PROTO17_BINARY_OPERATOR
template <typename F, typename ...T>
constexpr auto eval_call (F && f, T && ...t) BOOST_PROTO17_NOEXCEPT_DECLTYPE_RETURN(
static_cast<F &&>(f)(static_cast<T &&>(t)...)
@@ -49,15 +98,84 @@ namespace boost::proto17 {
#undef BOOST_PROTO17_NOEXCEPT_DECLTYPE_RETURN
using adl_detail::eval_plus_fn;
using adl_detail::eval_minus_fn;
using adl_detail::eval_call_fn;
#define BOOST_PROTO17_USING_OPERATOR_FN(op_name) using adl_detail::eval_ ## op_name ## _fn;
BOOST_PROTO17_USING_OPERATOR_FN(shift_left) // <<
BOOST_PROTO17_USING_OPERATOR_FN(shift_right) // >>
BOOST_PROTO17_USING_OPERATOR_FN(multiplies) // *
BOOST_PROTO17_USING_OPERATOR_FN(divides) // /
BOOST_PROTO17_USING_OPERATOR_FN(modulus) // %
BOOST_PROTO17_USING_OPERATOR_FN(plus) // +
BOOST_PROTO17_USING_OPERATOR_FN(minus) // -
BOOST_PROTO17_USING_OPERATOR_FN(less) // <
BOOST_PROTO17_USING_OPERATOR_FN(greater) // >
BOOST_PROTO17_USING_OPERATOR_FN(less_equal) // <=
BOOST_PROTO17_USING_OPERATOR_FN(greater_equal) // >=
BOOST_PROTO17_USING_OPERATOR_FN(equal_to) // ==
BOOST_PROTO17_USING_OPERATOR_FN(not_equal_to) // !=
BOOST_PROTO17_USING_OPERATOR_FN(logical_or) // ||
BOOST_PROTO17_USING_OPERATOR_FN(logical_and) // &&
BOOST_PROTO17_USING_OPERATOR_FN(bitwise_and) // &
BOOST_PROTO17_USING_OPERATOR_FN(bitwise_or) // |
BOOST_PROTO17_USING_OPERATOR_FN(bitwise_xor) // ^
BOOST_PROTO17_USING_OPERATOR_FN(comma) // ,
BOOST_PROTO17_USING_OPERATOR_FN(mem_ptr) // ->*
BOOST_PROTO17_USING_OPERATOR_FN(assign) // =
BOOST_PROTO17_USING_OPERATOR_FN(shift_left_assign) // <<=
BOOST_PROTO17_USING_OPERATOR_FN(shift_right_assign) // >>=
BOOST_PROTO17_USING_OPERATOR_FN(multiplies_assign) // *=
BOOST_PROTO17_USING_OPERATOR_FN(divides_assign) // /=
BOOST_PROTO17_USING_OPERATOR_FN(modulus_assign) // %=
BOOST_PROTO17_USING_OPERATOR_FN(plus_assign) // +=
BOOST_PROTO17_USING_OPERATOR_FN(minus_assign) // -=
BOOST_PROTO17_USING_OPERATOR_FN(bitwise_and_assign) // &=
BOOST_PROTO17_USING_OPERATOR_FN(bitwise_or_assign) // |=
BOOST_PROTO17_USING_OPERATOR_FN(bitwise_xor_assign) // ^=
BOOST_PROTO17_USING_OPERATOR_FN(subscript) // []
BOOST_PROTO17_USING_OPERATOR_FN(call) // ()
#undef BOOST_PROTO17_USING_OPERATOR_FN
inline namespace function_objects {
inline constexpr eval_plus_fn eval_plus{};
inline constexpr eval_minus_fn eval_minus{};
inline constexpr eval_call_fn eval_call{};
#define BOOST_PROTO17_DECLARE_OPERATOR_FN(op_name) \
inline constexpr eval_ ## op_name ## _fn eval_ ## op_name{};
BOOST_PROTO17_DECLARE_OPERATOR_FN(shift_left) // <<
BOOST_PROTO17_DECLARE_OPERATOR_FN(shift_right) // >>
BOOST_PROTO17_DECLARE_OPERATOR_FN(multiplies) // *
BOOST_PROTO17_DECLARE_OPERATOR_FN(divides) // /
BOOST_PROTO17_DECLARE_OPERATOR_FN(modulus) // %
BOOST_PROTO17_DECLARE_OPERATOR_FN(plus) // +
BOOST_PROTO17_DECLARE_OPERATOR_FN(minus) // -
BOOST_PROTO17_DECLARE_OPERATOR_FN(less) // <
BOOST_PROTO17_DECLARE_OPERATOR_FN(greater) // >
BOOST_PROTO17_DECLARE_OPERATOR_FN(less_equal) // <=
BOOST_PROTO17_DECLARE_OPERATOR_FN(greater_equal) // >=
BOOST_PROTO17_DECLARE_OPERATOR_FN(equal_to) // ==
BOOST_PROTO17_DECLARE_OPERATOR_FN(not_equal_to) // !=
BOOST_PROTO17_DECLARE_OPERATOR_FN(logical_or) // ||
BOOST_PROTO17_DECLARE_OPERATOR_FN(logical_and) // &&
BOOST_PROTO17_DECLARE_OPERATOR_FN(bitwise_and) // &
BOOST_PROTO17_DECLARE_OPERATOR_FN(bitwise_or) // |
BOOST_PROTO17_DECLARE_OPERATOR_FN(bitwise_xor) // ^
BOOST_PROTO17_DECLARE_OPERATOR_FN(comma) // ,
BOOST_PROTO17_DECLARE_OPERATOR_FN(mem_ptr) // ->*
BOOST_PROTO17_DECLARE_OPERATOR_FN(assign) // =
BOOST_PROTO17_DECLARE_OPERATOR_FN(shift_left_assign) // <<=
BOOST_PROTO17_DECLARE_OPERATOR_FN(shift_right_assign) // >>=
BOOST_PROTO17_DECLARE_OPERATOR_FN(multiplies_assign) // *=
BOOST_PROTO17_DECLARE_OPERATOR_FN(divides_assign) // /=
BOOST_PROTO17_DECLARE_OPERATOR_FN(modulus_assign) // %=
BOOST_PROTO17_DECLARE_OPERATOR_FN(plus_assign) // +=
BOOST_PROTO17_DECLARE_OPERATOR_FN(minus_assign) // -=
BOOST_PROTO17_DECLARE_OPERATOR_FN(bitwise_and_assign) // &=
BOOST_PROTO17_DECLARE_OPERATOR_FN(bitwise_or_assign) // |=
BOOST_PROTO17_DECLARE_OPERATOR_FN(bitwise_xor_assign) // ^=
BOOST_PROTO17_DECLARE_OPERATOR_FN(subscript) // []
BOOST_PROTO17_DECLARE_OPERATOR_FN(call) // ()
#undef BOOST_PROTO17_DECLARE_OPERATOR_FN
}

View File

@@ -15,9 +15,52 @@ namespace boost::proto17 {
inline std::ostream & print_kind (std::ostream & os, expr_kind kind)
{
switch (kind) {
case expr_kind::unary_plus: return os << "+";
case expr_kind::negate: return os << "-";
case expr_kind::dereference: return os << "*";
case expr_kind::complement: return os << "~";
case expr_kind::address_of: return os << "&";
case expr_kind::logical_not: return os << "!";
case expr_kind::pre_inc: return os << "++";
case expr_kind::pre_dec: return os << "--";
case expr_kind::post_inc: return os << "++(int)";
case expr_kind::post_dec: return os << "--(int)";
case expr_kind::shift_left: return os << "<<";
case expr_kind::shift_right: return os << ">>";
case expr_kind::multiplies: return os << "*";
case expr_kind::divides: return os << "/";
case expr_kind::modulus: return os << "%";
case expr_kind::plus: return os << "+";
case expr_kind::minus: return os << "-";
// TODO
case expr_kind::less: return os << "<";
case expr_kind::greater: return os << ">";
case expr_kind::less_equal: return os << "<=";
case expr_kind::greater_equal: return os << ">=";
case expr_kind::equal_to: return os << "==";
case expr_kind::not_equal_to: return os << "!=";
case expr_kind::logical_or: return os << "||";
case expr_kind::logical_and: return os << "&&";
case expr_kind::bitwise_and: return os << "&";
case expr_kind::bitwise_or: return os << "|";
case expr_kind::bitwise_xor: return os << "^";
case expr_kind::comma: return os << ",";
case expr_kind::mem_ptr: return os << "->*";
case expr_kind::assign: return os << "=";
case expr_kind::shift_left_assign: return os << "<<=";
case expr_kind::shift_right_assign: return os << ">>=";
case expr_kind::multiplies_assign: return os << "*=";
case expr_kind::divides_assign: return os << "/=";
case expr_kind::modulus_assign: return os << "%=";
case expr_kind::plus_assign: return os << "+=";
case expr_kind::minus_assign: return os << "-=";
case expr_kind::bitwise_and_assign: return os << "&=";
case expr_kind::bitwise_or_assign: return os << "|=";
case expr_kind::bitwise_xor_assign: return os << "^=";
case expr_kind::subscript: return os << "[]";
case expr_kind::call: return os << "()";
default: return os << "** ERROR: UNKNOWN OPERATOR! **";
}
}