mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
rb_ary_slice_bang: do not goto into a branch
I'm not necessarily against every goto in general, but jumping into a branch is definitely a bad idea. Better refactor.
This commit is contained in:
parent
73f98d25eb
commit
4f2425549a
Notes:
git
2020-06-29 11:07:17 +09:00
1 changed files with 38 additions and 22 deletions
60
array.c
60
array.c
|
@ -4407,6 +4407,37 @@ rb_ary_delete_at_m(VALUE ary, VALUE pos)
|
||||||
return rb_ary_delete_at(ary, NUM2LONG(pos));
|
return rb_ary_delete_at(ary, NUM2LONG(pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
ary_slice_bang_by_rb_ary_splice(VALUE ary, long pos, long len)
|
||||||
|
{
|
||||||
|
const long orig_len = RARRAY_LEN(ary);
|
||||||
|
|
||||||
|
if (len < 0) {
|
||||||
|
return Qnil;
|
||||||
|
}
|
||||||
|
else if (pos < -orig_len) {
|
||||||
|
return Qnil;
|
||||||
|
}
|
||||||
|
else if (pos < 0) {
|
||||||
|
pos += orig_len;
|
||||||
|
}
|
||||||
|
else if (orig_len < pos) {
|
||||||
|
return Qnil;
|
||||||
|
}
|
||||||
|
else if (orig_len < pos + len) {
|
||||||
|
len = orig_len - pos;
|
||||||
|
}
|
||||||
|
if (len == 0) {
|
||||||
|
return rb_ary_new2(0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
VALUE arg2 = rb_ary_new4(len, RARRAY_CONST_PTR_TRANSIENT(ary)+pos);
|
||||||
|
RBASIC_SET_CLASS(arg2, rb_obj_class(ary));
|
||||||
|
rb_ary_splice(ary, pos, len, 0, 0);
|
||||||
|
return arg2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* ary.slice!(index) -> obj or nil
|
* ary.slice!(index) -> obj or nil
|
||||||
|
@ -4431,39 +4462,24 @@ rb_ary_delete_at_m(VALUE ary, VALUE pos)
|
||||||
static VALUE
|
static VALUE
|
||||||
rb_ary_slice_bang(int argc, VALUE *argv, VALUE ary)
|
rb_ary_slice_bang(int argc, VALUE *argv, VALUE ary)
|
||||||
{
|
{
|
||||||
VALUE arg1, arg2;
|
VALUE arg1;
|
||||||
long pos, len, orig_len;
|
long pos, len;
|
||||||
|
|
||||||
rb_ary_modify_check(ary);
|
rb_ary_modify_check(ary);
|
||||||
|
rb_check_arity(argc, 1, 2);
|
||||||
|
arg1 = argv[0];
|
||||||
|
|
||||||
if (argc == 2) {
|
if (argc == 2) {
|
||||||
pos = NUM2LONG(argv[0]);
|
pos = NUM2LONG(argv[0]);
|
||||||
len = NUM2LONG(argv[1]);
|
len = NUM2LONG(argv[1]);
|
||||||
delete_pos_len:
|
return ary_slice_bang_by_rb_ary_splice(ary, pos, len);
|
||||||
if (len < 0) return Qnil;
|
|
||||||
orig_len = RARRAY_LEN(ary);
|
|
||||||
if (pos < 0) {
|
|
||||||
pos += orig_len;
|
|
||||||
if (pos < 0) return Qnil;
|
|
||||||
}
|
|
||||||
else if (orig_len < pos) return Qnil;
|
|
||||||
if (orig_len < pos + len) {
|
|
||||||
len = orig_len - pos;
|
|
||||||
}
|
|
||||||
if (len == 0) return rb_ary_new2(0);
|
|
||||||
arg2 = rb_ary_new4(len, RARRAY_CONST_PTR_TRANSIENT(ary)+pos);
|
|
||||||
RBASIC_SET_CLASS(arg2, rb_obj_class(ary));
|
|
||||||
rb_ary_splice(ary, pos, len, 0, 0);
|
|
||||||
return arg2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rb_check_arity(argc, 1, 2);
|
|
||||||
arg1 = argv[0];
|
|
||||||
|
|
||||||
if (!FIXNUM_P(arg1)) {
|
if (!FIXNUM_P(arg1)) {
|
||||||
switch (rb_range_beg_len(arg1, &pos, &len, RARRAY_LEN(ary), 0)) {
|
switch (rb_range_beg_len(arg1, &pos, &len, RARRAY_LEN(ary), 0)) {
|
||||||
case Qtrue:
|
case Qtrue:
|
||||||
/* valid range */
|
/* valid range */
|
||||||
goto delete_pos_len;
|
return ary_slice_bang_by_rb_ary_splice(ary, pos, len);
|
||||||
case Qnil:
|
case Qnil:
|
||||||
/* invalid range */
|
/* invalid range */
|
||||||
return Qnil;
|
return Qnil;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue