about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2011-06-18 16:41:09 -0700
committerPatrick Walton <pcwalton@mimiga.net>2011-06-18 16:41:09 -0700
commitca2ff9c50dc0af698d50fce3304909d60448bd8c (patch)
treeae1543a72515a3634ee7e4887b4e6ea64febb40e /src
parent5d90b1df4b9933adc20736a39a2b9a747760e0ab (diff)
downloadrust-ca2ff9c50dc0af698d50fce3304909d60448bd8c.tar.gz
rust-ca2ff9c50dc0af698d50fce3304909d60448bd8c.zip
stdlib: Add ivec::grow_set()
Diffstat (limited to 'src')
-rw-r--r--src/lib/ivec.rs21
-rw-r--r--src/test/run-pass/lib-ivec.rs12
2 files changed, 32 insertions, 1 deletions
diff --git a/src/lib/ivec.rs b/src/lib/ivec.rs
index 93c6896d9b7..2bc23c54b9c 100644
--- a/src/lib/ivec.rs
+++ b/src/lib/ivec.rs
@@ -29,7 +29,7 @@ fn to_ptr[T](&T[] v) -> *T {
     ret rustrt::ivec_to_ptr(v);
 }
 
-fn len[T](&T[] v) -> uint {
+fn len[T](&T[mutable?] v) -> uint {
     ret rusti::ivec_len(v);
 }
 
@@ -110,6 +110,7 @@ fn slice_mut[T](&T[mutable?] v, uint start, uint end) -> T[mutable] {
 
 /// Expands the given vector in-place by appending `n` copies of `initval`.
 fn grow[T](&mutable T[] v, uint n, &T initval) {
+    reserve(v, len(v) + n);
     let uint i = 0u;
     while (i < n) {
         v += ~[initval];
@@ -117,9 +118,20 @@ fn grow[T](&mutable T[] v, uint n, &T initval) {
     }
 }
 
+// TODO: Remove me once we have slots.
+fn grow_mut[T](&mutable T[mutable] v, uint n, &T initval) {
+    reserve(v, len(v) + n);
+    let uint i = 0u;
+    while (i < n) {
+        v += ~[mutable initval];
+        i += 1u;
+    }
+}
+
 /// Calls `f` `n` times and appends the results of these calls to the given
 /// vector.
 fn grow_fn[T](&mutable T[] v, uint n, fn(uint)->T init_fn) {
+    reserve(v, len(v) + n);
     let uint i = 0u;
     while (i < n) {
         v += ~[init_fn(i)];
@@ -127,6 +139,13 @@ fn grow_fn[T](&mutable T[] v, uint n, fn(uint)->T init_fn) {
     }
 }
 
+/// Sets the element at position `index` to `val`. If `index` is past the end
+/// of the vector, expands the vector by replicating `initval` to fill the
+/// intervening space.
+fn grow_set[T](&mutable T[mutable] v, uint index, &T initval, &T val) {
+    if (index >= len(v)) { grow_mut(v, index - len(v) + 1u, initval); }
+    v.(index) = val;
+}
 
 mod unsafe {
     fn copy_from_buf[T](&mutable T[] v, *T ptr, uint count) {
diff --git a/src/test/run-pass/lib-ivec.rs b/src/test/run-pass/lib-ivec.rs
index 15f9642d229..2d0955269fe 100644
--- a/src/test/run-pass/lib-ivec.rs
+++ b/src/test/run-pass/lib-ivec.rs
@@ -133,6 +133,17 @@ fn test_grow_fn() {
     assert (v.(2) == 4u);
 }
 
+fn test_grow_set() {
+    auto v = ~[ mutable 1, 2, 3 ];
+    ivec::grow_set(v, 4u, 4, 5);
+    assert (ivec::len(v) == 5u);
+    assert (v.(0) == 1);
+    assert (v.(1) == 2);
+    assert (v.(2) == 3);
+    assert (v.(3) == 4);
+    assert (v.(4) == 5);
+}
+
 fn main() {
     test_reserve_and_on_heap();
     test_unsafe_ptrs();
@@ -146,5 +157,6 @@ fn main() {
     // Appending
     test_grow();
     test_grow_fn();
+    test_grow_set();
 }