mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 16:54:01 +00:00
collections: remove List
It was decided in a meeting that this module wasn't needed, and more thought should be put into a persistent collections library.
This commit is contained in:
parent
b8601a3d8b
commit
a47d52c2f6
@ -27,8 +27,6 @@
|
||||
|
||||
extern crate collections;
|
||||
|
||||
use collections::list::{List, Cons, Nil};
|
||||
|
||||
use std::cast::{transmute, transmute_mut, transmute_mut_region};
|
||||
use std::cast;
|
||||
use std::cell::{Cell, RefCell};
|
||||
@ -87,7 +85,7 @@ pub struct Arena {
|
||||
// access the head.
|
||||
priv head: Chunk,
|
||||
priv copy_head: Chunk,
|
||||
priv chunks: RefCell<@List<Chunk>>,
|
||||
priv chunks: RefCell<Vec<Chunk>>,
|
||||
}
|
||||
|
||||
impl Arena {
|
||||
@ -99,7 +97,7 @@ impl Arena {
|
||||
Arena {
|
||||
head: chunk(initial_size, false),
|
||||
copy_head: chunk(initial_size, true),
|
||||
chunks: RefCell::new(@Nil),
|
||||
chunks: RefCell::new(Vec::new()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -117,7 +115,7 @@ impl Drop for Arena {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
destroy_chunk(&self.head);
|
||||
for chunk in self.chunks.get().iter() {
|
||||
for chunk in self.chunks.borrow().iter() {
|
||||
if !chunk.is_copy.get() {
|
||||
destroy_chunk(chunk);
|
||||
}
|
||||
@ -179,7 +177,7 @@ impl Arena {
|
||||
fn alloc_copy_grow(&mut self, n_bytes: uint, align: uint) -> *u8 {
|
||||
// Allocate a new chunk.
|
||||
let new_min_chunk_size = cmp::max(n_bytes, self.chunk_size());
|
||||
self.chunks.set(@Cons(self.copy_head.clone(), self.chunks.get()));
|
||||
self.chunks.borrow_mut().push(self.copy_head.clone());
|
||||
self.copy_head =
|
||||
chunk(num::next_power_of_two(new_min_chunk_size + 1u), true);
|
||||
|
||||
@ -219,7 +217,7 @@ impl Arena {
|
||||
-> (*u8, *u8) {
|
||||
// Allocate a new chunk.
|
||||
let new_min_chunk_size = cmp::max(n_bytes, self.chunk_size());
|
||||
self.chunks.set(@Cons(self.head.clone(), self.chunks.get()));
|
||||
self.chunks.borrow_mut().push(self.head.clone());
|
||||
self.head =
|
||||
chunk(num::next_power_of_two(new_min_chunk_size + 1u), false);
|
||||
|
||||
|
@ -33,7 +33,6 @@ pub use deque::Deque;
|
||||
pub use dlist::DList;
|
||||
pub use enum_set::EnumSet;
|
||||
pub use hashmap::{HashMap, HashSet};
|
||||
pub use list::List;
|
||||
pub use lru_cache::LruCache;
|
||||
pub use priority_queue::PriorityQueue;
|
||||
pub use ringbuf::RingBuf;
|
||||
@ -47,7 +46,6 @@ pub mod deque;
|
||||
pub mod dlist;
|
||||
pub mod enum_set;
|
||||
pub mod hashmap;
|
||||
pub mod list;
|
||||
pub mod lru_cache;
|
||||
pub mod priority_queue;
|
||||
pub mod ringbuf;
|
||||
|
@ -1,237 +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.
|
||||
|
||||
//! A standard, garbage-collected linked list.
|
||||
|
||||
use std::container::Container;
|
||||
|
||||
#[deriving(Clone, Eq)]
|
||||
#[allow(missing_doc)]
|
||||
pub enum List<T> {
|
||||
Cons(T, @List<T>),
|
||||
Nil,
|
||||
}
|
||||
|
||||
pub struct Items<'a, T> {
|
||||
priv head: &'a List<T>,
|
||||
priv next: Option<&'a @List<T>>
|
||||
}
|
||||
|
||||
impl<'a, T> Iterator<&'a T> for Items<'a, T> {
|
||||
fn next(&mut self) -> Option<&'a T> {
|
||||
match self.next {
|
||||
None => match *self.head {
|
||||
Nil => None,
|
||||
Cons(ref value, ref tail) => {
|
||||
self.next = Some(tail);
|
||||
Some(value)
|
||||
}
|
||||
},
|
||||
Some(next) => match **next {
|
||||
Nil => None,
|
||||
Cons(ref value, ref tail) => {
|
||||
self.next = Some(tail);
|
||||
Some(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> List<T> {
|
||||
/// Returns a forward iterator
|
||||
pub fn iter<'a>(&'a self) -> Items<'a, T> {
|
||||
Items {
|
||||
head: self,
|
||||
next: None
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the first element of a list
|
||||
pub fn head<'a>(&'a self) -> Option<&'a T> {
|
||||
match *self {
|
||||
Nil => None,
|
||||
Cons(ref head, _) => Some(head)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns all but the first element of a list
|
||||
pub fn tail(&self) -> Option<@List<T>> {
|
||||
match *self {
|
||||
Nil => None,
|
||||
Cons(_, tail) => Some(tail)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Container for List<T> {
|
||||
/// Returns the length of a list
|
||||
fn len(&self) -> uint { self.iter().len() }
|
||||
|
||||
/// Returns true if the list is empty
|
||||
fn is_empty(&self) -> bool { match *self { Nil => true, _ => false } }
|
||||
}
|
||||
|
||||
impl<T:Eq> List<T> {
|
||||
/// Returns true if a list contains an element with the given value
|
||||
pub fn contains(&self, element: T) -> bool {
|
||||
self.iter().any(|list_element| *list_element == element)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:'static + Clone> List<T> {
|
||||
/// Create a list from a vector
|
||||
pub fn from_vec(v: &[T]) -> List<T> {
|
||||
match v.len() {
|
||||
0 => Nil,
|
||||
_ => v.rev_iter().fold(Nil, |tail, value: &T| Cons(value.clone(), @tail))
|
||||
}
|
||||
}
|
||||
|
||||
/// Appends one list to another, returning a new list
|
||||
pub fn append(&self, other: List<T>) -> List<T> {
|
||||
match other {
|
||||
Nil => return self.clone(),
|
||||
_ => match *self {
|
||||
Nil => return other,
|
||||
Cons(ref value, tail) => Cons(value.clone(), @tail.append(other))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Push one element into the front of a list, returning a new list
|
||||
pub fn unshift(&self, element: T) -> List<T> {
|
||||
Cons(element, @(self.clone()))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use list::{List, Nil};
|
||||
use list;
|
||||
|
||||
#[test]
|
||||
fn test_iter() {
|
||||
let list = List::from_vec([0, 1, 2]);
|
||||
let mut iter = list.iter();
|
||||
assert_eq!(&0, iter.next().unwrap());
|
||||
assert_eq!(&1, iter.next().unwrap());
|
||||
assert_eq!(&2, iter.next().unwrap());
|
||||
assert_eq!(None, iter.next());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_empty() {
|
||||
let empty : list::List<int> = List::from_vec([]);
|
||||
let full1 = List::from_vec([1]);
|
||||
let full2 = List::from_vec(['r', 'u']);
|
||||
|
||||
assert!(empty.is_empty());
|
||||
assert!(!full1.is_empty());
|
||||
assert!(!full2.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_vec() {
|
||||
let list = List::from_vec([0, 1, 2]);
|
||||
assert_eq!(list.head().unwrap(), &0);
|
||||
|
||||
let mut tail = list.tail().unwrap();
|
||||
assert_eq!(tail.head().unwrap(), &1);
|
||||
|
||||
tail = tail.tail().unwrap();
|
||||
assert_eq!(tail.head().unwrap(), &2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_vec_empty() {
|
||||
let empty : list::List<int> = List::from_vec([]);
|
||||
assert!(empty == Nil::<int>);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fold() {
|
||||
fn add_(a: uint, b: &uint) -> uint { a + *b }
|
||||
fn subtract_(a: uint, b: &uint) -> uint { a - *b }
|
||||
|
||||
let empty = Nil::<uint>;
|
||||
assert_eq!(empty.iter().fold(0u, add_), 0u);
|
||||
assert_eq!(empty.iter().fold(10u, subtract_), 10u);
|
||||
|
||||
let list = List::from_vec([0u, 1u, 2u, 3u, 4u]);
|
||||
assert_eq!(list.iter().fold(0u, add_), 10u);
|
||||
assert_eq!(list.iter().fold(10u, subtract_), 0u);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_find_success() {
|
||||
fn match_(i: & &int) -> bool { **i == 2 }
|
||||
|
||||
let list = List::from_vec([0, 1, 2]);
|
||||
assert_eq!(list.iter().find(match_).unwrap(), &2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_find_fail() {
|
||||
fn match_(_i: & &int) -> bool { false }
|
||||
|
||||
let empty = Nil::<int>;
|
||||
assert_eq!(empty.iter().find(match_), None);
|
||||
|
||||
let list = List::from_vec([0, 1, 2]);
|
||||
assert_eq!(list.iter().find(match_), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_any() {
|
||||
fn match_(i: &int) -> bool { *i == 2 }
|
||||
|
||||
let empty = Nil::<int>;
|
||||
assert_eq!(empty.iter().any(match_), false);
|
||||
|
||||
let list = List::from_vec([0, 1, 2]);
|
||||
assert_eq!(list.iter().any(match_), true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_contains() {
|
||||
let empty = Nil::<int>;
|
||||
assert!((!empty.contains(5)));
|
||||
|
||||
let list = List::from_vec([5, 8, 6]);
|
||||
assert!((list.contains(5)));
|
||||
assert!((!list.contains(7)));
|
||||
assert!((list.contains(8)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_len() {
|
||||
let empty = Nil::<int>;
|
||||
assert_eq!(empty.len(), 0u);
|
||||
|
||||
let list = List::from_vec([0, 1, 2]);
|
||||
assert_eq!(list.len(), 3u);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_append() {
|
||||
assert!(List::from_vec([1, 2, 3, 4]) ==
|
||||
List::from_vec([1, 2]).append(List::from_vec([3, 4])));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unshift() {
|
||||
let list = List::from_vec([1]);
|
||||
let new_list = list.unshift(0);
|
||||
assert_eq!(list.len(), 1u);
|
||||
assert_eq!(new_list.len(), 2u);
|
||||
assert!(new_list == List::from_vec([0, 1]));
|
||||
}
|
||||
}
|
@ -72,7 +72,6 @@ use util::nodemap::{DefIdMap, FnvHashMap};
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use collections::List;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::print::pprust::*;
|
||||
use syntax::{ast, ast_map, abi};
|
||||
@ -327,7 +326,7 @@ pub fn require_same_types(tcx: &ty::ctxt,
|
||||
|
||||
// a list of mapping from in-scope-region-names ("isr") to the
|
||||
// corresponding ty::Region
|
||||
pub type isr_alist = @List<(ty::BoundRegion, ty::Region)>;
|
||||
pub type isr_alist = @Vec<(ty::BoundRegion, ty::Region)>;
|
||||
|
||||
trait get_region<'a, T:'static> {
|
||||
fn get(&'a self, br: ty::BoundRegion) -> ty::Region;
|
||||
|
@ -13,12 +13,16 @@
|
||||
extern crate collections;
|
||||
extern crate time;
|
||||
|
||||
use collections::list::{List, Cons, Nil};
|
||||
use time::precise_time_s;
|
||||
use std::os;
|
||||
use std::task;
|
||||
use std::vec;
|
||||
|
||||
#[deriving(Clone)]
|
||||
enum List<T> {
|
||||
Nil, Cons(T, @List<T>)
|
||||
}
|
||||
|
||||
enum UniqueList {
|
||||
ULNil, ULCons(~UniqueList)
|
||||
}
|
||||
|
@ -10,9 +10,6 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
extern crate collections;
|
||||
use collections::list::List;
|
||||
|
||||
#[deriving(Clone)]
|
||||
enum foo {
|
||||
a(uint),
|
||||
@ -24,9 +21,21 @@ fn check_log<T>(exp: ~str, v: T) {
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let x = List::from_vec([a(22u), b(~"hi")]);
|
||||
let exp = ~"Cons(a(22u), @Cons(b(~\"hi\"), @Nil))";
|
||||
let mut x = Some(a(22u));
|
||||
let exp = ~"Some(a(22u))";
|
||||
let act = format!("{:?}", x);
|
||||
assert!(act == exp);
|
||||
assert_eq!(act, exp);
|
||||
check_log(exp, x);
|
||||
|
||||
x = Some(b(~"hi"));
|
||||
let exp = ~"Some(b(~\"hi\"))";
|
||||
let act = format!("{:?}", x);
|
||||
assert_eq!(act, exp);
|
||||
check_log(exp, x);
|
||||
|
||||
x = None;
|
||||
let exp = ~"None";
|
||||
let act = format!("{:?}", x);
|
||||
assert_eq!(act, exp);
|
||||
check_log(exp, x);
|
||||
}
|
||||
|
@ -16,21 +16,21 @@ extern crate collections;
|
||||
|
||||
use collections::list::{List, Cons, Nil};
|
||||
|
||||
fn pure_length_go<T>(ls: @List<T>, acc: uint) -> uint {
|
||||
match *ls { Nil => { acc } Cons(_, tl) => { pure_length_go(tl, acc + 1u) } }
|
||||
fn pure_length_go<T>(ls: &List<T>, acc: uint) -> uint {
|
||||
match *ls { Nil => { acc } Cons(_, ref tl) => { pure_length_go(&**tl, acc + 1u) } }
|
||||
}
|
||||
|
||||
fn pure_length<T>(ls: @List<T>) -> uint { pure_length_go(ls, 0u) }
|
||||
fn pure_length<T>(ls: &List<T>) -> uint { pure_length_go(ls, 0u) }
|
||||
|
||||
fn nonempty_list<T>(ls: @List<T>) -> bool { pure_length(ls) > 0u }
|
||||
fn nonempty_list<T>(ls: &List<T>) -> bool { pure_length(ls) > 0u }
|
||||
|
||||
fn safe_head<T:Clone>(ls: @List<T>) -> T {
|
||||
fn safe_head<T:Clone>(ls: &List<T>) -> T {
|
||||
assert!(!ls.is_empty());
|
||||
return ls.head().unwrap().clone();
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let mylist = @Cons(@1u, @Nil);
|
||||
assert!((nonempty_list(mylist)));
|
||||
assert_eq!(*safe_head(mylist), 1u);
|
||||
let mylist = Cons(1u, ~Nil);
|
||||
assert!((nonempty_list(&mylist)));
|
||||
assert_eq!(safe_head(&mylist), 1u);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user