inline constexpr typename SIDIM_STD::common_type<distance<TRep1, TInterval1>, distance<TRep2, TInterval2> >::type operator-(const distance<TRep1, TInterval1>& x, const distance<TRep2, TInterval2>& y) { using common_type = typename SIDIM_STD::common_type< distance<TRep1, TInterval1>, distance<TRep2, TInterval2> >::type; return common_type(common_type(x).count() - common_type(y).count()); }
static inline constexpr bool cmp(const TDistance1& d1, const TDistance2& d2) { using common_type = typename SIDIM_STD::common_type<TDistance1, TDistance2>::type; return common_type(d1).count() < common_type(d2).count(); }
type check_binary(int binop, expression e1, expression e2) { type t1 = default_conversion(e1), t2 = default_conversion(e2); type rtype = NULL; bool common = FALSE; /* XXX: Misc warnings (see build_binary_op) */ if (t1 == error_type || t2 == error_type) rtype = error_type; else switch(binop) { case kind_plus: if (type_pointer(t1) && type_integer(t2)) rtype = pointer_int_sum(t1, t2); else if (type_pointer(t2) && type_integer(t1)) rtype = pointer_int_sum(t2, t1); else common = TRUE; break; case kind_minus: if (type_pointer(t1) && type_integer(t2)) rtype = pointer_int_sum(t1, t2); else if (type_pointer(t1) && type_pointer(t2) && compatible_pointer_types(t1, t2)) rtype = ptrdiff_t_type; else common = TRUE; break; case kind_plus_assign: case kind_minus_assign: if (type_pointer(t1) && type_integer(t2)) rtype = pointer_int_sum(t1, t2); else common = TRUE; break; case kind_times: case kind_divide: case kind_times_assign: case kind_divide_assign: common = TRUE; break; case kind_modulo: case kind_bitand: case kind_bitor: case kind_bitxor: case kind_lshift: case kind_rshift: case kind_modulo_assign: case kind_bitand_assign: case kind_bitor_assign: case kind_bitxor_assign: case kind_lshift_assign: case kind_rshift_assign: if (type_integer(t1) && type_integer(t2)) rtype = common_type(t1, t2); break; case kind_leq: case kind_geq: case kind_lt: case kind_gt: rtype = int_type; /* Default to assuming success */ if (type_real(t1) && type_real(t2)) ; else if (type_pointer(t1) && type_pointer(t2)) { if (compatible_pointer_types(t1, t2)) { /* XXX: how can this happen ? */ if (type_incomplete(t1) != type_incomplete(t2)) pedwarn("comparison of complete and incomplete pointers"); else if (pedantic && type_function(type_points_to(t1))) pedwarn("ANSI C forbids ordered comparisons of pointers to functions"); } else pedwarn("comparison of distinct pointer types lacks a cast"); } /* XXX: Use of definite_zero may lead to extra warnings when !extra_warnings */ else if ((type_pointer(t1) && definite_zero(e2)) || (type_pointer(t2) && definite_zero(e1))) { if (pedantic || extra_warnings) pedwarn("ordered comparison of pointer with integer zero"); } else if ((type_pointer(t1) && type_integer(t2)) || (type_pointer(t2) && type_integer(t1))) { if (!flag_traditional) pedwarn("comparison between pointer and integer"); } else rtype = NULL; /* Force error */ break; case kind_eq: case kind_ne: rtype = int_type; /* Default to assuming success */ if (type_arithmetic(t1) && type_arithmetic(t2)) ; else if (type_pointer(t1) && type_pointer(t2)) { if (!compatible_pointer_types(t1, t2) && !valid_compare(t1, t2, e1) && !valid_compare(t2, t1, e2)) pedwarn("comparison of distinct pointer types lacks a cast"); } else if ((type_pointer(t1) && definite_null(e2)) || (type_pointer(t2) && definite_null(e1))) ; else if ((type_pointer(t1) && type_integer(t2)) || (type_pointer(t2) && type_integer(t1))) { if (!flag_traditional) pedwarn("comparison between pointer and integer"); } else rtype = NULL; /* Force error */ break; case kind_andand: case kind_oror: if (type_scalar(t1) && type_scalar(t2)) rtype = int_type; break; default: assert(0); break; } if (common && type_arithmetic(t1) && type_arithmetic(t2)) rtype = common_type(t1, t2); if (!rtype) { error("invalid operands to binary %s", binary_op_name(binop)); rtype = error_type; } return rtype; }