libstd: changes to in response to #5656

This commit is contained in:
Niko Matsakis 2013-04-10 13:14:06 -07:00
parent 61b9e0ebfa
commit 03396473b8
7 changed files with 390 additions and 14 deletions

View File

@ -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<T>(&self, op: &fn() -> T) -> &'self T {
#[cfg(stage0)]
priv fn alloc_pod<T>(&self, op: &fn() -> T) -> &'self T {
unsafe {
let tydesc = sys::get_type_desc::<T>();
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::<T>();
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<T>(&self, op: &fn() -> T) -> &'self T {
#[cfg(stage0)]
priv fn alloc_nonpod<T>(&self, op: &fn() -> T) -> &'self T {
unsafe {
let tydesc = sys::get_type_desc::<T>();
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::<T>();
let (ty_ptr, ptr) =
@ -269,6 +309,7 @@ pub impl Arena {
// The external interface
#[inline(always)]
#[cfg(stage0)]
fn alloc<T>(&self, op: &fn() -> T) -> &'self T {
unsafe {
if !rusti::needs_drop::<T>() {
@ -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::<T>() {
self.alloc_pod(op)
} else {
self.alloc_nonpod(op)
}
}
}
}
#[test]

View File

@ -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])
}
/**

View File

@ -41,6 +41,7 @@ impl<T> Mutable for Deque<T> {
}
}
#[cfg(stage0)]
pub impl<T> Deque<T> {
/// Create an empty Deque
fn new() -> Deque<T> {
@ -51,21 +52,142 @@ pub impl<T> Deque<T> {
/// 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<T> Deque<T> {
/// Create an empty Deque
fn new() -> Deque<T> {
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))

View File

@ -55,7 +55,7 @@ pub impl<A:Copy> Future<A> {
}
pub impl<A> Future<A> {
#[cfg(stage0)]
fn get_ref(&self) -> &'self A {
/*!
* Executes the future's closure and then returns a borrowed
@ -80,6 +80,34 @@ pub impl<A> Future<A> {
}
}
}
#[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<A>(val: A) -> Future<A> {

View File

@ -50,13 +50,29 @@ impl<T:Ord> Mutable for PriorityQueue<T> {
pub impl <T:Ord> PriorityQueue<T> {
/// 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) }

View File

@ -51,6 +51,7 @@ impl<V> Map<uint, V> for SmallIntMap<V> {
}
/// 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<V> Map<uint, V> for SmallIntMap<V> {
}
}
/// 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<V> Map<uint, V> for SmallIntMap<V> {
}
/// 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<V> Map<uint, V> for SmallIntMap<V> {
}
}
/// 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<V> Map<uint, V> for SmallIntMap<V> {
}
}
/// 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<V> SmallIntMap<V> {
fn new() -> SmallIntMap<V> { 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<V> SmallIntMap<V> {
}
}
/// 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<V:Copy> SmallIntMap<V> {

View File

@ -105,26 +105,45 @@ impl<K: TotalOrd, V> Map<K, V> for TreeMap<K, V> {
}
/// 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<K, V>> = &self.root;
loop {
@ -141,12 +160,42 @@ impl<K: TotalOrd, V> Map<K, V> for TreeMap<K, V> {
}
}
/// 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<K, V>> = &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<K: TotalOrd, V> TreeMap<K, V> {
fn new() -> TreeMap<K, V> { 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<K: TotalOrd, V> TreeMap<K, V> {
/// 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 <T: TotalOrd> TreeSet<T> {
/// 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