2
0
mirror of https://github.com/boostorg/yap.git synced 2026-02-25 17:02:19 +00:00

Add BOOST_PROTO17_USER_UDT_BINARY_OPERATOR.

This commit is contained in:
Zach Laine
2016-11-30 19:23:16 -06:00
parent f74cf1789e
commit 0494018fca
2 changed files with 87 additions and 0 deletions

View File

@@ -181,6 +181,11 @@ namespace boost::proto17 {
// free_binary_op_result
// TODO: Must is_expr<> below be an ExprTemplate instantiation?
// Without that, we potentially have one kind of expression template
// making another one when a non-expr value appears of the lhs of one
// of its binary ops.
template <
template <expr_kind, class> class ExprTemplate,
expr_kind OpKind,
@@ -242,6 +247,56 @@ namespace boost::proto17 {
>::type;
// udt_binary_op_result
template <typename T, template <class> class UdtTrait>
struct is_udt_arg
{ static bool const value = !is_expr<T>::value && UdtTrait<remove_cv_ref_t<T>>::value; };
template <
template <expr_kind, class> class ExprTemplate,
expr_kind OpKind,
typename T,
typename U,
template <class> class TUdtTrait,
template <class> class UUdtTrait,
bool Valid = is_udt_arg<T, TUdtTrait>::value && is_udt_arg<U, UUdtTrait>::value
>
struct udt_binary_op_result;
template <
template <expr_kind, class> class ExprTemplate,
expr_kind OpKind,
typename T,
typename U,
template <class> class TUdtTrait,
template <class> class UUdtTrait
>
struct udt_binary_op_result<ExprTemplate, OpKind, T, U, TUdtTrait, UUdtTrait, true>
{
using lhs_type = operand_type_t<ExprTemplate, T>;
using rhs_type = operand_type_t<ExprTemplate, U>;
using type = ExprTemplate<OpKind, hana::tuple<lhs_type, rhs_type>>;
};
template <
template <expr_kind, class> class ExprTemplate,
expr_kind OpKind,
typename T,
typename U,
template <class> class TUdtTrait,
template <class> class UUdtTrait
>
using udt_binary_op_result_t = typename udt_binary_op_result<
ExprTemplate,
OpKind,
T,
U,
TUdtTrait,
UUdtTrait
>::type;
// expr_arity
enum class expr_arity {

View File

@@ -213,4 +213,36 @@
} \
} \
#define BOOST_PROTO17_USER_UDT_BINARY_OPERATOR(op_name, expr_template, t_udt_trait, u_udt_trait) \
template <typename T, typename U> \
auto operator BOOST_PROTO17_INDIRECT_CALL(op_name)() (T && lhs, U && rhs) \
-> ::boost::proto17::detail::udt_binary_op_result_t< \
expr_template, \
::boost::proto17::expr_kind::op_name, \
T, \
U, \
t_udt_trait, \
u_udt_trait \
> \
{ \
using result_types = ::boost::proto17::detail::udt_binary_op_result< \
expr_template, \
::boost::proto17::expr_kind::op_name, \
T, \
U, \
t_udt_trait, \
u_udt_trait \
>; \
using lhs_type = typename result_types::lhs_type; \
using rhs_type = typename result_types::rhs_type; \
using tuple_type = ::boost::hana::tuple<lhs_type, rhs_type>; \
return { \
tuple_type{ \
lhs_type{static_cast<T &&>(lhs)}, \
rhs_type{static_cast<U &&>(rhs)}, \
} \
}; \
} \
#endif