Unverified Commit 1bf6c846 authored by Yukihiro "Matz" Matsumoto's avatar Yukihiro "Matz" Matsumoto Committed by GitHub

Merge pull request #4213 from shuujii/range-rafactor

range: Refactor range.h/range.c
parents 2a9ccf24 eb216fc8
...@@ -38,7 +38,7 @@ struct RRange { ...@@ -38,7 +38,7 @@ struct RRange {
mrb_range_edges *edges; mrb_range_edges *edges;
mrb_bool excl; mrb_bool excl;
}; };
# define mrb_gc_free_range(mrb, p) mrb_free(mrb, ((struct RRange*)p)->edges) # define mrb_gc_free_range(mrb, p) mrb_free(mrb, (p)->edges)
# define RANGE_BEG(p) ((p)->edges->beg) # define RANGE_BEG(p) ((p)->edges->beg)
# define RANGE_END(p) ((p)->edges->end) # define RANGE_END(p) ((p)->edges->end)
#endif #endif
......
...@@ -14,20 +14,8 @@ ...@@ -14,20 +14,8 @@
#define RANGE_INITIALIZED(p) ((p)->flags |= RANGE_INITIALIZED_MASK) #define RANGE_INITIALIZED(p) ((p)->flags |= RANGE_INITIALIZED_MASK)
#define RANGE_INITIALIZED_P(p) ((p)->flags & RANGE_INITIALIZED_MASK) #define RANGE_INITIALIZED_P(p) ((p)->flags & RANGE_INITIALIZED_MASK)
MRB_API struct RRange*
mrb_range_ptr(mrb_state *mrb, mrb_value range)
{
struct RRange *r = mrb_range_raw_ptr(range);
/* check for if #initialize_copy was removed [#3320] */
if (!RANGE_INITIALIZED_P(r)) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized range");
}
return r;
}
static void static void
range_check(mrb_state *mrb, mrb_value a, mrb_value b) r_check(mrb_state *mrb, mrb_value a, mrb_value b)
{ {
mrb_value ans; mrb_value ans;
enum mrb_vtype ta; enum mrb_vtype ta;
...@@ -51,6 +39,43 @@ range_check(mrb_state *mrb, mrb_value a, mrb_value b) ...@@ -51,6 +39,43 @@ range_check(mrb_state *mrb, mrb_value a, mrb_value b)
} }
} }
static mrb_bool
r_le(mrb_state *mrb, mrb_value a, mrb_value b)
{
mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */
/* output :a < b => -1, a = b => 0, a > b => +1 */
if (mrb_fixnum_p(r)) {
mrb_int c = mrb_fixnum(r);
if (c == 0 || c == -1) return TRUE;
}
return FALSE;
}
static mrb_bool
r_gt(mrb_state *mrb, mrb_value a, mrb_value b)
{
mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b);
/* output :a < b => -1, a = b => 0, a > b => +1 */
return mrb_fixnum_p(r) && mrb_fixnum(r) == 1;
}
static mrb_bool
r_ge(mrb_state *mrb, mrb_value a, mrb_value b)
{
mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */
/* output :a < b => -1, a = b => 0, a > b => +1 */
if (mrb_fixnum_p(r)) {
mrb_int c = mrb_fixnum(r);
if (c == 0 || c == 1) return TRUE;
}
return FALSE;
}
static void static void
range_ptr_alloc_edges(mrb_state *mrb, struct RRange *r) range_ptr_alloc_edges(mrb_state *mrb, struct RRange *r)
{ {
...@@ -62,7 +87,7 @@ range_ptr_alloc_edges(mrb_state *mrb, struct RRange *r) ...@@ -62,7 +87,7 @@ range_ptr_alloc_edges(mrb_state *mrb, struct RRange *r)
static struct RRange * static struct RRange *
range_ptr_init(mrb_state *mrb, struct RRange *r, mrb_value beg, mrb_value end, mrb_bool excl) range_ptr_init(mrb_state *mrb, struct RRange *r, mrb_value beg, mrb_value end, mrb_bool excl)
{ {
range_check(mrb, beg, end); r_check(mrb, beg, end);
if (r) { if (r) {
if (RANGE_INITIALIZED_P(r)) { if (RANGE_INITIALIZED_P(r)) {
...@@ -93,13 +118,6 @@ range_ptr_replace(mrb_state *mrb, struct RRange *r, mrb_value beg, mrb_value end ...@@ -93,13 +118,6 @@ range_ptr_replace(mrb_state *mrb, struct RRange *r, mrb_value beg, mrb_value end
mrb_write_barrier(mrb, (struct RBasic*)r); mrb_write_barrier(mrb, (struct RBasic*)r);
} }
MRB_API mrb_value
mrb_range_new(mrb_state *mrb, mrb_value beg, mrb_value end, mrb_bool excl)
{
struct RRange *r = range_ptr_init(mrb, NULL, beg, end, excl);
return mrb_range_value(r);
}
/* /*
* call-seq: * call-seq:
* rng.first => obj * rng.first => obj
...@@ -123,7 +141,6 @@ range_beg(mrb_state *mrb, mrb_value range) ...@@ -123,7 +141,6 @@ range_beg(mrb_state *mrb, mrb_value range)
* (1..10).end #=> 10 * (1..10).end #=> 10
* (1...10).end #=> 10 * (1...10).end #=> 10
*/ */
static mrb_value static mrb_value
range_end(mrb_state *mrb, mrb_value range) range_end(mrb_state *mrb, mrb_value range)
{ {
...@@ -136,8 +153,8 @@ range_end(mrb_state *mrb, mrb_value range) ...@@ -136,8 +153,8 @@ range_end(mrb_state *mrb, mrb_value range)
* *
* Returns <code>true</code> if <i>range</i> excludes its end value. * Returns <code>true</code> if <i>range</i> excludes its end value.
*/ */
mrb_value static mrb_value
mrb_range_excl(mrb_state *mrb, mrb_value range) range_excl(mrb_state *mrb, mrb_value range)
{ {
return mrb_bool_value(mrb_range_excl_p(mrb, range)); return mrb_bool_value(mrb_range_excl_p(mrb, range));
} }
...@@ -150,21 +167,18 @@ mrb_range_excl(mrb_state *mrb, mrb_value range) ...@@ -150,21 +167,18 @@ mrb_range_excl(mrb_state *mrb, mrb_value range)
* parameter is omitted or is <code>false</code>, the <i>range</i> will include * parameter is omitted or is <code>false</code>, the <i>range</i> will include
* the end object; otherwise, it will be excluded. * the end object; otherwise, it will be excluded.
*/ */
static mrb_value
mrb_value range_initialize(mrb_state *mrb, mrb_value range)
mrb_range_initialize(mrb_state *mrb, mrb_value range)
{ {
mrb_value beg, end; mrb_value beg, end;
mrb_bool exclusive; mrb_bool exclusive = FALSE;
mrb_int n; mrb_int n;
n = mrb_get_args(mrb, "oo|b", &beg, &end, &exclusive); n = mrb_get_args(mrb, "oo|b", &beg, &end, &exclusive);
if (n != 3) {
exclusive = FALSE;
}
range_ptr_replace(mrb, mrb_range_raw_ptr(range), beg, end, exclusive); range_ptr_replace(mrb, mrb_range_raw_ptr(range), beg, end, exclusive);
return range; return range;
} }
/* /*
* call-seq: * call-seq:
* range == obj => true or false * range == obj => true or false
...@@ -177,11 +191,9 @@ mrb_range_initialize(mrb_state *mrb, mrb_value range) ...@@ -177,11 +191,9 @@ mrb_range_initialize(mrb_state *mrb, mrb_value range)
* (0..2) == (0..2) #=> true * (0..2) == (0..2) #=> true
* (0..2) == Range.new(0,2) #=> true * (0..2) == Range.new(0,2) #=> true
* (0..2) == (0...2) #=> false * (0..2) == (0...2) #=> false
*
*/ */
static mrb_value
mrb_value range_eq(mrb_state *mrb, mrb_value range)
mrb_range_eq(mrb_state *mrb, mrb_value range)
{ {
struct RRange *rr; struct RRange *rr;
struct RRange *ro; struct RRange *ro;
...@@ -204,52 +216,14 @@ mrb_range_eq(mrb_state *mrb, mrb_value range) ...@@ -204,52 +216,14 @@ mrb_range_eq(mrb_state *mrb, mrb_value range)
return mrb_true_value(); return mrb_true_value();
} }
static mrb_bool
r_le(mrb_state *mrb, mrb_value a, mrb_value b)
{
mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */
/* output :a < b => -1, a = b => 0, a > b => +1 */
if (mrb_fixnum_p(r)) {
mrb_int c = mrb_fixnum(r);
if (c == 0 || c == -1) return TRUE;
}
return FALSE;
}
static mrb_bool
r_gt(mrb_state *mrb, mrb_value a, mrb_value b)
{
mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b);
/* output :a < b => -1, a = b => 0, a > b => +1 */
return mrb_fixnum_p(r) && mrb_fixnum(r) == 1;
}
static mrb_bool
r_ge(mrb_state *mrb, mrb_value a, mrb_value b)
{
mrb_value r = mrb_funcall(mrb, a, "<=>", 1, b); /* compare result */
/* output :a < b => -1, a = b => 0, a > b => +1 */
if (mrb_fixnum_p(r)) {
mrb_int c = mrb_fixnum(r);
if (c == 0 || c == 1) return TRUE;
}
return FALSE;
}
/* /*
* call-seq: * call-seq:
* range === obj => true or false * range === obj => true or false
* range.member?(val) => true or false * range.member?(val) => true or false
* range.include?(val) => true or false * range.include?(val) => true or false
*
*/ */
mrb_value static mrb_value
mrb_range_include(mrb_state *mrb, mrb_value range) range_include(mrb_state *mrb, mrb_value range)
{ {
mrb_value val; mrb_value val;
struct RRange *r = mrb_range_ptr(mrb, range); struct RRange *r = mrb_range_ptr(mrb, range);
...@@ -267,39 +241,6 @@ mrb_range_include(mrb_state *mrb, mrb_value range) ...@@ -267,39 +241,6 @@ mrb_range_include(mrb_state *mrb, mrb_value range)
return mrb_bool_value(include_p); return mrb_bool_value(include_p);
} }
MRB_API mrb_int
mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc)
{
mrb_int beg, end;
struct RRange *r;
if (mrb_type(range) != MRB_TT_RANGE) return 0;
r = mrb_range_ptr(mrb, range);
beg = mrb_int(mrb, RANGE_BEG(r));
end = mrb_int(mrb, RANGE_END(r));
if (beg < 0) {
beg += len;
if (beg < 0) return 2;
}
if (trunc) {
if (beg > len) return 2;
if (end > len) end = len;
}
if (end < 0) end += len;
if (!RANGE_EXCL(r) && (!trunc || end < len))
end++; /* include end point */
len = end - beg;
if (len < 0) len = 0;
*begp = beg;
*lenp = len;
return 1;
}
/* 15.2.14.4.12(x) */ /* 15.2.14.4.12(x) */
/* /*
* call-seq: * call-seq:
...@@ -307,7 +248,6 @@ mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, ...@@ -307,7 +248,6 @@ mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp,
* *
* Convert this range object to a printable form. * Convert this range object to a printable form.
*/ */
static mrb_value static mrb_value
range_to_s(mrb_state *mrb, mrb_value range) range_to_s(mrb_state *mrb, mrb_value range)
{ {
...@@ -332,7 +272,6 @@ range_to_s(mrb_state *mrb, mrb_value range) ...@@ -332,7 +272,6 @@ range_to_s(mrb_state *mrb, mrb_value range)
* <code>inspect</code> to convert the start and end * <code>inspect</code> to convert the start and end
* objects). * objects).
*/ */
static mrb_value static mrb_value
range_inspect(mrb_state *mrb, mrb_value range) range_inspect(mrb_state *mrb, mrb_value range)
{ {
...@@ -360,9 +299,7 @@ range_inspect(mrb_state *mrb, mrb_value range) ...@@ -360,9 +299,7 @@ range_inspect(mrb_state *mrb, mrb_value range)
* (0..2).eql?(0..2) #=> true * (0..2).eql?(0..2) #=> true
* (0..2).eql?(Range.new(0,2)) #=> true * (0..2).eql?(Range.new(0,2)) #=> true
* (0..2).eql?(0...2) #=> false * (0..2).eql?(0...2) #=> false
*
*/ */
static mrb_value static mrb_value
range_eql(mrb_state *mrb, mrb_value range) range_eql(mrb_state *mrb, mrb_value range)
{ {
...@@ -372,9 +309,7 @@ range_eql(mrb_state *mrb, mrb_value range) ...@@ -372,9 +309,7 @@ range_eql(mrb_state *mrb, mrb_value range)
mrb_get_args(mrb, "o", &obj); mrb_get_args(mrb, "o", &obj);
if (mrb_obj_equal(mrb, range, obj)) return mrb_true_value(); if (mrb_obj_equal(mrb, range, obj)) return mrb_true_value();
if (!mrb_obj_is_kind_of(mrb, obj, mrb->range_class)) { if (!mrb_obj_is_kind_of(mrb, obj, mrb->range_class)) return mrb_false_value();
return mrb_false_value();
}
if (mrb_type(obj) != MRB_TT_RANGE) return mrb_false_value(); if (mrb_type(obj) != MRB_TT_RANGE) return mrb_false_value();
r = mrb_range_ptr(mrb, range); r = mrb_range_ptr(mrb, range);
...@@ -445,6 +380,57 @@ mrb_gc_mark_range(mrb_state *mrb, struct RRange *r) ...@@ -445,6 +380,57 @@ mrb_gc_mark_range(mrb_state *mrb, struct RRange *r)
} }
} }
MRB_API struct RRange*
mrb_range_ptr(mrb_state *mrb, mrb_value range)
{
struct RRange *r = mrb_range_raw_ptr(range);
/* check for if #initialize_copy was removed [#3320] */
if (!RANGE_INITIALIZED_P(r)) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized range");
}
return r;
}
MRB_API mrb_value
mrb_range_new(mrb_state *mrb, mrb_value beg, mrb_value end, mrb_bool excl)
{
struct RRange *r = range_ptr_init(mrb, NULL, beg, end, excl);
return mrb_range_value(r);
}
MRB_API mrb_int
mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc)
{
mrb_int beg, end;
struct RRange *r;
if (mrb_type(range) != MRB_TT_RANGE) return 0;
r = mrb_range_ptr(mrb, range);
beg = mrb_int(mrb, RANGE_BEG(r));
end = mrb_int(mrb, RANGE_END(r));
if (beg < 0) {
beg += len;
if (beg < 0) return 2;
}
if (trunc) {
if (beg > len) return 2;
if (end > len) end = len;
}
if (end < 0) end += len;
if (!RANGE_EXCL(r) && (!trunc || end < len)) end++; /* include end point */
len = end - beg;
if (len < 0) len = 0;
*begp = beg;
*lenp = len;
return 1;
}
void void
mrb_init_range(mrb_state *mrb) mrb_init_range(mrb_state *mrb)
{ {
...@@ -456,15 +442,14 @@ mrb_init_range(mrb_state *mrb) ...@@ -456,15 +442,14 @@ mrb_init_range(mrb_state *mrb)
mrb_define_method(mrb, r, "begin", range_beg, MRB_ARGS_NONE()); /* 15.2.14.4.3 */ mrb_define_method(mrb, r, "begin", range_beg, MRB_ARGS_NONE()); /* 15.2.14.4.3 */
mrb_define_method(mrb, r, "end", range_end, MRB_ARGS_NONE()); /* 15.2.14.4.5 */ mrb_define_method(mrb, r, "end", range_end, MRB_ARGS_NONE()); /* 15.2.14.4.5 */
mrb_define_method(mrb, r, "==", mrb_range_eq, MRB_ARGS_REQ(1)); /* 15.2.14.4.1 */ mrb_define_method(mrb, r, "==", range_eq, MRB_ARGS_REQ(1)); /* 15.2.14.4.1 */
mrb_define_method(mrb, r, "===", mrb_range_include, MRB_ARGS_REQ(1)); /* 15.2.14.4.2 */ mrb_define_method(mrb, r, "===", range_include, MRB_ARGS_REQ(1)); /* 15.2.14.4.2 */
mrb_define_method(mrb, r, "exclude_end?", mrb_range_excl, MRB_ARGS_NONE()); /* 15.2.14.4.6 */ mrb_define_method(mrb, r, "exclude_end?", range_excl, MRB_ARGS_NONE()); /* 15.2.14.4.6 */
mrb_define_method(mrb, r, "first", range_beg, MRB_ARGS_NONE()); /* 15.2.14.4.7 */ mrb_define_method(mrb, r, "first", range_beg, MRB_ARGS_NONE()); /* 15.2.14.4.7 */
mrb_define_method(mrb, r, "include?", mrb_range_include, MRB_ARGS_REQ(1)); /* 15.2.14.4.8 */ mrb_define_method(mrb, r, "include?", range_include, MRB_ARGS_REQ(1)); /* 15.2.14.4.8 */
mrb_define_method(mrb, r, "initialize", mrb_range_initialize, MRB_ARGS_ANY()); /* 15.2.14.4.9 */ mrb_define_method(mrb, r, "initialize", range_initialize, MRB_ARGS_ANY()); /* 15.2.14.4.9 */
mrb_define_method(mrb, r, "last", range_end, MRB_ARGS_NONE()); /* 15.2.14.4.10 */ mrb_define_method(mrb, r, "last", range_end, MRB_ARGS_NONE()); /* 15.2.14.4.10 */
mrb_define_method(mrb, r, "member?", mrb_range_include, MRB_ARGS_REQ(1)); /* 15.2.14.4.11 */ mrb_define_method(mrb, r, "member?", range_include, MRB_ARGS_REQ(1)); /* 15.2.14.4.11 */
mrb_define_method(mrb, r, "to_s", range_to_s, MRB_ARGS_NONE()); /* 15.2.14.4.12(x) */ mrb_define_method(mrb, r, "to_s", range_to_s, MRB_ARGS_NONE()); /* 15.2.14.4.12(x) */
mrb_define_method(mrb, r, "inspect", range_inspect, MRB_ARGS_NONE()); /* 15.2.14.4.13(x) */ mrb_define_method(mrb, r, "inspect", range_inspect, MRB_ARGS_NONE()); /* 15.2.14.4.13(x) */
mrb_define_method(mrb, r, "eql?", range_eql, MRB_ARGS_REQ(1)); /* 15.2.14.4.14(x) */ mrb_define_method(mrb, r, "eql?", range_eql, MRB_ARGS_REQ(1)); /* 15.2.14.4.14(x) */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment