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:
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user