diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2011-01-05 20:10:59 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2011-01-05 20:10:59 +0000 |
commit | c8aaf31fdd06df05c8c58df3d312280c5a02fc09 (patch) | |
tree | edd156110766ed5e43f11c393f49e4300dbe57a6 /array.c | |
parent | 697a45b196c606147997372c20d14c6b2eccdda4 (diff) |
* array.c (rb_ary_resize): new utility function. [ruby-dev:42912]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@30465 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'array.c')
-rw-r--r-- | array.c | 45 |
1 files changed, 45 insertions, 0 deletions
@@ -1308,6 +1308,51 @@ rb_ary_splice(VALUE ary, long beg, long len, VALUE rpl) } } +/*! + * 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 |