mirror of
https://github.com/boostorg/yap.git
synced 2026-02-23 16:22:09 +00:00
Remove the expression ctor taking individual values; add specialization for terminal that does.
This commit is contained in:
233
expression.hpp
233
expression.hpp
@@ -50,11 +50,238 @@ namespace boost::proto17 {
|
||||
|
||||
static const expr_kind kind = Kind;
|
||||
|
||||
expression (T && ... t) :
|
||||
elements (static_cast<T &&>(t)...)
|
||||
expression (hana::tuple<T...> && rhs) :
|
||||
elements (std::move(rhs))
|
||||
{}
|
||||
|
||||
expression (hana::tuple<T...> && rhs) :
|
||||
tuple_type elements;
|
||||
|
||||
#ifdef BOOST_PROTO17_CONVERSION_OPERATOR_TEMPLATE
|
||||
template <typename R>
|
||||
operator R ()
|
||||
{ return eval_expression_as(*this, hana::basic_type<R>{}); }
|
||||
#endif
|
||||
|
||||
decltype(auto) value () const &
|
||||
{
|
||||
using namespace hana::literals;
|
||||
static_assert(
|
||||
decltype(hana::size(elements))::value == 1UL,
|
||||
"value() is only defined for unary expressions."
|
||||
);
|
||||
return elements[0_c];
|
||||
}
|
||||
|
||||
decltype(auto) value () &
|
||||
{
|
||||
using namespace hana::literals;
|
||||
static_assert(
|
||||
decltype(hana::size(elements))::value == 1UL,
|
||||
"value() is only defined for unary expressions."
|
||||
);
|
||||
return elements[0_c];
|
||||
}
|
||||
|
||||
decltype(auto) value () &&
|
||||
{
|
||||
using namespace hana::literals;
|
||||
static_assert(
|
||||
decltype(hana::size(elements))::value == 1UL,
|
||||
"value() is only defined for unary expressions."
|
||||
);
|
||||
return static_cast<tuple_type &&>(elements)[0_c];
|
||||
}
|
||||
|
||||
decltype(auto) left () const &
|
||||
{
|
||||
using namespace hana::literals;
|
||||
static_assert(
|
||||
decltype(hana::size(elements))::value == 2UL,
|
||||
"left() and right() are only defined for binary expressions."
|
||||
);
|
||||
return elements[0_c];
|
||||
}
|
||||
|
||||
decltype(auto) left () &
|
||||
{
|
||||
using namespace hana::literals;
|
||||
static_assert(
|
||||
decltype(hana::size(elements))::value == 2UL,
|
||||
"left() and right() are only defined for binary expressions."
|
||||
);
|
||||
return elements[0_c];
|
||||
}
|
||||
|
||||
decltype(auto) left () &&
|
||||
{
|
||||
using namespace hana::literals;
|
||||
static_assert(
|
||||
decltype(hana::size(elements))::value == 2UL,
|
||||
"left() and right() are only defined for binary expressions."
|
||||
);
|
||||
return static_cast<tuple_type &&>(elements)[0_c];
|
||||
}
|
||||
|
||||
decltype(auto) right () const &
|
||||
{
|
||||
using namespace hana::literals;
|
||||
static_assert(
|
||||
decltype(hana::size(elements))::value == 2UL,
|
||||
"left() and right() are only defined for binary expressions."
|
||||
);
|
||||
return elements[1_c];
|
||||
}
|
||||
|
||||
decltype(auto) right () &
|
||||
{
|
||||
using namespace hana::literals;
|
||||
static_assert(
|
||||
decltype(hana::size(elements))::value == 2UL,
|
||||
"left() and right() are only defined for binary expressions."
|
||||
);
|
||||
return elements[1_c];
|
||||
}
|
||||
|
||||
decltype(auto) right () &&
|
||||
{
|
||||
using namespace hana::literals;
|
||||
static_assert(
|
||||
decltype(hana::size(elements))::value == 2UL,
|
||||
"left() and right() are only defined for binary expressions."
|
||||
);
|
||||
return static_cast<tuple_type &&>(elements)[1_c];
|
||||
}
|
||||
|
||||
#define BOOST_PROTO17_UNARY_MEMBER_OPERATOR(op, op_name) \
|
||||
auto operator op const & \
|
||||
{ \
|
||||
return expression<expr_kind::op_name, this_type>{ \
|
||||
hana::tuple<this_type>{*this} \
|
||||
}; \
|
||||
} \
|
||||
auto operator op && \
|
||||
{ \
|
||||
return expression<expr_kind::op_name, this_type>{ \
|
||||
hana::tuple<this_type>{std::move(*this)} \
|
||||
}; \
|
||||
}
|
||||
|
||||
BOOST_PROTO17_UNARY_MEMBER_OPERATOR(+(), unary_plus) // +
|
||||
BOOST_PROTO17_UNARY_MEMBER_OPERATOR(-(), negate) // -
|
||||
BOOST_PROTO17_UNARY_MEMBER_OPERATOR(*(), dereference) // *
|
||||
BOOST_PROTO17_UNARY_MEMBER_OPERATOR(~(), complement) // ~
|
||||
BOOST_PROTO17_UNARY_MEMBER_OPERATOR(&(), address_of) // &
|
||||
BOOST_PROTO17_UNARY_MEMBER_OPERATOR(!(), logical_not) // !
|
||||
BOOST_PROTO17_UNARY_MEMBER_OPERATOR(++(), pre_inc) // ++
|
||||
BOOST_PROTO17_UNARY_MEMBER_OPERATOR(--(), pre_dec) // --
|
||||
BOOST_PROTO17_UNARY_MEMBER_OPERATOR(++(int), post_inc) // ++(int)
|
||||
BOOST_PROTO17_UNARY_MEMBER_OPERATOR(--(int), post_dec) // --(int)
|
||||
|
||||
#undef BOOST_PROTO17_UNARY_MEMBER_OPERATOR
|
||||
|
||||
#define BOOST_PROTO17_BINARY_MEMBER_OPERATOR(op, op_name) \
|
||||
template <typename U> \
|
||||
auto operator op (U && rhs) const & \
|
||||
{ \
|
||||
using rhs_type = detail::operand_type_t<U>; \
|
||||
return expression<expr_kind::op_name, this_type, rhs_type>{ \
|
||||
hana::tuple<this_type, rhs_type>{ \
|
||||
*this, \
|
||||
static_cast<U &&>(rhs) \
|
||||
} \
|
||||
}; \
|
||||
} \
|
||||
template <typename U> \
|
||||
auto operator op (U && rhs) && \
|
||||
{ \
|
||||
using rhs_type = detail::operand_type_t<U>; \
|
||||
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>
|
||||
auto operator, (U && rhs) const &
|
||||
{
|
||||
using rhs_type = detail::operand_type_t<U>;
|
||||
return expression<expr_kind::comma, this_type, rhs_type>{
|
||||
hana::tuple<this_type, rhs_type>{*this, static_cast<U &&>(rhs)}
|
||||
};
|
||||
}
|
||||
template <typename U>
|
||||
auto operator, (U && rhs) &&
|
||||
{
|
||||
using rhs_type = detail::operand_type_t<U>;
|
||||
return expression<expr_kind::comma, 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) // []
|
||||
|
||||
#undef BOOST_PROTO17_BINARY_MEMBER_OPERATOR
|
||||
|
||||
template <typename ...U>
|
||||
auto operator() (U && ...u) const &
|
||||
{
|
||||
using tuple_type = hana::tuple<this_type, detail::operand_type_t<U>...>;
|
||||
return detail::make_call_expression<tuple_type>(*this, static_cast<U &&>(u)...);
|
||||
}
|
||||
template <typename ...U>
|
||||
auto operator() (U && ...u) &&
|
||||
{
|
||||
using tuple_type = hana::tuple<this_type, detail::operand_type_t<U>...>;
|
||||
return detail::make_call_expression<tuple_type>(std::move(*this), static_cast<U &&>(u)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct expression<expr_kind::terminal, T>
|
||||
{
|
||||
using this_type = expression<expr_kind::terminal, T>;
|
||||
using tuple_type = hana::tuple<T>;
|
||||
|
||||
static const expr_kind kind = expr_kind::terminal;
|
||||
|
||||
expression (T && t) :
|
||||
elements (static_cast<T &&>(t))
|
||||
{}
|
||||
|
||||
expression (hana::tuple<T> && rhs) :
|
||||
elements (std::move(rhs))
|
||||
{}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user