From 8cffa04def055836cdc3e85ed94b1a8d923712eb Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sat, 29 Jun 2024 08:32:06 +0900 Subject: [PATCH] array.c: implement Array#== and Array#eql? in C It seems OK to call comparison from C method from measurement. --- mrblib/array.rb | 41 --------------------------------- src/array.c | 60 +++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 53 insertions(+), 48 deletions(-) diff --git a/mrblib/array.rb b/mrblib/array.rb index 851f15cca..38a040600 100644 --- a/mrblib/array.rb +++ b/mrblib/array.rb @@ -75,47 +75,6 @@ class Array # ISO 15.2.12.5.20 alias map! collect! - ## - # call-seq: - # array == other -> true or false - # - # Equality---Two arrays are equal if they contain the same number - # of elements and if each element is equal to (according to - # Object.==) the corresponding element in the other array. - # - def ==(other) - other = self.__ary_eq(other) - return false if other == false - return true if other == true - len = self.size - i = 0 - while i < len - return false if self[i] != other[i] - i += 1 - end - return true - end - - ## - # call-seq: - # array.eql? other_array -> true or false - # - # Returns true if +self+ and _other_ are the same object, - # or are both arrays with the same content. - # - def eql?(other) - other = self.__ary_eq(other) - return false if other == false - return true if other == true - len = self.size - i = 0 - while i < len - return false unless self[i].eql?(other[i]) - i += 1 - end - return true - end - ## # call-seq: # array <=> other_array -> -1, 0, or 1 diff --git a/src/array.c b/src/array.c index c00b4f5d5..22f0d8c55 100644 --- a/src/array.c +++ b/src/array.c @@ -1358,19 +1358,64 @@ mrb_ary_to_s(mrb_state *mrb, mrb_value self) return ret; } +/* check array equality: 1=equal,0=not_equal,-1=need_elments_check */ +static mrb_int +ary_eq(mrb_state *mrb, mrb_value ary1, mrb_value ary2) +{ + if (mrb_obj_equal(mrb, ary1, ary2)) return 1; + if (!mrb_array_p(ary2)) return 0; + if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return 0; + + return -1; +} + +/* + * call-seq: + * array == other -> true or false + * + * Equality---Two arrays are equal if they contain the same number + * of elements and if each element is equal to (according to + * Object.==) the corresponding element in the other array. + * + */ static mrb_value mrb_ary_eq(mrb_state *mrb, mrb_value ary1) { mrb_value ary2 = mrb_get_arg1(mrb); + mrb_int n = ary_eq(mrb, ary1, ary2); - mrb->c->ci->mid = 0; - if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_true_value(); - if (!mrb_array_p(ary2)) { - return mrb_false_value(); + if (n == 1) return mrb_true_value(); + if (n == 0) return mrb_false_value(); + + for (mrb_int i=0; i true or false + * + * Returns true if +self+ and _other_ are the same object, + * or are both arrays with the same content. + * + */ +static mrb_value +mrb_ary_eql(mrb_state *mrb, mrb_value ary1) +{ + mrb_value ary2 = mrb_get_arg1(mrb); + mrb_int n = ary_eq(mrb, ary1, ary2); + + if (n == 1) return mrb_true_value(); + if (n == 0) return mrb_false_value(); + + for (mrb_int i=0; i