mirror of
https://github.com/boostorg/yap.git
synced 2026-02-23 16:22:09 +00:00
Add detail::expr_arity and expression tag types.
This commit is contained in:
@@ -156,7 +156,7 @@ namespace boost::proto17 {
|
||||
template <typename Expr, typename Tuple, typename Transform>
|
||||
auto transform_nonterminal (Expr const & expr, Tuple && tuple, Transform && transform);
|
||||
|
||||
template <typename Expr, typename Transform, typename = std::void_t<>>
|
||||
template <typename Expr, typename Transform, expr_arity Arity, typename = std::void_t<>>
|
||||
struct default_transform_expression
|
||||
{
|
||||
auto operator() (Expr && expr, Transform && transform)
|
||||
@@ -164,7 +164,11 @@ namespace boost::proto17 {
|
||||
constexpr expr_kind kind = remove_cv_ref_t<Expr>::kind;
|
||||
if constexpr (kind == expr_kind::expr_ref) {
|
||||
decltype(auto) ref = ::boost::proto17::value(expr);
|
||||
default_transform_expression<decltype(ref), Transform> transformer;
|
||||
default_transform_expression<
|
||||
decltype(ref),
|
||||
Transform,
|
||||
detail::arity_of<kind>()
|
||||
> transformer;
|
||||
return transformer(ref, static_cast<Transform &&>(transform));
|
||||
} else if constexpr (kind == expr_kind::terminal || kind == expr_kind::placeholder) {
|
||||
return static_cast<Expr &&>(expr);
|
||||
@@ -186,10 +190,11 @@ namespace boost::proto17 {
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Expr, typename Transform>
|
||||
template <typename Expr, typename Transform, expr_arity Arity>
|
||||
struct default_transform_expression<
|
||||
Expr,
|
||||
Transform,
|
||||
Arity,
|
||||
std::void_t<decltype(std::declval<Transform>()(std::declval<Expr>()))>
|
||||
>
|
||||
{
|
||||
@@ -213,7 +218,7 @@ namespace boost::proto17 {
|
||||
static_cast<Tuple &&>(tuple),
|
||||
[&transform](auto && element) {
|
||||
using element_t = decltype(element);
|
||||
default_transform_expression<element_t, Transform> transformer;
|
||||
default_transform_expression<element_t, Transform, detail::arity_of<Expr::kind>()> transformer;
|
||||
return transformer(
|
||||
static_cast<element_t &&>(element),
|
||||
static_cast<Transform &&>(transform)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "../expression_fwd.hpp"
|
||||
|
||||
#include <boost/hana/tuple.hpp>
|
||||
#include <boost/hana/size.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
@@ -191,6 +192,142 @@ namespace boost::proto17 {
|
||||
U
|
||||
>::type;
|
||||
|
||||
enum class expr_arity {
|
||||
invalid,
|
||||
one,
|
||||
two,
|
||||
n
|
||||
};
|
||||
|
||||
template <expr_kind Kind>
|
||||
constexpr expr_arity arity_of ()
|
||||
{
|
||||
switch (Kind) {
|
||||
case expr_kind::expr_ref:
|
||||
|
||||
case expr_kind::terminal:
|
||||
case expr_kind::placeholder:
|
||||
|
||||
// unary
|
||||
case expr_kind::unary_plus: // +
|
||||
case expr_kind::negate: // -
|
||||
case expr_kind::dereference: // *
|
||||
case expr_kind::complement: // ~
|
||||
case expr_kind::address_of: // &
|
||||
case expr_kind::logical_not: // !
|
||||
case expr_kind::pre_inc: // ++
|
||||
case expr_kind::pre_dec: // --
|
||||
case expr_kind::post_inc: // ++(int)
|
||||
case expr_kind::post_dec: // --(int)
|
||||
return expr_arity::one;
|
||||
|
||||
// binary
|
||||
case expr_kind::shift_left: // <<
|
||||
case expr_kind::shift_right: // >>
|
||||
case expr_kind::multiplies: // *
|
||||
case expr_kind::divides: // /
|
||||
case expr_kind::modulus: // %
|
||||
case expr_kind::plus: // +
|
||||
case expr_kind::minus: // -
|
||||
case expr_kind::less: // <
|
||||
case expr_kind::greater: // >
|
||||
case expr_kind::less_equal: // <=
|
||||
case expr_kind::greater_equal: // >=
|
||||
case expr_kind::equal_to: // ==
|
||||
case expr_kind::not_equal_to: // !=
|
||||
case expr_kind::logical_or: // ||
|
||||
case expr_kind::logical_and: // &&
|
||||
case expr_kind::bitwise_and: // &
|
||||
case expr_kind::bitwise_or: // |
|
||||
case expr_kind::bitwise_xor: // ^
|
||||
case expr_kind::comma: // :
|
||||
case expr_kind::mem_ptr: // ->*
|
||||
case expr_kind::assign: // =
|
||||
case expr_kind::shift_left_assign: // <<=
|
||||
case expr_kind::shift_right_assign: // >>=
|
||||
case expr_kind::multiplies_assign: // *=
|
||||
case expr_kind::divides_assign: // /=
|
||||
case expr_kind::modulus_assign: // %=
|
||||
case expr_kind::plus_assign: // +=
|
||||
case expr_kind::minus_assign: // -=
|
||||
case expr_kind::bitwise_and_assign: // &=
|
||||
case expr_kind::bitwise_or_assign: // |=
|
||||
case expr_kind::bitwise_xor_assign: // ^=
|
||||
case expr_kind::subscript: // []
|
||||
return expr_arity::two;
|
||||
|
||||
// n-ary
|
||||
case expr_kind::call: // ()
|
||||
return expr_arity::n;
|
||||
|
||||
default:
|
||||
return expr_arity::invalid;
|
||||
}
|
||||
}
|
||||
|
||||
template <expr_kind Kind>
|
||||
constexpr auto tag_for ()
|
||||
{
|
||||
#define CASE(x) if constexpr (Kind == expr_kind::x) return x ## _tag{}
|
||||
|
||||
CASE(expr_ref);
|
||||
|
||||
CASE(terminal);
|
||||
CASE(placeholder);
|
||||
|
||||
// unary
|
||||
CASE(unary_plus); // +
|
||||
CASE(negate); // -
|
||||
CASE(dereference); // *
|
||||
CASE(complement); // ~
|
||||
CASE(address_of); // &
|
||||
CASE(logical_not); // !
|
||||
CASE(pre_inc); // ++
|
||||
CASE(pre_dec); // --
|
||||
CASE(post_inc); // ++(int)
|
||||
CASE(post_dec); // --(int)
|
||||
|
||||
// binary
|
||||
CASE(shift_left); // <<
|
||||
CASE(shift_right); // >>
|
||||
CASE(multiplies); // *
|
||||
CASE(divides); // /
|
||||
CASE(modulus); // %
|
||||
CASE(plus); // +
|
||||
CASE(minus); // -
|
||||
CASE(less); // <
|
||||
CASE(greater); // >
|
||||
CASE(less_equal); // <=
|
||||
CASE(greater_equal); // >=
|
||||
CASE(equal_to); // ==
|
||||
CASE(not_equal_to); // !=
|
||||
CASE(logical_or); // ||
|
||||
CASE(logical_and); // &&
|
||||
CASE(bitwise_and); // &
|
||||
CASE(bitwise_or); // |
|
||||
CASE(bitwise_xor); // ^
|
||||
CASE(comma); // );
|
||||
CASE(mem_ptr); // ->*
|
||||
CASE(assign); // =
|
||||
CASE(shift_left_assign); // <<=
|
||||
CASE(shift_right_assign); // >>=
|
||||
CASE(multiplies_assign); // *=
|
||||
CASE(divides_assign); // /=
|
||||
CASE(modulus_assign); // %=
|
||||
CASE(plus_assign); // +=
|
||||
CASE(minus_assign); // -=
|
||||
CASE(bitwise_and_assign); // &=
|
||||
CASE(bitwise_or_assign); // |=
|
||||
CASE(bitwise_xor_assign); // ^=
|
||||
CASE(subscript); // []
|
||||
|
||||
// n-ary
|
||||
CASE(call); // ()
|
||||
|
||||
#undef CASE
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -295,7 +295,7 @@ namespace boost::proto17 {
|
||||
{
|
||||
using namespace hana::literals;
|
||||
static_assert(
|
||||
decltype(hana::size(expr.elements))::value == 1UL,
|
||||
detail::arity_of<Expr::kind>() == detail::expr_arity::one,
|
||||
"value() is only defined for unary expressions."
|
||||
);
|
||||
if constexpr (Expr::kind == expr_kind::expr_ref) {
|
||||
@@ -310,7 +310,7 @@ namespace boost::proto17 {
|
||||
{
|
||||
using namespace hana::literals;
|
||||
static_assert(
|
||||
decltype(hana::size(expr.elements))::value == 1UL,
|
||||
detail::arity_of<Expr::kind>() == detail::expr_arity::one,
|
||||
"value() is only defined for unary expressions."
|
||||
);
|
||||
if constexpr (Expr::kind == expr_kind::expr_ref) {
|
||||
@@ -325,7 +325,7 @@ namespace boost::proto17 {
|
||||
{
|
||||
using namespace hana::literals;
|
||||
static_assert(
|
||||
decltype(hana::size(expr.elements))::value == 1UL,
|
||||
detail::arity_of<Expr::kind>() == detail::expr_arity::one,
|
||||
"value() is only defined for unary expressions."
|
||||
);
|
||||
if constexpr (Expr::kind == expr_kind::expr_ref) {
|
||||
@@ -340,7 +340,7 @@ namespace boost::proto17 {
|
||||
{
|
||||
using namespace hana::literals;
|
||||
static_assert(
|
||||
decltype(hana::size(expr.elements))::value == 2UL,
|
||||
detail::arity_of<Expr::kind>() == detail::expr_arity::two,
|
||||
"left() and right() are only defined for binary expressions."
|
||||
);
|
||||
return expr.elements[0_c];
|
||||
@@ -351,7 +351,7 @@ namespace boost::proto17 {
|
||||
{
|
||||
using namespace hana::literals;
|
||||
static_assert(
|
||||
decltype(hana::size(expr.elements))::value == 2UL,
|
||||
detail::arity_of<Expr::kind>() == detail::expr_arity::two,
|
||||
"left() and right() are only defined for binary expressions."
|
||||
);
|
||||
return expr.elements[0_c];
|
||||
@@ -362,7 +362,7 @@ namespace boost::proto17 {
|
||||
{
|
||||
using namespace hana::literals;
|
||||
static_assert(
|
||||
decltype(hana::size(expr.elements))::value == 2UL,
|
||||
detail::arity_of<Expr::kind>() == detail::expr_arity::two,
|
||||
"left() and right() are only defined for binary expressions."
|
||||
);
|
||||
return std::move(expr.elements)[0_c];
|
||||
@@ -373,7 +373,7 @@ namespace boost::proto17 {
|
||||
{
|
||||
using namespace hana::literals;
|
||||
static_assert(
|
||||
decltype(hana::size(expr.elements))::value == 2UL,
|
||||
detail::arity_of<Expr::kind>() == detail::expr_arity::two,
|
||||
"left() and right() are only defined for binary expressions."
|
||||
);
|
||||
return expr.elements[1_c];
|
||||
@@ -384,7 +384,7 @@ namespace boost::proto17 {
|
||||
{
|
||||
using namespace hana::literals;
|
||||
static_assert(
|
||||
decltype(hana::size(expr.elements))::value == 2UL,
|
||||
detail::arity_of<Expr::kind>() == detail::expr_arity::two,
|
||||
"left() and right() are only defined for binary expressions."
|
||||
);
|
||||
return expr.elements[1_c];
|
||||
@@ -395,7 +395,7 @@ namespace boost::proto17 {
|
||||
{
|
||||
using namespace hana::literals;
|
||||
static_assert(
|
||||
decltype(hana::size(expr.elements))::value == 2UL,
|
||||
detail::arity_of<Expr::kind>() == detail::expr_arity::two,
|
||||
"left() and right() are only defined for binary expressions."
|
||||
);
|
||||
return std::move(expr.elements)[1_c];
|
||||
@@ -516,7 +516,8 @@ namespace boost::proto17 {
|
||||
template <typename Expr, typename Transform>
|
||||
auto transform (Expr && expr, Transform && transform)
|
||||
{
|
||||
return detail::default_transform_expression<Expr, Transform>{}(
|
||||
constexpr expr_kind kind = detail::remove_cv_ref_t<Expr>::kind;
|
||||
return detail::default_transform_expression<Expr, Transform, detail::arity_of<kind>()>{}(
|
||||
static_cast<Expr &&>(expr),
|
||||
static_cast<Transform &&>(transform)
|
||||
);
|
||||
|
||||
@@ -120,6 +120,62 @@ namespace boost::proto17 {
|
||||
|
||||
}
|
||||
|
||||
// Tag types -- one per expr_kind:
|
||||
|
||||
struct expr_ref_tag {}; // TODO: Needed?
|
||||
|
||||
struct terminal_tag {};
|
||||
struct placeholder_tag {};
|
||||
|
||||
// unary
|
||||
struct unary_plus_tag {}; // +
|
||||
struct negate_tag {}; // -
|
||||
struct dereference_tag {}; // *
|
||||
struct complement_tag {}; // ~
|
||||
struct address_of_tag {}; // &
|
||||
struct logical_not_tag {}; // !
|
||||
struct pre_inc_tag {}; // ++
|
||||
struct pre_dec_tag {}; // --
|
||||
struct post_inc_tag {}; // ++(int)
|
||||
struct post_dec_tag {}; // --(int)
|
||||
|
||||
// binary
|
||||
struct shift_left_tag {}; // <<
|
||||
struct shift_right_tag {}; // >>
|
||||
struct multiplies_tag {}; // *
|
||||
struct divides_tag {}; // /
|
||||
struct modulus_tag {}; // %
|
||||
struct plus_tag {}; // +
|
||||
struct minus_tag {}; // -
|
||||
struct less_tag {}; // <
|
||||
struct greater_tag {}; // >
|
||||
struct less_equal_tag {}; // <=
|
||||
struct greater_equal_tag {}; // >=
|
||||
struct equal_to_tag {}; // ==
|
||||
struct not_equal_to_tag {}; // !=
|
||||
struct logical_or_tag {}; // ||
|
||||
struct logical_and_tag {}; // &&
|
||||
struct bitwise_and_tag {}; // &
|
||||
struct bitwise_or_tag {}; // |
|
||||
struct bitwise_xor_tag {}; // ^
|
||||
struct comma_tag {}; // _tag {};
|
||||
struct mem_ptr_tag {}; // ->*
|
||||
struct assign_tag {}; // =
|
||||
struct shift_left_assign_tag {}; // <<=
|
||||
struct shift_right_assign_tag {}; // >>=
|
||||
struct multiplies_assign_tag {}; // *=
|
||||
struct divides_assign_tag {}; // /=
|
||||
struct modulus_assign_tag {}; // %=
|
||||
struct plus_assign_tag {}; // +=
|
||||
struct minus_assign_tag {}; // -=
|
||||
struct bitwise_and_assign_tag {}; // &=
|
||||
struct bitwise_or_assign_tag {}; // |=
|
||||
struct bitwise_xor_assign_tag {}; // ^=
|
||||
struct subscript_tag {}; // []
|
||||
|
||||
// n-ary
|
||||
struct call_tag {}; // ()
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user