diff --git a/src/libstd/arena.rs b/src/libstd/arena.rs index 81c28f94d9f..3d2c3ac70b6 100644 --- a/src/libstd/arena.rs +++ b/src/libstd/arena.rs @@ -171,7 +171,7 @@ unsafe fn un_bitpack_tydesc_ptr(p: uint) -> (*TypeDesc, bool) { pub impl Arena { // Functions for the POD part of the arena - fn alloc_pod_grow(&self, n_bytes: uint, align: uint) -> *u8 { + priv fn alloc_pod_grow(&self, n_bytes: uint, align: uint) -> *u8 { // Allocate a new chunk. let chunk_size = at_vec::capacity(self.pod_head.data); let new_min_chunk_size = uint::max(n_bytes, chunk_size); @@ -183,7 +183,7 @@ pub impl Arena { } #[inline(always)] - fn alloc_pod_inner(&self, n_bytes: uint, align: uint) -> *u8 { + priv fn alloc_pod_inner(&self, n_bytes: uint, align: uint) -> *u8 { let head = &mut self.pod_head; let start = round_up_to(head.fill, align); @@ -202,7 +202,22 @@ pub impl Arena { } #[inline(always)] - fn alloc_pod(&self, op: &fn() -> T) -> &'self T { + #[cfg(stage0)] + priv fn alloc_pod(&self, op: &fn() -> T) -> &'self T { + unsafe { + let tydesc = sys::get_type_desc::(); + let ptr = self.alloc_pod_inner((*tydesc).size, (*tydesc).align); + let ptr: *mut T = reinterpret_cast(&ptr); + rusti::move_val_init(&mut (*ptr), op()); + return reinterpret_cast(&ptr); + } + } + + #[inline(always)] + #[cfg(stage1)] + #[cfg(stage2)] + #[cfg(stage3)] + priv fn alloc_pod<'a, T>(&'a self, op: &fn() -> T) -> &'a T { unsafe { let tydesc = sys::get_type_desc::(); let ptr = self.alloc_pod_inner((*tydesc).size, (*tydesc).align); @@ -213,7 +228,7 @@ pub impl Arena { } // Functions for the non-POD part of the arena - fn alloc_nonpod_grow(&self, n_bytes: uint, align: uint) -> (*u8, *u8) { + priv fn alloc_nonpod_grow(&self, n_bytes: uint, align: uint) -> (*u8, *u8) { // Allocate a new chunk. let chunk_size = at_vec::capacity(self.head.data); let new_min_chunk_size = uint::max(n_bytes, chunk_size); @@ -225,7 +240,7 @@ pub impl Arena { } #[inline(always)] - fn alloc_nonpod_inner(&self, n_bytes: uint, align: uint) -> (*u8, *u8) { + priv fn alloc_nonpod_inner(&self, n_bytes: uint, align: uint) -> (*u8, *u8) { let head = &mut self.head; let tydesc_start = head.fill; @@ -247,7 +262,32 @@ pub impl Arena { } #[inline(always)] - fn alloc_nonpod(&self, op: &fn() -> T) -> &'self T { + #[cfg(stage0)] + priv fn alloc_nonpod(&self, op: &fn() -> T) -> &'self T { + unsafe { + let tydesc = sys::get_type_desc::(); + let (ty_ptr, ptr) = + self.alloc_nonpod_inner((*tydesc).size, (*tydesc).align); + let ty_ptr: *mut uint = reinterpret_cast(&ty_ptr); + let ptr: *mut T = reinterpret_cast(&ptr); + // Write in our tydesc along with a bit indicating that it + // has *not* been initialized yet. + *ty_ptr = reinterpret_cast(&tydesc); + // Actually initialize it + rusti::move_val_init(&mut(*ptr), op()); + // Now that we are done, update the tydesc to indicate that + // the object is there. + *ty_ptr = bitpack_tydesc_ptr(tydesc, true); + + return reinterpret_cast(&ptr); + } + } + + #[inline(always)] + #[cfg(stage1)] + #[cfg(stage2)] + #[cfg(stage3)] + priv fn alloc_nonpod<'a, T>(&'a self, op: &fn() -> T) -> &'a T { unsafe { let tydesc = sys::get_type_desc::(); let (ty_ptr, ptr) = @@ -269,6 +309,7 @@ pub impl Arena { // The external interface #[inline(always)] + #[cfg(stage0)] fn alloc(&self, op: &fn() -> T) -> &'self T { unsafe { if !rusti::needs_drop::() { @@ -278,6 +319,21 @@ pub impl Arena { } } } + + // The external interface + #[inline(always)] + #[cfg(stage1)] + #[cfg(stage2)] + #[cfg(stage3)] + fn alloc<'a, T>(&'a self, op: &fn() -> T) -> &'a T { + unsafe { + if !rusti::needs_drop::() { + self.alloc_pod(op) + } else { + self.alloc_nonpod(op) + } + } + } } #[test] diff --git a/src/libstd/bitv.rs b/src/libstd/bitv.rs index f69e2130e71..632a38e8ca2 100644 --- a/src/libstd/bitv.rs +++ b/src/libstd/bitv.rs @@ -437,8 +437,7 @@ pub impl Bitv { if offset >= bitv.nbits { 0 } else { - // NOTE cannot use bitv[offset] until snapshot - bitv.index(&offset) as u8 << (7 - bit) + bitv[offset] as u8 << (7 - bit) } } @@ -460,8 +459,7 @@ pub impl Bitv { * Transform self into a [bool] by turning each bit into a bool */ fn to_bools(&self) -> ~[bool] { - // NOTE cannot use self[i] until snapshot - vec::from_fn(self.nbits, |i| self.index(&i)) + vec::from_fn(self.nbits, |i| self[i]) } /** diff --git a/src/libstd/deque.rs b/src/libstd/deque.rs index e7ec86963ee..a88d13fda66 100644 --- a/src/libstd/deque.rs +++ b/src/libstd/deque.rs @@ -41,6 +41,7 @@ impl Mutable for Deque { } } +#[cfg(stage0)] pub impl Deque { /// Create an empty Deque fn new() -> Deque { @@ -51,21 +52,142 @@ pub impl Deque { /// Return a reference to the first element in the deque /// /// Fails if the deque is empty + #[cfg(stage0)] fn peek_front(&self) -> &'self T { get(self.elts, self.lo) } + /// Return a reference to the first element in the deque + /// + /// Fails if the deque is empty + #[cfg(stage1)] + #[cfg(stage2)] + #[cfg(stage3)] + fn peek_front<'a>(&'a self) -> &'a T { get(self.elts, self.lo) } + /// Return a reference to the last element in the deque /// /// Fails if the deque is empty + #[cfg(stage0)] fn peek_back(&self) -> &'self T { get(self.elts, self.hi - 1u) } + /// Return a reference to the last element in the deque + /// + /// Fails if the deque is empty + #[cfg(stage1)] + #[cfg(stage2)] + #[cfg(stage3)] + fn peek_back<'a>(&'a self) -> &'a T { get(self.elts, self.hi - 1u) } + /// Retrieve an element in the deque by index /// /// Fails if there is no element with the given index + #[cfg(stage0)] fn get(&self, i: int) -> &'self T { let idx = (self.lo + (i as uint)) % self.elts.len(); get(self.elts, idx) } + /// Retrieve an element in the deque by index + /// + /// Fails if there is no element with the given index + #[cfg(stage1)] + #[cfg(stage2)] + #[cfg(stage3)] + fn get<'a>(&'a self, i: int) -> &'a T { + let idx = (self.lo + (i as uint)) % self.elts.len(); + get(self.elts, idx) + } + + /// Iterate over the elements in the deque + fn each(&self, f: &fn(&T) -> bool) { + self.eachi(|_i, e| f(e)) + } + + /// Iterate over the elements in the deque by index + fn eachi(&self, f: &fn(uint, &T) -> bool) { + for uint::range(0, self.nelts) |i| { + if !f(i, self.get(i as int)) { return; } + } + } + + /// Remove and return the first element in the deque + /// + /// Fails if the deque is empty + fn pop_front(&mut self) -> T { + let mut result = self.elts[self.lo].swap_unwrap(); + self.lo = (self.lo + 1u) % self.elts.len(); + self.nelts -= 1u; + result + } + + /// Remove and return the last element in the deque + /// + /// Fails if the deque is empty + fn pop_back(&mut self) -> T { + if self.hi == 0u { + self.hi = self.elts.len() - 1u; + } else { self.hi -= 1u; } + let mut result = self.elts[self.hi].swap_unwrap(); + self.elts[self.hi] = None; + self.nelts -= 1u; + result + } + + /// Prepend an element to the deque + fn add_front(&mut self, t: T) { + let oldlo = self.lo; + if self.lo == 0u { + self.lo = self.elts.len() - 1u; + } else { self.lo -= 1u; } + if self.lo == self.hi { + self.elts = grow(self.nelts, oldlo, self.elts); + self.lo = self.elts.len() - 1u; + self.hi = self.nelts; + } + self.elts[self.lo] = Some(t); + self.nelts += 1u; + } + + /// Append an element to the deque + fn add_back(&mut self, t: T) { + if self.lo == self.hi && self.nelts != 0u { + self.elts = grow(self.nelts, self.lo, self.elts); + self.lo = 0u; + self.hi = self.nelts; + } + self.elts[self.hi] = Some(t); + self.hi = (self.hi + 1u) % self.elts.len(); + self.nelts += 1u; + } +} + +#[cfg(stage1)] +#[cfg(stage2)] +#[cfg(stage3)] +pub impl Deque { + /// Create an empty Deque + fn new() -> Deque { + Deque{nelts: 0, lo: 0, hi: 0, + elts: vec::from_fn(initial_capacity, |_| None)} + } + + /// Return a reference to the first element in the deque + /// + /// Fails if the deque is empty + fn peek_front<'a>(&'a self) -> &'a T { get(self.elts, self.lo) } + + /// Return a reference to the last element in the deque + /// + /// Fails if the deque is empty + fn peek_back<'a>(&'a self) -> &'a T { get(self.elts, self.hi - 1u) } + + /// Retrieve an element in the deque by index + /// + /// Fails if there is no element with the given index + fn get<'a>(&'a self, i: int) -> &'a T { + let idx = (self.lo + (i as uint)) % self.elts.len(); + get(self.elts, idx) + } + /// Iterate over the elements in the deque fn each(&self, f: &fn(&T) -> bool) { self.eachi(|_i, e| f(e)) diff --git a/src/libstd/future.rs b/src/libstd/future.rs index a4887306d2a..feea8fb4fcd 100644 --- a/src/libstd/future.rs +++ b/src/libstd/future.rs @@ -55,7 +55,7 @@ pub impl Future { } pub impl Future { - + #[cfg(stage0)] fn get_ref(&self) -> &'self A { /*! * Executes the future's closure and then returns a borrowed @@ -80,6 +80,34 @@ pub impl Future { } } } + + #[cfg(stage1)] + #[cfg(stage2)] + #[cfg(stage3)] + fn get_ref<'a>(&'a self) -> &'a A { + /*! + * Executes the future's closure and then returns a borrowed + * pointer to the result. The borrowed pointer lasts as long as + * the future. + */ + unsafe { + match self.state { + Forced(ref mut v) => { return cast::transmute(v); } + Evaluating => fail!(~"Recursive forcing of future!"), + Pending(_) => {} + } + + let mut state = Evaluating; + self.state <-> state; + match state { + Forced(_) | Evaluating => fail!(~"Logic error."), + Pending(f) => { + self.state = Forced(f()); + self.get_ref() + } + } + } + } } pub fn from_value(val: A) -> Future { diff --git a/src/libstd/priority_queue.rs b/src/libstd/priority_queue.rs index dd56e413595..c8d250f90f6 100644 --- a/src/libstd/priority_queue.rs +++ b/src/libstd/priority_queue.rs @@ -50,13 +50,29 @@ impl Mutable for PriorityQueue { pub impl PriorityQueue { /// Returns the greatest item in the queue - fails if empty + #[cfg(stage0)] fn top(&self) -> &'self T { &self.data[0] } + /// Returns the greatest item in the queue - fails if empty + #[cfg(stage1)] + #[cfg(stage2)] + #[cfg(stage3)] + fn top<'a>(&'a self) -> &'a T { &self.data[0] } + /// Returns the greatest item in the queue - None if empty + #[cfg(stage0)] fn maybe_top(&self) -> Option<&'self T> { if self.is_empty() { None } else { Some(self.top()) } } + /// Returns the greatest item in the queue - None if empty + #[cfg(stage1)] + #[cfg(stage2)] + #[cfg(stage3)] + fn maybe_top<'a>(&'a self) -> Option<&'a T> { + if self.is_empty() { None } else { Some(self.top()) } + } + /// Returns the number of elements the queue can hold without reallocating fn capacity(&self) -> uint { vec::capacity(&self.data) } diff --git a/src/libstd/smallintmap.rs b/src/libstd/smallintmap.rs index 811cd710a62..d50804ba47b 100644 --- a/src/libstd/smallintmap.rs +++ b/src/libstd/smallintmap.rs @@ -51,6 +51,7 @@ impl Map for SmallIntMap { } /// Visit all key-value pairs in order + #[cfg(stage0)] fn each(&self, it: &fn(&uint, &'self V) -> bool) { for uint::range(0, self.v.len()) |i| { match self.v[i] { @@ -60,18 +61,40 @@ impl Map for SmallIntMap { } } + /// Visit all key-value pairs in order + #[cfg(stage1)] + #[cfg(stage2)] + #[cfg(stage3)] + fn each<'a>(&'a self, it: &fn(&uint, &'a V) -> bool) { + for uint::range(0, self.v.len()) |i| { + match self.v[i] { + Some(ref elt) => if !it(&i, elt) { break }, + None => () + } + } + } + /// Visit all keys in order fn each_key(&self, blk: &fn(key: &uint) -> bool) { self.each(|k, _| blk(k)) } /// Visit all values in order + #[cfg(stage0)] fn each_value(&self, blk: &fn(value: &V) -> bool) { self.each(|_, v| blk(v)) } + /// Visit all values in order + #[cfg(stage1)] + #[cfg(stage2)] + #[cfg(stage3)] + fn each_value<'a>(&'a self, blk: &fn(value: &'a V) -> bool) { + self.each(|_, v| blk(v)) + } + /// Iterate over the map and mutate the contained values - fn mutate_values(&mut self, it: &fn(&uint, &'self mut V) -> bool) { + fn mutate_values(&mut self, it: &fn(&uint, &mut V) -> bool) { for uint::range(0, self.v.len()) |i| { match self.v[i] { Some(ref mut elt) => if !it(&i, elt) { break }, @@ -81,6 +104,7 @@ impl Map for SmallIntMap { } /// Return a reference to the value corresponding to the key + #[cfg(stage0)] fn find(&self, key: &uint) -> Option<&'self V> { if *key < self.v.len() { match self.v[*key] { @@ -92,7 +116,23 @@ impl Map for SmallIntMap { } } + /// Return a reference to the value corresponding to the key + #[cfg(stage1)] + #[cfg(stage2)] + #[cfg(stage3)] + fn find<'a>(&'a self, key: &uint) -> Option<&'a V> { + if *key < self.v.len() { + match self.v[*key] { + Some(ref value) => Some(value), + None => None + } + } else { + None + } + } + /// Return a mutable reference to the value corresponding to the key + #[cfg(stage0)] fn find_mut(&mut self, key: &uint) -> Option<&'self mut V> { if *key < self.v.len() { match self.v[*key] { @@ -104,6 +144,21 @@ impl Map for SmallIntMap { } } + /// Return a mutable reference to the value corresponding to the key + #[cfg(stage1)] + #[cfg(stage2)] + #[cfg(stage3)] + fn find_mut<'a>(&'a mut self, key: &uint) -> Option<&'a mut V> { + if *key < self.v.len() { + match self.v[*key] { + Some(ref mut value) => Some(value), + None => None + } + } else { + None + } + } + /// Insert a key-value pair into the map. An existing value for a /// key is replaced by the new value. Return true if the key did /// not already exist in the map. @@ -134,6 +189,7 @@ pub impl SmallIntMap { fn new() -> SmallIntMap { SmallIntMap{v: ~[]} } /// Visit all key-value pairs in reverse order + #[cfg(stage0)] fn each_reverse(&self, it: &fn(uint, &'self V) -> bool) { for uint::range_rev(self.v.len(), 0) |i| { match self.v[i - 1] { @@ -143,9 +199,30 @@ pub impl SmallIntMap { } } + /// Visit all key-value pairs in reverse order + #[cfg(stage1)] + #[cfg(stage2)] + #[cfg(stage3)] + fn each_reverse<'a>(&'a self, it: &fn(uint, &'a V) -> bool) { + for uint::range_rev(self.v.len(), 0) |i| { + match self.v[i - 1] { + Some(ref elt) => if !it(i - 1, elt) { break }, + None => () + } + } + } + + #[cfg(stage0)] fn get(&self, key: &uint) -> &'self V { self.find(key).expect("key not present") } + + #[cfg(stage1)] + #[cfg(stage2)] + #[cfg(stage3)] + fn get<'a>(&'a self, key: &uint) -> &'a V { + self.find(key).expect("key not present") + } } pub impl SmallIntMap { diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs index 041ea855cb3..006455c44e4 100644 --- a/src/libstd/treemap.rs +++ b/src/libstd/treemap.rs @@ -105,26 +105,45 @@ impl Map for TreeMap { } /// Visit all key-value pairs in order + #[cfg(stage0)] fn each(&self, f: &fn(&'self K, &'self V) -> bool) { each(&self.root, f) } + /// Visit all key-value pairs in order + #[cfg(stage1)] + #[cfg(stage2)] + #[cfg(stage3)] + fn each<'a>(&'a self, f: &fn(&'a K, &'a V) -> bool) { + each(&self.root, f) + } + /// Visit all keys in order fn each_key(&self, f: &fn(&K) -> bool) { self.each(|k, _| f(k)) } /// Visit all values in order + #[cfg(stage0)] fn each_value(&self, f: &fn(&V) -> bool) { self.each(|_, v| f(v)) } + /// Visit all values in order + #[cfg(stage1)] + #[cfg(stage2)] + #[cfg(stage3)] + fn each_value<'a>(&'a self, f: &fn(&'a V) -> bool) { + self.each(|_, v| f(v)) + } + /// Iterate over the map and mutate the contained values - fn mutate_values(&mut self, f: &fn(&'self K, &'self mut V) -> bool) { + fn mutate_values(&mut self, f: &fn(&K, &mut V) -> bool) { mutate_values(&mut self.root, f); } /// Return a reference to the value corresponding to the key + #[cfg(stage0)] fn find(&self, key: &K) -> Option<&'self V> { let mut current: &'self Option<~TreeNode> = &self.root; loop { @@ -141,12 +160,42 @@ impl Map for TreeMap { } } + /// Return a reference to the value corresponding to the key + #[cfg(stage1)] + #[cfg(stage2)] + #[cfg(stage3)] + fn find<'a>(&'a self, key: &K) -> Option<&'a V> { + let mut current: &'a Option<~TreeNode> = &self.root; + loop { + match *current { + Some(ref r) => { + match key.cmp(&r.key) { + Less => current = &r.left, + Greater => current = &r.right, + Equal => return Some(&r.value) + } + } + None => return None + } + } + } + /// Return a mutable reference to the value corresponding to the key #[inline(always)] + #[cfg(stage0)] fn find_mut(&mut self, key: &K) -> Option<&'self mut V> { find_mut(&mut self.root, key) } + /// Return a mutable reference to the value corresponding to the key + #[inline(always)] + #[cfg(stage1)] + #[cfg(stage2)] + #[cfg(stage3)] + fn find_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V> { + find_mut(&mut self.root, key) + } + /// Insert a key-value pair into the map. An existing value for a /// key is replaced by the new value. Return true if the key did /// not already exist in the map. @@ -170,7 +219,16 @@ pub impl TreeMap { fn new() -> TreeMap { TreeMap{root: None, length: 0} } /// Visit all key-value pairs in reverse order - fn each_reverse(&'self self, f: &fn(&'self K, &'self V) -> bool) { + #[cfg(stage0)] + fn each_reverse(&self, f: &fn(&'self K, &'self V) -> bool) { + each_reverse(&self.root, f); + } + + /// Visit all key-value pairs in reverse order + #[cfg(stage1)] + #[cfg(stage2)] + #[cfg(stage3)] + fn each_reverse<'a>(&'a self, f: &fn(&'a K, &'a V) -> bool) { each_reverse(&self.root, f); } @@ -186,9 +244,19 @@ pub impl TreeMap { /// Get a lazy iterator over the key-value pairs in the map. /// Requires that it be frozen (immutable). + #[cfg(stage0)] fn iter(&self) -> TreeMapIterator<'self, K, V> { TreeMapIterator{stack: ~[], node: &self.root} } + + /// Get a lazy iterator over the key-value pairs in the map. + /// Requires that it be frozen (immutable). + #[cfg(stage1)] + #[cfg(stage2)] + #[cfg(stage3)] + fn iter<'a>(&'a self) -> TreeMapIterator<'a, K, V> { + TreeMapIterator{stack: ~[], node: &self.root} + } } /// Lazy forward iterator over a map @@ -490,9 +558,20 @@ pub impl TreeSet { /// Get a lazy iterator over the values in the set. /// Requires that it be frozen (immutable). #[inline(always)] + #[cfg(stage0)] fn iter(&self) -> TreeSetIterator<'self, T> { TreeSetIterator{iter: self.map.iter()} } + + /// Get a lazy iterator over the values in the set. + /// Requires that it be frozen (immutable). + #[inline(always)] + #[cfg(stage1)] + #[cfg(stage2)] + #[cfg(stage3)] + fn iter<'a>(&'a self) -> TreeSetIterator<'a, T> { + TreeSetIterator{iter: self.map.iter()} + } } /// Lazy forward iterator over a set