Project

General

Profile

0002-introduce-Array-max-and-Array-min.patch

mame (Yusuke Endoh), 03/14/2016 01:28 PM

View differences:

array.c
4178 4178
    return ary3;
4179 4179
}
4180 4180

  
4181
/*
4182
 *  call-seq:
4183
 *     ary.max                   -> obj
4184
 *     ary.max { |a, b| block }  -> obj
4185
 *     ary.max(n)                -> array
4186
 *     ary.max(n) {|a,b| block } -> array
4187
 *
4188
 *  Returns the object in _ary_ with the maximum value. The
4189
 *  first form assumes all objects implement <code>Comparable</code>;
4190
 *  the second uses the block to return <em>a <=> b</em>.
4191
 *
4192
 *     a = %w(albatross dog horse)
4193
 *     a.max                                   #=> "horse"
4194
 *     a.max { |a, b| a.length <=> b.length }  #=> "albatross"
4195
 *
4196
 *  If the +n+ argument is given, maximum +n+ elements are returned
4197
 *  as an array.
4198
 *
4199
 *     a = %w[albatross dog horse]
4200
 *     a.max(2)                                  #=> ["horse", "dog"]
4201
 *     a.max(2) {|a, b| a.length <=> b.length }  #=> ["albatross", "horse"]
4202
 */
4203
static VALUE
4204
rb_ary_max(int argc, VALUE *argv, VALUE ary)
4205
{
4206
    struct cmp_opt_data cmp_opt = { 0, 0 };
4207
    VALUE result = Qundef, v;
4208
    VALUE num;
4209
    long i;
4210

  
4211
    rb_scan_args(argc, argv, "01", &num);
4212

  
4213
    if (!NIL_P(num) || rb_block_given_p())
4214
       return rb_call_super(argc, argv); /* XXX: should redefine? */
4215

  
4216
    for (i = 0; i < RARRAY_LEN(ary); i++) {
4217
       v = RARRAY_AREF(ary, i);
4218
       if (result == Qundef || OPTIMIZED_CMP(v, result, cmp_opt) > 0) {
4219
           result = v;
4220
       }
4221
    }
4222
    if (result == Qundef) return Qnil;
4223
    return result;
4224
}
4225

  
4226
/*
4227
 *  call-seq:
4228
 *     ary.min                     -> obj
4229
 *     ary.min {| a,b | block }    -> obj
4230
 *     ary.min(n)                  -> array
4231
 *     ary.min(n) {| a,b | block } -> array
4232
 *
4233
 *  Returns the object in _ary_ with the minimum value. The
4234
 *  first form assumes all objects implement <code>Comparable</code>;
4235
 *  the second uses the block to return <em>a <=> b</em>.
4236
 *
4237
 *     a = %w(albatross dog horse)
4238
 *     a.min                                   #=> "albatross"
4239
 *     a.min { |a, b| a.length <=> b.length }  #=> "dog"
4240
 *
4241
 *  If the +n+ argument is given, minimum +n+ elements are returned
4242
 *  as an array.
4243
 *
4244
 *     a = %w[albatross dog horse]
4245
 *     a.min(2)                                  #=> ["albatross", "dog"]
4246
 *     a.min(2) {|a, b| a.length <=> b.length }  #=> ["dog", "horse"]
4247
 */
4248
static VALUE
4249
rb_ary_min(int argc, VALUE *argv, VALUE ary)
4250
{
4251
    struct cmp_opt_data cmp_opt = { 0, 0 };
4252
    VALUE result = Qundef, v;
4253
    VALUE num;
4254
    long i;
4255

  
4256
    rb_scan_args(argc, argv, "01", &num);
4257

  
4258
    if (!NIL_P(num) || rb_block_given_p())
4259
       return rb_call_super(argc, argv); /* XXX: should redefine? */
4260

  
4261
    for (i = 0; i < RARRAY_LEN(ary); i++) {
4262
       v = RARRAY_AREF(ary, i);
4263
       if (result == Qundef || OPTIMIZED_CMP(v, result, cmp_opt) < 0) {
4264
           result = v;
4265
       }
4266
    }
4267
    if (result == Qundef) return Qnil;
4268
    return result;
4269
}
4270

  
4181 4271
static int
4182 4272
push_value(st_data_t key, st_data_t val, st_data_t ary)
4183 4273
{
......
5867 5957
    rb_define_method(rb_cArray, "&", rb_ary_and, 1);
5868 5958
    rb_define_method(rb_cArray, "|", rb_ary_or, 1);
5869 5959

  
5960
    rb_define_method(rb_cArray, "max", rb_ary_max, -1);
5961
    rb_define_method(rb_cArray, "min", rb_ary_min, -1);
5962

  
5870 5963
    rb_define_method(rb_cArray, "uniq", rb_ary_uniq, 0);
5871 5964
    rb_define_method(rb_cArray, "uniq!", rb_ary_uniq_bang, 0);
5872 5965
    rb_define_method(rb_cArray, "compact", rb_ary_compact, 0);
enum.c
1412 1412
    return memo->v1;
1413 1413
}
1414 1414

  
1415
#define OPTIMIZED_CMP(a, b, data) \
1416
    ((FIXNUM_P(a) && FIXNUM_P(b) && CMP_OPTIMIZABLE(data, Fixnum)) ? \
1417
     (((long)a > (long)b) ? 1 : ((long)a < (long)b) ? -1 : 0) : \
1418
     (STRING_P(a) && STRING_P(b) && CMP_OPTIMIZABLE(data, String)) ? \
1419
     rb_str_cmp(a, b) : \
1420
     rb_cmpint(rb_funcallv(a, id_cmp, 1, &b), a, b))
1421

  
1422 1415
struct min_t {
1423 1416
    VALUE min;
1424 1417
    struct cmp_opt_data cmp_opt;
internal.h
698 698
      rb_method_basic_definition_p(TOKEN_PASTE(rb_c,type), id_cmp) && \
699 699
      ((data).opt_methods |= CMP_OPTIMIZABLE_BIT(type))))
700 700

  
701
#define OPTIMIZED_CMP(a, b, data) \
702
    ((FIXNUM_P(a) && FIXNUM_P(b) && CMP_OPTIMIZABLE(data, Fixnum)) ? \
703
     (((long)a > (long)b) ? 1 : ((long)a < (long)b) ? -1 : 0) : \
704
     (STRING_P(a) && STRING_P(b) && CMP_OPTIMIZABLE(data, String)) ? \
705
     rb_str_cmp(a, b) : \
706
     rb_cmpint(rb_funcallv(a, id_cmp, 1, &b), a, b))
707

  
701 708
/* ment is in method.h */
702 709

  
703 710
/* global variable */
704
-