summaryrefslogtreecommitdiff
path: root/array.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-01-05 20:10:59 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-01-05 20:10:59 +0000
commitc8aaf31fdd06df05c8c58df3d312280c5a02fc09 (patch)
treeedd156110766ed5e43f11c393f49e4300dbe57a6 /array.c
parent697a45b196c606147997372c20d14c6b2eccdda4 (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.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/array.c b/array.c
index b7c913d40d..54213449dd 100644
--- a/array.c
+++ b/array.c
@@ -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