GitHub

@@ -1409,6 +1409,76 @@ mrb_ary_delete(mrb_state *mrb, mrb_value self)

14091409

return ret;

14101410

}

141114111412+

static mrb_bool

1413+

sort_cmp(mrb_state *mrb, mrb_value *p, mrb_int a, mrb_int b, mrb_value blk)

1414+

{

1415+

mrb_int cmp;

1416+1417+

if (mrb_nil_p(blk)) {

1418+

cmp = mrb_cmp(mrb, p[a], p[b]);

1419+

}

1420+

else {

1421+

mrb_value c = mrb_funcall_id(mrb, blk, MRB_SYM(call), 2, p[a], p[b]);

1422+

if (mrb_nil_p(c) || !mrb_fixnum_p(c)) {

1423+

mrb_raisef(mrb, E_ARGUMENT_ERROR, "comparison of %!v and %!v failed", p[a], p[b]);

1424+

}

1425+

cmp = mrb_fixnum(c);

1426+

}

1427+

return cmp > 0;

1428+

}

1429+1430+

static void

1431+

heapify(mrb_state *mrb, mrb_value *a, mrb_int index, mrb_int size, mrb_value blk)

1432+

{

1433+

mrb_int max = index;

1434+

mrb_int left_index = 2 * index + 1;

1435+

mrb_int right_index = left_index + 1;

1436+

if (left_index < size && sort_cmp(mrb, a, left_index, max, blk)) {

1437+

max = left_index;

1438+

}

1439+

if (right_index < size && sort_cmp(mrb, a, right_index, max, blk)) {

1440+

max = right_index;

1441+

}

1442+

if (max != index) {

1443+

mrb_value tmp = a[max];

1444+

a[max] = a[index];

1445+

a[index] = tmp;

1446+

heapify(mrb, a, max, size, blk);

1447+

}

1448+

}

1449+1450+

/*

1451+

* call-seq:

1452+

* array.sort! -> self

1453+

* array.sort! {|a, b| ... } -> self

1454+

*

1455+

* Sort all elements and replace +self+ with these

1456+

* elements.

1457+

*/

1458+

static mrb_value

1459+

mrb_ary_sort_bang(mrb_state *mrb, mrb_value ary)

1460+

{

1461+

mrb_value blk;

1462+1463+

mrb_int n = RARRAY_LEN(ary);

1464+

if (n < 2) return ary;

1465+1466+

ary_modify(mrb, mrb_ary_ptr(ary));

1467+

mrb_get_args(mrb, "&", &blk);

1468+1469+

mrb_value *a = RARRAY_PTR(ary);

1470+

for (mrb_int i = n / 2 - 1; i > -1; i--) {

1471+

heapify(mrb, a, i, n, blk);

1472+

}

1473+

for (mrb_int i = n - 1; i > 0; i--) {

1474+

mrb_value tmp = a[0];

1475+

a[0] = a[i];

1476+

a[i] = tmp;

1477+

heapify(mrb, a, 0, i, blk);

1478+

}

1479+

return ary;

1480+

}

1481+14121482

void

14131483

mrb_init_array(mrb_state *mrb)

14141484

{

@@ -1446,6 +1516,7 @@ mrb_init_array(mrb_state *mrb)

14461516

mrb_define_method_id(mrb, a, MRB_SYM(unshift), mrb_ary_unshift_m, MRB_ARGS_ANY()); /* 15.2.12.5.30 */

14471517

mrb_define_method_id(mrb, a, MRB_SYM(to_s), mrb_ary_to_s, MRB_ARGS_NONE());

14481518

mrb_define_method_id(mrb, a, MRB_SYM(inspect), mrb_ary_to_s, MRB_ARGS_NONE());

1519+

mrb_define_method_id(mrb, a, MRB_SYM_B(sort), mrb_ary_sort_bang, MRB_ARGS_NONE());

1449152014501521

mrb_define_method_id(mrb, a, MRB_SYM(__ary_eq), mrb_ary_eq, MRB_ARGS_REQ(1));

14511522

mrb_define_method_id(mrb, a, MRB_SYM(__ary_cmp), mrb_ary_cmp, MRB_ARGS_REQ(1));

Read the original on github.com ↗