ruby-changes:18442
From: nobu <ko1@a...>
Date: Thu, 6 Jan 2011 05:11:33 +0900 (JST)
Subject: [ruby-changes:18442] Ruby:r30465 (trunk): * array.c (rb_ary_resize): new utility function.
nobu 2011-01-06 05:10:59 +0900 (Thu, 06 Jan 2011) New Revision: 30465 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=30465 Log: * array.c (rb_ary_resize): new utility function. [ruby-dev:42912] Added directories: trunk/ext/-test-/array/ trunk/ext/-test-/array/resize/ trunk/test/-ext-/array/ Added files: trunk/ext/-test-/array/resize/extconf.rb trunk/ext/-test-/array/resize/resize.c trunk/test/-ext-/array/test_resize.rb Modified files: trunk/array.c trunk/include/ruby/intern.h Index: array.c =================================================================== --- array.c (revision 30464) +++ array.c (revision 30465) @@ -1308,6 +1308,51 @@ } } +/*! + * expands or shrinks \a ary to \a len elements. + * expanded region will be filled with Qnil. + * \param ary an arrray + * \param len new size + * \return \a ary + * \post the size of \a ary is \a len. + */ +VALUE +rb_ary_resize(VALUE ary, long len) +{ + long olen; + + rb_ary_modify(ary); + olen = RARRAY_LEN(ary); + if (len == olen) return ary; + if (len > ARY_MAX_SIZE) { + rb_raise(rb_eIndexError, "index %ld too big", len); + } + if (len > olen) { + if (len >= ARY_CAPA(ary)) { + ary_double_capa(ary, len); + } + rb_mem_clear(RARRAY_PTR(ary) + olen, len - olen); + ARY_SET_HEAP_LEN(ary, len); + } + else if (ARY_EMBED_P(ary)) { + ARY_SET_EMBED_LEN(ary, len); + } + else if (len <= RARRAY_EMBED_LEN_MAX) { + VALUE tmp[RARRAY_EMBED_LEN_MAX]; + MEMCPY(tmp, ARY_HEAP_PTR(ary), VALUE, len); + ary_discard(ary); + MEMCPY(ARY_EMBED_PTR(ary), tmp, VALUE, len); + ARY_SET_EMBED_LEN(ary, len); + } + else { + if (olen > len + ARY_DEFAULT_SIZE) { + REALLOC_N(RARRAY(ary)->as.heap.ptr, VALUE, len); + } + ARY_SET_HEAP_LEN(ary, len); + } + return ary; +} + /* * call-seq: * ary[index] = obj -> obj Index: include/ruby/intern.h =================================================================== --- include/ruby/intern.h (revision 30464) +++ include/ruby/intern.h (revision 30465) @@ -83,6 +83,7 @@ VALUE rb_ary_cmp(VALUE, VALUE); VALUE rb_ary_replace(VALUE copy, VALUE orig); VALUE rb_get_values_at(VALUE, long, int, VALUE*, VALUE(*)(VALUE,long)); +VALUE rb_ary_resize(VALUE ary, long len); /* bignum.c */ VALUE rb_big_new(long, int); int rb_bigzero_p(VALUE x); Index: ext/-test-/array/resize/resize.c =================================================================== --- ext/-test-/array/resize/resize.c (revision 0) +++ ext/-test-/array/resize/resize.c (revision 30465) @@ -0,0 +1,14 @@ +#include "ruby/ruby.h" + +static VALUE +ary_resize(VALUE ary, VALUE len) +{ + rb_ary_resize(ary, NUM2LONG(len)); + return ary; +} + +void +Init_resize(void) +{ + rb_define_method(rb_cArray, "resize", ary_resize, 1); +} Property changes on: ext/-test-/array/resize/resize.c ___________________________________________________________________ Added: svn:eol-style + LF Index: ext/-test-/array/resize/extconf.rb =================================================================== --- ext/-test-/array/resize/extconf.rb (revision 0) +++ ext/-test-/array/resize/extconf.rb (revision 30465) @@ -0,0 +1 @@ +create_makefile("-test-/array/resize") Property changes on: ext/-test-/array/resize/extconf.rb ___________________________________________________________________ Added: svn:eol-style + LF Index: test/-ext-/array/test_resize.rb =================================================================== --- test/-ext-/array/test_resize.rb (revision 0) +++ test/-ext-/array/test_resize.rb (revision 30465) @@ -0,0 +1,29 @@ +require 'test/unit' +require '-test-/array/resize' + +class TestArray < Test::Unit::TestCase + class TestResize < Test::Unit::TestCase + def test_expand + feature = '[ruby-dev:42912]' + ary = [*1..10] + ary.resize(10) + assert_equal(10, ary.size, feature) + assert_equal([*1..10], ary, feature) + ary.resize(100) + assert_equal(100, ary.size, feature) + assert_equal([*1..10]+[nil]*90, ary, feature) + ary.resize(20) + assert_equal(20, ary.size, feature) + assert_equal([*1..10]+[nil]*10, ary, feature) + ary.resize(2) + assert_equal(2, ary.size, feature) + assert_equal([1,2], ary, feature) + ary.resize(3) + assert_equal(3, ary.size, feature) + assert_equal([1,2,nil], ary, feature) + ary.resize(10) + assert_equal(10, ary.size, feature) + assert_equal([1,2]+[nil]*8, ary, feature) + end + end +end Property changes on: test/-ext-/array/test_resize.rb ___________________________________________________________________ Added: svn:eol-style + LF -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/