about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/core.rc11
-rw-r--r--src/libcore/dvec.rs355
-rw-r--r--src/libcore/io.rs42
-rw-r--r--src/libcore/iter-trait/dvec.rs37
-rw-r--r--src/libcore/prelude.rs1
-rw-r--r--src/libcore/repr.rs13
-rw-r--r--src/libcore/task/local_data_priv.rs25
7 files changed, 41 insertions, 443 deletions
diff --git a/src/libcore/core.rc b/src/libcore/core.rc
index 21d83618684..79a5d297178 100644
--- a/src/libcore/core.rc
+++ b/src/libcore/core.rc
@@ -21,10 +21,10 @@ used features.
 the floating point types, the `bool` type, tuples, characters, strings,
 vectors (`vec`), managed boxes (`managed`), owned boxes (`owned`), and unsafe
 and borrowed pointers (`ptr`).  Additionally, `core` provides task management
-and creation (`task`), communication primitives (`comm` and `pipes`), an
-efficient vector builder (`dvec`), platform abstractions (`os` and `path`),
-basic I/O abstractions (`io`), common traits (`cmp`, `num`, `to_str`), and
-complete bindings to the C standard library (`libc`).
+and creation (`task`), communication primitives (`comm` and `pipes`), platform
+abstractions (`os` and `path`), basic I/O abstractions (`io`), common traits
+(`cmp`, `num`, `to_str`), and complete bindings to the C standard library
+(`libc`).
 
 `core` is linked to all crates by default and its contents imported.
 Implicitly, all crates behave as if they included the following prologue:
@@ -141,9 +141,6 @@ pub mod container;
 pub mod option;
 pub mod result;
 pub mod either;
-pub mod dvec;
-#[path="iter-trait.rs"] #[merge = "iter-trait/dvec.rs"]
-pub mod dvec_iter;
 pub mod dlist;
 #[path="iter-trait.rs"] #[merge = "iter-trait/dlist.rs"]
 pub mod dlist_iter;
diff --git a/src/libcore/dvec.rs b/src/libcore/dvec.rs
deleted file mode 100644
index 43daf5fa6a5..00000000000
--- a/src/libcore/dvec.rs
+++ /dev/null
@@ -1,355 +0,0 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-
-Dynamic vector
-
-A growable vector that makes use of unique pointers so that the
-result can be sent between tasks and so forth.
-
-Note that recursive use is not permitted.
-
-*/
-
-use cast;
-use prelude::*;
-use ptr::null;
-use vec;
-
-/**
- * A growable, modifiable vector type that accumulates elements into a
- * unique vector.
- *
- * # Limitations on recursive use
- *
- * This class works by swapping the unique vector out of the data
- * structure whenever it is to be used.  Therefore, recursive use is not
- * permitted.  That is, while iterating through a vector, you cannot
- * access the vector in any other way or else the program will fail.  If
- * you wish, you can use the `swap()` method to gain access to the raw
- * vector and transform it or use it any way you like.  Eventually, we
- * may permit read-only access during iteration or other use.
- *
- * # WARNING
- *
- * For maximum performance, this type is implemented using some rather
- * unsafe code.  In particular, this innocent looking `~[mut A]` pointer
- * *may be null!*  Therefore, it is important you not reach into the
- * data structure manually but instead use the provided extensions.
- *
- * The reason that I did not use an unsafe pointer in the structure
- * itself is that I wanted to ensure that the vector would be freed when
- * the dvec is dropped.  The reason that I did not use an `Option<T>`
- * instead of a nullable pointer is that I found experimentally that it
- * becomes approximately 50% slower. This can probably be improved
- * through optimization.  You can run your own experiments using
- * `src/test/bench/vec-append.rs`. My own tests found that using null
- * pointers achieved about 103 million pushes/second.  Using an option
- * type could only produce 47 million pushes/second.
- */
-pub struct DVec<A> {
-    mut data: ~[A]
-}
-
-/// Creates a new, empty dvec
-pub pure fn DVec<A>() -> DVec<A> {
-    DVec {data: ~[]}
-}
-
-/// Creates a new dvec with a single element
-pub pure fn from_elem<A>(e: A) -> DVec<A> {
-    DVec {data: ~[e]}
-}
-
-/// Creates a new dvec with the contents of a vector
-pub pure fn from_vec<A>(v: ~[A]) -> DVec<A> {
-    DVec {data: v}
-}
-
-/// Consumes the vector and returns its contents
-pub pure fn unwrap<A>(d: DVec<A>) -> ~[A] {
-    let DVec {data: v} = d;
-    v
-}
-
-priv impl<A> DVec<A> {
-    #[inline(always)]
-    pure fn check_not_borrowed(&self) {
-        unsafe {
-            let data: *() = cast::reinterpret_cast(&self.data);
-            if data.is_null() {
-                fail!(~"Recursive use of dvec");
-            }
-        }
-    }
-
-    #[inline(always)]
-    fn give_back(&self, data: ~[A]) {
-        unsafe {
-            self.data = data;
-        }
-    }
-
-    #[inline(always)]
-    fn unwrap(self) -> ~[A] { unwrap(self) }
-}
-
-// In theory, most everything should work with any A, but in practice
-// almost nothing works without the copy bound due to limitations
-// around closures.
-pub impl<A> DVec<A> {
-    // FIXME (#3758): This should not need to be public.
-    #[inline(always)]
-    fn check_out<B>(&self, f: &fn(v: ~[A]) -> B) -> B {
-        unsafe {
-            let mut data = cast::reinterpret_cast(&null::<()>());
-            data <-> self.data;
-            let data_ptr: *() = cast::reinterpret_cast(&data);
-            if data_ptr.is_null() { fail!(~"Recursive use of dvec"); }
-            return f(data);
-        }
-    }
-
-    /// Reserves space for N elements
-    fn reserve(&self, count: uint) {
-        vec::reserve(&mut self.data, count)
-    }
-
-    /**
-     * Swaps out the current vector and hands it off to a user-provided
-     * function `f`.  The function should transform it however is desired
-     * and return a new vector to replace it with.
-     */
-    #[inline(always)]
-    fn swap(&self, f: &fn(v: ~[A]) -> ~[A]) {
-        self.check_out(|v| self.give_back(f(v)))
-    }
-
-    /// Returns the number of elements currently in the dvec
-    #[inline(always)]
-    pure fn len(&self) -> uint {
-        self.check_not_borrowed();
-        return self.data.len();
-    }
-
-    /// Overwrite the current contents
-    #[inline(always)]
-    fn set(&self, w: ~[A]) {
-        self.check_not_borrowed();
-        self.data = w;
-    }
-
-    /// Remove and return the last element
-    fn pop(&self) -> A {
-        do self.check_out |v| {
-            let mut v = v;
-            let result = v.pop();
-            self.give_back(v);
-            result
-        }
-    }
-
-    /// Insert a single item at the front of the list
-    fn unshift(&self, t: A) {
-        unsafe {
-            let mut data = cast::reinterpret_cast(&null::<()>());
-            data <-> self.data;
-            let data_ptr: *() = cast::reinterpret_cast(&data);
-            if data_ptr.is_null() { fail!(~"Recursive use of dvec"); }
-            self.data = ~[t];
-            self.data.push_all_move(data);
-        }
-    }
-
-    /// Append a single item to the end of the list
-    #[inline(always)]
-    fn push(&self, t: A) {
-        self.check_not_borrowed();
-        self.data.push(t);
-    }
-
-    /// Remove and return the first element
-    fn shift(&self) -> A {
-        do self.check_out |v| {
-            let mut v = v;
-            let result = v.shift();
-            self.give_back(v);
-            result
-        }
-    }
-
-    /// Reverse the elements in the list, in place
-    fn reverse(&self) {
-        do self.check_out |v| {
-            let mut v = v;
-            vec::reverse(v);
-            self.give_back(v);
-        }
-    }
-
-    /// Gives access to the vector as a slice with immutable contents
-    fn borrow<R>(&self, op: fn(x: &[A]) -> R) -> R {
-        do self.check_out |v| {
-            let result = op(v);
-            self.give_back(v);
-            result
-        }
-    }
-
-    /// Gives access to the vector as a slice with mutable contents
-    fn borrow_mut<R>(&self, op: &fn(x: &mut [A]) -> R) -> R {
-        do self.check_out |v| {
-            let mut v = v;
-            let result = op(v);
-            self.give_back(v);
-            result
-        }
-    }
-}
-
-pub impl<A:Copy> DVec<A> {
-    /**
-     * Append all elements of a vector to the end of the list
-     *
-     * Equivalent to `append_iter()` but potentially more efficient.
-     */
-    fn push_all(&self, ts: &[const A]) {
-        self.push_slice(ts, 0u, vec::len(ts));
-    }
-
-    /// Appends elements from `from_idx` to `to_idx` (exclusive)
-    fn push_slice(&self, ts: &[const A], from_idx: uint, to_idx: uint) {
-        do self.swap |v| {
-            let mut v = v;
-            let new_len = vec::len(v) + to_idx - from_idx;
-            vec::reserve(&mut v, new_len);
-            let mut i = from_idx;
-            while i < to_idx {
-                v.push(ts[i]);
-                i += 1u;
-            }
-            v
-        }
-    }
-
-    /**
-     * Append all elements of an iterable.
-     *
-     * Failure will occur if the iterable's `each()` method
-     * attempts to access this vector.
-     */
-    /*
-    fn append_iter<A, I:iter::base_iter<A>>(ts: I) {
-        do self.swap |v| {
-           let mut v = match ts.size_hint() {
-             none { v }
-             Some(h) {
-               let len = v.len() + h;
-               let mut v = v;
-               vec::reserve(v, len);
-               v
-            }
-           };
-
-        for ts.each |t| { v.push(*t) };
-           v
-        }
-    }
-    */
-
-    /**
-     * Gets a copy of the current contents.
-     *
-     * See `unwrap()` if you do not wish to copy the contents.
-     */
-    pure fn get(&self) -> ~[A] {
-        unsafe {
-            do self.check_out |v| {
-                let w = copy v;
-                self.give_back(v);
-                w
-            }
-        }
-    }
-
-    /// Copy out an individual element
-    #[inline(always)]
-    pure fn get_elt(&self, idx: uint) -> A {
-        self.check_not_borrowed();
-        return self.data[idx];
-    }
-
-    /// Overwrites the contents of the element at `idx` with `a`
-    fn set_elt(&self, idx: uint, a: A) {
-        self.check_not_borrowed();
-        self.data[idx] = a;
-    }
-
-    /**
-     * Overwrites the contents of the element at `idx` with `a`,
-     * growing the vector if necessary.  New elements will be initialized
-     * with `initval`
-     */
-    fn grow_set_elt(&self, idx: uint, initval: &A, val: A) {
-        do self.swap |v| {
-            let mut v = v;
-            v.grow_set(idx, initval, val);
-            v
-        }
-    }
-
-    /// Returns the last element, failing if the vector is empty
-    #[inline(always)]
-    pure fn last(&self) -> A {
-        self.check_not_borrowed();
-
-        let length = self.len();
-        if length == 0 {
-            fail!(~"attempt to retrieve the last element of an empty vector");
-        }
-
-        return self.data[length - 1];
-    }
-
-    /// Iterates over the elements in reverse order
-    #[inline(always)]
-    fn rev_each(&self, f: fn(v: &A) -> bool) {
-        do self.swap |v| {
-            // FIXME(#2263)---we should be able to write
-            // `vec::rev_each(v, f);` but we cannot write now
-            for vec::rev_each(v) |e| {
-                if !f(e) { break; }
-            }
-            v
-        }
-    }
-
-    /// Iterates over the elements and indices in reverse order
-    #[inline(always)]
-    fn rev_eachi(&self, f: fn(uint, v: &A) -> bool) {
-        do self.swap |v| {
-            // FIXME(#2263)---we should be able to write
-            // `vec::rev_eachi(v, f);` but we cannot write now
-            for vec::rev_eachi(v) |i, e| {
-                if !f(i, e) { break; }
-            }
-            v
-        }
-    }
-}
-
-impl<A:Copy> Index<uint,A> for DVec<A> {
-    #[inline(always)]
-    pure fn index(&self, idx: uint) -> A {
-        self.get_elt(idx)
-    }
-}
-
diff --git a/src/libcore/io.rs b/src/libcore/io.rs
index cc40b90d61a..4634eb8793d 100644
--- a/src/libcore/io.rs
+++ b/src/libcore/io.rs
@@ -16,7 +16,6 @@ Basic input/output
 
 use result::Result;
 
-use dvec::DVec;
 use int;
 use libc;
 use libc::{c_int, c_long, c_uint, c_void, size_t, ssize_t};
@@ -1109,30 +1108,25 @@ pub fn print(s: &str) { stdout().write_str(s); }
 pub fn println(s: &str) { stdout().write_line(s); }
 
 pub struct BytesWriter {
-    bytes: DVec<u8>,
+    mut bytes: ~[u8],
     mut pos: uint,
 }
 
 impl Writer for BytesWriter {
     fn write(&self, v: &[const u8]) {
-        do self.bytes.swap |bytes| {
-            let mut bytes = bytes;
-            let v_len = v.len();
-            let bytes_len = bytes.len();
-
-            let count = uint::max(bytes_len, self.pos + v_len);
-            vec::reserve(&mut bytes, count);
-            unsafe { vec::raw::set_len(&mut bytes, count); }
-
-            {
-                let view = vec::mut_slice(bytes, self.pos, count);
-                vec::bytes::copy_memory(view, v, v_len);
-            }
+        let v_len = v.len();
+        let bytes_len = self.bytes.len();
 
-            self.pos += v_len;
+        let count = uint::max(bytes_len, self.pos + v_len);
+        vec::reserve(&mut self.bytes, count);
 
-            bytes
+        unsafe {
+            vec::raw::set_len(&mut self.bytes, count);
+            let view = vec::mut_slice(self.bytes, self.pos, count);
+            vec::bytes::copy_memory(view, v, v_len);
         }
+
+        self.pos += v_len;
     }
     fn seek(&self, offset: int, whence: SeekStyle) {
         let pos = self.pos;
@@ -1145,14 +1139,14 @@ impl Writer for BytesWriter {
 }
 
 pub pure fn BytesWriter() -> BytesWriter {
-    BytesWriter { bytes: DVec(), mut pos: 0u }
+    BytesWriter { bytes: ~[], mut pos: 0u }
 }
 
 pub pure fn with_bytes_writer(f: fn(Writer)) -> ~[u8] {
     let wr = @BytesWriter();
     f(wr as Writer);
-    // FIXME (#3758): This should not be needed.
-    unsafe { wr.bytes.check_out(|bytes| bytes) }
+    let @BytesWriter{bytes, _} = wr;
+    return bytes;
 }
 
 pub pure fn with_str_writer(f: fn(Writer)) -> ~str {
@@ -1448,17 +1442,15 @@ mod tests {
     fn bytes_buffer_overwrite() {
         let wr = BytesWriter();
         wr.write(~[0u8, 1u8, 2u8, 3u8]);
-        fail_unless!(wr.bytes.borrow(|bytes| bytes == ~[0u8, 1u8, 2u8, 3u8]));
+        fail_unless!(wr.bytes == ~[0u8, 1u8, 2u8, 3u8]);
         wr.seek(-2, SeekCur);
         wr.write(~[4u8, 5u8, 6u8, 7u8]);
-        fail_unless!(wr.bytes.borrow(|bytes| bytes ==
-            ~[0u8, 1u8, 4u8, 5u8, 6u8, 7u8]));
+        fail_unless!(wr.bytes == ~[0u8, 1u8, 4u8, 5u8, 6u8, 7u8]);
         wr.seek(-2, SeekEnd);
         wr.write(~[8u8]);
         wr.seek(1, SeekSet);
         wr.write(~[9u8]);
-        fail_unless!(wr.bytes.borrow(|bytes| bytes ==
-            ~[0u8, 9u8, 4u8, 5u8, 8u8, 7u8]));
+        fail_unless!(wr.bytes == ~[0u8, 9u8, 4u8, 5u8, 8u8, 7u8]);
     }
 
     #[test]
diff --git a/src/libcore/iter-trait/dvec.rs b/src/libcore/iter-trait/dvec.rs
deleted file mode 100644
index 986aa18ad4a..00000000000
--- a/src/libcore/iter-trait/dvec.rs
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-mod inst {
-    use dvec;
-    use option::{Option, Some};
-
-    #[allow(non_camel_case_types)]
-    pub type IMPL_T<A> = dvec::DVec<A>;
-
-    /**
-    * Iterates through the current contents.
-    *
-    * Attempts to access this dvec during iteration will fail.
-    */
-    #[inline(always)]
-    pub pure fn EACH<A>(self: &IMPL_T<A>, f: fn(v: &A) -> bool) {
-        unsafe {
-            do self.swap |v| {
-                v.each(f);
-                v
-            }
-        }
-    }
-
-    #[inline(always)]
-    pub pure fn SIZE_HINT<A>(self: &IMPL_T<A>) -> Option<uint> {
-        Some(self.len())
-    }
-}
diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs
index e4be0cf98dd..2f575ce7d28 100644
--- a/src/libcore/prelude.rs
+++ b/src/libcore/prelude.rs
@@ -50,7 +50,6 @@ pub use bool;
 pub use cast;
 pub use char;
 pub use cmp;
-pub use dvec;
 pub use either;
 pub use f32;
 pub use f64;
diff --git a/src/libcore/repr.rs b/src/libcore/repr.rs
index eaae9d03e8e..e9122754eb4 100644
--- a/src/libcore/repr.rs
+++ b/src/libcore/repr.rs
@@ -16,7 +16,6 @@ More runtime type reflection
 
 use cast::transmute;
 use char;
-use dvec::DVec;
 use intrinsic;
 use intrinsic::{TyDesc, TyVisitor, visit_tydesc};
 use io::{Writer, WriterUtil};
@@ -147,14 +146,14 @@ enum VariantState {
 
 pub struct ReprVisitor {
     mut ptr: *c_void,
-    ptr_stk: DVec<*c_void>,
-    var_stk: DVec<VariantState>,
+    mut ptr_stk: ~[*c_void],
+    mut var_stk: ~[VariantState],
     writer: @Writer
 }
 pub fn ReprVisitor(ptr: *c_void, writer: @Writer) -> ReprVisitor {
     ReprVisitor { ptr: ptr,
-                  ptr_stk: DVec(),
-                  var_stk: DVec(),
+                  ptr_stk: ~[],
+                  var_stk: ~[],
                   writer: writer }
 }
 
@@ -500,7 +499,7 @@ impl TyVisitor for ReprVisitor {
     }
 
     fn visit_enum_variant_field(&self, i: uint, inner: *TyDesc) -> bool {
-        match self.var_stk.last() {
+        match self.var_stk[self.var_stk.len() - 1] {
             Degenerate | TagMatch => {
                 if i != 0 {
                     self.writer.write_str(", ");
@@ -518,7 +517,7 @@ impl TyVisitor for ReprVisitor {
                                 _disr_val: int,
                                 n_fields: uint,
                                 _name: &str) -> bool {
-        match self.var_stk.last() {
+        match self.var_stk[self.var_stk.len() - 1] {
             Degenerate | TagMatch => {
                 if n_fields > 0 {
                     self.writer.write_char(')');
diff --git a/src/libcore/task/local_data_priv.rs b/src/libcore/task/local_data_priv.rs
index cb1283019eb..f035916f594 100644
--- a/src/libcore/task/local_data_priv.rs
+++ b/src/libcore/task/local_data_priv.rs
@@ -12,7 +12,6 @@
 
 use cast;
 use cmp::Eq;
-use dvec;
 use libc;
 use option;
 use prelude::*;
@@ -35,11 +34,11 @@ impl Eq for LocalData {
     pure fn ne(&self, other: &@LocalData) -> bool { !(*self).eq(other) }
 }
 
-// We use dvec because it's the best data structure in core. If TLS is used
-// heavily in future, this could be made more efficient with a proper map.
+// If TLS is used heavily in future, this could be made more efficient with a
+// proper map.
 type TaskLocalElement = (*libc::c_void, *libc::c_void, LocalData);
 // Has to be a pointer at outermost layer; the foreign call returns void *.
-type TaskLocalMap = @dvec::DVec<Option<TaskLocalElement>>;
+type TaskLocalMap = @mut ~[Option<TaskLocalElement>];
 
 extern fn cleanup_task_local_map(map_ptr: *libc::c_void) {
     unsafe {
@@ -60,17 +59,21 @@ unsafe fn get_task_local_map(task: *rust_task) -> TaskLocalMap {
     // drop when they finish. No "re-storing after modifying" is needed.
     let map_ptr = rt::rust_get_task_local_data(task);
     if map_ptr.is_null() {
-        let map: TaskLocalMap = @dvec::DVec();
+        let map: TaskLocalMap = @mut ~[];
         // Use reinterpret_cast -- transmute would take map away from us also.
         rt::rust_set_task_local_data(
             task, cast::reinterpret_cast(&map));
         rt::rust_task_local_data_atexit(task, cleanup_task_local_map);
         // Also need to reference it an extra time to keep it for now.
-        cast::bump_box_refcount(map);
+        let nonmut = cast::transmute::<TaskLocalMap,
+                                       @~[Option<TaskLocalElement>]>(map);
+        cast::bump_box_refcount(nonmut);
         map
     } else {
         let map = cast::transmute(map_ptr);
-        cast::bump_box_refcount(map);
+        let nonmut = cast::transmute::<TaskLocalMap,
+                                       @~[Option<TaskLocalElement>]>(map);
+        cast::bump_box_refcount(nonmut);
         map
     }
 }
@@ -118,7 +121,7 @@ unsafe fn local_get_helper<T:Durable>(
         let data: @T = cast::transmute(data_ptr);
         cast::bump_box_refcount(data);
         if do_pop {
-            (*map).set_elt(index, None);
+            map[index] = None;
         }
         data
     }
@@ -159,13 +162,13 @@ pub unsafe fn local_set<T:Durable>(
         Some((index, _old_data_ptr)) => {
             // Key already had a value set, _old_data_ptr, whose reference
             // will get dropped when the local_data box is overwritten.
-            (*map).set_elt(index, new_entry);
+            map[index] = new_entry;
         }
         None => {
             // Find an empty slot. If not, grow the vector.
             match (*map).position(|x| x.is_none()) {
-                Some(empty_index) => (*map).set_elt(empty_index, new_entry),
-                None => (*map).push(new_entry)
+                Some(empty_index) => { map[empty_index] = new_entry; }
+                None => { map.push(new_entry); }
             }
         }
     }