Project

General

Profile

Feature #14473 » v4-0001-range.c-allow-cover-to-accept-Range-argument.patch

owst (Owen Stephens), 07/19/2018 12:01 AM

View differences:

range.c
return Qundef;
}
static VALUE r_cover_range_p(VALUE range, VALUE beg, VALUE end, VALUE val);
/*
* call-seq:
* rng.cover?(obj) -> true or false
* rng.cover?(obj) -> true or false
* rng.cover?(range) -> true or false
*
* Returns <code>true</code> if +obj+ is between the begin and end of
* the range.
......
* This tests <code>begin <= obj <= end</code> when #exclude_end? is +false+
* and <code>begin <= obj < end</code> when #exclude_end? is +true+.
*
* ("a".."z").cover?("c") #=> true
* ("a".."z").cover?("5") #=> false
* ("a".."z").cover?("cc") #=> true
* Returns <code>true</code> for a Range when it is covered by the receiver,
* by comparing the begin and end values directly. This requires the end
* object of the receiver to implement <code>succ</code> if the end of +range+
* is greater than the end of the receiver and +range+ excludes its end, but
* the receiver does not.
*
* ("a".."z").cover?("c") #=> true
* ("a".."z").cover?("5") #=> false
* ("a".."z").cover?("cc") #=> true
* ("a".."z").cover?("b".."c") #=> true
* ("a".."z").cover?("0".."z") #=> false
*/
static VALUE
range_cover(VALUE range, VALUE val)
{
......
beg = RANGE_BEG(range);
end = RANGE_END(range);
if (rb_obj_is_kind_of(val, rb_cRange)) {
return RBOOL(r_cover_range_p(range, beg, end, val));
}
return r_cover_p(range, beg, end, val);
}
static VALUE
r_cover_range_p(VALUE range, VALUE beg, VALUE end, VALUE val)
{
VALUE val_beg, val_end;
int cmp_end;
val_beg = RANGE_BEG(val);
val_end = RANGE_END(val);
if (!r_cover_p(range, beg, end, val_beg)) return FALSE;
cmp_end = r_less(end, val_end);
if (EXCL(range) == EXCL(val)) {
return cmp_end >= 0;
} else if (EXCL(range)) {
return cmp_end > 0;
} else if (cmp_end >= 0) {
return TRUE;
} else if (!discrete_object_p(end)) {
rb_raise(rb_eTypeError, "can't iterate from %s",
rb_obj_classname(end));
}
return r_less(rb_funcallv(end, id_succ, 0, 0), val_end) == 0;
}
static VALUE
r_cover_p(VALUE range, VALUE beg, VALUE end, VALUE val)
{
test/ruby/test_range.rb
assert_not_operator(5..., :cover?, 0)
assert_not_operator(5..., :cover?, "a")
assert_operator(5.., :cover?, 10)
assert_operator(2..5, :cover?, 2..5)
assert_operator(2...6, :cover?, 2...6)
assert_operator(2...6, :cover?, 2..5)
assert_operator(2..5, :cover?, 2...6)
assert_operator(2..5, :cover?, 2..4)
assert_operator(2..5, :cover?, 2...4)
assert_operator(2..5, :cover?, 2...5)
assert_operator(2..5, :cover?, 3..5)
assert_operator(2..5, :cover?, 3..4)
assert_operator(2..5, :cover?, 3...6)
assert_operator(2...6, :cover?, 2...5)
assert_operator(2...6, :cover?, 2..5)
assert_operator(2..6, :cover?, 2...6)
assert_operator(2.., :cover?, 2..)
assert_operator(2.., :cover?, 3..)
assert_operator(1.0..4.0, :cover?, 2.0...3.0)
assert_not_operator(2..5, :cover?, 1..5)
assert_not_operator(2...6, :cover?, 1..5)
assert_not_operator(2..5, :cover?, 1...6)
assert_not_operator(1..3, :cover?, 1...6)
assert_not_operator(2..5, :cover?, 2..6)
assert_not_operator(2...6, :cover?, 2..6)
assert_not_operator(2...6, :cover?, 2...7)
assert_not_operator(2..3, :cover?, 1..4)
assert_not_operator(1..2, :cover?, 4..3)
assert_not_operator(2..1, :cover?, 1..2)
assert_not_operator(1...2, :cover?, 1...3)
assert_not_operator(2.., :cover?, 1..)
end
def test_beg_len
(4-4/6)