Merge remote-tracking branch 'mozilla/master'

Conflicts:
	src/libextra/test.rs
	src/libstd/at_vec.rs
	src/libstd/cleanup.rs
	src/libstd/rt/comm.rs
	src/libstd/rt/global_heap.rs
	src/libstd/task/spawn.rs
	src/libstd/unstable/lang.rs
	src/libstd/vec.rs
	src/rt/rustrt.def.in
	src/test/run-pass/extern-pub.rs
This commit is contained in:
Brian Anderson 2013-07-02 17:36:58 -07:00
commit 1098d6980b
765 changed files with 23500 additions and 17316 deletions

View file

@ -19,7 +19,7 @@
*
* ~~~ {.rust}
* extern mod std;
* use std::arc;
* use extra::arc;
* let numbers=vec::from_fn(100, |ind| (ind as float)*rand::random());
* let shared_numbers=arc::ARC(numbers);
*
@ -39,15 +39,14 @@
#[allow(missing_doc)];
use core::prelude::*;
use sync;
use sync::{Mutex, mutex_with_condvars, RWlock, rwlock_with_condvars};
use core::cast;
use core::unstable::sync::UnsafeAtomicRcBox;
use core::task;
use core::borrow;
use std::cast;
use std::unstable::sync::UnsafeAtomicRcBox;
use std::task;
use std::borrow;
/// As sync::condvar, a mechanism for unlock-and-descheduling and signaling.
pub struct Condvar<'self> {
@ -112,7 +111,7 @@ impl<'self> Condvar<'self> {
pub struct ARC<T> { x: UnsafeAtomicRcBox<T> }
/// Create an atomically reference counted wrapper.
pub fn ARC<T:Const + Owned>(data: T) -> ARC<T> {
pub fn ARC<T:Freeze + Send>(data: T) -> ARC<T> {
ARC { x: UnsafeAtomicRcBox::new(data) }
}
@ -120,7 +119,7 @@ pub fn ARC<T:Const + Owned>(data: T) -> ARC<T> {
* Access the underlying data in an atomically reference counted
* wrapper.
*/
impl<T:Const+Owned> ARC<T> {
impl<T:Freeze+Send> ARC<T> {
pub fn get<'a>(&'a self) -> &'a T {
unsafe { &*self.x.get_immut() }
}
@ -133,7 +132,7 @@ impl<T:Const+Owned> ARC<T> {
* object. However, one of the `arc` objects can be sent to another task,
* allowing them to share the underlying data.
*/
impl<T:Const + Owned> Clone for ARC<T> {
impl<T:Freeze + Send> Clone for ARC<T> {
fn clone(&self) -> ARC<T> {
ARC { x: self.x.clone() }
}
@ -149,14 +148,14 @@ struct MutexARCInner<T> { lock: Mutex, failed: bool, data: T }
struct MutexARC<T> { x: UnsafeAtomicRcBox<MutexARCInner<T>> }
/// Create a mutex-protected ARC with the supplied data.
pub fn MutexARC<T:Owned>(user_data: T) -> MutexARC<T> {
pub fn MutexARC<T:Send>(user_data: T) -> MutexARC<T> {
mutex_arc_with_condvars(user_data, 1)
}
/**
* Create a mutex-protected ARC with the supplied data and a specified number
* of condvars (as sync::mutex_with_condvars).
*/
pub fn mutex_arc_with_condvars<T:Owned>(user_data: T,
pub fn mutex_arc_with_condvars<T:Send>(user_data: T,
num_condvars: uint) -> MutexARC<T> {
let data =
MutexARCInner { lock: mutex_with_condvars(num_condvars),
@ -164,7 +163,7 @@ pub fn mutex_arc_with_condvars<T:Owned>(user_data: T,
MutexARC { x: UnsafeAtomicRcBox::new(data) }
}
impl<T:Owned> Clone for MutexARC<T> {
impl<T:Send> Clone for MutexARC<T> {
/// Duplicate a mutex-protected ARC, as arc::clone.
fn clone(&self) -> MutexARC<T> {
// NB: Cloning the underlying mutex is not necessary. Its reference
@ -173,7 +172,7 @@ impl<T:Owned> Clone for MutexARC<T> {
}
}
impl<T:Owned> MutexARC<T> {
impl<T:Send> MutexARC<T> {
/**
* Access the underlying mutable data with mutual exclusion from other
@ -247,7 +246,7 @@ struct PoisonOnFail {
}
impl Drop for PoisonOnFail {
fn finalize(&self) {
fn drop(&self) {
unsafe {
/* assert!(!*self.failed);
-- might be false in case of cond.wait() */
@ -276,20 +275,21 @@ struct RWARCInner<T> { lock: RWlock, failed: bool, data: T }
*
* Unlike mutex_arcs, rw_arcs are safe, because they cannot be nested.
*/
#[mutable]
#[mutable] // XXX remove after snap
#[no_freeze]
struct RWARC<T> {
x: UnsafeAtomicRcBox<RWARCInner<T>>,
}
/// Create a reader/writer ARC with the supplied data.
pub fn RWARC<T:Const + Owned>(user_data: T) -> RWARC<T> {
pub fn RWARC<T:Freeze + Send>(user_data: T) -> RWARC<T> {
rw_arc_with_condvars(user_data, 1)
}
/**
* Create a reader/writer ARC with the supplied data and a specified number
* of condvars (as sync::rwlock_with_condvars).
*/
pub fn rw_arc_with_condvars<T:Const + Owned>(
pub fn rw_arc_with_condvars<T:Freeze + Send>(
user_data: T,
num_condvars: uint) -> RWARC<T>
{
@ -299,7 +299,7 @@ pub fn rw_arc_with_condvars<T:Const + Owned>(
RWARC { x: UnsafeAtomicRcBox::new(data), }
}
impl<T:Const + Owned> RWARC<T> {
impl<T:Freeze + Send> RWARC<T> {
/// Duplicate a rwlock-protected ARC, as arc::clone.
pub fn clone(&self) -> RWARC<T> {
RWARC {
@ -309,7 +309,7 @@ impl<T:Const + Owned> RWARC<T> {
}
impl<T:Const + Owned> RWARC<T> {
impl<T:Freeze + Send> RWARC<T> {
/**
* Access the underlying data mutably. Locks the rwlock in write mode;
* other readers and writers will block.
@ -435,8 +435,8 @@ impl<T:Const + Owned> RWARC<T> {
// lock it. This wraps the unsafety, with the justification that the 'lock'
// field is never overwritten; only 'failed' and 'data'.
#[doc(hidden)]
fn borrow_rwlock<T:Const + Owned>(state: *const RWARCInner<T>) -> *RWlock {
unsafe { cast::transmute(&const (*state).lock) }
fn borrow_rwlock<T:Freeze + Send>(state: *mut RWARCInner<T>) -> *RWlock {
unsafe { cast::transmute(&(*state).lock) }
}
/// The "write permission" token used for RWARC.write_downgrade().
@ -452,7 +452,7 @@ pub struct RWReadMode<'self, T> {
token: sync::RWlockReadMode<'self>,
}
impl<'self, T:Const + Owned> RWWriteMode<'self, T> {
impl<'self, T:Freeze + Send> RWWriteMode<'self, T> {
/// Access the pre-downgrade RWARC in write mode.
pub fn write<U>(&mut self, blk: &fn(x: &mut T) -> U) -> U {
match *self {
@ -493,7 +493,7 @@ impl<'self, T:Const + Owned> RWWriteMode<'self, T> {
}
}
impl<'self, T:Const + Owned> RWReadMode<'self, T> {
impl<'self, T:Freeze + Send> RWReadMode<'self, T> {
/// Access the post-downgrade rwlock in read mode.
pub fn read<U>(&self, blk: &fn(x: &T) -> U) -> U {
match *self {
@ -513,13 +513,13 @@ impl<'self, T:Const + Owned> RWReadMode<'self, T> {
#[cfg(test)]
mod tests {
use core::prelude::*;
use arc::*;
use core::cell::Cell;
use core::comm;
use core::task;
use std::cell::Cell;
use std::comm;
use std::task;
use std::uint;
#[test]
fn manually_share_arc() {
@ -725,7 +725,7 @@ mod tests {
}
// Wait for children to pass their asserts
for children.each |r| {
for children.iter().advance |r| {
r.recv();
}
@ -789,18 +789,20 @@ mod tests {
}
assert_eq!(*state, 42);
*state = 31337;
// FIXME: #7372: hits type inference bug with iterators
// send to other readers
for reader_convos.each |x| {
match *x {
for uint::range(0, reader_convos.len()) |i| {
match reader_convos[i] {
(ref rc, _) => rc.send(()),
}
}
}
let read_mode = arc.downgrade(write_mode);
do (&read_mode).read |state| {
// FIXME: #7372: hits type inference bug with iterators
// complete handshake with other readers
for reader_convos.each |x| {
match *x {
for uint::range(0, reader_convos.len()) |i| {
match reader_convos[i] {
(_, ref rp) => rp.recv(),
}
}

View file

@ -1,4 +1,4 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// 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.
//
@ -34,37 +34,27 @@
#[allow(missing_doc)];
use core::prelude::*;
use list::{MutList, MutCons, MutNil};
use core::at_vec;
use core::cast::{transmute, transmute_mut_region};
use core::cast;
use core::libc::size_t;
use core::ptr;
use core::sys::TypeDesc;
use core::sys;
use core::uint;
use core::vec;
use core::unstable::intrinsics;
use std::at_vec;
use std::cast::{transmute, transmute_mut, transmute_mut_region};
use std::cast;
use std::ptr;
use std::sys;
use std::uint;
use std::vec;
use std::unstable::intrinsics;
use std::unstable::intrinsics::{TyDesc};
pub mod rustrt {
use core::libc::size_t;
use core::sys::TypeDesc;
#[cfg(not(stage0))]
use std::unstable::intrinsics::{get_tydesc};
pub extern {
#[rust_stack]
unsafe fn rust_call_tydesc_glue(root: *u8,
tydesc: *TypeDesc,
field: size_t);
}
#[cfg(stage0)]
unsafe fn get_tydesc<T>() -> *TyDesc {
intrinsics::get_tydesc::<T>() as *TyDesc
}
// This probably belongs somewhere else. Needs to be kept in sync with
// changes to glue...
static tydesc_drop_glue_index: size_t = 3 as size_t;
// The way arena uses arrays is really deeply awful. The arrays are
// allocated, and have capacities reserved, but the fill for the array
// will always stay at 0.
@ -74,6 +64,8 @@ struct Chunk {
is_pod: bool,
}
#[mutable] // XXX remove after snap
#[no_freeze]
pub struct Arena {
// The head is separated out from the list as a unbenchmarked
// microoptimization, to avoid needing to case on the list to
@ -85,7 +77,7 @@ pub struct Arena {
#[unsafe_destructor]
impl Drop for Arena {
fn finalize(&self) {
fn drop(&self) {
unsafe {
destroy_chunk(&self.head);
for self.chunks.each |chunk| {
@ -124,6 +116,19 @@ fn round_up_to(base: uint, align: uint) -> uint {
(base + (align - 1)) & !(align - 1)
}
#[inline]
#[cfg(not(stage0))]
unsafe fn call_drop_glue(tydesc: *TyDesc, data: *i8) {
// This function should be inlined when stage0 is gone
((*tydesc).drop_glue)(data);
}
#[inline]
#[cfg(stage0)]
unsafe fn call_drop_glue(tydesc: *TyDesc, data: *i8) {
((*tydesc).drop_glue)(0 as **TyDesc, data);
}
// Walk down a chunk, running the destructors for any objects stored
// in it.
unsafe fn destroy_chunk(chunk: &Chunk) {
@ -136,19 +141,18 @@ unsafe fn destroy_chunk(chunk: &Chunk) {
let (tydesc, is_done) = un_bitpack_tydesc_ptr(*tydesc_data);
let (size, align) = ((*tydesc).size, (*tydesc).align);
let after_tydesc = idx + sys::size_of::<*TypeDesc>();
let after_tydesc = idx + sys::size_of::<*TyDesc>();
let start = round_up_to(after_tydesc, align);
//debug!("freeing object: idx = %u, size = %u, align = %u, done = %b",
// start, size, align, is_done);
if is_done {
rustrt::rust_call_tydesc_glue(
ptr::offset(buf, start), tydesc, tydesc_drop_glue_index);
call_drop_glue(tydesc, ptr::offset(buf, start) as *i8);
}
// Find where the next tydesc lives
idx = round_up_to(start + size, sys::pref_align_of::<*TypeDesc>());
idx = round_up_to(start + size, sys::pref_align_of::<*TyDesc>());
}
}
@ -157,12 +161,12 @@ unsafe fn destroy_chunk(chunk: &Chunk) {
// is necessary in order to properly do cleanup if a failure occurs
// during an initializer.
#[inline]
unsafe fn bitpack_tydesc_ptr(p: *TypeDesc, is_done: bool) -> uint {
unsafe fn bitpack_tydesc_ptr(p: *TyDesc, is_done: bool) -> uint {
let p_bits: uint = transmute(p);
p_bits | (is_done as uint)
}
#[inline]
unsafe fn un_bitpack_tydesc_ptr(p: uint) -> (*TypeDesc, bool) {
unsafe fn un_bitpack_tydesc_ptr(p: uint) -> (*TyDesc, bool) {
(transmute(p & !1), p & 1 == 1)
}
@ -182,27 +186,25 @@ impl Arena {
#[inline]
fn alloc_pod_inner(&mut self, n_bytes: uint, align: uint) -> *u8 {
unsafe {
// XXX: Borrow check
let head = transmute_mut_region(&mut self.pod_head);
let start = round_up_to(head.fill, align);
let this = transmute_mut_region(self);
let start = round_up_to(this.pod_head.fill, align);
let end = start + n_bytes;
if end > at_vec::capacity(head.data) {
return self.alloc_pod_grow(n_bytes, align);
if end > at_vec::capacity(this.pod_head.data) {
return this.alloc_pod_grow(n_bytes, align);
}
head.fill = end;
this.pod_head.fill = end;
//debug!("idx = %u, size = %u, align = %u, fill = %u",
// start, n_bytes, align, head.fill);
ptr::offset(vec::raw::to_ptr(head.data), start)
ptr::offset(vec::raw::to_ptr(this.pod_head.data), start)
}
}
#[inline]
fn alloc_pod<'a, T>(&'a mut self, op: &fn() -> T) -> &'a T {
unsafe {
let tydesc = sys::get_type_desc::<T>();
let tydesc = get_tydesc::<T>();
let ptr = self.alloc_pod_inner((*tydesc).size, (*tydesc).align);
let ptr: *mut T = transmute(ptr);
intrinsics::move_val_init(&mut (*ptr), op());
@ -227,21 +229,31 @@ impl Arena {
fn alloc_nonpod_inner(&mut self, n_bytes: uint, align: uint)
-> (*u8, *u8) {
unsafe {
let head = transmute_mut_region(&mut self.head);
let start;
let end;
let tydesc_start;
let after_tydesc;
let tydesc_start = head.fill;
let after_tydesc = head.fill + sys::size_of::<*TypeDesc>();
let start = round_up_to(after_tydesc, align);
let end = start + n_bytes;
if end > at_vec::capacity(head.data) {
{
let head = transmute_mut_region(&mut self.head);
tydesc_start = head.fill;
after_tydesc = head.fill + sys::size_of::<*TyDesc>();
start = round_up_to(after_tydesc, align);
end = start + n_bytes;
}
if end > at_vec::capacity(self.head.data) {
return self.alloc_nonpod_grow(n_bytes, align);
}
head.fill = round_up_to(end, sys::pref_align_of::<*TypeDesc>());
let head = transmute_mut_region(&mut self.head);
head.fill = round_up_to(end, sys::pref_align_of::<*TyDesc>());
//debug!("idx = %u, size = %u, align = %u, fill = %u",
// start, n_bytes, align, head.fill);
let buf = vec::raw::to_ptr(head.data);
let buf = vec::raw::to_ptr(self.head.data);
return (ptr::offset(buf, tydesc_start), ptr::offset(buf, start));
}
}
@ -249,7 +261,7 @@ impl Arena {
#[inline]
fn alloc_nonpod<'a, T>(&'a mut self, op: &fn() -> T) -> &'a T {
unsafe {
let tydesc = sys::get_type_desc::<T>();
let tydesc = get_tydesc::<T>();
let (ty_ptr, ptr) =
self.alloc_nonpod_inner((*tydesc).size, (*tydesc).align);
let ty_ptr: *mut uint = transmute(ty_ptr);
@ -269,23 +281,22 @@ impl Arena {
// The external interface
#[inline]
pub fn alloc<'a, T>(&'a mut self, op: &fn() -> T) -> &'a T {
pub fn alloc<'a, T>(&'a self, op: &fn() -> T) -> &'a T {
unsafe {
// XXX: Borrow check
let this = transmute_mut_region(self);
if !intrinsics::needs_drop::<T>() {
return this.alloc_pod(op);
let this = transmute_mut(self);
if intrinsics::needs_drop::<T>() {
this.alloc_nonpod(op)
} else {
this.alloc_pod(op)
}
// XXX: Borrow check
let this = transmute_mut_region(self);
this.alloc_nonpod(op)
}
}
}
#[test]
fn test_arena_destructors() {
let mut arena = Arena();
let arena = Arena();
for uint::range(0, 10) |i| {
// Arena allocate something with drop glue to make sure it
// doesn't leak.
@ -300,7 +311,7 @@ fn test_arena_destructors() {
#[should_fail]
#[ignore(cfg(windows))]
fn test_arena_destructors_fail() {
let mut arena = Arena();
let arena = Arena();
// Put some stuff in the arena.
for uint::range(0, 10) |i| {
// Arena allocate something with drop glue to make sure it

View file

@ -10,9 +10,8 @@
//! Base64 binary-to-text encoding
use core::prelude::*;
use core::vec;
use std::vec;
/// A trait for converting a value to base64 encoding.
pub trait ToBase64 {
@ -36,8 +35,8 @@ impl<'self> ToBase64 for &'self [u8] {
* # Example
*
* ~~~ {.rust}
* extern mod std;
* use std::base64::ToBase64;
* extern mod extra;
* use extra::base64::ToBase64;
*
* fn main () {
* let str = [52,32].to_base64();
@ -99,8 +98,8 @@ impl<'self> ToBase64 for &'self str {
* # Example
*
* ~~~ {.rust}
* extern mod std;
* use std::base64::ToBase64;
* extern mod extra;
* use extra::base64::ToBase64;
*
* fn main () {
* let str = "Hello, World".to_base64();
@ -127,9 +126,9 @@ impl<'self> FromBase64 for &'self [u8] {
* # Example
*
* ~~~ {.rust}
* extern mod std;
* use std::base64::ToBase64;
* use std::base64::FromBase64;
* extern mod extra;
* use extra::base64::ToBase64;
* use extra::base64::FromBase64;
*
* fn main () {
* let str = [52,32].to_base64();
@ -199,7 +198,7 @@ impl<'self> FromBase64 for &'self str {
* Convert any base64 encoded string (literal, `@`, `&`, or `~`)
* to the byte values it encodes.
*
* You can use the `from_bytes` function in `core::str`
* You can use the `from_bytes` function in `std::str`
* to turn a `[u8]` into a string with characters corresponding to those values.
*
* # Example
@ -207,10 +206,10 @@ impl<'self> FromBase64 for &'self str {
* This converts a string literal to base64 and back.
*
* ~~~ {.rust}
* extern mod std;
* use std::base64::ToBase64;
* use std::base64::FromBase64;
* use core::str;
* extern mod extra;
* use extra::base64::ToBase64;
* use extra::base64::FromBase64;
* use std::str;
*
* fn main () {
* let hello_str = "Hello, World".to_base64();

View file

@ -10,12 +10,11 @@
#[allow(missing_doc)];
use core::prelude::*;
use core::cmp;
use core::ops;
use core::uint;
use core::vec;
use std::cmp;
use std::ops;
use std::uint;
use std::vec;
struct SmallBitv {
/// only the lowest nbits of this value are used. the rest is undefined.
@ -476,9 +475,15 @@ impl Bitv {
* character is either '0' or '1'.
*/
pub fn to_str(&self) -> ~str {
let mut rs = ~"";
for self.each() |i| { if i { rs += "1"; } else { rs += "0"; } };
rs
let mut rs = ~"";
for self.each() |i| {
if i {
rs.push_char('1');
} else {
rs.push_char('0');
}
};
rs
}
@ -639,7 +644,7 @@ impl BitvSet {
if self.capacity() < other.capacity() {
self.bitv.storage.grow(other.capacity() / uint::bits, &0);
}
for other.bitv.storage.eachi |i, &w| {
for other.bitv.storage.iter().enumerate().advance |(i, &w)| {
let old = self.bitv.storage[i];
let new = f(old, w);
self.bitv.storage[i] = new;
@ -666,13 +671,9 @@ impl BitvSet {
pub fn symmetric_difference_with(&mut self, other: &BitvSet) {
self.other_op(other, |w1, w2| w1 ^ w2);
}
}
impl BaseIter<uint> for BitvSet {
fn size_hint(&self) -> Option<uint> { Some(self.len()) }
fn each(&self, blk: &fn(v: &uint) -> bool) -> bool {
for self.bitv.storage.eachi |i, &w| {
pub fn each(&self, blk: &fn(v: &uint) -> bool) -> bool {
for self.bitv.storage.iter().enumerate().advance |(i, &w)| {
if !iterate_bits(i * uint::bits, w, |b| blk(&b)) {
return false;
}
@ -703,8 +704,8 @@ impl cmp::Eq for BitvSet {
}
impl Container for BitvSet {
fn len(&const self) -> uint { self.size }
fn is_empty(&const self) -> bool { self.size == 0 }
fn len(&self) -> uint { self.size }
fn is_empty(&self) -> bool { self.size == 0 }
}
impl Mutable for BitvSet {
@ -826,7 +827,7 @@ impl BitvSet {
f: &fn(uint, uint, uint) -> bool) -> bool {
let min = uint::min(self.bitv.storage.len(),
other.bitv.storage.len());
self.bitv.storage.slice(0, min).eachi(|i, &w| {
self.bitv.storage.slice(0, min).iter().enumerate().advance(|(i, &w)| {
f(i * uint::bits, w, other.bitv.storage[i])
})
}
@ -845,12 +846,12 @@ impl BitvSet {
let min = uint::min(len1, len2);
/* only one of these loops will execute and that's the point */
for self.bitv.storage.slice(min, len1).eachi |i, &w| {
for self.bitv.storage.slice(min, len1).iter().enumerate().advance |(i, &w)| {
if !f(true, (i + min) * uint::bits, w) {
return false;
}
}
for other.bitv.storage.slice(min, len2).eachi |i, &w| {
for other.bitv.storage.slice(min, len2).iter().enumerate().advance |(i, &w)| {
if !f(false, (i + min) * uint::bits, w) {
return false;
}
@ -861,15 +862,15 @@ impl BitvSet {
#[cfg(test)]
mod tests {
use std::test::BenchHarness;
use extra::test::BenchHarness;
use bitv::*;
use bitv;
use core::uint;
use core::vec;
use core::rand;
use core::rand::Rng;
use std::uint;
use std::vec;
use std::rand;
use std::rand::Rng;
static bench_bits : uint = 1 << 14;

View file

@ -36,10 +36,9 @@
* still held if needed.
*/
use core::prelude::*;
use core::option;
use core::ptr;
use std::option;
use std::ptr;
/**
* The type representing a foreign chunk of memory
@ -57,7 +56,7 @@ struct DtorRes {
#[unsafe_destructor]
impl Drop for DtorRes {
fn finalize(&self) {
fn drop(&self) {
match self.dtor {
option::None => (),
option::Some(f) => f()
@ -150,8 +149,8 @@ mod tests {
use c_vec::*;
use core::libc::*;
use core::libc;
use std::libc::*;
use std::libc;
fn malloc(n: size_t) -> CVec<u8> {
unsafe {
@ -159,8 +158,7 @@ mod tests {
assert!(mem as int != 0);
return c_vec_with_dtor(mem as *mut u8, n as uint,
|| unsafe { free(mem) });
c_vec_with_dtor(mem as *mut u8, n as uint, || free(mem))
}
}

View file

@ -16,12 +16,11 @@ Higher level communication abstractions.
#[allow(missing_doc)];
use core::prelude::*;
use core::comm::{GenericChan, GenericSmartChan, GenericPort};
use core::comm::{Chan, Port, Selectable, Peekable};
use core::comm;
use core::pipes;
use std::comm::{GenericChan, GenericSmartChan, GenericPort};
use std::comm::{Chan, Port, Selectable, Peekable};
use std::comm;
use std::pipes;
/// An extension of `pipes::stream` that allows both sending and receiving.
pub struct DuplexStream<T, U> {
@ -30,7 +29,7 @@ pub struct DuplexStream<T, U> {
}
// Allow these methods to be used without import:
impl<T:Owned,U:Owned> DuplexStream<T, U> {
impl<T:Send,U:Send> DuplexStream<T, U> {
pub fn send(&self, x: T) {
self.chan.send(x)
}
@ -48,19 +47,19 @@ impl<T:Owned,U:Owned> DuplexStream<T, U> {
}
}
impl<T:Owned,U:Owned> GenericChan<T> for DuplexStream<T, U> {
impl<T:Send,U:Send> GenericChan<T> for DuplexStream<T, U> {
fn send(&self, x: T) {
self.chan.send(x)
}
}
impl<T:Owned,U:Owned> GenericSmartChan<T> for DuplexStream<T, U> {
impl<T:Send,U:Send> GenericSmartChan<T> for DuplexStream<T, U> {
fn try_send(&self, x: T) -> bool {
self.chan.try_send(x)
}
}
impl<T:Owned,U:Owned> GenericPort<U> for DuplexStream<T, U> {
impl<T:Send,U:Send> GenericPort<U> for DuplexStream<T, U> {
fn recv(&self) -> U {
self.port.recv()
}
@ -70,20 +69,20 @@ impl<T:Owned,U:Owned> GenericPort<U> for DuplexStream<T, U> {
}
}
impl<T:Owned,U:Owned> Peekable<U> for DuplexStream<T, U> {
impl<T:Send,U:Send> Peekable<U> for DuplexStream<T, U> {
fn peek(&self) -> bool {
self.port.peek()
}
}
impl<T:Owned,U:Owned> Selectable for DuplexStream<T, U> {
impl<T:Send,U:Send> Selectable for DuplexStream<T, U> {
fn header(&mut self) -> *mut pipes::PacketHeader {
self.port.header()
}
}
/// Creates a bidirectional stream.
pub fn DuplexStream<T:Owned,U:Owned>()
pub fn DuplexStream<T:Send,U:Send>()
-> (DuplexStream<T, U>, DuplexStream<U, T>)
{
let (p1, c2) = comm::stream();

View file

@ -0,0 +1,87 @@
// 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.
use std::uint;
use std::vec;
/**
* The Digest trait specifies an interface common to digest functions, such as SHA-1 and the SHA-2
* family of digest functions.
*/
pub trait Digest {
/**
* Provide message data.
*
* # Arguments
*
* * input - A vector of message data
*/
fn input(&mut self, input: &[u8]);
/**
* Retrieve the digest result. This method may be called multiple times.
*/
fn result(&mut self, out: &mut [u8]);
/**
* Reset the digest. This method must be called after result() and before supplying more
* data.
*/
fn reset(&mut self);
/**
* Get the output size in bits.
*/
fn output_bits(&self) -> uint;
}
fn to_hex(rr: &[u8]) -> ~str {
let mut s = ~"";
for rr.iter().advance() |b| {
let hex = uint::to_str_radix(*b as uint, 16u);
if hex.len() == 1 {
s.push_char('0');
}
s.push_str(hex);
}
return s;
}
/// Contains utility methods for Digests.
/// FIXME: #7339: Convert to default methods when issues with them are resolved.
pub trait DigestUtil {
/**
* Convenience functon that feeds a string into a digest
*
* # Arguments
*
* * in The string to feed into the digest
*/
fn input_str(&mut self, in: &str);
/**
* Convenience functon that retrieves the result of a digest as a
* ~str in hexadecimal format.
*/
fn result_str(&mut self) -> ~str;
}
impl<D: Digest> DigestUtil for D {
fn input_str(&mut self, in: &str) {
self.input(in.as_bytes());
}
fn result_str(&mut self) -> ~str {
let mut buf = vec::from_elem((self.output_bits()+7)/8, 0u8);
self.result(buf);
return to_hex(buf);
}
}

369
src/libextra/crypto/sha1.rs Normal file
View file

@ -0,0 +1,369 @@
// 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.
/*!
* An implementation of the SHA-1 cryptographic hash.
*
* First create a `sha1` object using the `sha1` constructor, then
* feed it input using the `input` or `input_str` methods, which may be
* called any number of times.
*
* After the entire input has been fed to the hash read the result using
* the `result` or `result_str` methods.
*
* The `sha1` object may be reused to create multiple hashes by calling
* the `reset` method.
*/
use digest::Digest;
/*
* A SHA-1 implementation derived from Paul E. Jones's reference
* implementation, which is written for clarity, not speed. At some
* point this will want to be rewritten.
*/
// Some unexported constants
static DIGEST_BUF_LEN: uint = 5u;
static MSG_BLOCK_LEN: uint = 64u;
static WORK_BUF_LEN: uint = 80u;
static K0: u32 = 0x5A827999u32;
static K1: u32 = 0x6ED9EBA1u32;
static K2: u32 = 0x8F1BBCDCu32;
static K3: u32 = 0xCA62C1D6u32;
/// Structure representing the state of a Sha1 computation
pub struct Sha1 {
priv h: [u32, ..DIGEST_BUF_LEN],
priv len_low: u32,
priv len_high: u32,
priv msg_block: [u8, ..MSG_BLOCK_LEN],
priv msg_block_idx: uint,
priv computed: bool,
priv work_buf: [u32, ..WORK_BUF_LEN]
}
fn add_input(st: &mut Sha1, msg: &[u8]) {
assert!((!st.computed));
for msg.iter().advance |element| {
st.msg_block[st.msg_block_idx] = *element;
st.msg_block_idx += 1;
st.len_low += 8;
if st.len_low == 0 {
st.len_high += 1;
if st.len_high == 0 {
// FIXME: Need better failure mode (#2346)
fail!();
}
}
if st.msg_block_idx == MSG_BLOCK_LEN { process_msg_block(st); }
}
}
fn process_msg_block(st: &mut Sha1) {
let mut t: int; // Loop counter
let mut w = st.work_buf;
// Initialize the first 16 words of the vector w
t = 0;
while t < 16 {
let mut tmp;
tmp = (st.msg_block[t * 4] as u32) << 24u32;
tmp = tmp | (st.msg_block[t * 4 + 1] as u32) << 16u32;
tmp = tmp | (st.msg_block[t * 4 + 2] as u32) << 8u32;
tmp = tmp | (st.msg_block[t * 4 + 3] as u32);
w[t] = tmp;
t += 1;
}
// Initialize the rest of vector w
while t < 80 {
let val = w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16];
w[t] = circular_shift(1, val);
t += 1;
}
let mut a = st.h[0];
let mut b = st.h[1];
let mut c = st.h[2];
let mut d = st.h[3];
let mut e = st.h[4];
let mut temp: u32;
t = 0;
while t < 20 {
temp = circular_shift(5, a) + (b & c | !b & d) + e + w[t] + K0;
e = d;
d = c;
c = circular_shift(30, b);
b = a;
a = temp;
t += 1;
}
while t < 40 {
temp = circular_shift(5, a) + (b ^ c ^ d) + e + w[t] + K1;
e = d;
d = c;
c = circular_shift(30, b);
b = a;
a = temp;
t += 1;
}
while t < 60 {
temp =
circular_shift(5, a) + (b & c | b & d | c & d) + e + w[t] +
K2;
e = d;
d = c;
c = circular_shift(30, b);
b = a;
a = temp;
t += 1;
}
while t < 80 {
temp = circular_shift(5, a) + (b ^ c ^ d) + e + w[t] + K3;
e = d;
d = c;
c = circular_shift(30, b);
b = a;
a = temp;
t += 1;
}
st.h[0] = st.h[0] + a;
st.h[1] = st.h[1] + b;
st.h[2] = st.h[2] + c;
st.h[3] = st.h[3] + d;
st.h[4] = st.h[4] + e;
st.msg_block_idx = 0;
}
fn circular_shift(bits: u32, word: u32) -> u32 {
return word << bits | word >> 32u32 - bits;
}
fn mk_result(st: &mut Sha1, rs: &mut [u8]) {
if !st.computed { pad_msg(st); st.computed = true; }
let mut i = 0;
for st.h.mut_iter().advance |ptr_hpart| {
let hpart = *ptr_hpart;
rs[i] = (hpart >> 24u32 & 0xFFu32) as u8;
rs[i+1] = (hpart >> 16u32 & 0xFFu32) as u8;
rs[i+2] = (hpart >> 8u32 & 0xFFu32) as u8;
rs[i+3] = (hpart & 0xFFu32) as u8;
i += 4;
}
}
/*
* According to the standard, the message must be padded to an even
* 512 bits. The first padding bit must be a '1'. The last 64 bits
* represent the length of the original message. All bits in between
* should be 0. This function will pad the message according to those
* rules by filling the msg_block vector accordingly. It will also
* call process_msg_block() appropriately. When it returns, it
* can be assumed that the message digest has been computed.
*/
fn pad_msg(st: &mut Sha1) {
/*
* Check to see if the current message block is too small to hold
* the initial padding bits and length. If so, we will pad the
* block, process it, and then continue padding into a second block.
*/
if st.msg_block_idx > 55 {
st.msg_block[st.msg_block_idx] = 0x80;
st.msg_block_idx += 1;
while st.msg_block_idx < MSG_BLOCK_LEN {
st.msg_block[st.msg_block_idx] = 0;
st.msg_block_idx += 1;
}
process_msg_block(st);
} else {
st.msg_block[st.msg_block_idx] = 0x80;
st.msg_block_idx += 1;
}
while st.msg_block_idx < 56 {
st.msg_block[st.msg_block_idx] = 0u8;
st.msg_block_idx += 1;
}
// Store the message length as the last 8 octets
st.msg_block[56] = (st.len_high >> 24u32 & 0xFFu32) as u8;
st.msg_block[57] = (st.len_high >> 16u32 & 0xFFu32) as u8;
st.msg_block[58] = (st.len_high >> 8u32 & 0xFFu32) as u8;
st.msg_block[59] = (st.len_high & 0xFFu32) as u8;
st.msg_block[60] = (st.len_low >> 24u32 & 0xFFu32) as u8;
st.msg_block[61] = (st.len_low >> 16u32 & 0xFFu32) as u8;
st.msg_block[62] = (st.len_low >> 8u32 & 0xFFu32) as u8;
st.msg_block[63] = (st.len_low & 0xFFu32) as u8;
process_msg_block(st);
}
impl Sha1 {
/// Construct a `sha` object
pub fn new() -> Sha1 {
let mut st = Sha1 {
h: [0u32, ..DIGEST_BUF_LEN],
len_low: 0u32,
len_high: 0u32,
msg_block: [0u8, ..MSG_BLOCK_LEN],
msg_block_idx: 0,
computed: false,
work_buf: [0u32, ..WORK_BUF_LEN]
};
st.reset();
return st;
}
}
impl Digest for Sha1 {
pub fn reset(&mut self) {
self.len_low = 0;
self.len_high = 0;
self.msg_block_idx = 0;
self.h[0] = 0x67452301u32;
self.h[1] = 0xEFCDAB89u32;
self.h[2] = 0x98BADCFEu32;
self.h[3] = 0x10325476u32;
self.h[4] = 0xC3D2E1F0u32;
self.computed = false;
}
pub fn input(&mut self, msg: &[u8]) { add_input(self, msg); }
pub fn result(&mut self, out: &mut [u8]) { return mk_result(self, out); }
pub fn output_bits(&self) -> uint { 160 }
}
#[cfg(test)]
mod tests {
use std::vec;
use digest::{Digest, DigestUtil};
use sha1::Sha1;
#[test]
fn test() {
struct Test {
input: ~str,
output: ~[u8],
output_str: ~str,
}
fn a_million_letter_a() -> ~str {
let mut i = 0;
let mut rs = ~"";
while i < 100000 {
rs.push_str("aaaaaaaaaa");
i += 1;
}
return rs;
}
// Test messages from FIPS 180-1
let fips_180_1_tests = ~[
Test {
input: ~"abc",
output: ~[
0xA9u8, 0x99u8, 0x3Eu8, 0x36u8,
0x47u8, 0x06u8, 0x81u8, 0x6Au8,
0xBAu8, 0x3Eu8, 0x25u8, 0x71u8,
0x78u8, 0x50u8, 0xC2u8, 0x6Cu8,
0x9Cu8, 0xD0u8, 0xD8u8, 0x9Du8,
],
output_str: ~"a9993e364706816aba3e25717850c26c9cd0d89d"
},
Test {
input:
~"abcdbcdecdefdefgefghfghighij" +
"hijkijkljklmklmnlmnomnopnopq",
output: ~[
0x84u8, 0x98u8, 0x3Eu8, 0x44u8,
0x1Cu8, 0x3Bu8, 0xD2u8, 0x6Eu8,
0xBAu8, 0xAEu8, 0x4Au8, 0xA1u8,
0xF9u8, 0x51u8, 0x29u8, 0xE5u8,
0xE5u8, 0x46u8, 0x70u8, 0xF1u8,
],
output_str: ~"84983e441c3bd26ebaae4aa1f95129e5e54670f1"
},
Test {
input: a_million_letter_a(),
output: ~[
0x34u8, 0xAAu8, 0x97u8, 0x3Cu8,
0xD4u8, 0xC4u8, 0xDAu8, 0xA4u8,
0xF6u8, 0x1Eu8, 0xEBu8, 0x2Bu8,
0xDBu8, 0xADu8, 0x27u8, 0x31u8,
0x65u8, 0x34u8, 0x01u8, 0x6Fu8,
],
output_str: ~"34aa973cd4c4daa4f61eeb2bdbad27316534016f"
},
];
// Examples from wikipedia
let wikipedia_tests = ~[
Test {
input: ~"The quick brown fox jumps over the lazy dog",
output: ~[
0x2fu8, 0xd4u8, 0xe1u8, 0xc6u8,
0x7au8, 0x2du8, 0x28u8, 0xfcu8,
0xedu8, 0x84u8, 0x9eu8, 0xe1u8,
0xbbu8, 0x76u8, 0xe7u8, 0x39u8,
0x1bu8, 0x93u8, 0xebu8, 0x12u8,
],
output_str: ~"2fd4e1c67a2d28fced849ee1bb76e7391b93eb12",
},
Test {
input: ~"The quick brown fox jumps over the lazy cog",
output: ~[
0xdeu8, 0x9fu8, 0x2cu8, 0x7fu8,
0xd2u8, 0x5eu8, 0x1bu8, 0x3au8,
0xfau8, 0xd3u8, 0xe8u8, 0x5au8,
0x0bu8, 0xd1u8, 0x7du8, 0x9bu8,
0x10u8, 0x0du8, 0xb4u8, 0xb3u8,
],
output_str: ~"de9f2c7fd25e1b3afad3e85a0bd17d9b100db4b3",
},
];
let tests = fips_180_1_tests + wikipedia_tests;
// Test that it works when accepting the message all at once
let mut out = [0u8, ..20];
let mut sh = ~Sha1::new();
for tests.iter().advance |t| {
(*sh).input_str(t.input);
sh.result(out);
assert!(vec::eq(t.output, out));
let out_str = (*sh).result_str();
assert_eq!(out_str.len(), 40);
assert!(out_str == t.output_str);
sh.reset();
}
// Test that it works when accepting the message in pieces
for tests.iter().advance |t| {
let len = t.input.len();
let mut left = len;
while left > 0u {
let take = (left + 1u) / 2u;
(*sh).input_str(t.input.slice(len - left, take + len - left));
left = left - take;
}
sh.result(out);
assert!(vec::eq(t.output, out));
let out_str = (*sh).result_str();
assert_eq!(out_str.len(), 40);
assert!(out_str == t.output_str);
sh.reset();
}
}
}

1123
src/libextra/crypto/sha2.rs Normal file

File diff suppressed because it is too large Load diff

View file

@ -12,57 +12,63 @@
#[allow(missing_doc)];
use core::cast::transmute;
use core::sys;
use std::cast::transmute;
#[cfg(stage0)]
use intrinsic::{get_tydesc};
#[cfg(not(stage0))]
use std::unstable::intrinsics::{get_tydesc};
pub mod rustrt {
use core::sys;
#[cfg(stage0)]
use intrinsic::{TyDesc};
#[cfg(not(stage0))]
use std::unstable::intrinsics::{TyDesc};
#[abi = "cdecl"]
pub extern {
pub unsafe fn debug_tydesc(td: *sys::TypeDesc);
pub unsafe fn debug_opaque(td: *sys::TypeDesc, x: *());
pub unsafe fn debug_box(td: *sys::TypeDesc, x: *());
pub unsafe fn debug_tag(td: *sys::TypeDesc, x: *());
pub unsafe fn debug_fn(td: *sys::TypeDesc, x: *());
pub unsafe fn debug_ptrcast(td: *sys::TypeDesc, x: *()) -> *();
pub unsafe fn debug_tydesc(td: *TyDesc);
pub unsafe fn debug_opaque(td: *TyDesc, x: *());
pub unsafe fn debug_box(td: *TyDesc, x: *());
pub unsafe fn debug_tag(td: *TyDesc, x: *());
pub unsafe fn debug_fn(td: *TyDesc, x: *());
pub unsafe fn debug_ptrcast(td: *TyDesc, x: *()) -> *();
pub unsafe fn rust_dbg_breakpoint();
}
}
pub fn debug_tydesc<T>() {
unsafe {
rustrt::debug_tydesc(sys::get_type_desc::<T>());
rustrt::debug_tydesc(get_tydesc::<T>());
}
}
pub fn debug_opaque<T>(x: T) {
unsafe {
rustrt::debug_opaque(sys::get_type_desc::<T>(), transmute(&x));
rustrt::debug_opaque(get_tydesc::<T>(), transmute(&x));
}
}
pub fn debug_box<T>(x: @T) {
unsafe {
rustrt::debug_box(sys::get_type_desc::<T>(), transmute(&x));
rustrt::debug_box(get_tydesc::<T>(), transmute(&x));
}
}
pub fn debug_tag<T>(x: T) {
unsafe {
rustrt::debug_tag(sys::get_type_desc::<T>(), transmute(&x));
rustrt::debug_tag(get_tydesc::<T>(), transmute(&x));
}
}
pub fn debug_fn<T>(x: T) {
unsafe {
rustrt::debug_fn(sys::get_type_desc::<T>(), transmute(&x));
rustrt::debug_fn(get_tydesc::<T>(), transmute(&x));
}
}
pub unsafe fn ptr_cast<T, U>(x: @T) -> @U {
transmute(
rustrt::debug_ptrcast(sys::get_type_desc::<T>(), transmute(x)))
rustrt::debug_ptrcast(get_tydesc::<T>(), transmute(x)))
}
/// Triggers a debugger breakpoint

View file

@ -10,11 +10,10 @@
//! A double-ended queue implemented as a circular buffer
use core::prelude::*;
use core::uint;
use core::util::replace;
use core::vec;
use std::uint;
use std::util::replace;
use std::vec;
use std::cast::transmute;
static initial_capacity: uint = 32u; // 2^5
@ -28,10 +27,10 @@ pub struct Deque<T> {
impl<T> Container for Deque<T> {
/// Return the number of elements in the deque
fn len(&const self) -> uint { self.nelts }
fn len(&self) -> uint { self.nelts }
/// Return true if the deque contains no elements
fn is_empty(&const self) -> bool { self.len() == 0 }
fn is_empty(&self) -> bool { self.len() == 0 }
}
impl<T> Mutable for Deque<T> {
@ -137,7 +136,7 @@ impl<T> Deque<T> {
///
/// * n - The number of elements to reserve space for
pub fn reserve(&mut self, n: uint) {
vec::reserve(&mut self.elts, n);
self.elts.reserve(n);
}
/// Reserve capacity for at least `n` elements in the given deque,
@ -151,10 +150,89 @@ impl<T> Deque<T> {
///
/// * n - The number of elements to reserve space for
pub fn reserve_at_least(&mut self, n: uint) {
vec::reserve_at_least(&mut self.elts, n);
self.elts.reserve_at_least(n);
}
/// Front-to-back iterator.
pub fn iter<'a>(&'a self) -> DequeIterator<'a, T> {
DequeIterator { idx: self.lo, nelts: self.nelts, used: 0, vec: self.elts }
}
/// Front-to-back iterator which returns mutable values.
pub fn mut_iter<'a>(&'a mut self) -> DequeMutIterator<'a, T> {
DequeMutIterator { idx: self.lo, nelts: self.nelts, used: 0, vec: self.elts }
}
/// Back-to-front iterator.
pub fn rev_iter<'a>(&'a self) -> DequeRevIterator<'a, T> {
DequeRevIterator { idx: self.hi - 1u, nelts: self.nelts, used: 0, vec: self.elts }
}
/// Back-to-front iterator which returns mutable values.
pub fn mut_rev_iter<'a>(&'a mut self) -> DequeMutRevIterator<'a, T> {
DequeMutRevIterator { idx: self.hi - 1u, nelts: self.nelts, used: 0, vec: self.elts }
}
}
macro_rules! iterator {
(impl $name:ident -> $elem:ty, $step:expr) => {
impl<'self, T> Iterator<$elem> for $name<'self, T> {
#[inline]
fn next(&mut self) -> Option<$elem> {
if self.used >= self.nelts {
return None;
}
let ret = unsafe {
match self.vec[self.idx % self.vec.len()] {
Some(ref e) => Some(transmute(e)),
None => None
}
};
self.idx += $step;
self.used += 1;
ret
}
}
}
}
/// Deque iterator
pub struct DequeIterator<'self, T> {
priv idx: uint,
priv nelts: uint,
priv used: uint,
priv vec: &'self [Option<T>]
}
iterator!{impl DequeIterator -> &'self T, 1}
/// Deque reverse iterator
pub struct DequeRevIterator<'self, T> {
priv idx: uint,
priv nelts: uint,
priv used: uint,
priv vec: &'self [Option<T>]
}
iterator!{impl DequeRevIterator -> &'self T, -1}
/// Deque mutable iterator
pub struct DequeMutIterator<'self, T> {
priv idx: uint,
priv nelts: uint,
priv used: uint,
priv vec: &'self mut [Option<T>]
}
iterator!{impl DequeMutIterator -> &'self mut T, 1}
/// Deque mutable reverse iterator
pub struct DequeMutRevIterator<'self, T> {
priv idx: uint,
priv nelts: uint,
priv used: uint,
priv vec: &'self mut [Option<T>]
}
iterator!{impl DequeMutRevIterator -> &'self mut T, -1}
/// Grow is only called on full elts, so nelts is also len(elts), unlike
/// elsewhere.
fn grow<T>(nelts: uint, lo: uint, elts: &mut [Option<T>]) -> ~[Option<T>] {
@ -175,9 +253,9 @@ fn get<'r, T>(elts: &'r [Option<T>], i: uint) -> &'r T {
#[cfg(test)]
mod tests {
use super::*;
use core::cmp::Eq;
use core::kinds::Copy;
use core::vec::capacity;
use std::cmp::Eq;
use std::kinds::Copy;
use std::int;
#[test]
fn test_simple() {
@ -318,8 +396,7 @@ mod tests {
#[test]
fn test_param_taggy() {
test_parameterized::<Taggy>(One(1), Two(1, 2), Three(1, 2, 3),
Two(17, 42));
test_parameterized::<Taggy>(One(1), Two(1, 2), Three(1, 2, 3), Two(17, 42));
}
#[test]
@ -363,11 +440,11 @@ mod tests {
let mut d = Deque::new();
d.add_back(0u64);
d.reserve(50);
assert_eq!(capacity(&mut d.elts), 50);
assert_eq!(d.elts.capacity(), 50);
let mut d = Deque::new();
d.add_back(0u32);
d.reserve(50);
assert_eq!(capacity(&mut d.elts), 50);
assert_eq!(d.elts.capacity(), 50);
}
#[test]
@ -375,11 +452,38 @@ mod tests {
let mut d = Deque::new();
d.add_back(0u64);
d.reserve_at_least(50);
assert_eq!(capacity(&mut d.elts), 64);
assert_eq!(d.elts.capacity(), 64);
let mut d = Deque::new();
d.add_back(0u32);
d.reserve_at_least(50);
assert_eq!(capacity(&mut d.elts), 64);
assert_eq!(d.elts.capacity(), 64);
}
#[test]
fn test_iter() {
let mut d = Deque::new();
for int::range(0,5) |i| {
d.add_back(i);
}
assert_eq!(d.iter().collect::<~[&int]>(), ~[&0,&1,&2,&3,&4]);
for int::range(6,9) |i| {
d.add_front(i);
}
assert_eq!(d.iter().collect::<~[&int]>(), ~[&8,&7,&6,&0,&1,&2,&3,&4]);
}
#[test]
fn test_rev_iter() {
let mut d = Deque::new();
for int::range(0,5) |i| {
d.add_back(i);
}
assert_eq!(d.rev_iter().collect::<~[&int]>(), ~[&4,&3,&2,&1,&0]);
for int::range(6,9) |i| {
d.add_front(i);
}
assert_eq!(d.rev_iter().collect::<~[&int]>(), ~[&4,&3,&2,&1,&0,&6,&7,&8]);
}
}

View file

@ -18,11 +18,8 @@ Do not use ==, !=, <, etc on doubly-linked lists -- it may not terminate.
*/
use core::prelude::*;
use core::managed;
use core::old_iter;
use core::vec;
use std::managed;
pub type DListLink<T> = Option<@mut DListNode<T>>;
@ -213,6 +210,42 @@ impl<T> DList<T> {
}
impl<T> DList<T> {
/**
* Iterates through the current contents.
*
* Attempts to access this dlist during iteration are allowed (to
* allow for e.g. breadth-first search with in-place enqueues), but
* removing the current node is forbidden.
*/
pub fn each(@mut self, f: &fn(v: &T) -> bool) -> bool {
let mut link = self.peek_n();
while link.is_some() {
let nobe = link.get();
assert!(nobe.linked);
{
let frozen_nobe = &*nobe;
if !f(&frozen_nobe.data) { return false; }
}
// Check (weakly) that the user didn't do a remove.
if self.size == 0 {
fail!("The dlist became empty during iteration??")
}
if !nobe.linked ||
(!((nobe.prev.is_some()
|| managed::mut_ptr_eq(self.hd.expect("headless dlist?"),
nobe))
&& (nobe.next.is_some()
|| managed::mut_ptr_eq(self.tl.expect("tailless dlist?"),
nobe)))) {
fail!("Removing a dlist node during iteration is forbidden!")
}
link = nobe.next_link();
}
return true;
}
/// Get the size of the list. O(1).
pub fn len(@mut self) -> uint { self.size }
/// Returns true if the list is empty. O(1).
@ -484,67 +517,13 @@ impl<T:Copy> DList<T> {
/// Get data at the list's tail, failing if empty. O(1).
pub fn tail(@mut self) -> T { copy self.tail_n().data }
/// Get the elements of the list as a vector. O(n).
pub fn to_vec(@mut self) -> ~[T] {
let mut v = vec::with_capacity(self.size);
for old_iter::eachi(&self) |index,data| {
v[index] = copy *data;
}
v
}
}
impl<T> BaseIter<T> for @mut DList<T> {
/**
* Iterates through the current contents.
*
* Attempts to access this dlist during iteration are allowed (to
* allow for e.g. breadth-first search with in-place enqueues), but
* removing the current node is forbidden.
*/
fn each(&self, f: &fn(v: &T) -> bool) -> bool {
let mut link = self.peek_n();
while link.is_some() {
let nobe = link.get();
assert!(nobe.linked);
{
let frozen_nobe = &*nobe;
if !f(&frozen_nobe.data) { return false; }
}
// Check (weakly) that the user didn't do a remove.
if self.size == 0 {
fail!("The dlist became empty during iteration??")
}
if !nobe.linked ||
(!((nobe.prev.is_some()
|| managed::mut_ptr_eq(self.hd.expect("headless dlist?"),
nobe))
&& (nobe.next.is_some()
|| managed::mut_ptr_eq(self.tl.expect("tailless dlist?"),
nobe)))) {
fail!("Removing a dlist node during iteration is forbidden!")
}
link = nobe.next_link();
}
return true;
}
#[inline]
fn size_hint(&self) -> Option<uint> { Some(self.len()) }
}
#[cfg(test)]
mod tests {
use core::prelude::*;
use super::*;
use core::old_iter;
use core::vec;
#[test]
fn test_dlist_concat() {
let a = from_vec([1,2]);
@ -759,11 +738,6 @@ mod tests {
assert_eq!(l.len(), 3);
}
#[test]
fn test_dlist_foldl() {
let l = from_vec(vec::from_fn(101, |x|x));
assert_eq!(old_iter::foldl(&l, 0, |accum,elem| *accum+*elem), 5050);
}
#[test]
fn test_dlist_break_early() {
let l = from_vec([1,2,3,4,5]);
let mut x = 0;

View file

@ -10,7 +10,8 @@
#[allow(missing_doc)];
use core::prelude::*;
use std::str;
// Simple Extensible Binary Markup Language (ebml) reader and writer on a
// cursor model. See the specification here:
@ -34,6 +35,20 @@ pub struct Doc {
end: uint,
}
impl Doc {
pub fn get(&self, tag: uint) -> Doc {
reader::get_doc(*self, tag)
}
pub fn as_str_slice<'a>(&'a self) -> &'a str {
str::from_bytes_slice(self.data.slice(self.start, self.end))
}
pub fn as_str(&self) -> ~str {
self.as_str_slice().to_owned()
}
}
pub struct TaggedDoc {
tag: uint,
doc: Doc,
@ -78,31 +93,21 @@ pub mod reader {
use serialize;
use core::prelude::*;
use core::cast::transmute;
use core::int;
use core::io;
use core::ptr::offset;
use core::str;
use core::unstable::intrinsics::bswap32;
use core::vec;
use std::cast::transmute;
use std::int;
use std::io;
use std::option::{None, Option, Some};
#[cfg(target_arch = "x86")]
#[cfg(target_arch = "x86_64")]
use std::ptr::offset;
#[cfg(target_arch = "x86")]
#[cfg(target_arch = "x86_64")]
use std::unstable::intrinsics::bswap32;
// ebml reading
impl Doc {
pub fn get(&self, tag: uint) -> Doc {
get_doc(*self, tag)
}
pub fn as_str_slice<'a>(&'a self) -> &'a str {
str::from_bytes_slice(self.data.slice(self.start, self.end))
}
pub fn as_str(&self) -> ~str {
self.as_str_slice().to_owned()
}
}
struct Res {
val: uint,
next: uint
@ -248,7 +253,7 @@ pub mod reader {
}
pub fn with_doc_data<T>(d: Doc, f: &fn(x: &[u8]) -> T) -> T {
f(vec::slice(*d.data, d.start, d.end))
f(d.data.slice(d.start, d.end))
}
@ -372,7 +377,7 @@ pub mod reader {
fn read_u8 (&mut self) -> u8 { doc_as_u8 (self.next_doc(EsU8 )) }
fn read_uint(&mut self) -> uint {
let v = doc_as_u64(self.next_doc(EsUint));
if v > (::core::uint::max_value as u64) {
if v > (::std::uint::max_value as u64) {
fail!("uint %? too large for this architecture", v);
}
v as uint
@ -605,8 +610,8 @@ pub mod reader {
pub mod writer {
use super::*;
use core::cast;
use core::io;
use std::cast;
use std::io;
// ebml writing
pub struct Encoder {
@ -951,8 +956,8 @@ mod tests {
use serialize::Encodable;
use serialize;
use core::io;
use core::option::{None, Option, Some};
use std::io;
use std::option::{None, Option, Some};
#[test]
fn test_option_int() {

View file

@ -21,7 +21,7 @@ Rust extras are part of the standard Rust distribution.
*/
#[link(name = "extra",
vers = "0.7-pre",
vers = "0.7",
uuid = "122bed0b-c19b-4b82-b0b7-7ae8aead7297",
url = "https://github.com/mozilla/rust/tree/master/src/libextra")];
@ -32,13 +32,9 @@ Rust extras are part of the standard Rust distribution.
#[deny(non_camel_case_types)];
#[deny(missing_doc)];
#[no_std];
use std::str::{StrSlice, OwnedStr};
extern mod core(name = "std", vers = "0.7-pre");
use core::str::{StrSlice, OwnedStr};
pub use core::os;
pub use std::os;
pub mod uv_ll;
@ -86,13 +82,20 @@ pub mod sort;
pub mod dlist;
pub mod treemap;
// Crypto
#[path="crypto/digest.rs"]
pub mod digest;
#[path="crypto/sha1.rs"]
pub mod sha1;
#[path="crypto/sha2.rs"]
pub mod sha2;
// And ... other stuff
pub mod ebml;
pub mod dbg;
pub mod getopts;
pub mod json;
pub mod sha1;
pub mod md4;
pub mod tempfile;
pub mod term;
@ -128,21 +131,16 @@ pub mod serialize;
// 'extra' so that macro-expanded references to extra::serialize and such
// can be resolved within libextra.
#[doc(hidden)]
pub mod std {
pub mod extra {
pub use serialize;
pub use test;
// For bootstrapping.
pub use core::clone;
pub use core::condition;
pub use core::cmp;
pub use core::sys;
pub use core::unstable;
pub use core::str;
pub use core::os;
}
#[doc(hidden)]
pub mod extra {
pub use serialize;
pub use test;
pub use std::clone;
pub use std::condition;
pub use std::cmp;
pub use std::sys;
pub use std::unstable;
pub use std::str;
pub use std::os;
}

View file

@ -57,14 +57,14 @@ For more complicated uses (e.g. if one needs to pause iteration and
resume it later), a `FileInput` instance can be constructed via the
`from_vec`, `from_vec_raw` and `from_args` functions.
Once created, the `each_line` (from the `core::io::ReaderUtil` trait)
Once created, the `each_line` (from the `std::io::ReaderUtil` trait)
and `each_line_state` methods allow one to iterate on the lines; the
latter provides more information about the position within the
iteration to the caller.
It is possible (and safe) to skip lines and files using the
`read_line` and `next_file` methods. Also, `FileInput` implements
`core::io::Reader`, and the state will be updated correctly while
`std::io::Reader`, and the state will be updated correctly while
using any of those methods.
E.g. the following program reads until an empty line, pauses for user
@ -96,12 +96,10 @@ total line count).
#[allow(missing_doc)];
use core::prelude::*;
use core::io::ReaderUtil;
use core::io;
use core::os;
use core::vec;
use std::io::ReaderUtil;
use std::io;
use std::os;
/**
A summary of the internal state of a `FileInput` object. `line_num`
@ -354,13 +352,13 @@ a literal `-`.
*/
// XXX: stupid, unclear name
pub fn pathify(vec: &[~str], stdin_hyphen : bool) -> ~[Option<Path>] {
vec::map(vec, |&str : & ~str| {
if stdin_hyphen && str == ~"-" {
vec.iter().transform(|str| {
if stdin_hyphen && "-" == *str {
None
} else {
Some(Path(str))
Some(Path(*str))
}
})
}).collect()
}
/**
@ -410,18 +408,17 @@ pub fn input_vec_state(files: ~[Option<Path>],
#[cfg(test)]
mod test {
use core::prelude::*;
use super::{FileInput, pathify, input_vec, input_vec_state};
use core::io;
use core::uint;
use core::vec;
use std::io;
use std::uint;
use std::vec;
fn make_file(path : &Path, contents: &[~str]) {
let file = io::file_writer(path, [io::Create, io::Truncate]).get();
for contents.each |&str| {
for contents.iter().advance |&str| {
file.write_str(str);
file.write_char('\n');
}
@ -448,7 +445,7 @@ mod test {
|i| fmt!("tmp/lib-fileinput-test-fileinput-read-byte-%u.tmp", i)), true);
// 3 files containing 0\n, 1\n, and 2\n respectively
for filenames.eachi |i, &filename| {
for filenames.iter().enumerate().advance |(i, &filename)| {
make_file(filename.get_ref(), [fmt!("%u", i)]);
}
@ -478,7 +475,7 @@ mod test {
|i| fmt!("tmp/lib-fileinput-test-fileinput-read-%u.tmp", i)), true);
// 3 files containing 1\n, 2\n, and 3\n respectively
for filenames.eachi |i, &filename| {
for filenames.iter().enumerate().advance |(i, &filename)| {
make_file(filename.get_ref(), [fmt!("%u", i)]);
}
@ -498,7 +495,7 @@ mod test {
3,
|i| fmt!("tmp/lib-fileinput-test-input-vec-%u.tmp", i)), true);
for filenames.eachi |i, &filename| {
for filenames.iter().enumerate().advance |(i, &filename)| {
let contents =
vec::from_fn(3, |j| fmt!("%u %u", i, j));
make_file(filename.get_ref(), contents);
@ -518,7 +515,7 @@ mod test {
3,
|i| fmt!("tmp/lib-fileinput-test-input-vec-state-%u.tmp", i)),true);
for filenames.eachi |i, &filename| {
for filenames.iter().enumerate().advance |(i, &filename)| {
let contents =
vec::from_fn(3, |j| fmt!("%u %u", i, j + 1));
make_file(filename.get_ref(), contents);
@ -582,7 +579,7 @@ mod test {
3,
|i| fmt!("tmp/lib-fileinput-test-next-file-%u.tmp", i)),true);
for filenames.eachi |i, &filename| {
for filenames.iter().enumerate().advance |(i, &filename)| {
let contents =
vec::from_fn(3, |j| fmt!("%u %u", i, j + 1));
make_file(&filename.get(), contents);

View file

@ -16,12 +16,12 @@ Simple compression
#[allow(missing_doc)];
use core::libc::{c_void, size_t, c_int};
use core::libc;
use core::vec;
use std::libc::{c_void, size_t, c_int};
use std::libc;
use std::vec;
pub mod rustrt {
use core::libc::{c_int, c_void, size_t};
use std::libc::{c_int, c_void, size_t};
#[link_name = "rustrt"]
pub extern {
@ -44,8 +44,8 @@ static lz_fast : c_int = 0x1; // LZ with only one probe
static lz_norm : c_int = 0x80; // LZ with 128 probes, "normal"
static lz_best : c_int = 0xfff; // LZ with 4095 probes, "best"
pub fn deflate_bytes(bytes: &const [u8]) -> ~[u8] {
do vec::as_const_buf(bytes) |b, len| {
pub fn deflate_bytes(bytes: &[u8]) -> ~[u8] {
do vec::as_imm_buf(bytes) |b, len| {
unsafe {
let mut outsz : size_t = 0;
let res =
@ -62,8 +62,8 @@ pub fn deflate_bytes(bytes: &const [u8]) -> ~[u8] {
}
}
pub fn inflate_bytes(bytes: &const [u8]) -> ~[u8] {
do vec::as_const_buf(bytes) |b, len| {
pub fn inflate_bytes(bytes: &[u8]) -> ~[u8] {
do vec::as_imm_buf(bytes) |b, len| {
unsafe {
let mut outsz : size_t = 0;
let res =
@ -83,9 +83,8 @@ pub fn inflate_bytes(bytes: &const [u8]) -> ~[u8] {
#[cfg(test)]
mod tests {
use super::*;
use core::rand;
use core::rand::RngUtil;
use core::prelude::*;
use std::rand;
use std::rand::RngUtil;
#[test]
#[allow(non_implicitly_copyable_typarams)]

View file

@ -49,14 +49,13 @@ block the scheduler thread, so will their pipes.
#[allow(missing_doc)];
use core::prelude::*;
// The basic send/recv interface FlatChan and PortChan will implement
use core::io;
use core::comm::GenericChan;
use core::comm::GenericPort;
use core::sys::size_of;
use core::vec;
use std::io;
use std::comm::GenericChan;
use std::comm::GenericPort;
use std::sys::size_of;
use std::vec;
/**
A FlatPort, consisting of a `BytePort` that receives byte vectors,
@ -95,9 +94,9 @@ pub mod serial {
use flatpipes::bytepipes::{PipeBytePort, PipeByteChan};
use flatpipes::{FlatPort, FlatChan};
use core::io::{Reader, Writer};
use core::comm::{Port, Chan};
use core::comm;
use std::io::{Reader, Writer};
use std::comm::{Port, Chan};
use std::comm;
pub type ReaderPort<T, R> = FlatPort<
T, DeserializingUnflattener<DefaultDecoder, T>,
@ -166,22 +165,21 @@ Constructors for flat pipes that send POD types using memcpy.
# Safety Note
This module is currently unsafe because it uses `Copy Owned` as a type
parameter bounds meaning POD (plain old data), but `Copy Owned` and
This module is currently unsafe because it uses `Copy Send` as a type
parameter bounds meaning POD (plain old data), but `Copy Send` and
POD are not equivelant.
*/
pub mod pod {
use core::prelude::*;
use flatpipes::flatteners::{PodUnflattener, PodFlattener};
use flatpipes::bytepipes::{ReaderBytePort, WriterByteChan};
use flatpipes::bytepipes::{PipeBytePort, PipeByteChan};
use flatpipes::{FlatPort, FlatChan};
use core::io::{Reader, Writer};
use core::comm::{Port, Chan};
use core::comm;
use std::io::{Reader, Writer};
use std::comm::{Port, Chan};
use std::comm;
pub type ReaderPort<T, R> =
FlatPort<T, PodUnflattener<T>, ReaderBytePort<R>>;
@ -191,7 +189,7 @@ pub mod pod {
pub type PipeChan<T> = FlatChan<T, PodFlattener<T>, PipeByteChan>;
/// Create a `FlatPort` from a `Reader`
pub fn reader_port<T:Copy + Owned,R:Reader>(
pub fn reader_port<T:Copy + Send,R:Reader>(
reader: R
) -> ReaderPort<T, R> {
let unflat: PodUnflattener<T> = PodUnflattener::new();
@ -200,7 +198,7 @@ pub mod pod {
}
/// Create a `FlatChan` from a `Writer`
pub fn writer_chan<T:Copy + Owned,W:Writer>(
pub fn writer_chan<T:Copy + Send,W:Writer>(
writer: W
) -> WriterChan<T, W> {
let flat: PodFlattener<T> = PodFlattener::new();
@ -209,21 +207,21 @@ pub mod pod {
}
/// Create a `FlatPort` from a `Port<~[u8]>`
pub fn pipe_port<T:Copy + Owned>(port: Port<~[u8]>) -> PipePort<T> {
pub fn pipe_port<T:Copy + Send>(port: Port<~[u8]>) -> PipePort<T> {
let unflat: PodUnflattener<T> = PodUnflattener::new();
let byte_port = PipeBytePort::new(port);
FlatPort::new(unflat, byte_port)
}
/// Create a `FlatChan` from a `Chan<~[u8]>`
pub fn pipe_chan<T:Copy + Owned>(chan: Chan<~[u8]>) -> PipeChan<T> {
pub fn pipe_chan<T:Copy + Send>(chan: Chan<~[u8]>) -> PipeChan<T> {
let flat: PodFlattener<T> = PodFlattener::new();
let byte_chan = PipeByteChan::new(chan);
FlatChan::new(flat, byte_chan)
}
/// Create a pair of `FlatChan` and `FlatPort`, backed by pipes
pub fn pipe_stream<T:Copy + Owned>() -> (PipePort<T>, PipeChan<T>) {
pub fn pipe_stream<T:Copy + Send>() -> (PipePort<T>, PipeChan<T>) {
let (port, chan) = comm::stream();
return (pipe_port(port), pipe_chan(chan));
}
@ -307,11 +305,11 @@ impl<T,U:Unflattener<T>,P:BytePort> GenericPort<T> for FlatPort<T, U, P> {
impl<T,F:Flattener<T>,C:ByteChan> GenericChan<T> for FlatChan<T, F, C> {
fn send(&self, val: T) {
self.byte_chan.send(CONTINUE.to_vec());
self.byte_chan.send(CONTINUE.to_owned());
let bytes = self.flattener.flatten(val);
let len = bytes.len() as u64;
do io::u64_to_be_bytes(len, size_of::<u64>()) |len_bytes| {
self.byte_chan.send(len_bytes.to_vec());
self.byte_chan.send(len_bytes.to_owned());
}
self.byte_chan.send(bytes);
}
@ -337,7 +335,6 @@ impl<T,F:Flattener<T>,C:ByteChan> FlatChan<T, F, C> {
pub mod flatteners {
use core::prelude::*;
use ebml;
use flatpipes::{Flattener, Unflattener};
@ -345,14 +342,14 @@ pub mod flatteners {
use json;
use serialize::{Encoder, Decoder, Encodable, Decodable};
use core::cast;
use core::io::{Writer, Reader, ReaderUtil};
use core::io;
use core::ptr;
use core::sys::size_of;
use core::vec;
use std::cast;
use std::io::{Writer, Reader, ReaderUtil};
use std::io;
use std::ptr;
use std::sys::size_of;
use std::vec;
// FIXME #4074: Copy + Owned != POD
// FIXME #4074: Copy + Send != POD
pub struct PodUnflattener<T> {
bogus: ()
}
@ -361,7 +358,7 @@ pub mod flatteners {
bogus: ()
}
impl<T:Copy + Owned> Unflattener<T> for PodUnflattener<T> {
impl<T:Copy + Send> Unflattener<T> for PodUnflattener<T> {
fn unflatten(&self, buf: ~[u8]) -> T {
assert!(size_of::<T>() != 0);
assert_eq!(size_of::<T>(), buf.len());
@ -371,7 +368,7 @@ pub mod flatteners {
}
}
impl<T:Copy + Owned> Flattener<T> for PodFlattener<T> {
impl<T:Copy + Send> Flattener<T> for PodFlattener<T> {
fn flatten(&self, val: T) -> ~[u8] {
assert!(size_of::<T>() != 0);
let val: *T = ptr::to_unsafe_ptr(&val);
@ -380,7 +377,7 @@ pub mod flatteners {
}
}
impl<T:Copy + Owned> PodUnflattener<T> {
impl<T:Copy + Send> PodUnflattener<T> {
pub fn new() -> PodUnflattener<T> {
PodUnflattener {
bogus: ()
@ -388,7 +385,7 @@ pub mod flatteners {
}
}
impl<T:Copy + Owned> PodFlattener<T> {
impl<T:Copy + Send> PodFlattener<T> {
pub fn new() -> PodFlattener<T> {
PodFlattener {
bogus: ()
@ -509,13 +506,12 @@ pub mod flatteners {
}
pub mod bytepipes {
use core::prelude::*;
use flatpipes::{ByteChan, BytePort};
use core::comm::{Port, Chan};
use core::comm;
use core::io::{Writer, Reader, ReaderUtil};
use std::comm::{Port, Chan};
use std::comm;
use std::io::{Writer, Reader, ReaderUtil};
pub struct ReaderBytePort<R> {
reader: R
@ -583,12 +579,12 @@ pub mod bytepipes {
impl BytePort for PipeBytePort {
fn try_recv(&self, count: uint) -> Option<~[u8]> {
if self.buf.len() >= count {
let mut bytes = ::core::util::replace(&mut *self.buf, ~[]);
let mut bytes = ::std::util::replace(&mut *self.buf, ~[]);
*self.buf = bytes.slice(count, bytes.len()).to_owned();
bytes.truncate(count);
return Some(bytes);
} else if !self.buf.is_empty() {
let mut bytes = ::core::util::replace(&mut *self.buf, ~[]);
let mut bytes = ::std::util::replace(&mut *self.buf, ~[]);
assert!(count > bytes.len());
match self.try_recv(count - bytes.len()) {
Some(rest) => {
@ -637,7 +633,6 @@ pub mod bytepipes {
#[cfg(test)]
mod test {
use core::prelude::*;
use flatpipes::{Flattener, Unflattener};
use flatpipes::bytepipes::*;
@ -647,11 +642,11 @@ mod test {
use flatpipes::{BytePort, FlatChan, FlatPort};
use net::tcp::TcpSocketBuf;
use core::comm;
use core::int;
use core::io::BytesWriter;
use core::result;
use core::task;
use std::comm;
use std::int;
use std::io::BytesWriter;
use std::result;
use std::task;
#[test]
#[ignore(reason = "ebml failure")]
@ -772,7 +767,7 @@ mod test {
writer_chan: WriterChanFactory<F>,
port: uint) {
use core::cell::Cell;
use std::cell::Cell;
use net::ip;
use net::tcp;
use uv;
@ -871,17 +866,16 @@ mod test {
// Tests that the different backends behave the same when the
// binary streaming protocol is broken
mod broken_protocol {
use core::prelude::*;
use flatpipes::{BytePort, FlatPort};
use flatpipes::flatteners::PodUnflattener;
use flatpipes::pod;
use io_util::BufReader;
use core::comm;
use core::io;
use core::sys;
use core::task;
use std::comm;
use std::io;
use std::sys;
use std::task;
type PortLoader<P> =
~fn(~[u8]) -> FlatPort<int, PodUnflattener<int>, P>;
@ -937,7 +931,7 @@ mod test {
fn test_try_recv_none3<P:BytePort>(loader: PortLoader<P>) {
static CONTINUE: [u8, ..4] = [0xAA, 0xBB, 0xCC, 0xDD];
// The control word is followed by garbage
let bytes = CONTINUE.to_vec() + [0];
let bytes = CONTINUE.to_owned() + [0];
let port = loader(bytes);
let res: Option<int> = port.try_recv();
assert!(res.is_none());
@ -959,9 +953,9 @@ mod test {
// then undeserializable garbage
let len_bytes = do io::u64_to_be_bytes(
1, sys::size_of::<u64>()) |len_bytes| {
len_bytes.to_vec()
len_bytes.to_owned()
};
let bytes = CONTINUE.to_vec() + len_bytes + [0, 0, 0, 0];
let bytes = CONTINUE.to_owned() + len_bytes + [0, 0, 0, 0];
let port = loader(bytes);

View file

@ -19,10 +19,9 @@
* of features.
*/
use core::prelude::*;
use core::cmp::{Eq, Ord};
use core::option::{Some, None};
use std::cmp::{Eq, Ord};
use std::option::{Some, None};
pub type Treemap<K, V> = @TreeNode<K, V>;
@ -66,9 +65,9 @@ pub fn traverse<K, V: Copy>(m: Treemap<K, V>, f: &fn(&K, &V)) {
// matches to me, so I changed it. but that may be a
// de-optimization -- tjc
Node(@ref k, @ref v, left, right) => {
traverse(left, f);
traverse(left, |k,v| f(k,v));
f(k, v);
traverse(right, f);
traverse(right, |k,v| f(k,v));
}
}
}

View file

@ -17,7 +17,7 @@
* ~~~ {.rust}
* # fn fib(n: uint) -> uint {42};
* # fn make_a_sandwich() {};
* let mut delayed_fib = std::future::spawn (|| fib(5000) );
* let mut delayed_fib = extra::future::spawn (|| fib(5000) );
* make_a_sandwich();
* println(fmt!("fib(5000) = %?", delayed_fib.get()))
* ~~~
@ -25,13 +25,12 @@
#[allow(missing_doc)];
use core::prelude::*;
use core::cast;
use core::cell::Cell;
use core::comm::{PortOne, oneshot, send_one, recv_one};
use core::task;
use core::util::replace;
use std::cast;
use std::cell::Cell;
use std::comm::{PortOne, oneshot, send_one, recv_one};
use std::task;
use std::util::replace;
#[doc = "The future type"]
pub struct Future<A> {
@ -44,7 +43,7 @@ pub struct Future<A> {
// over ~fn's that have pipes and so forth within!
#[unsafe_destructor]
impl<A> Drop for Future<A> {
fn finalize(&self) {}
fn drop(&self) {}
}
priv enum FutureState<A> {
@ -101,7 +100,7 @@ pub fn from_value<A>(val: A) -> Future<A> {
Future {state: Forced(val)}
}
pub fn from_port<A:Owned>(port: PortOne<A>) -> Future<A> {
pub fn from_port<A:Send>(port: PortOne<A>) -> Future<A> {
/*!
* Create a future from a port
*
@ -127,7 +126,7 @@ pub fn from_fn<A>(f: ~fn() -> A) -> Future<A> {
Future {state: Pending(f)}
}
pub fn spawn<A:Owned>(blk: ~fn() -> A) -> Future<A> {
pub fn spawn<A:Send>(blk: ~fn() -> A) -> Future<A> {
/*!
* Create a future from a unique closure.
*
@ -151,9 +150,9 @@ pub fn spawn<A:Owned>(blk: ~fn() -> A) -> Future<A> {
mod test {
use future::*;
use core::cell::Cell;
use core::comm::{oneshot, send_one};
use core::task;
use std::cell::Cell;
use std::comm::{oneshot, send_one};
use std::task;
#[test]
fn test_from_value() {

View file

@ -81,14 +81,13 @@
#[allow(missing_doc)];
use core::prelude::*;
use core::cmp::Eq;
use core::result::{Err, Ok};
use core::result;
use core::option::{Some, None};
use core::str;
use core::vec;
use std::cmp::Eq;
use std::result::{Err, Ok};
use std::result;
use std::option::{Some, None};
use std::str;
use std::vec;
#[deriving(Eq)]
pub enum Name {
@ -177,7 +176,7 @@ fn name_str(nm: &Name) -> ~str {
}
fn find_opt(opts: &[Opt], nm: Name) -> Option<uint> {
vec::position(opts, |opt| opt.name == nm)
opts.iter().position_(|opt| opt.name == nm)
}
/**
@ -295,7 +294,7 @@ pub fn getopts(args: &[~str], opts: &[Opt]) -> Result {
}
}
let mut name_pos = 0;
for names.each() |nm| {
for names.iter().advance() |nm| {
name_pos += 1;
let optid = match find_opt(opts, copy *nm) {
Some(id) => id,
@ -373,7 +372,7 @@ pub fn opt_count(mm: &Matches, nm: &str) -> uint {
/// Returns true if any of several options were matched
pub fn opts_present(mm: &Matches, names: &[~str]) -> bool {
for names.each |nm| {
for names.iter().advance |nm| {
match find_opt(mm.opts, mkname(*nm)) {
Some(id) if !mm.vals[id].is_empty() => return true,
_ => (),
@ -400,7 +399,7 @@ pub fn opt_str(mm: &Matches, nm: &str) -> ~str {
* option took an argument
*/
pub fn opts_str(mm: &Matches, names: &[~str]) -> ~str {
for names.each |nm| {
for names.iter().advance |nm| {
match opt_val(mm, *nm) {
Val(ref s) => return copy *s,
_ => ()
@ -418,10 +417,11 @@ pub fn opts_str(mm: &Matches, names: &[~str]) -> ~str {
*/
pub fn opt_strs(mm: &Matches, nm: &str) -> ~[~str] {
let mut acc: ~[~str] = ~[];
for vec::each(opt_vals(mm, nm)) |v| {
let r = opt_vals(mm, nm);
for r.iter().advance |v| {
match *v { Val(ref s) => acc.push(copy *s), _ => () }
}
return acc;
acc
}
/// Returns the string argument supplied to a matching option or none
@ -465,8 +465,8 @@ pub mod groups {
use getopts::{HasArg, Long, Maybe, Multi, No, Occur, Opt, Optional, Req};
use getopts::{Short, Yes};
use core::str;
use core::vec;
use std::str;
use std::vec;
/** one group of options, e.g., both -h and --help, along with
* their shared description and properties
@ -592,9 +592,9 @@ pub mod groups {
*/
pub fn usage(brief: &str, opts: &[OptGroup]) -> ~str {
let desc_sep = ~"\n" + " ".repeat(24);
let desc_sep = "\n" + " ".repeat(24);
let rows = vec::map(opts, |optref| {
let mut rows = opts.iter().transform(|optref| {
let OptGroup{short_name: short_name,
long_name: long_name,
hint: hint,
@ -605,33 +605,47 @@ pub mod groups {
let mut row = " ".repeat(4);
// short option
row += match short_name.len() {
0 => ~"",
1 => ~"-" + short_name + " ",
match short_name.len() {
0 => {}
1 => {
row.push_char('-');
row.push_str(short_name);
row.push_char(' ');
}
_ => fail!("the short name should only be 1 ascii char long"),
};
}
// long option
row += match long_name.len() {
0 => ~"",
_ => ~"--" + long_name + " ",
};
match long_name.len() {
0 => {}
_ => {
row.push_str("--");
row.push_str(long_name);
row.push_char(' ');
}
}
// arg
row += match hasarg {
No => ~"",
Yes => hint,
Maybe => ~"[" + hint + "]",
};
match hasarg {
No => {}
Yes => row.push_str(hint),
Maybe => {
row.push_char('[');
row.push_str(hint);
row.push_char(']');
}
}
// FIXME: #5516
// here we just need to indent the start of the description
let rowlen = row.len();
row += if rowlen < 24 {
" ".repeat(24 - rowlen)
if rowlen < 24 {
for (24 - rowlen).times {
row.push_char(' ')
}
} else {
copy desc_sep
};
row.push_str(desc_sep)
}
// Normalize desc to contain words separated by one space character
let mut desc_normalized_whitespace = ~"";
@ -648,14 +662,14 @@ pub mod groups {
// FIXME: #5516
// wrapped description
row += desc_rows.connect(desc_sep);
row.push_str(desc_rows.connect(desc_sep));
row
});
return str::to_owned(brief) +
"\n\nOptions:\n" +
rows.connect("\n") +
rows.collect::<~[~str]>().connect("\n") +
"\n\n";
}
} // end groups module
@ -666,8 +680,8 @@ mod tests {
use getopts::groups::OptGroup;
use getopts::*;
use core::result::{Err, Ok};
use core::result;
use std::result::{Err, Ok};
use std::result;
fn check_fail_type(f: Fail_, ft: FailType) {
match f {

View file

@ -8,8 +8,9 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use core::io::{Reader, BytesReader};
use core::io;
use std::io::{Reader, BytesReader};
use std::io;
use std::cast;
/// An implementation of the io::Reader interface which reads a buffer of bytes
pub struct BufReader {
@ -29,10 +30,13 @@ impl BufReader {
}
fn as_bytes_reader<A>(&self, f: &fn(&BytesReader) -> A) -> A {
// XXX FIXME(#5723)
let bytes = ::std::util::id::<&[u8]>(self.buf);
let bytes: &'static [u8] = unsafe { cast::transmute(bytes) };
// Recreating the BytesReader state every call since
// I can't get the borrowing to work correctly
let bytes_reader = BytesReader {
bytes: ::core::util::id::<&[u8]>(self.buf),
bytes: bytes,
pos: @mut *self.pos
};

View file

@ -16,16 +16,15 @@
//! json serialization
use core::prelude::*;
use core::char;
use core::float;
use core::hashmap::HashMap;
use core::io::{WriterUtil, ReaderUtil};
use core::io;
use core::str;
use core::to_str;
use core::vec;
use std::char;
use std::float;
use std::hashmap::HashMap;
use std::io::{WriterUtil, ReaderUtil};
use std::io;
use std::str;
use std::to_str;
use std::vec;
use serialize::Encodable;
use serialize;
@ -60,25 +59,27 @@ fn escape_str(s: &str) -> ~str {
let mut escaped = ~"\"";
for s.iter().advance |c| {
match c {
'"' => escaped += "\\\"",
'\\' => escaped += "\\\\",
'\x08' => escaped += "\\b",
'\x0c' => escaped += "\\f",
'\n' => escaped += "\\n",
'\r' => escaped += "\\r",
'\t' => escaped += "\\t",
_ => escaped += str::from_char(c)
'"' => escaped.push_str("\\\""),
'\\' => escaped.push_str("\\\\"),
'\x08' => escaped.push_str("\\b"),
'\x0c' => escaped.push_str("\\f"),
'\n' => escaped.push_str("\\n"),
'\r' => escaped.push_str("\\r"),
'\t' => escaped.push_str("\\t"),
_ => escaped.push_char(c),
}
};
escaped += "\"";
escaped.push_char('"');
escaped
}
fn spaces(n: uint) -> ~str {
let mut ss = ~"";
for n.times { ss.push_str(" "); }
for n.times {
ss.push_str(" ");
}
return ss;
}
@ -950,7 +951,7 @@ impl serialize::Decoder for Decoder {
}
ref json => fail!("invalid variant: %?", *json),
};
let idx = match vec::position(names, |n| str::eq_slice(*n, name)) {
let idx = match names.iter().position_(|n| str::eq_slice(*n, name)) {
Some(idx) => idx,
None => fail!("Unknown variant name: %?", name),
};
@ -1123,7 +1124,7 @@ impl Eq for Json {
&Object(ref d1) => {
if d0.len() == d1.len() {
let mut equal = true;
for d0.each |k, v0| {
for d0.iter().advance |(k, v0)| {
match d1.find(k) {
Some(v1) if v0 == v1 => { },
_ => { equal = false; break }
@ -1186,12 +1187,12 @@ impl Ord for Json {
let mut d1_flat = ~[];
// FIXME #4430: this is horribly inefficient...
for d0.each |k, v| {
for d0.iter().advance |(k, v)| {
d0_flat.push((@copy *k, @copy *v));
}
d0_flat.qsort();
for d1.each |k, v| {
for d1.iter().advance |(k, v)| {
d1_flat.push((@copy *k, @copy *v));
}
d1_flat.qsort();
@ -1326,7 +1327,7 @@ impl<A:ToJson> ToJson for ~[A] {
impl<A:ToJson + Copy> ToJson for HashMap<~str, A> {
fn to_json(&self) -> Json {
let mut d = HashMap::new();
for self.each |key, value| {
for self.iter().advance |(key, value)| {
d.insert(copy *key, value.to_json());
}
Object(~d)
@ -1354,15 +1355,14 @@ impl to_str::ToStr for Error {
#[cfg(test)]
mod tests {
use core::prelude::*;
use super::*;
use core::hashmap::HashMap;
use core::io;
use core::result;
use std::hashmap::HashMap;
use std::io;
use std::result;
use std::serialize::Decodable;
use extra::serialize::Decodable;
#[deriving(Eq, Encodable, Decodable)]
enum Animal {
@ -1385,7 +1385,7 @@ mod tests {
fn mk_object(items: &[(~str, Json)]) -> Json {
let mut d = ~HashMap::new();
for items.each |item| {
for items.iter().advance |item| {
match *item {
(ref key, ref value) => { d.insert(copy *key, copy *value); },
}

View file

@ -10,7 +10,6 @@
//! A standard, garbage-collected linked list.
use core::prelude::*;
#[deriving(Eq)]
@ -181,7 +180,7 @@ mod tests {
use list::*;
use list;
use core::option;
use std::option;
#[test]
fn test_is_empty() {

View file

@ -8,10 +8,9 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use core::prelude::*;
use core::uint;
use core::vec;
use std::uint;
use std::vec;
struct Quad {
a: u32,
@ -59,7 +58,8 @@ pub fn md4(msg: &[u8]) -> Quad {
while i < e {
let (aa, bb, cc, dd) = (a, b, c, d);
let mut (j, base) = (0u, i);
let mut j = 0u;
let mut base = i;
while j < 16u {
x[j] = (msg[base] as u32) + (msg[base + 1u] as u32 << 8u32) +
(msg[base + 2u] as u32 << 16u32) +
@ -118,8 +118,10 @@ pub fn md4_str(msg: &[u8]) -> ~str {
let mut i = 0u32;
while i < 4u32 {
let byte = (u >> (i * 8u32)) as u8;
if byte <= 16u8 { result += "0"; }
result += uint::to_str_radix(byte as uint, 16u);
if byte <= 16u8 {
result.push_char('0')
}
result.push_str(uint::to_str_radix(byte as uint, 16u));
i += 1u32;
}
}

View file

@ -12,13 +12,12 @@
#[allow(missing_doc)];
use core::prelude::*;
use core::libc;
use core::comm::{stream, SharedChan};
use core::ptr;
use core::result;
use core::str;
use std::libc;
use std::comm::{stream, SharedChan};
use std::ptr;
use std::result;
use std::str;
use iotask = uv::iotask::IoTask;
use interact = uv::iotask::interact;
@ -55,7 +54,7 @@ pub struct ParseAddrErr {
*
* # Arguments
*
* * ip - a `std::net::ip::IpAddr`
* * ip - a `extra::net::ip::IpAddr`
*/
pub fn format_addr(ip: &IpAddr) -> ~str {
match *ip {
@ -80,7 +79,7 @@ pub fn format_addr(ip: &IpAddr) -> ~str {
* Get the associated port
*
* # Arguments
* * ip - a `std::net::ip::IpAddr`
* * ip - a `extra::net::ip::IpAddr`
*/
pub fn get_port(ip: &IpAddr) -> uint {
match *ip {
@ -149,16 +148,15 @@ pub fn get_addr(node: &str, iotask: &iotask)
}
pub mod v4 {
use core::prelude::*;
use net::ip::{IpAddr, Ipv4, ParseAddrErr};
use uv::ll;
use uv_ip4_addr = uv::ll::ip4_addr;
use uv_ip4_name = uv::ll::ip4_name;
use core::cast::transmute;
use core::result;
use core::uint;
use std::cast::transmute;
use std::result;
use std::uint;
/**
* Convert a str to `ip_addr`
@ -205,7 +203,7 @@ pub mod v4 {
}).collect();
if parts.len() != 4 {
Err(fmt!("'%s' doesn't have 4 parts", ip))
} else if parts.contains(&256) {
} else if parts.iter().any_(|x| *x == 256u) {
Err(fmt!("invalid octal in addr '%s'", ip))
} else {
Ok(Ipv4Rep {
@ -248,13 +246,12 @@ pub mod v4 {
}
}
pub mod v6 {
use core::prelude::*;
use net::ip::{IpAddr, Ipv6, ParseAddrErr};
use uv_ip6_addr = uv::ll::ip6_addr;
use uv_ip6_name = uv::ll::ip6_name;
use core::result;
use std::result;
/**
* Convert a str to `ip_addr`
@ -371,7 +368,7 @@ mod test {
use net_ip::v6;
use uv;
use core::result;
use std::result;
#[test]
fn test_ip_ipv4_parse_and_format_ip() {
@ -426,7 +423,7 @@ mod test {
let results = result::unwrap(ga_result);
debug!("test_get_addr: Number of results for %s: %?",
localhost_name, results.len());
for results.each |r| {
for results.iter().advance |r| {
let ipv_prefix = match *r {
Ipv4(_) => ~"IPv4",
Ipv6(_) => ~"IPv6"

View file

@ -13,7 +13,6 @@
#[allow(missing_doc)];
use core::prelude::*;
use future;
use future_spawn = future::spawn;
@ -22,18 +21,18 @@ use uv;
use uv::iotask;
use uv::iotask::IoTask;
use core::io;
use core::libc::size_t;
use core::libc;
use core::comm::{stream, Port, SharedChan};
use core::ptr;
use core::result::{Result};
use core::result;
use core::uint;
use core::vec;
use std::io;
use std::libc::size_t;
use std::libc;
use std::comm::{stream, Port, SharedChan};
use std::ptr;
use std::result::{Result};
use std::result;
use std::uint;
use std::vec;
pub mod rustrt {
use core::libc;
use std::libc;
#[nolink]
pub extern {
@ -57,7 +56,7 @@ pub struct TcpSocket {
#[unsafe_destructor]
impl Drop for TcpSocket {
fn finalize(&self) {
fn drop(&self) {
tear_down_socket_data(self.socket_data)
}
}
@ -360,7 +359,7 @@ pub fn write_future(sock: &TcpSocket, raw_write_data: ~[u8])
* # Returns
*
* * A `Result` instance that will either contain a
* `core::comm::Port<Result<~[u8], TcpErrData>>` that the user can read
* `std::comm::Port<Result<~[u8], TcpErrData>>` that the user can read
* (and * optionally, loop on) from until `read_stop` is called, or a
* `TcpErrData` record
*/
@ -619,7 +618,7 @@ pub fn accept(new_conn: TcpNewConnection)
* callback's arguments are:
* * `new_conn` - an opaque type that can be passed to
* `net::tcp::accept` in order to be converted to a `TcpSocket`.
* * `kill_ch` - channel of type `core::comm::Chan<Option<tcp_err_data>>`.
* * `kill_ch` - channel of type `std::comm::Chan<Option<tcp_err_data>>`.
* this channel can be used to send a message to cause `listen` to begin
* closing the underlying libuv data structures.
*
@ -683,7 +682,7 @@ fn listen_common(host_ip: ip::IpAddr,
// will defeat a move sigil, as is done to the host_ip
// arg above.. this same pattern works w/o complaint in
// tcp::connect (because the iotask::interact cb isn't
// nested within a core::comm::listen block)
// nested within a std::comm::listen block)
let loc_ip = copy(host_ip);
do iotask::interact(iotask) |loop_ptr| {
unsafe {
@ -976,9 +975,7 @@ impl io::Writer for TcpSocketBuf {
let socket_data_ptr: *TcpSocketData =
&(*((*(self.data)).sock).socket_data);
let w_result = write_common_impl(socket_data_ptr,
vec::slice(data,
0,
data.len()).to_vec());
data.slice(0, data.len()).to_owned());
if w_result.is_err() {
let err_data = w_result.get_err();
debug!(
@ -1431,7 +1428,6 @@ struct TcpBufferedSocketData {
#[cfg(test)]
mod test {
use core::prelude::*;
use net::ip;
use net::tcp::{GenericListenErr, TcpConnectErrData, TcpListenErrData};
@ -1440,12 +1436,12 @@ mod test {
use uv::iotask::IoTask;
use uv;
use core::cell::Cell;
use core::comm::{stream, SharedChan};
use core::io;
use core::result;
use core::str;
use core::task;
use std::cell::Cell;
use std::comm::{stream, SharedChan};
use std::io;
use std::result;
use std::str;
use std::task;
// FIXME don't run on fbsd or linux 32 bit (#2064)
#[cfg(target_os="win32")]
@ -1459,33 +1455,23 @@ mod test {
#[test]
fn test_gl_tcp_server_and_client_ipv4() {
unsafe {
impl_gl_tcp_ipv4_server_and_client();
}
impl_gl_tcp_ipv4_server_and_client();
}
#[test]
fn test_gl_tcp_get_peer_addr() {
unsafe {
impl_gl_tcp_ipv4_get_peer_addr();
}
impl_gl_tcp_ipv4_get_peer_addr();
}
#[test]
fn test_gl_tcp_ipv4_client_error_connection_refused() {
unsafe {
impl_gl_tcp_ipv4_client_error_connection_refused();
}
impl_gl_tcp_ipv4_client_error_connection_refused();
}
#[test]
fn test_gl_tcp_server_address_in_use() {
unsafe {
impl_gl_tcp_ipv4_server_address_in_use();
}
impl_gl_tcp_ipv4_server_address_in_use();
}
#[test]
fn test_gl_tcp_server_access_denied() {
unsafe {
impl_gl_tcp_ipv4_server_access_denied();
}
impl_gl_tcp_ipv4_server_access_denied();
}
// Strange failure on Windows. --pcwalton
#[test]
@ -1757,7 +1743,7 @@ mod test {
}
pub fn impl_tcp_socket_impl_reader_handles_eof() {
use core::io::{Reader,ReaderUtil};
use std::io::{Reader,ReaderUtil};
let hl_loop = &uv::global_loop::get();
let server_ip = "127.0.0.1";

View file

@ -12,14 +12,13 @@
#[allow(missing_doc)];
use core::prelude::*;
use core::cmp::Eq;
use core::io::{Reader, ReaderUtil};
use core::io;
use core::hashmap::HashMap;
use core::to_bytes;
use core::uint;
use std::cmp::Eq;
use std::io::{Reader, ReaderUtil};
use std::io;
use std::hashmap::HashMap;
use std::to_bytes;
use std::uint;
#[deriving(Clone, Eq)]
struct Url {
@ -93,10 +92,10 @@ fn encode_inner(s: &str, full_url: bool) -> ~str {
out.push_char(ch);
}
_ => out += fmt!("%%%X", ch as uint)
_ => out.push_str(fmt!("%%%X", ch as uint))
}
} else {
out += fmt!("%%%X", ch as uint);
out.push_str(fmt!("%%%X", ch as uint));
}
}
}
@ -192,7 +191,7 @@ fn encode_plus(s: &str) -> ~str {
out.push_char(ch);
}
' ' => out.push_char('+'),
_ => out += fmt!("%%%X", ch as uint)
_ => out.push_str(fmt!("%%%X", ch as uint))
}
}
@ -207,10 +206,10 @@ pub fn encode_form_urlencoded(m: &HashMap<~str, ~[~str]>) -> ~str {
let mut out = ~"";
let mut first = true;
for m.each |key, values| {
for m.iter().advance |(key, values)| {
let key = encode_plus(*key);
for values.each |value| {
for values.iter().advance |value| {
if first {
first = false;
} else {
@ -218,7 +217,7 @@ pub fn encode_form_urlencoded(m: &HashMap<~str, ~[~str]>) -> ~str {
first = false;
}
out += fmt!("%s=%s", key, encode_plus(*value));
out.push_str(fmt!("%s=%s", key, encode_plus(*value)));
}
}
@ -342,7 +341,7 @@ fn query_from_str(rawquery: &str) -> Query {
pub fn query_to_str(query: &Query) -> ~str {
let mut strvec = ~[];
for query.each |kv| {
for query.iter().advance |kv| {
match kv {
&(ref k, ref v) => {
strvec.push(fmt!("%s=%s",
@ -415,7 +414,9 @@ fn get_authority(rawurl: &str) ->
let mut port = None;
let mut colon_count = 0;
let mut (pos, begin, end) = (0, 2, len);
let mut pos = 0;
let mut begin = 2;
let mut end = len;
for rawurl.iter().enumerate().advance |(i,c)| {
if i < 2 { loop; } // ignore the leading //
@ -519,8 +520,9 @@ fn get_authority(rawurl: &str) ->
let end = end; // make end immutable so it can be captured
let host_is_end_plus_one: &fn() -> bool = || {
let xs = ['?', '#', '/'];
end+1 == len
&& !['?', '#', '/'].contains(&(rawurl[end] as char))
&& !xs.iter().any_(|x| *x == (rawurl[end] as char))
};
// finish up
@ -800,7 +802,7 @@ mod tests {
use net_url::*;
use core::hashmap::HashMap;
use std::hashmap::HashMap;
#[test]
fn test_url_parse() {

View file

@ -18,13 +18,12 @@ A BigInt is a combination of BigUint and Sign.
#[allow(missing_doc)];
use core::prelude::*;
use core::cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater};
use core::int;
use core::num::{IntConvertible, Zero, One, ToStrRadix, FromStrRadix, Orderable};
use core::str;
use core::uint;
use core::vec;
use std::cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater};
use std::int;
use std::num::{IntConvertible, Zero, One, ToStrRadix, FromStrRadix, Orderable};
use std::str;
use std::uint;
use std::vec;
/**
A BigDigit is a BigUint's composing element.
@ -284,13 +283,13 @@ impl Mul<BigUint, BigUint> for BigUint {
if n == 1 { return copy *a; }
let mut carry = 0;
let prod = do vec::map(a.data) |ai| {
let prod = do a.data.iter().transform |ai| {
let (hi, lo) = BigDigit::from_uint(
(*ai as uint) * (n as uint) + (carry as uint)
);
carry = hi;
lo
};
}.collect::<~[BigDigit]>();
if carry == 0 { return BigUint::new(prod) };
return BigUint::new(prod + [carry]);
}
@ -298,9 +297,8 @@ impl Mul<BigUint, BigUint> for BigUint {
fn cut_at(a: &BigUint, n: uint) -> (BigUint, BigUint) {
let mid = uint::min(a.data.len(), n);
return (BigUint::from_slice(vec::slice(a.data, mid,
a.data.len())),
BigUint::from_slice(vec::slice(a.data, 0, mid)));
return (BigUint::from_slice(a.data.slice(mid, a.data.len())),
BigUint::from_slice(a.data.slice(0, mid)));
}
@ -381,7 +379,8 @@ impl Integer for BigUint {
let mut d = Zero::zero::<BigUint>();
let mut n = 1;
while m >= b {
let mut (d0, d_unit, b_unit) = div_estimate(&m, &b, n);
let (d0, d_unit, b_unit) = div_estimate(&m, &b, n);
let mut d0 = d0;
let mut prod = b * d0;
while prod > m {
// FIXME(#6050): overloaded operators force moves with generic types
@ -413,7 +412,7 @@ impl Integer for BigUint {
return (Zero::zero(), Zero::zero(), copy *a);
}
let an = vec::slice(a.data, a.data.len() - n, a.data.len());
let an = a.data.slice(a.data.len() - n, a.data.len());
let bn = *b.data.last();
let mut d = ~[];
let mut carry = 0;
@ -443,7 +442,8 @@ impl Integer for BigUint {
fn gcd(&self, other: &BigUint) -> BigUint {
// Use Euclid's algorithm
let mut (m, n) = (copy *self, copy *other);
let mut m = copy *self;
let mut n = copy *other;
while !m.is_zero() {
let temp = m;
m = n % temp;
@ -507,11 +507,11 @@ impl ToStrRadix for BigUint {
let mut m = n;
while m > divider {
let (d, m0) = m.div_mod_floor(&divider);
result += [m0.to_uint() as BigDigit];
result.push(m0.to_uint() as BigDigit);
m = d;
}
if !m.is_zero() {
result += [m.to_uint() as BigDigit];
result.push(m.to_uint() as BigDigit);
}
return result;
}
@ -578,7 +578,7 @@ impl BigUint {
let mut power: BigUint = One::one();
loop {
let start = uint::max(end, unit_len) - unit_len;
match uint::parse_bytes(vec::slice(buf, start, end), radix) {
match uint::parse_bytes(buf.slice(start, end), radix) {
// FIXME(#6102): Assignment operator for BigInt causes ICE
// Some(d) => n += BigUint::from_uint(d) * power,
Some(d) => n = n + BigUint::from_uint(d) * power,
@ -618,13 +618,13 @@ impl BigUint {
if n_bits == 0 || self.is_zero() { return copy *self; }
let mut carry = 0;
let shifted = do vec::map(self.data) |elem| {
let shifted = do self.data.iter().transform |elem| {
let (hi, lo) = BigDigit::from_uint(
(*elem as uint) << n_bits | (carry as uint)
);
carry = hi;
lo
};
}.collect::<~[BigDigit]>();
if carry == 0 { return BigUint::new(shifted); }
return BigUint::new(shifted + [carry]);
}
@ -634,7 +634,7 @@ impl BigUint {
if n_unit == 0 { return copy *self; }
if self.data.len() < n_unit { return Zero::zero(); }
return BigUint::from_slice(
vec::slice(self.data, n_unit, self.data.len())
self.data.slice(n_unit, self.data.len())
);
}
@ -1132,7 +1132,7 @@ impl BigInt {
sign = Minus;
start = 1;
}
return BigUint::parse_bytes(vec::slice(buf, start, buf.len()), radix)
return BigUint::parse_bytes(buf.slice(start, buf.len()), radix)
.map_consume(|bu| BigInt::from_biguint(sign, bu));
}
@ -1147,16 +1147,15 @@ impl BigInt {
#[cfg(test)]
mod biguint_tests {
use core::prelude::*;
use super::*;
use core::cmp::{Less, Equal, Greater};
use core::int;
use core::num::{IntConvertible, Zero, One, FromStrRadix};
use core::str;
use core::uint;
use core::vec;
use std::cmp::{Less, Equal, Greater};
use std::int;
use std::num::{IntConvertible, Zero, One, FromStrRadix};
use std::str;
use std::uint;
use std::vec;
#[test]
fn test_from_slice() {
@ -1173,10 +1172,10 @@ mod biguint_tests {
#[test]
fn test_cmp() {
let data = [ &[], &[1], &[2], &[-1], &[0, 1], &[2, 1], &[1, 1, 1] ]
let data: ~[BigUint] = [ &[], &[1], &[2], &[-1], &[0, 1], &[2, 1], &[1, 1, 1] ]
.map(|v| BigUint::from_slice(*v));
for data.eachi |i, ni| {
for vec::slice(data, i, data.len()).eachi |j0, nj| {
for data.iter().enumerate().advance |(i, ni)| {
for data.slice(i, data.len()).iter().enumerate().advance |(j0, nj)| {
let j = j0 + i;
if i == j {
assert_eq!(ni.cmp(nj), Equal);
@ -1349,7 +1348,7 @@ mod biguint_tests {
#[test]
fn test_add() {
for sum_triples.each |elm| {
for sum_triples.iter().advance |elm| {
let (aVec, bVec, cVec) = *elm;
let a = BigUint::from_slice(aVec);
let b = BigUint::from_slice(bVec);
@ -1362,7 +1361,7 @@ mod biguint_tests {
#[test]
fn test_sub() {
for sum_triples.each |elm| {
for sum_triples.iter().advance |elm| {
let (aVec, bVec, cVec) = *elm;
let a = BigUint::from_slice(aVec);
let b = BigUint::from_slice(bVec);
@ -1413,7 +1412,7 @@ mod biguint_tests {
#[test]
fn test_mul() {
for mul_triples.each |elm| {
for mul_triples.iter().advance |elm| {
let (aVec, bVec, cVec) = *elm;
let a = BigUint::from_slice(aVec);
let b = BigUint::from_slice(bVec);
@ -1423,7 +1422,7 @@ mod biguint_tests {
assert!(b * a == c);
}
for div_rem_quadruples.each |elm| {
for div_rem_quadruples.iter().advance |elm| {
let (aVec, bVec, cVec, dVec) = *elm;
let a = BigUint::from_slice(aVec);
let b = BigUint::from_slice(bVec);
@ -1437,7 +1436,7 @@ mod biguint_tests {
#[test]
fn test_div_rem() {
for mul_triples.each |elm| {
for mul_triples.iter().advance |elm| {
let (aVec, bVec, cVec) = *elm;
let a = BigUint::from_slice(aVec);
let b = BigUint::from_slice(bVec);
@ -1451,7 +1450,7 @@ mod biguint_tests {
}
}
for div_rem_quadruples.each |elm| {
for div_rem_quadruples.iter().advance |elm| {
let (aVec, bVec, cVec, dVec) = *elm;
let a = BigUint::from_slice(aVec);
let b = BigUint::from_slice(bVec);
@ -1567,9 +1566,10 @@ mod biguint_tests {
#[test]
fn test_to_str_radix() {
for to_str_pairs().each |num_pair| {
let r = to_str_pairs();
for r.iter().advance |num_pair| {
let &(n, rs) = num_pair;
for rs.each |str_pair| {
for rs.iter().advance |str_pair| {
let &(radix, str) = str_pair;
assert_eq!(n.to_str_radix(radix), str);
}
@ -1578,9 +1578,10 @@ mod biguint_tests {
#[test]
fn test_from_str_radix() {
for to_str_pairs().each |num_pair| {
let r = to_str_pairs();
for r.iter().advance |num_pair| {
let &(n, rs) = num_pair;
for rs.each |str_pair| {
for rs.iter().advance |str_pair| {
let &(radix, str) = str_pair;
assert_eq!(&n, &FromStrRadix::from_str_radix(str, radix).get());
}
@ -1620,15 +1621,14 @@ mod biguint_tests {
#[cfg(test)]
mod bigint_tests {
use core::prelude::*;
use super::*;
use core::cmp::{Less, Equal, Greater};
use core::int;
use core::num::{IntConvertible, Zero, One, FromStrRadix};
use core::uint;
use core::vec;
use std::cmp::{Less, Equal, Greater};
use std::int;
use std::num::{IntConvertible, Zero, One, FromStrRadix};
use std::uint;
use std::vec;
#[test]
fn test_from_biguint() {
@ -1651,8 +1651,8 @@ mod bigint_tests {
nums.push(Zero::zero());
nums.push_all_move(vs.map(|s| BigInt::from_slice(Plus, *s)));
for nums.eachi |i, ni| {
for vec::slice(nums, i, nums.len()).eachi |j0, nj| {
for nums.iter().enumerate().advance |(i, ni)| {
for nums.slice(i, nums.len()).iter().enumerate().advance |(j0, nj)| {
let j = i + j0;
if i == j {
assert_eq!(ni.cmp(nj), Equal);
@ -1756,7 +1756,7 @@ mod bigint_tests {
#[test]
fn test_add() {
for sum_triples.each |elm| {
for sum_triples.iter().advance |elm| {
let (aVec, bVec, cVec) = *elm;
let a = BigInt::from_slice(Plus, aVec);
let b = BigInt::from_slice(Plus, bVec);
@ -1775,7 +1775,7 @@ mod bigint_tests {
#[test]
fn test_sub() {
for sum_triples.each |elm| {
for sum_triples.iter().advance |elm| {
let (aVec, bVec, cVec) = *elm;
let a = BigInt::from_slice(Plus, aVec);
let b = BigInt::from_slice(Plus, bVec);
@ -1832,7 +1832,7 @@ mod bigint_tests {
#[test]
fn test_mul() {
for mul_triples.each |elm| {
for mul_triples.iter().advance |elm| {
let (aVec, bVec, cVec) = *elm;
let a = BigInt::from_slice(Plus, aVec);
let b = BigInt::from_slice(Plus, bVec);
@ -1845,7 +1845,7 @@ mod bigint_tests {
assert!((-b) * a == -c);
}
for div_rem_quadruples.each |elm| {
for div_rem_quadruples.iter().advance |elm| {
let (aVec, bVec, cVec, dVec) = *elm;
let a = BigInt::from_slice(Plus, aVec);
let b = BigInt::from_slice(Plus, bVec);
@ -1884,7 +1884,7 @@ mod bigint_tests {
}
}
for mul_triples.each |elm| {
for mul_triples.iter().advance |elm| {
let (aVec, bVec, cVec) = *elm;
let a = BigInt::from_slice(Plus, aVec);
let b = BigInt::from_slice(Plus, bVec);
@ -1894,7 +1894,7 @@ mod bigint_tests {
if !b.is_zero() { check(&c, &b, &a, &Zero::zero()); }
}
for div_rem_quadruples.each |elm| {
for div_rem_quadruples.iter().advance |elm| {
let (aVec, bVec, cVec, dVec) = *elm;
let a = BigInt::from_slice(Plus, aVec);
let b = BigInt::from_slice(Plus, bVec);
@ -1927,7 +1927,7 @@ mod bigint_tests {
check_sub(&a.neg(), b, &q.neg(), &r.neg());
check_sub(&a.neg(), &b.neg(), q, &r.neg());
}
for mul_triples.each |elm| {
for mul_triples.iter().advance |elm| {
let (aVec, bVec, cVec) = *elm;
let a = BigInt::from_slice(Plus, aVec);
let b = BigInt::from_slice(Plus, bVec);
@ -1937,7 +1937,7 @@ mod bigint_tests {
if !b.is_zero() { check(&c, &b, &a, &Zero::zero()); }
}
for div_rem_quadruples.each |elm| {
for div_rem_quadruples.iter().advance |elm| {
let (aVec, bVec, cVec, dVec) = *elm;
let a = BigInt::from_slice(Plus, aVec);
let b = BigInt::from_slice(Plus, bVec);

View file

@ -11,9 +11,8 @@
//! Complex numbers.
use core::prelude::*;
use core::num::{Zero,One,ToStrRadix};
use std::num::{Zero,One,ToStrRadix};
// FIXME #1284: handle complex NaN & infinity etc. This
// probably doesn't map to C's _Complex correctly.
@ -193,7 +192,7 @@ impl<T: ToStrRadix + Num + Ord> ToStrRadix for Cmplx<T> {
#[cfg(test)]
mod test {
use super::*;
use core::num::{Zero,One,Real};
use std::num::{Zero,One,Real};
pub static _0_0i : Complex = Cmplx { re: 0f, im: 0f };
pub static _1_0i : Complex = Cmplx { re: 1f, im: 0f };
@ -238,14 +237,14 @@ mod test {
fn test_scale_unscale() {
assert_eq!(_05_05i.scale(2f), _1_1i);
assert_eq!(_1_1i.unscale(2f), _05_05i);
for all_consts.each |&c| {
for all_consts.iter().advance |&c| {
assert_eq!(c.scale(2f).unscale(2f), c);
}
}
#[test]
fn test_conj() {
for all_consts.each |&c| {
for all_consts.iter().advance |&c| {
assert_eq!(c.conj(), Cmplx::new(c.re, -c.im));
assert_eq!(c.conj().conj(), c);
}
@ -282,12 +281,12 @@ mod test {
let (r, theta) = c.to_polar();
assert!((c - Cmplx::from_polar(&r, &theta)).norm() < 1e-6);
}
for all_consts.each |&c| { test(c); }
for all_consts.iter().advance |&c| { test(c); }
}
mod arith {
use super::*;
use core::num::Zero;
use std::num::Zero;
#[test]
fn test_add() {
@ -295,7 +294,7 @@ mod test {
assert_eq!(_0_1i + _1_0i, _1_1i);
assert_eq!(_1_0i + _neg1_1i, _0_1i);
for all_consts.each |&c| {
for all_consts.iter().advance |&c| {
assert_eq!(_0_0i + c, c);
assert_eq!(c + _0_0i, c);
}
@ -307,7 +306,7 @@ mod test {
assert_eq!(_0_1i - _1_0i, _neg1_1i);
assert_eq!(_0_1i - _neg1_1i, _1_0i);
for all_consts.each |&c| {
for all_consts.iter().advance |&c| {
assert_eq!(c - _0_0i, c);
assert_eq!(c - c, _0_0i);
}
@ -322,7 +321,7 @@ mod test {
assert_eq!(_0_1i * _0_1i, -_1_0i);
assert_eq!(_0_1i * _0_1i * _0_1i * _0_1i, _1_0i);
for all_consts.each |&c| {
for all_consts.iter().advance |&c| {
assert_eq!(c * _1_0i, c);
assert_eq!(_1_0i * c, c);
}
@ -330,7 +329,7 @@ mod test {
#[test]
fn test_div() {
assert_eq!(_neg1_1i / _0_1i, _1_1i);
for all_consts.each |&c| {
for all_consts.iter().advance |&c| {
if c != Zero::zero() {
assert_eq!(c / c, _1_0i);
}
@ -340,7 +339,7 @@ mod test {
fn test_neg() {
assert_eq!(-_1_0i + _0_1i, _neg1_1i);
assert_eq!((-_0_1i) * _0_1i, _1_0i);
for all_consts.each |&c| {
for all_consts.iter().advance |&c| {
assert_eq!(-(-c), c);
}
}

View file

@ -10,11 +10,10 @@
//! Rational numbers
use core::prelude::*;
use core::cmp;
use core::from_str::FromStr;
use core::num::{Zero,One,ToStrRadix,FromStrRadix,Round};
use std::cmp;
use std::from_str::FromStr;
use std::num::{Zero,One,ToStrRadix,FromStrRadix,Round};
use super::bigint::BigInt;
/// Represents the ratio between 2 numbers.
@ -277,11 +276,10 @@ impl<T: FromStrRadix + Clone + Integer + Ord>
#[cfg(test)]
mod test {
use core::prelude::*;
use super::*;
use core::num::{Zero,One,FromStrRadix,IntConvertible};
use core::from_str::FromStr;
use std::num::{Zero,One,FromStrRadix,IntConvertible};
use std::from_str::FromStr;
pub static _0 : Rational = Ratio { numer: 0, denom: 1};
pub static _1 : Rational = Ratio { numer: 1, denom: 1};
@ -482,7 +480,8 @@ mod test {
assert_eq!(FromStr::from_str::<Rational>(s), None);
}
for ["0 /1", "abc", "", "1/", "--1/2","3/2/1"].each |&s| {
let xs = ["0 /1", "abc", "", "1/", "--1/2","3/2/1"];
for xs.iter().advance |&s| {
test(s);
}
}
@ -521,7 +520,8 @@ mod test {
assert_eq!(FromStrRadix::from_str_radix::<Rational>(s, 3), None);
}
for ["0 /1", "abc", "", "1/", "--1/2","3/2/1", "3/2"].each |&s| {
let xs = ["0 /1", "abc", "", "1/", "--1/2","3/2/1", "3/2"];
for xs.iter().advance |&s| {
test(s);
}
}

View file

@ -8,13 +8,12 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use core::prelude::*;
use core::cast;
use core::ptr;
use core::sys;
use core::uint;
use core::vec;
use std::cast;
use std::ptr;
use std::sys;
use std::uint;
use std::vec;
use future_spawn = future::spawn;
/**
@ -33,7 +32,7 @@ static min_granularity : uint = 1024u;
* This is used to build most of the other parallel vector functions,
* like map or alli.
*/
fn map_slices<A:Copy + Owned,B:Copy + Owned>(
fn map_slices<A:Copy + Send,B:Copy + Send>(
xs: &[A],
f: &fn() -> ~fn(uint, v: &[A]) -> B)
-> ~[B] {
@ -88,26 +87,26 @@ fn map_slices<A:Copy + Owned,B:Copy + Owned>(
}
/// A parallel version of map.
pub fn map<A:Copy + Owned,B:Copy + Owned>(
pub fn map<A:Copy + Send,B:Copy + Send>(
xs: &[A], fn_factory: &fn() -> ~fn(&A) -> B) -> ~[B] {
vec::concat(map_slices(xs, || {
let f = fn_factory();
let result: ~fn(uint, &[A]) -> ~[B] =
|_, slice| vec::map(slice, |x| f(x));
|_, slice| slice.iter().transform(|x| f(x)).collect();
result
}))
}
/// A parallel version of mapi.
pub fn mapi<A:Copy + Owned,B:Copy + Owned>(
pub fn mapi<A:Copy + Send,B:Copy + Send>(
xs: &[A],
fn_factory: &fn() -> ~fn(uint, &A) -> B) -> ~[B] {
let slices = map_slices(xs, || {
let f = fn_factory();
let result: ~fn(uint, &[A]) -> ~[B] = |base, slice| {
vec::mapi(slice, |i, x| {
slice.iter().enumerate().transform(|(i, x)| {
f(i + base, x)
})
}).collect()
};
result
});
@ -118,7 +117,7 @@ pub fn mapi<A:Copy + Owned,B:Copy + Owned>(
}
/// Returns true if the function holds for all elements in the vector.
pub fn alli<A:Copy + Owned>(
pub fn alli<A:Copy + Send>(
xs: &[A],
fn_factory: &fn() -> ~fn(uint, &A) -> bool) -> bool
{
@ -133,7 +132,7 @@ pub fn alli<A:Copy + Owned>(
}
/// Returns true if the function holds for any elements in the vector.
pub fn any<A:Copy + Owned>(
pub fn any<A:Copy + Send>(
xs: &[A],
fn_factory: &fn() -> ~fn(&A) -> bool) -> bool {
let mapped = map_slices(xs, || {

View file

@ -12,27 +12,16 @@
#[allow(missing_doc)];
use core::prelude::*;
use core::old_iter::BaseIter;
use core::unstable::intrinsics::{move_val_init, init};
use core::util::{replace, swap};
use core::vec;
use std::unstable::intrinsics::{move_val_init, init};
use std::util::{replace, swap};
use std::vec;
#[allow(missing_doc)]
/// A priority queue implemented with a binary heap
pub struct PriorityQueue<T> {
priv data: ~[T],
}
impl<T:Ord> BaseIter<T> for PriorityQueue<T> {
/// Visit all values in the underlying vector.
///
/// The values are **not** visited in order.
fn each(&self, f: &fn(&T) -> bool) -> bool { self.data.each(f) }
fn size_hint(&self) -> Option<uint> { self.data.size_hint() }
}
impl<T:Ord> Container for PriorityQueue<T> {
/// Returns the length of the queue
fn len(&self) -> uint { self.data.len() }
@ -47,6 +36,12 @@ impl<T:Ord> Mutable for PriorityQueue<T> {
}
impl<T:Ord> PriorityQueue<T> {
/// An iterator visiting all values in underlying vector, in
/// arbitrary order.
pub fn iter<'a>(&'a self) -> PriorityQueueIterator<'a, T> {
PriorityQueueIterator { iter: self.data.iter() }
}
/// Returns the greatest item in the queue - fails if empty
pub fn top<'a>(&'a self) -> &'a T { &self.data[0] }
@ -56,12 +51,12 @@ impl<T:Ord> PriorityQueue<T> {
}
/// Returns the number of elements the queue can hold without reallocating
pub fn capacity(&self) -> uint { vec::capacity(&self.data) }
pub fn capacity(&self) -> uint { self.data.capacity() }
pub fn reserve(&mut self, n: uint) { vec::reserve(&mut self.data, n) }
pub fn reserve(&mut self, n: uint) { self.data.reserve(n) }
pub fn reserve_at_least(&mut self, n: uint) {
vec::reserve_at_least(&mut self.data, n)
self.data.reserve_at_least(n)
}
/// Pop the greatest item from the queue - fails if empty
@ -112,7 +107,7 @@ impl<T:Ord> PriorityQueue<T> {
let mut end = q.len();
while end > 1 {
end -= 1;
vec::swap(q.data, 0, end);
q.data.swap(0, end);
q.siftdown_range(0, end)
}
q.to_vec()
@ -183,11 +178,33 @@ impl<T:Ord> PriorityQueue<T> {
}
}
/// PriorityQueue iterator
pub struct PriorityQueueIterator <'self, T> {
priv iter: vec::VecIterator<'self, T>,
}
impl<'self, T> Iterator<&'self T> for PriorityQueueIterator<'self, T> {
#[inline]
fn next(&mut self) -> Option<(&'self T)> { self.iter.next() }
}
#[cfg(test)]
mod tests {
use sort::merge_sort;
use priority_queue::PriorityQueue;
#[test]
fn test_iterator() {
let data = ~[5, 9, 3];
let iterout = ~[9, 5, 3];
let pq = PriorityQueue::from_vec(data);
let mut i = 0;
for pq.iter().advance |el| {
assert_eq!(*el, iterout[i]);
i += 1;
}
}
#[test]
fn test_top_and_pop() {
let data = ~[2u, 4, 6, 2, 1, 8, 10, 3, 5, 7, 0, 9, 1];

View file

@ -13,21 +13,20 @@
/** Task-local reference counted smart pointers
Task-local reference counted smart pointers are an alternative to managed boxes with deterministic
destruction. They are restricted to containing types that are either `Owned` or `Const` (or both) to
destruction. They are restricted to containing types that are either `Send` or `Freeze` (or both) to
prevent cycles.
Neither `Rc<T>` or `RcMut<T>` is ever `Owned` and `RcMut<T>` is never `Const`. If `T` is `Const`, a
Neither `Rc<T>` or `RcMut<T>` is ever `Send` and `RcMut<T>` is never `Freeze`. If `T` is `Freeze`, a
cycle cannot be created with `Rc<T>` because there is no way to modify it after creation.
*/
use core::prelude::*;
use core::cast;
use core::libc::{c_void, size_t, malloc, free};
use core::ptr;
use core::sys;
use core::unstable::intrinsics;
use std::cast;
use std::libc::{c_void, size_t, malloc, free};
use std::ptr;
use std::sys;
use std::unstable::intrinsics;
struct RcBox<T> {
value: T,
@ -35,7 +34,8 @@ struct RcBox<T> {
}
/// Immutable reference counted pointer type
#[non_owned]
#[unsafe_no_drop_flag]
#[no_send]
pub struct Rc<T> {
priv ptr: *mut RcBox<T>,
}
@ -50,12 +50,12 @@ impl<T> Rc<T> {
}
// FIXME: #6516: should be a static method
pub fn rc_from_owned<T: Owned>(value: T) -> Rc<T> {
pub fn rc_from_owned<T: Send>(value: T) -> Rc<T> {
unsafe { Rc::new(value) }
}
// FIXME: #6516: should be a static method
pub fn rc_from_const<T: Const>(value: T) -> Rc<T> {
pub fn rc_from_const<T: Freeze>(value: T) -> Rc<T> {
unsafe { Rc::new(value) }
}
@ -68,12 +68,14 @@ impl<T> Rc<T> {
#[unsafe_destructor]
impl<T> Drop for Rc<T> {
fn finalize(&self) {
fn drop(&self) {
unsafe {
(*self.ptr).count -= 1;
if (*self.ptr).count == 0 {
ptr::replace_ptr(self.ptr, intrinsics::uninit());
free(self.ptr as *c_void)
if self.ptr.is_not_null() {
(*self.ptr).count -= 1;
if (*self.ptr).count == 0 {
ptr::replace_ptr(self.ptr, intrinsics::uninit());
free(self.ptr as *c_void)
}
}
}
}
@ -101,7 +103,7 @@ impl<T: DeepClone> DeepClone for Rc<T> {
#[cfg(test)]
mod test_rc {
use super::*;
use core::cell::Cell;
use std::cell::Cell;
#[test]
fn test_clone() {
@ -165,7 +167,10 @@ struct RcMutBox<T> {
/// Mutable reference counted pointer type
#[non_owned]
#[mutable]
#[no_send]
#[mutable] // XXX remove after snap
#[no_freeze]
#[unsafe_no_drop_flag]
pub struct RcMut<T> {
priv ptr: *mut RcMutBox<T>,
}
@ -180,12 +185,12 @@ impl<T> RcMut<T> {
}
// FIXME: #6516: should be a static method
pub fn rc_mut_from_owned<T: Owned>(value: T) -> RcMut<T> {
pub fn rc_mut_from_owned<T: Send>(value: T) -> RcMut<T> {
unsafe { RcMut::new(value) }
}
// FIXME: #6516: should be a static method
pub fn rc_mut_from_const<T: Const>(value: T) -> RcMut<T> {
pub fn rc_mut_from_const<T: Freeze>(value: T) -> RcMut<T> {
unsafe { RcMut::new(value) }
}
@ -218,12 +223,14 @@ impl<T> RcMut<T> {
#[unsafe_destructor]
impl<T> Drop for RcMut<T> {
fn finalize(&self) {
fn drop(&self) {
unsafe {
(*self.ptr).count -= 1;
if (*self.ptr).count == 0 {
ptr::replace_ptr(self.ptr, uninit());
free(self.ptr as *c_void)
if self.ptr.is_not_null() {
(*self.ptr).count -= 1;
if (*self.ptr).count == 0 {
ptr::replace_ptr(self.ptr, uninit());
free(self.ptr as *c_void)
}
}
}
}

View file

@ -11,14 +11,13 @@
// FIXME #3921. This is unsafe because linenoise uses global mutable
// state without mutexes.
use core::prelude::*;
use core::libc::{c_char, c_int};
use core::local_data;
use core::str;
use std::libc::{c_char, c_int};
use std::local_data;
use std::str;
pub mod rustrt {
use core::libc::{c_char, c_int};
use std::libc::{c_char, c_int};
pub extern {
pub unsafe fn linenoise(prompt: *c_char) -> *c_char;

View file

@ -35,11 +35,10 @@
#[allow(missing_doc)];
use core::prelude::*;
use core::uint;
use core::vec;
use core::str;
use std::uint;
use std::vec;
use std::str;
/// The type of ropes.
pub type Rope = node::Root;
@ -447,7 +446,6 @@ pub fn loop_leaves(rope: Rope, it: &fn(node::Leaf) -> bool) -> bool{
pub mod iterator {
pub mod leaf {
use core::prelude::*;
use rope::{Rope, node};
@ -462,7 +460,6 @@ pub mod iterator {
}
}
pub mod char {
use core::prelude::*;
use rope::{Rope, node};
@ -558,13 +555,12 @@ pub fn char_at(rope: Rope, pos: uint) -> char {
Section: Implementation
*/
pub mod node {
use core::prelude::*;
use rope::node;
use core::cast;
use core::uint;
use core::vec;
use std::cast;
use std::uint;
use std::vec;
/// Implementation of type `rope`
pub enum Root {
@ -1078,7 +1074,7 @@ pub mod node {
pub fn loop_chars(node: @Node, it: &fn(c: char) -> bool) -> bool {
return loop_leaves(node,|leaf| {
leaf.content.slice(leaf.byte_offset, leaf.byte_len).iter().all(it)
leaf.content.slice(leaf.byte_offset, leaf.byte_len).iter().all(|c| it(c))
});
}
@ -1101,7 +1097,7 @@ pub mod node {
loop {
match (*current) {
Leaf(x) => return it(x),
Concat(ref x) => if loop_leaves(x.left, it) { //non tail call
Concat(ref x) => if loop_leaves(x.left, |l| it(l)) { //non tail call
current = x.right; //tail call
} else {
return false;
@ -1141,11 +1137,10 @@ pub mod node {
}
pub mod leaf_iterator {
use core::prelude::*;
use rope::node::{Concat, Leaf, Node, height};
use core::vec;
use std::vec;
pub struct T {
stack: ~[@Node],
@ -1184,7 +1179,6 @@ pub mod node {
}
pub mod char_iterator {
use core::prelude::*;
use rope::node::{Leaf, Node};
use rope::node::leaf_iterator;
@ -1267,12 +1261,11 @@ pub mod node {
#[cfg(test)]
mod tests {
use core::prelude::*;
use rope::*;
use core::uint;
use core::vec;
use std::uint;
use std::vec;
//Utility function, used for sanity check
fn rope_to_string(r: Rope) -> ~str {

View file

@ -12,15 +12,14 @@
#[allow(missing_doc)];
use core::prelude::*;
use core::char;
use core::cmp;
use core::io::{ReaderUtil};
use core::io;
use core::option::{Option, Some, None};
use core::to_str::ToStr;
use core::uint;
use std::char;
use std::cmp;
use std::io::{ReaderUtil};
use std::io;
use std::option::{Option, Some, None};
use std::to_str::ToStr;
use std::uint;
#[deriving(Eq)]
pub enum Identifier {
@ -79,12 +78,12 @@ impl ToStr for Version {
let s = if self.pre.is_empty() {
s
} else {
s + "-" + self.pre.map(|i| i.to_str()).connect(".")
fmt!("%s-%s", s, self.pre.map(|i| i.to_str()).connect("."))
};
if self.build.is_empty() {
s
} else {
s + "+" + self.build.map(|i| i.to_str()).connect(".")
fmt!("%s+%s", s, self.build.map(|i| i.to_str()).connect("."))
}
}
}

View file

@ -17,13 +17,12 @@ Core encoding and decoding interfaces.
#[allow(missing_doc)];
#[forbid(non_camel_case_types)];
use core::prelude::*;
use core::at_vec;
use core::hashmap::{HashMap, HashSet};
use core::trie::{TrieMap, TrieSet};
use core::uint;
use core::vec;
use std::at_vec;
use std::hashmap::{HashMap, HashSet};
use std::trie::{TrieMap, TrieSet};
use std::uint;
use std::vec;
use deque::Deque;
use dlist::DList;
use treemap::{TreeMap, TreeSet};
@ -432,7 +431,7 @@ impl<D:Decoder,T:Decodable<D>> Decodable<D> for @T {
impl<'self, S:Encoder,T:Encodable<S>> Encodable<S> for &'self [T] {
fn encode(&self, s: &mut S) {
do s.emit_seq(self.len()) |s| {
for self.eachi |i, e| {
for self.iter().enumerate().advance |(i, e)| {
s.emit_seq_elt(i, |s| e.encode(s))
}
}
@ -442,7 +441,7 @@ impl<'self, S:Encoder,T:Encodable<S>> Encodable<S> for &'self [T] {
impl<S:Encoder,T:Encodable<S>> Encodable<S> for ~[T] {
fn encode(&self, s: &mut S) {
do s.emit_seq(self.len()) |s| {
for self.eachi |i, e| {
for self.iter().enumerate().advance |(i, e)| {
s.emit_seq_elt(i, |s| e.encode(s))
}
}
@ -462,7 +461,7 @@ impl<D:Decoder,T:Decodable<D>> Decodable<D> for ~[T] {
impl<S:Encoder,T:Encodable<S>> Encodable<S> for @[T] {
fn encode(&self, s: &mut S) {
do s.emit_seq(self.len()) |s| {
for self.eachi |i, e| {
for self.iter().enumerate().advance |(i, e)| {
s.emit_seq_elt(i, |s| e.encode(s))
}
}
@ -710,7 +709,7 @@ impl<
fn encode(&self, e: &mut E) {
do e.emit_map(self.len()) |e| {
let mut i = 0;
for self.each |key, val| {
for self.iter().advance |(key, val)| {
e.emit_map_elt_key(i, |e| key.encode(e));
e.emit_map_elt_val(i, |e| val.encode(e));
i += 1;
@ -744,7 +743,7 @@ impl<
fn encode(&self, s: &mut S) {
do s.emit_seq(self.len()) |s| {
let mut i = 0;
for self.each |e| {
for self.iter().advance |e| {
s.emit_seq_elt(i, |s| e.encode(s));
i += 1;
}
@ -832,7 +831,7 @@ impl<
fn encode(&self, e: &mut E) {
do e.emit_map(self.len()) |e| {
let mut i = 0;
for self.each |key, val| {
for self.iter().advance |(key, val)| {
e.emit_map_elt_key(i, |e| key.encode(e));
e.emit_map_elt_val(i, |e| val.encode(e));
i += 1;
@ -866,7 +865,7 @@ impl<
fn encode(&self, s: &mut S) {
do s.emit_seq(self.len()) |s| {
let mut i = 0;
for self.each |e| {
for self.iter().advance |e| {
s.emit_seq_elt(i, |s| e.encode(s));
i += 1;
}
@ -901,7 +900,7 @@ pub trait EncoderHelpers {
impl<S:Encoder> EncoderHelpers for S {
fn emit_from_vec<T>(&mut self, v: &[T], f: &fn(&mut S, &T)) {
do self.emit_seq(v.len()) |this| {
for v.eachi |i, e| {
for v.iter().enumerate().advance |(i, e)| {
do this.emit_seq_elt(i) |this| {
f(this, e)
}

View file

@ -1,410 +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.
/*!
* An implementation of the SHA-1 cryptographic hash.
*
* First create a `sha1` object using the `sha1` constructor, then
* feed it input using the `input` or `input_str` methods, which may be
* called any number of times.
*
* After the entire input has been fed to the hash read the result using
* the `result` or `result_str` methods.
*
* The `sha1` object may be reused to create multiple hashes by calling
* the `reset` method.
*/
use core::prelude::*;
use core::uint;
use core::vec;
/*
* A SHA-1 implementation derived from Paul E. Jones's reference
* implementation, which is written for clarity, not speed. At some
* point this will want to be rewritten.
*/
/// The SHA-1 interface
trait Sha1 {
/// Provide message input as bytes
fn input(&mut self, &const [u8]);
/// Provide message input as string
fn input_str(&mut self, &str);
/**
* Read the digest as a vector of 20 bytes. After calling this no further
* input may be provided until reset is called.
*/
fn result(&mut self) -> ~[u8];
/**
* Read the digest as a hex string. After calling this no further
* input may be provided until reset is called.
*/
fn result_str(&mut self) -> ~str;
/// Reset the SHA-1 state for reuse
fn reset(&mut self);
}
// Some unexported constants
static digest_buf_len: uint = 5u;
static msg_block_len: uint = 64u;
static work_buf_len: uint = 80u;
static k0: u32 = 0x5A827999u32;
static k1: u32 = 0x6ED9EBA1u32;
static k2: u32 = 0x8F1BBCDCu32;
static k3: u32 = 0xCA62C1D6u32;
/// Construct a `sha` object
pub fn sha1() -> @Sha1 {
struct Sha1State
{ h: ~[u32],
len_low: u32,
len_high: u32,
msg_block: ~[u8],
msg_block_idx: uint,
computed: bool,
work_buf: @mut ~[u32]};
fn add_input(st: &mut Sha1State, msg: &const [u8]) {
assert!((!st.computed));
for vec::each_const(msg) |element| {
st.msg_block[st.msg_block_idx] = *element;
st.msg_block_idx += 1u;
st.len_low += 8u32;
if st.len_low == 0u32 {
st.len_high += 1u32;
if st.len_high == 0u32 {
// FIXME: Need better failure mode (#2346)
fail!();
}
}
if st.msg_block_idx == msg_block_len { process_msg_block(st); }
}
}
fn process_msg_block(st: &mut Sha1State) {
assert_eq!(st.h.len(), digest_buf_len);
assert_eq!(st.work_buf.len(), work_buf_len);
let mut t: int; // Loop counter
let w = st.work_buf;
// Initialize the first 16 words of the vector w
t = 0;
while t < 16 {
let mut tmp;
tmp = (st.msg_block[t * 4] as u32) << 24u32;
tmp = tmp | (st.msg_block[t * 4 + 1] as u32) << 16u32;
tmp = tmp | (st.msg_block[t * 4 + 2] as u32) << 8u32;
tmp = tmp | (st.msg_block[t * 4 + 3] as u32);
w[t] = tmp;
t += 1;
}
// Initialize the rest of vector w
while t < 80 {
let val = w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16];
w[t] = circular_shift(1u32, val);
t += 1;
}
let mut a = st.h[0];
let mut b = st.h[1];
let mut c = st.h[2];
let mut d = st.h[3];
let mut e = st.h[4];
let mut temp: u32;
t = 0;
while t < 20 {
temp = circular_shift(5u32, a) + (b & c | !b & d) + e + w[t] + k0;
e = d;
d = c;
c = circular_shift(30u32, b);
b = a;
a = temp;
t += 1;
}
while t < 40 {
temp = circular_shift(5u32, a) + (b ^ c ^ d) + e + w[t] + k1;
e = d;
d = c;
c = circular_shift(30u32, b);
b = a;
a = temp;
t += 1;
}
while t < 60 {
temp =
circular_shift(5u32, a) + (b & c | b & d | c & d) + e + w[t] +
k2;
e = d;
d = c;
c = circular_shift(30u32, b);
b = a;
a = temp;
t += 1;
}
while t < 80 {
temp = circular_shift(5u32, a) + (b ^ c ^ d) + e + w[t] + k3;
e = d;
d = c;
c = circular_shift(30u32, b);
b = a;
a = temp;
t += 1;
}
st.h[0] = st.h[0] + a;
st.h[1] = st.h[1] + b;
st.h[2] = st.h[2] + c;
st.h[3] = st.h[3] + d;
st.h[4] = st.h[4] + e;
st.msg_block_idx = 0u;
}
fn circular_shift(bits: u32, word: u32) -> u32 {
return word << bits | word >> 32u32 - bits;
}
fn mk_result(st: &mut Sha1State) -> ~[u8] {
if !(*st).computed { pad_msg(st); (*st).computed = true; }
let mut rs: ~[u8] = ~[];
for st.h.mut_iter().advance |ptr_hpart| {
let hpart = *ptr_hpart;
let a = (hpart >> 24u32 & 0xFFu32) as u8;
let b = (hpart >> 16u32 & 0xFFu32) as u8;
let c = (hpart >> 8u32 & 0xFFu32) as u8;
let d = (hpart & 0xFFu32) as u8;
rs = vec::append(copy rs, [a, b, c, d]);
}
return rs;
}
/*
* According to the standard, the message must be padded to an even
* 512 bits. The first padding bit must be a '1'. The last 64 bits
* represent the length of the original message. All bits in between
* should be 0. This function will pad the message according to those
* rules by filling the msg_block vector accordingly. It will also
* call process_msg_block() appropriately. When it returns, it
* can be assumed that the message digest has been computed.
*/
fn pad_msg(st: &mut Sha1State) {
assert_eq!((*st).msg_block.len(), msg_block_len);
/*
* Check to see if the current message block is too small to hold
* the initial padding bits and length. If so, we will pad the
* block, process it, and then continue padding into a second block.
*/
if (*st).msg_block_idx > 55u {
(*st).msg_block[(*st).msg_block_idx] = 0x80u8;
(*st).msg_block_idx += 1u;
while (*st).msg_block_idx < msg_block_len {
(*st).msg_block[(*st).msg_block_idx] = 0u8;
(*st).msg_block_idx += 1u;
}
process_msg_block(st);
} else {
(*st).msg_block[(*st).msg_block_idx] = 0x80u8;
(*st).msg_block_idx += 1u;
}
while (*st).msg_block_idx < 56u {
(*st).msg_block[(*st).msg_block_idx] = 0u8;
(*st).msg_block_idx += 1u;
}
// Store the message length as the last 8 octets
(*st).msg_block[56] = ((*st).len_high >> 24u32 & 0xFFu32) as u8;
(*st).msg_block[57] = ((*st).len_high >> 16u32 & 0xFFu32) as u8;
(*st).msg_block[58] = ((*st).len_high >> 8u32 & 0xFFu32) as u8;
(*st).msg_block[59] = ((*st).len_high & 0xFFu32) as u8;
(*st).msg_block[60] = ((*st).len_low >> 24u32 & 0xFFu32) as u8;
(*st).msg_block[61] = ((*st).len_low >> 16u32 & 0xFFu32) as u8;
(*st).msg_block[62] = ((*st).len_low >> 8u32 & 0xFFu32) as u8;
(*st).msg_block[63] = ((*st).len_low & 0xFFu32) as u8;
process_msg_block(st);
}
impl Sha1 for Sha1State {
fn reset(&mut self) {
assert_eq!(self.h.len(), digest_buf_len);
self.len_low = 0u32;
self.len_high = 0u32;
self.msg_block_idx = 0u;
self.h[0] = 0x67452301u32;
self.h[1] = 0xEFCDAB89u32;
self.h[2] = 0x98BADCFEu32;
self.h[3] = 0x10325476u32;
self.h[4] = 0xC3D2E1F0u32;
self.computed = false;
}
fn input(&mut self, msg: &const [u8]) { add_input(self, msg); }
fn input_str(&mut self, msg: &str) {
add_input(self, msg.as_bytes());
}
fn result(&mut self) -> ~[u8] { return mk_result(self); }
fn result_str(&mut self) -> ~str {
let rr = mk_result(self);
let mut s = ~"";
for rr.each |b| {
let hex = uint::to_str_radix(*b as uint, 16u);
if hex.len() == 1 {
s += "0";
}
s += hex;
}
return s;
}
}
let st = Sha1State {
h: vec::from_elem(digest_buf_len, 0u32),
len_low: 0u32,
len_high: 0u32,
msg_block: vec::from_elem(msg_block_len, 0u8),
msg_block_idx: 0u,
computed: false,
work_buf: @mut vec::from_elem(work_buf_len, 0u32)
};
let mut sh = @st as @Sha1;
sh.reset();
return sh;
}
#[cfg(test)]
mod tests {
use sha1;
#[test]
fn test() {
struct Test {
input: ~str,
output: ~[u8],
output_str: ~str,
}
fn a_million_letter_a() -> ~str {
let mut i = 0;
let mut rs = ~"";
while i < 100000 {
rs.push_str("aaaaaaaaaa");
i += 1;
}
return rs;
}
// Test messages from FIPS 180-1
let fips_180_1_tests = ~[
Test {
input: ~"abc",
output: ~[
0xA9u8, 0x99u8, 0x3Eu8, 0x36u8,
0x47u8, 0x06u8, 0x81u8, 0x6Au8,
0xBAu8, 0x3Eu8, 0x25u8, 0x71u8,
0x78u8, 0x50u8, 0xC2u8, 0x6Cu8,
0x9Cu8, 0xD0u8, 0xD8u8, 0x9Du8,
],
output_str: ~"a9993e364706816aba3e25717850c26c9cd0d89d"
},
Test {
input:
~"abcdbcdecdefdefgefghfghighij" +
"hijkijkljklmklmnlmnomnopnopq",
output: ~[
0x84u8, 0x98u8, 0x3Eu8, 0x44u8,
0x1Cu8, 0x3Bu8, 0xD2u8, 0x6Eu8,
0xBAu8, 0xAEu8, 0x4Au8, 0xA1u8,
0xF9u8, 0x51u8, 0x29u8, 0xE5u8,
0xE5u8, 0x46u8, 0x70u8, 0xF1u8,
],
output_str: ~"84983e441c3bd26ebaae4aa1f95129e5e54670f1"
},
Test {
input: a_million_letter_a(),
output: ~[
0x34u8, 0xAAu8, 0x97u8, 0x3Cu8,
0xD4u8, 0xC4u8, 0xDAu8, 0xA4u8,
0xF6u8, 0x1Eu8, 0xEBu8, 0x2Bu8,
0xDBu8, 0xADu8, 0x27u8, 0x31u8,
0x65u8, 0x34u8, 0x01u8, 0x6Fu8,
],
output_str: ~"34aa973cd4c4daa4f61eeb2bdbad27316534016f"
},
];
// Examples from wikipedia
let wikipedia_tests = ~[
Test {
input: ~"The quick brown fox jumps over the lazy dog",
output: ~[
0x2fu8, 0xd4u8, 0xe1u8, 0xc6u8,
0x7au8, 0x2du8, 0x28u8, 0xfcu8,
0xedu8, 0x84u8, 0x9eu8, 0xe1u8,
0xbbu8, 0x76u8, 0xe7u8, 0x39u8,
0x1bu8, 0x93u8, 0xebu8, 0x12u8,
],
output_str: ~"2fd4e1c67a2d28fced849ee1bb76e7391b93eb12",
},
Test {
input: ~"The quick brown fox jumps over the lazy cog",
output: ~[
0xdeu8, 0x9fu8, 0x2cu8, 0x7fu8,
0xd2u8, 0x5eu8, 0x1bu8, 0x3au8,
0xfau8, 0xd3u8, 0xe8u8, 0x5au8,
0x0bu8, 0xd1u8, 0x7du8, 0x9bu8,
0x10u8, 0x0du8, 0xb4u8, 0xb3u8,
],
output_str: ~"de9f2c7fd25e1b3afad3e85a0bd17d9b100db4b3",
},
];
let tests = fips_180_1_tests + wikipedia_tests;
fn check_vec_eq(v0: ~[u8], v1: ~[u8]) {
assert_eq!(v0.len(), v1.len());
let len = v0.len();
let mut i = 0u;
while i < len {
let a = v0[i];
let b = v1[i];
assert_eq!(a, b);
i += 1u;
}
}
// Test that it works when accepting the message all at once
let mut sh = sha1::sha1();
for tests.each |t| {
sh.input_str(t.input);
let out = sh.result();
check_vec_eq(copy t.output, out);
let out_str = sh.result_str();
assert_eq!(out_str.len(), 40);
assert!(out_str == t.output_str);
sh.reset();
}
// Test that it works when accepting the message in pieces
for tests.each |t| {
let len = t.input.len();
let mut left = len;
while left > 0u {
let take = (left + 1u) / 2u;
sh.input_str(t.input.slice(len - left, take + len - left));
left = left - take;
}
let out = sh.result();
check_vec_eq(copy t.output, out);
let out_str = sh.result_str();
assert_eq!(out_str.len(), 40);
assert!(out_str == t.output_str);
sh.reset();
}
}
}

View file

@ -15,15 +15,11 @@
#[allow(missing_doc)];
use core::prelude::*;
use core::cmp;
use core::container::{Container, Mutable, Map, Set};
use core::old_iter::BaseIter;
use core::old_iter;
use core::uint;
use core::util::replace;
use core::vec;
use std::cmp;
use std::container::{Container, Mutable, Map, Set};
use std::uint;
use std::util::replace;
#[allow(missing_doc)]
pub struct SmallIntMap<T> {
@ -58,38 +54,6 @@ impl<V> Map<uint, V> for SmallIntMap<V> {
self.find(key).is_some()
}
/// Visit all key-value pairs in order
fn each<'a>(&'a self, it: &fn(&uint, &'a V) -> bool) -> bool {
for uint::range(0, self.v.len()) |i| {
match self.v[i] {
Some(ref elt) => if !it(&i, elt) { return false; },
None => ()
}
}
return true;
}
/// Visit all keys in order
fn each_key(&self, blk: &fn(key: &uint) -> bool) -> bool {
self.each(|k, _| blk(k))
}
/// Visit all values in order
fn each_value<'a>(&'a self, blk: &fn(value: &'a V) -> bool) -> bool {
self.each(|_, v| blk(v))
}
/// Iterate over the map and mutate the contained values
fn mutate_values(&mut self, it: &fn(&uint, &mut V) -> bool) -> bool {
for uint::range(0, self.v.len()) |i| {
match self.v[i] {
Some(ref mut elt) => if !it(&i, elt) { return false; },
None => ()
}
}
return true;
}
/// Return a reference to the value corresponding to the key
fn find<'a>(&'a self, key: &uint) -> Option<&'a V> {
if *key < self.v.len() {
@ -121,7 +85,7 @@ impl<V> Map<uint, V> for SmallIntMap<V> {
let exists = self.contains_key(&key);
let len = self.v.len();
if len <= key {
vec::grow_fn(&mut self.v, key - len + 1, |_| None);
self.v.grow_fn(key - len + 1, |_| None);
}
self.v[key] = Some(value);
!exists
@ -158,6 +122,38 @@ impl<V> SmallIntMap<V> {
/// Create an empty SmallIntMap
pub fn new() -> SmallIntMap<V> { SmallIntMap{v: ~[]} }
/// Visit all key-value pairs in order
pub fn each<'a>(&'a self, it: &fn(&uint, &'a V) -> bool) -> bool {
for uint::range(0, self.v.len()) |i| {
match self.v[i] {
Some(ref elt) => if !it(&i, elt) { return false; },
None => ()
}
}
return true;
}
/// Visit all keys in order
pub fn each_key(&self, blk: &fn(key: &uint) -> bool) -> bool {
self.each(|k, _| blk(k))
}
/// Visit all values in order
pub fn each_value<'a>(&'a self, blk: &fn(value: &'a V) -> bool) -> bool {
self.each(|_, v| blk(v))
}
/// Iterate over the map and mutate the contained values
pub fn mutate_values(&mut self, it: &fn(&uint, &mut V) -> bool) -> bool {
for uint::range(0, self.v.len()) |i| {
match self.v[i] {
Some(ref mut elt) => if !it(&i, elt) { return false; },
None => ()
}
}
return true;
}
/// Visit all key-value pairs in reverse order
pub fn each_reverse<'a>(&'a self, it: &fn(uint, &'a V) -> bool) -> bool {
for uint::range_rev(self.v.len(), 0) |i| {
@ -212,12 +208,6 @@ impl Mutable for SmallIntSet {
fn clear(&mut self) { self.map.clear() }
}
impl BaseIter<uint> for SmallIntSet {
/// Visit all values in order
fn each(&self, f: &fn(&uint) -> bool) -> bool { self.map.each_key(f) }
fn size_hint(&self) -> Option<uint> { Some(self.len()) }
}
impl Set<uint> for SmallIntSet {
/// Return true if the set contains a value
fn contains(&self, value: &uint) -> bool { self.map.contains_key(value) }
@ -233,12 +223,14 @@ impl Set<uint> for SmallIntSet {
/// Return true if the set has no elements in common with `other`.
/// This is equivalent to checking for an empty uintersection.
fn is_disjoint(&self, other: &SmallIntSet) -> bool {
old_iter::all(self, |v| !other.contains(v))
for self.each |v| { if other.contains(v) { return false } }
true
}
/// Return true if the set is a subset of another
fn is_subset(&self, other: &SmallIntSet) -> bool {
old_iter::all(self, |v| other.contains(v))
for self.each |v| { if !other.contains(v) { return false } }
true
}
/// Return true if the set is a superset of another
@ -286,11 +278,13 @@ impl Set<uint> for SmallIntSet {
impl SmallIntSet {
/// Create an empty SmallIntSet
pub fn new() -> SmallIntSet { SmallIntSet{map: SmallIntMap::new()} }
/// Visit all values in order
pub fn each(&self, f: &fn(&uint) -> bool) -> bool { self.map.each_key(f) }
}
#[cfg(test)]
mod tests {
use core::prelude::*;
use super::SmallIntMap;
@ -385,12 +379,9 @@ mod tests {
#[cfg(test)]
mod test_set {
use core::prelude::*;
use super::SmallIntSet;
use core::vec;
#[test]
fn test_disjoint() {
let mut xs = SmallIntSet::new();
@ -462,7 +453,7 @@ mod test_set {
let mut i = 0;
let expected = [3, 5, 11, 77];
for a.intersection(&b) |x| {
assert!(vec::contains(expected, x));
assert!(expected.contains(x));
i += 1
}
assert_eq!(i, expected.len());
@ -485,7 +476,7 @@ mod test_set {
let mut i = 0;
let expected = [1, 5, 11];
for a.difference(&b) |x| {
assert!(vec::contains(expected, x));
assert!(expected.contains(x));
i += 1
}
assert_eq!(i, expected.len());
@ -510,7 +501,7 @@ mod test_set {
let mut i = 0;
let expected = [1, 5, 11, 14, 22];
for a.symmetric_difference(&b) |x| {
assert!(vec::contains(expected, x));
assert!(expected.contains(x));
i += 1
}
assert_eq!(i, expected.len());
@ -539,7 +530,7 @@ mod test_set {
let mut i = 0;
let expected = [1, 3, 5, 9, 11, 13, 16, 19, 24];
for a.union(&b) |x| {
assert!(vec::contains(expected, x));
assert!(expected.contains(x));
i += 1
}
assert_eq!(i, expected.len());

View file

@ -10,12 +10,11 @@
//! Sorting methods
use core::prelude::*;
use core::cmp::{Eq, Ord};
use core::uint;
use core::util::swap;
use core::vec;
use std::cmp::{Eq, Ord};
use std::uint;
use std::util::swap;
use std::vec;
type Le<'self, T> = &'self fn(v1: &T, v2: &T) -> bool;
@ -42,7 +41,8 @@ pub fn merge_sort<T:Copy>(v: &[T], le: Le<T>) -> ~[T] {
let mid = v_len / 2 + begin;
let a = (begin, mid);
let b = (mid, end);
return merge(le, merge_sort_(v, a, le), merge_sort_(v, b, le));
return merge(|x,y| le(x,y), merge_sort_(v, a, |x,y| le(x,y)),
merge_sort_(v, b, |x,y| le(x,y)));
}
fn merge<T:Copy>(le: Le<T>, a: &[T], b: &[T]) -> ~[T] {
@ -57,25 +57,25 @@ pub fn merge_sort<T:Copy>(v: &[T], le: Le<T>) -> ~[T] {
a_ix += 1;
} else { rs.push(copy b[b_ix]); b_ix += 1; }
}
rs.push_all(vec::slice(a, a_ix, a_len));
rs.push_all(vec::slice(b, b_ix, b_len));
rs.push_all(a.slice(a_ix, a_len));
rs.push_all(b.slice(b_ix, b_len));
rs
}
}
fn part<T>(arr: &mut [T], left: uint,
right: uint, pivot: uint, compare_func: Le<T>) -> uint {
vec::swap(arr, pivot, right);
arr.swap(pivot, right);
let mut storage_index: uint = left;
let mut i: uint = left;
while i < right {
if compare_func(&arr[i], &arr[right]) {
vec::swap(arr, i, storage_index);
arr.swap(i, storage_index);
storage_index += 1;
}
i += 1;
}
vec::swap(arr, storage_index, right);
arr.swap(storage_index, right);
return storage_index;
}
@ -83,10 +83,10 @@ fn qsort<T>(arr: &mut [T], left: uint,
right: uint, compare_func: Le<T>) {
if right > left {
let pivot = (left + right) / 2u;
let new_pivot = part::<T>(arr, left, right, pivot, compare_func);
let new_pivot = part::<T>(arr, left, right, pivot, |x,y| compare_func(x,y));
if new_pivot != 0u {
// Need to do this check before recursing due to overflow
qsort::<T>(arr, left, new_pivot - 1u, compare_func);
qsort::<T>(arr, left, new_pivot - 1u, |x,y| compare_func(x,y));
}
qsort::<T>(arr, new_pivot + 1u, right, compare_func);
}
@ -120,29 +120,29 @@ fn qsort3<T:Copy + Ord + Eq>(arr: &mut [T], left: int, right: int) {
j -= 1;
}
if i >= j { break; }
vec::swap(arr, i as uint, j as uint);
arr.swap(i as uint, j as uint);
if arr[i] == v {
p += 1;
vec::swap(arr, p as uint, i as uint);
arr.swap(p as uint, i as uint);
}
if v == arr[j] {
q -= 1;
vec::swap(arr, j as uint, q as uint);
arr.swap(j as uint, q as uint);
}
}
vec::swap(arr, i as uint, right as uint);
arr.swap(i as uint, right as uint);
j = i - 1;
i += 1;
let mut k: int = left;
while k < p {
vec::swap(arr, k as uint, j as uint);
arr.swap(k as uint, j as uint);
k += 1;
j -= 1;
if k == arr.len() as int { break; }
}
k = right - 1;
while k > q {
vec::swap(arr, i as uint, k as uint);
arr.swap(i as uint, k as uint);
k -= 1;
i += 1;
if k == 0 { break; }
@ -201,12 +201,12 @@ pub fn tim_sort<T:Copy + Ord>(array: &mut [T]) {
loop {
let run_len: uint = {
// This scope contains the slice `arr` here:
let arr = vec::mut_slice(array, idx, size);
let arr = array.mut_slice(idx, size);
let mut run_len: uint = count_run_ascending(arr);
if run_len < min_run {
let force = if remaining <= min_run {remaining} else {min_run};
let slice = vec::mut_slice(arr, 0, force);
let slice = arr.mut_slice(0, force);
binarysort(slice, run_len);
run_len = force;
}
@ -259,7 +259,7 @@ fn binarysort<T:Copy + Ord>(array: &mut [T], start: uint) {
fn reverse_slice<T>(v: &mut [T], start: uint, end:uint) {
let mut i = start;
while i < end / 2 {
vec::swap(v, i, end - i - 1);
v.swap(i, end - i - 1);
i += 1;
}
}
@ -443,14 +443,14 @@ impl<T:Copy + Ord> MergeState<T> {
}
let k = { // constrain lifetime of slice below
let slice = vec::slice(array, b1, b1+l1);
let slice = array.slice(b1, b1+l1);
gallop_right(&array[b2], slice, 0)
};
b1 += k;
l1 -= k;
if l1 != 0 {
let l2 = { // constrain lifetime of slice below
let slice = vec::slice(array, b2, b2+l2);
let slice = array.slice(b2, b2+l2);
gallop_left(&array[b1+l1-1],slice,l2-1)
};
if l2 > 0 {
@ -479,7 +479,7 @@ impl<T:Copy + Ord> MergeState<T> {
let mut len1 = len1;
let mut len2 = len2;
vec::swap(array, dest, c2);
array.swap(dest, c2);
dest += 1; c2 += 1; len2 -= 1;
if len2 == 0 {
@ -501,7 +501,7 @@ impl<T:Copy + Ord> MergeState<T> {
loop {
assert!(len1 > 1 && len2 != 0);
if array[c2] < tmp[c1] {
vec::swap(array, dest, c2);
array.swap(dest, c2);
dest += 1; c2 += 1; len2 -= 1;
count2 += 1; count1 = 0;
if len2 == 0 {
@ -526,7 +526,7 @@ impl<T:Copy + Ord> MergeState<T> {
assert!(len1 > 1 && len2 != 0);
count1 = {
let tmp_view = vec::slice(tmp, c1, c1+len1);
let tmp_view = tmp.slice(c1, c1+len1);
gallop_right(&array[c2], tmp_view, 0)
};
if count1 != 0 {
@ -534,12 +534,12 @@ impl<T:Copy + Ord> MergeState<T> {
dest += count1; c1 += count1; len1 -= count1;
if len1 <= 1 { break_outer = true; break; }
}
vec::swap(array, dest, c2);
array.swap(dest, c2);
dest += 1; c2 += 1; len2 -= 1;
if len2 == 0 { break_outer = true; break; }
count2 = {
let tmp_view = vec::slice(array, c2, c2+len2);
let tmp_view = array.slice(c2, c2+len2);
gallop_left(&tmp[c1], tmp_view, 0)
};
if count2 != 0 {
@ -589,7 +589,7 @@ impl<T:Copy + Ord> MergeState<T> {
let mut len1 = len1;
let mut len2 = len2;
vec::swap(array, dest, c1);
array.swap(dest, c1);
dest -= 1; c1 -= 1; len1 -= 1;
if len1 == 0 {
@ -613,7 +613,7 @@ impl<T:Copy + Ord> MergeState<T> {
loop {
assert!(len1 != 0 && len2 > 1);
if tmp[c2] < array[c1] {
vec::swap(array, dest, c1);
array.swap(dest, c1);
dest -= 1; c1 -= 1; len1 -= 1;
count1 += 1; count2 = 0;
if len1 == 0 {
@ -638,7 +638,7 @@ impl<T:Copy + Ord> MergeState<T> {
assert!(len2 > 1 && len1 != 0);
{ // constrain scope of tmp_view:
let tmp_view = vec::mut_slice (array, base1, base1+len1);
let tmp_view = array.mut_slice(base1, base1+len1);
count1 = len1 - gallop_right(
&tmp[c2], tmp_view, len1-1);
}
@ -655,7 +655,7 @@ impl<T:Copy + Ord> MergeState<T> {
let count2;
{ // constrain scope of tmp_view
let tmp_view = vec::mut_slice(tmp, 0, len2);
let tmp_view = tmp.mut_slice(0, len2);
count2 = len2 - gallop_left(&array[c1],
tmp_view,
len2-1);
@ -666,7 +666,7 @@ impl<T:Copy + Ord> MergeState<T> {
copy_vec(array, dest+1, tmp.slice(c2+1, c2+1+count2));
if len2 <= 1 { break_outer = true; break; }
}
vec::swap(array, dest, c1);
array.swap(dest, c1);
dest -= 1; c1 -= 1; len1 -= 1;
if len1 == 0 { break_outer = true; break; }
min_gallop -= 1;
@ -731,7 +731,7 @@ fn copy_vec<T:Copy>(dest: &mut [T],
from: &[T]) {
assert!(s1+from.len() <= dest.len());
for from.eachi |i, v| {
for from.iter().enumerate().advance |(i, v)| {
dest[s1+i] = copy *v;
}
}
@ -743,7 +743,7 @@ fn shift_vec<T:Copy>(dest: &mut [T],
len: uint) {
assert!(s1+len <= dest.len());
let tmp = dest.slice(s2, s2+len).to_vec();
let tmp = dest.slice(s2, s2+len).to_owned();
copy_vec(dest, s1, tmp);
}
@ -790,12 +790,11 @@ mod test_qsort3 {
#[cfg(test)]
mod test_qsort {
use core::prelude::*;
use sort::*;
use core::int;
use core::vec;
use std::int;
use std::vec;
fn check_sort(v1: &mut [int], v2: &mut [int]) {
let len = v1.len();
@ -846,7 +845,7 @@ mod test_qsort {
let immut_names = names;
let pairs = vec::zip_slice(expected, immut_names);
for pairs.each |p| {
for pairs.iter().advance |p| {
let (a, b) = *p;
debug!("%d %d", a, b);
assert_eq!(a, b);
@ -856,7 +855,6 @@ mod test_qsort {
#[cfg(test)]
mod tests {
use core::prelude::*;
use sort::*;
@ -923,12 +921,11 @@ mod tests {
#[cfg(test)]
mod test_tim_sort {
use core::prelude::*;
use sort::tim_sort;
use core::rand::RngUtil;
use core::rand;
use core::vec;
use std::rand::RngUtil;
use std::rand;
use std::vec;
struct CVal {
val: float,
@ -1018,15 +1015,14 @@ mod test_tim_sort {
#[cfg(test)]
mod big_tests {
use core::prelude::*;
use sort::*;
use core::local_data;
use core::rand::RngUtil;
use core::rand;
use core::uint;
use core::vec;
use std::local_data;
use std::rand::RngUtil;
use std::rand;
use std::uint;
use std::vec;
#[test]
fn test_unique() {
@ -1053,7 +1049,7 @@ mod big_tests {
fn makeRange(n: uint) -> ~[uint] {
let one = do vec::from_fn(n) |i| { i };
let mut two = copy one;
vec::reverse(two);
two.reverse();
vec::append(two, one)
}
@ -1077,7 +1073,7 @@ mod big_tests {
tim_sort(arr); // *sort
isSorted(arr);
vec::reverse(arr);
arr.reverse();
tim_sort(arr); // \sort
isSorted(arr);
@ -1087,7 +1083,7 @@ mod big_tests {
for 3.times {
let i1 = rng.gen_uint_range(0, n);
let i2 = rng.gen_uint_range(0, n);
vec::swap(arr, i1, i2);
arr.swap(i1, i2);
}
tim_sort(arr); // 3sort
isSorted(arr);
@ -1111,7 +1107,7 @@ mod big_tests {
isSorted(arr);
let mut arr = if n > 4 {
let part = vec::slice(arr, 0, 4);
let part = arr.slice(0, 4);
multiplyVec(part, n)
} else { arr };
tim_sort(arr); // ~sort
@ -1149,7 +1145,7 @@ mod big_tests {
tim_sort(arr); // *sort
isSorted(arr);
vec::reverse(arr);
arr.reverse();
tim_sort(arr); // \sort
isSorted(arr);
@ -1159,7 +1155,7 @@ mod big_tests {
for 3.times {
let i1 = rng.gen_uint_range(0, n);
let i2 = rng.gen_uint_range(0, n);
vec::swap(arr, i1, i2);
arr.swap(i1, i2);
}
tim_sort(arr); // 3sort
isSorted(arr);
@ -1183,7 +1179,7 @@ mod big_tests {
isSorted(arr);
let mut arr = if n > 4 {
let part = vec::slice(arr, 0, 4);
let part = arr.slice(0, 4);
multiplyVec(part, n)
} else { arr };
tim_sort(arr); // ~sort
@ -1202,12 +1198,12 @@ mod big_tests {
struct LVal<'self> {
val: uint,
key: &'self fn(@uint),
key: &'self fn:Copy(@uint),
}
#[unsafe_destructor]
impl<'self> Drop for LVal<'self> {
fn finalize(&self) {
fn drop(&self) {
let x = unsafe { local_data::local_data_get(self.key) };
match x {
Some(@y) => {

View file

@ -10,12 +10,11 @@
#[allow(missing_doc)];
use core::prelude::*;
use core::f64;
use core::cmp;
use core::num;
use core::vec;
use std::f64;
use std::cmp;
use std::num;
use std::vec;
use sort;
// NB: this can probably be rewritten in terms of num::Num
@ -72,7 +71,7 @@ impl<'self> Stats for &'self [f64] {
} else {
let mean = self.mean();
let mut v = 0.0;
for self.each |s| {
for self.iter().advance |s| {
let x = *s - mean;
v += x*x;
}

View file

@ -15,14 +15,13 @@
* in std.
*/
use core::prelude::*;
use core::borrow;
use core::comm;
use core::task;
use core::unstable::sync::{Exclusive, exclusive, UnsafeAtomicRcBox};
use core::unstable::atomics;
use core::util;
use std::borrow;
use std::comm;
use std::task;
use std::unstable::sync::{Exclusive, exclusive, UnsafeAtomicRcBox};
use std::unstable::atomics;
use std::util;
/****************************************************************************
* Internals
@ -86,7 +85,7 @@ struct SemInner<Q> {
struct Sem<Q>(Exclusive<SemInner<Q>>);
#[doc(hidden)]
fn new_sem<Q:Owned>(count: int, q: Q) -> Sem<Q> {
fn new_sem<Q:Send>(count: int, q: Q) -> Sem<Q> {
Sem(exclusive(SemInner {
count: count, waiters: new_waitqueue(), blocked: q }))
}
@ -101,7 +100,7 @@ fn new_sem_and_signal(count: int, num_condvars: uint)
}
#[doc(hidden)]
impl<Q:Owned> Sem<Q> {
impl<Q:Send> Sem<Q> {
pub fn acquire(&self) {
unsafe {
let mut waiter_nobe = None;
@ -153,7 +152,7 @@ impl Sem<()> {
#[doc(hidden)]
impl Sem<~[Waitqueue]> {
pub fn access<U>(&self, blk: &fn() -> U) -> U {
pub fn access_waitqueue<U>(&self, blk: &fn() -> U) -> U {
let mut release = None;
unsafe {
do task::unkillable {
@ -175,8 +174,8 @@ struct SemReleaseGeneric<'self, Q> { sem: &'self Sem<Q> }
#[doc(hidden)]
#[unsafe_destructor]
impl<'self, Q:Owned> Drop for SemReleaseGeneric<'self, Q> {
fn finalize(&self) {
impl<'self, Q:Send> Drop for SemReleaseGeneric<'self, Q> {
fn drop(&self) {
self.sem.release();
}
}
@ -219,7 +218,7 @@ pub struct Condvar<'self> {
}
#[unsafe_destructor]
impl<'self> Drop for Condvar<'self> { fn finalize(&self) {} }
impl<'self> Drop for Condvar<'self> { fn drop(&self) {} }
impl<'self> Condvar<'self> {
/**
@ -295,7 +294,7 @@ impl<'self> Condvar<'self> {
#[unsafe_destructor]
impl<'self> Drop for CondvarReacquire<'self> {
fn finalize(&self) {
fn drop(&self) {
unsafe {
// Needs to succeed, instead of itself dying.
do task::unkillable {
@ -381,7 +380,7 @@ impl Sem<~[Waitqueue]> {
// The only other places that condvars get built are rwlock.write_cond()
// and rwlock_write_mode.
pub fn access_cond<U>(&self, blk: &fn(c: &Condvar) -> U) -> U {
do self.access {
do self.access_waitqueue {
blk(&Condvar { sem: self, order: Nothing })
}
}
@ -456,7 +455,9 @@ impl Clone for Mutex {
impl Mutex {
/// Run a function with ownership of the mutex.
pub fn lock<U>(&self, blk: &fn() -> U) -> U { (&self.sem).access(blk) }
pub fn lock<U>(&self, blk: &fn() -> U) -> U {
(&self.sem).access_waitqueue(blk)
}
/// Run a function with ownership of the mutex and a handle to a condvar.
pub fn lock_cond<U>(&self, blk: &fn(c: &Condvar) -> U) -> U {
@ -559,9 +560,11 @@ impl RWlock {
unsafe {
do task::unkillable {
(&self.order_lock).acquire();
do (&self.access_lock).access {
do (&self.access_lock).access_waitqueue {
(&self.order_lock).release();
task::rekillable(blk)
do task::rekillable {
blk()
}
}
}
}
@ -689,7 +692,7 @@ struct RWlockReleaseRead<'self> {
#[doc(hidden)]
#[unsafe_destructor]
impl<'self> Drop for RWlockReleaseRead<'self> {
fn finalize(&self) {
fn drop(&self) {
unsafe {
do task::unkillable {
let state = &mut *self.lock.state.get();
@ -726,7 +729,7 @@ struct RWlockReleaseDowngrade<'self> {
#[doc(hidden)]
#[unsafe_destructor]
impl<'self> Drop for RWlockReleaseDowngrade<'self> {
fn finalize(&self) {
fn drop(&self) {
unsafe {
do task::unkillable {
let writer_or_last_reader;
@ -769,12 +772,12 @@ fn RWlockReleaseDowngrade<'r>(lock: &'r RWlock)
/// The "write permission" token used for rwlock.write_downgrade().
pub struct RWlockWriteMode<'self> { priv lock: &'self RWlock }
#[unsafe_destructor]
impl<'self> Drop for RWlockWriteMode<'self> { fn finalize(&self) {} }
impl<'self> Drop for RWlockWriteMode<'self> { fn drop(&self) {} }
/// The "read permission" token used for rwlock.write_downgrade().
pub struct RWlockReadMode<'self> { priv lock: &'self RWlock }
#[unsafe_destructor]
impl<'self> Drop for RWlockReadMode<'self> { fn finalize(&self) {} }
impl<'self> Drop for RWlockReadMode<'self> { fn drop(&self) {} }
impl<'self> RWlockWriteMode<'self> {
/// Access the pre-downgrade rwlock in write mode.
@ -799,16 +802,14 @@ impl<'self> RWlockReadMode<'self> {
#[cfg(test)]
mod tests {
use core::prelude::*;
use sync::*;
use core::cast;
use core::cell::Cell;
use core::comm;
use core::result;
use core::task;
use core::vec;
use std::cast;
use std::cell::Cell;
use std::comm;
use std::result;
use std::task;
/************************************************************************
* Semaphore tests
@ -994,13 +995,13 @@ mod tests {
}
// wait until all children get in the mutex
for ports.each |port| { let _ = port.recv(); }
for ports.iter().advance |port| { let _ = port.recv(); }
do m.lock_cond |cond| {
let num_woken = cond.broadcast();
assert_eq!(num_woken, num_waiters);
}
// wait until all children wake up
for ports.each |port| { let _ = port.recv(); }
for ports.iter().advance |port| { let _ = port.recv(); }
}
#[test]
fn test_mutex_cond_broadcast() {
@ -1085,7 +1086,7 @@ mod tests {
}
}
}
for sibling_convos.each |p| {
for sibling_convos.iter().advance |p| {
let _ = p.recv(); // wait for sibling to get in the mutex
}
do m2.lock { }
@ -1094,7 +1095,8 @@ mod tests {
};
assert!(result.is_err());
// child task must have finished by the time try returns
for vec::each(p.recv()) |p| { p.recv(); } // wait on all its siblings
let r = p.recv();
for r.iter().advance |p| { p.recv(); } // wait on all its siblings
do m.lock_cond |cond| {
let woken = cond.broadcast();
assert_eq!(woken, 0);
@ -1104,7 +1106,7 @@ mod tests {
}
impl Drop for SendOnFailure {
fn finalize(&self) {
fn drop(&self) {
self.c.send(());
}
}
@ -1180,12 +1182,12 @@ mod tests {
Write => x.write(blk),
Downgrade =>
do x.write_downgrade |mode| {
(&mode).write(blk);
do mode.write { blk() };
},
DowngradeRead =>
do x.write_downgrade |mode| {
let mode = x.downgrade(mode);
(&mode).read(blk);
do mode.read { blk() };
},
}
}
@ -1338,10 +1340,10 @@ mod tests {
fn lock_cond(x: &RWlock, downgrade: bool, blk: &fn(c: &Condvar)) {
if downgrade {
do x.write_downgrade |mode| {
(&mode).write_cond(blk)
do mode.write_cond |c| { blk(c) }
}
} else {
x.write_cond(blk)
do x.write_cond |c| { blk(c) }
}
}
let x = ~RWlock();
@ -1361,13 +1363,13 @@ mod tests {
}
// wait until all children get in the mutex
for ports.each |port| { let _ = port.recv(); }
for ports.iter().advance |port| { let _ = port.recv(); }
do lock_cond(x, dg2) |cond| {
let num_woken = cond.broadcast();
assert_eq!(num_woken, num_waiters);
}
// wait until all children wake up
for ports.each |port| { let _ = port.recv(); }
for ports.iter().advance |port| { let _ = port.recv(); }
}
#[test]
fn test_rwlock_cond_broadcast() {

View file

@ -13,15 +13,14 @@
/// A task pool abstraction. Useful for achieving predictable CPU
/// parallelism.
use core::prelude::*;
use core::comm::Chan;
use core::comm;
use core::task::SchedMode;
use core::task;
use core::vec;
use std::comm::Chan;
use std::comm;
use std::task::SchedMode;
use std::task;
use std::vec;
#[cfg(test)] use core::task::SingleThreaded;
#[cfg(test)] use std::task::SingleThreaded;
enum Msg<T> {
Execute(~fn(&T)),
@ -35,8 +34,8 @@ pub struct TaskPool<T> {
#[unsafe_destructor]
impl<T> Drop for TaskPool<T> {
fn finalize(&self) {
for self.channels.each |channel| {
fn drop(&self) {
for self.channels.iter().advance |channel| {
channel.send(Quit);
}
}

View file

@ -10,11 +10,10 @@
//! Temporary files and directories
use core::prelude::*;
use core::os;
use core::rand::RngUtil;
use core::rand;
use std::os;
use std::rand::RngUtil;
use std::rand;
/// Attempts to make a temporary directory inside of `tmpdir` whose name will
/// have the suffix `suffix`. If no directory can be created, None is returned.
@ -31,11 +30,10 @@ pub fn mkdtemp(tmpdir: &Path, suffix: &str) -> Option<Path> {
#[cfg(test)]
mod tests {
use core::prelude::*;
use tempfile::mkdtemp;
use core::os;
use std::os;
#[test]
fn test_mkdtemp() {
@ -44,12 +42,12 @@ mod tests {
assert!(p.to_str().ends_with("foobar"));
}
// Ideally these would be in core::os but then core would need
// Ideally these would be in std::os but then core would need
// to depend on std
#[test]
fn recursive_mkdir_rel() {
use core::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
use core::os;
use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
use std::os;
let root = mkdtemp(&os::tmpdir(), "recursive_mkdir_rel").
expect("recursive_mkdir_rel");
@ -67,8 +65,8 @@ mod tests {
#[test]
fn recursive_mkdir_dot() {
use core::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
use core::os;
use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
use std::os;
let dot = Path(".");
assert!(os::mkdir_recursive(&dot, (S_IRUSR | S_IWUSR | S_IXUSR) as i32));
@ -78,8 +76,8 @@ mod tests {
#[test]
fn recursive_mkdir_rel_2() {
use core::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
use core::os;
use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
use std::os;
let root = mkdtemp(&os::tmpdir(), "recursive_mkdir_rel_2").
expect("recursive_mkdir_rel_2");
@ -102,8 +100,8 @@ mod tests {
// Ideally this would be in core, but needs mkdtemp
#[test]
pub fn test_rmdir_recursive_ok() {
use core::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
use core::os;
use std::libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
use std::os;
let rwx = (S_IRUSR | S_IWUSR | S_IXUSR) as i32;

View file

@ -12,47 +12,49 @@
#[allow(missing_doc)];
use core::prelude::*;
use core::io;
use core::os;
use std::io;
use terminfo::*;
use terminfo::searcher::open;
use terminfo::parser::compiled::parse;
use terminfo::parm::{expand, Number, Variables};
#[cfg(not(target_os = "win32"))] use std::os;
#[cfg(not(target_os = "win32"))] use terminfo::*;
#[cfg(not(target_os = "win32"))] use terminfo::searcher::open;
#[cfg(not(target_os = "win32"))] use terminfo::parser::compiled::parse;
#[cfg(not(target_os = "win32"))] use terminfo::parm::{expand, Number, Variables};
// FIXME (#2807): Windows support.
pub static color_black: u8 = 0u8;
pub static color_red: u8 = 1u8;
pub static color_green: u8 = 2u8;
pub static color_yellow: u8 = 3u8;
pub static color_blue: u8 = 4u8;
pub static color_magenta: u8 = 5u8;
pub static color_cyan: u8 = 6u8;
pub static color_light_gray: u8 = 7u8;
pub static color_light_grey: u8 = 7u8;
pub static color_dark_gray: u8 = 8u8;
pub static color_dark_grey: u8 = 8u8;
pub static color_bright_red: u8 = 9u8;
pub static color_bright_green: u8 = 10u8;
pub static color_bright_yellow: u8 = 11u8;
pub static color_bright_blue: u8 = 12u8;
pub static color_bright_magenta: u8 = 13u8;
pub static color_bright_cyan: u8 = 14u8;
pub static color_bright_white: u8 = 15u8;
pub mod color {
pub type Color = u16;
pub static black: Color = 0u16;
pub static red: Color = 1u16;
pub static green: Color = 2u16;
pub static yellow: Color = 3u16;
pub static blue: Color = 4u16;
pub static magenta: Color = 5u16;
pub static cyan: Color = 6u16;
pub static white: Color = 7u16;
pub static bright_black: Color = 8u16;
pub static bright_red: Color = 9u16;
pub static bright_green: Color = 10u16;
pub static bright_yellow: Color = 11u16;
pub static bright_blue: Color = 12u16;
pub static bright_magenta: Color = 13u16;
pub static bright_cyan: Color = 14u16;
pub static bright_white: Color = 15u16;
}
#[cfg(not(target_os = "win32"))]
pub struct Terminal {
color_supported: bool,
num_colors: u16,
priv out: @io::Writer,
priv ti: ~TermInfo
}
#[cfg(target_os = "win32")]
pub struct Terminal {
color_supported: bool,
num_colors: u16,
priv out: @io::Writer,
}
@ -66,66 +68,86 @@ impl Terminal {
let entry = open(term.unwrap());
if entry.is_err() {
return Err(entry.get_err());
return Err(entry.unwrap_err());
}
let ti = parse(entry.get(), false);
let ti = parse(entry.unwrap(), false);
if ti.is_err() {
return Err(entry.get_err());
return Err(ti.unwrap_err());
}
let mut inf = ti.get();
let cs = *inf.numbers.find_or_insert(~"colors", 0) >= 16
&& inf.strings.find(&~"setaf").is_some()
&& inf.strings.find_equiv(&("setab")).is_some();
let inf = ti.unwrap();
let nc = if inf.strings.find_equiv(&("setaf")).is_some()
&& inf.strings.find_equiv(&("setab")).is_some() {
inf.numbers.find_equiv(&("colors")).map_consume_default(0, |&n| n)
} else { 0 };
return Ok(Terminal {out: out, ti: inf, color_supported: cs});
return Ok(Terminal {out: out, ti: inf, num_colors: nc});
}
pub fn fg(&self, color: u8) {
if self.color_supported {
/// Sets the foreground color to the given color.
///
/// If the color is a bright color, but the terminal only supports 8 colors,
/// the corresponding normal color will be used instead.
pub fn fg(&self, color: color::Color) {
let color = self.dim_if_necessary(color);
if self.num_colors > color {
let s = expand(*self.ti.strings.find_equiv(&("setaf")).unwrap(),
[Number(color as int)], &mut Variables::new());
if s.is_ok() {
self.out.write(s.get());
self.out.write(s.unwrap());
} else {
warn!(s.get_err());
warn!("%s", s.unwrap_err());
}
}
}
pub fn bg(&self, color: u8) {
if self.color_supported {
/// Sets the background color to the given color.
///
/// If the color is a bright color, but the terminal only supports 8 colors,
/// the corresponding normal color will be used instead.
pub fn bg(&self, color: color::Color) {
let color = self.dim_if_necessary(color);
if self.num_colors > color {
let s = expand(*self.ti.strings.find_equiv(&("setab")).unwrap(),
[Number(color as int)], &mut Variables::new());
if s.is_ok() {
self.out.write(s.get());
self.out.write(s.unwrap());
} else {
warn!(s.get_err());
warn!("%s", s.unwrap_err());
}
}
}
pub fn reset(&self) {
if self.color_supported {
let mut vars = Variables::new();
let s = expand(*self.ti.strings.find_equiv(&("op")).unwrap(), [], &mut vars);
if s.is_ok() {
self.out.write(s.get());
} else {
warn!(s.get_err());
}
let mut vars = Variables::new();
let s = do self.ti.strings.find_equiv(&("op"))
.map_consume_default(Err(~"can't find terminfo capability `op`")) |&op| {
expand(op, [], &mut vars)
};
if s.is_ok() {
self.out.write(s.unwrap());
} else if self.num_colors > 0 {
warn!("%s", s.unwrap_err());
} else {
debug!("%s", s.unwrap_err());
}
}
priv fn dim_if_necessary(&self, color: color::Color) -> color::Color {
if color >= self.num_colors && color >= 8 && color < 16 {
color-8
} else { color }
}
}
#[cfg(target_os = "win32")]
impl Terminal {
pub fn new(out: @io::Writer) -> Result<Terminal, ~str> {
return Ok(Terminal {out: out, color_supported: false});
return Ok(Terminal {out: out, num_colors: 0});
}
pub fn fg(&self, color: u8) {
pub fn fg(&self, _color: color::Color) {
}
pub fn bg(&self, color: u8) {
pub fn bg(&self, _color: color::Color) {
}
pub fn reset(&self) {

View file

@ -10,9 +10,9 @@
//! Parameterized string expansion
use core::prelude::*;
use core::{char, int, vec};
use core::iterator::IteratorUtil;
use std::{char, vec, util};
use std::num::strconv::{SignNone,SignNeg,SignAll,int_to_str_bytes_common};
use std::iterator::IteratorUtil;
#[deriving(Eq)]
enum States {
@ -23,13 +23,21 @@ enum States {
PushParam,
CharConstant,
CharClose,
IntConstant,
IntConstant(int),
FormatPattern(Flags, FormatState),
SeekIfElse(int),
SeekIfElsePercent(int),
SeekIfEnd(int),
SeekIfEndPercent(int)
}
#[deriving(Eq)]
enum FormatState {
FormatStateFlags,
FormatStateWidth,
FormatStatePrecision
}
/// Types of parameters a capability can use
pub enum Param {
String(~str),
@ -71,8 +79,6 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables)
let mut stack: ~[Param] = ~[];
let mut intstate = ~[];
// Copy parameters into a local vector for mutability
let mut mparams = [Number(0), ..9];
for mparams.mut_iter().zip(params.iter()).advance |(dst, &src)| {
@ -100,26 +106,11 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables)
_ => return Err(~"a non-char was used with %c")
}
} else { return Err(~"stack is empty") },
's' => if stack.len() > 0 {
match stack.pop() {
String(s) => output.push_all(s.as_bytes()),
_ => return Err(~"a non-str was used with %s")
}
} else { return Err(~"stack is empty") },
'd' => if stack.len() > 0 {
match stack.pop() {
Number(x) => {
let s = x.to_str();
output.push_all(s.as_bytes())
}
_ => return Err(~"a non-number was used with %d")
}
} else { return Err(~"stack is empty") },
'p' => state = PushParam,
'P' => state = SetVar,
'g' => state = GetVar,
'\'' => state = CharConstant,
'{' => state = IntConstant,
'{' => state = IntConstant(0),
'l' => if stack.len() > 0 {
match stack.pop() {
String(s) => stack.push(Number(s.len() as int)),
@ -231,6 +222,30 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables)
(_, _) => return Err(~"first two params not numbers with %i")
},
// printf-style support for %doxXs
'd'|'o'|'x'|'X'|'s' => if stack.len() > 0 {
let flags = Flags::new();
let res = format(stack.pop(), FormatOp::from_char(cur), flags);
if res.is_err() { return res }
output.push_all(res.unwrap())
} else { return Err(~"stack is empty") },
':'|'#'|' '|'.'|'0'..'9' => {
let mut flags = Flags::new();
let mut fstate = FormatStateFlags;
match cur {
':' => (),
'#' => flags.alternate = true,
' ' => flags.space = true,
'.' => fstate = FormatStatePrecision,
'0'..'9' => {
flags.width = (cur - '0') as uint;
fstate = FormatStateWidth;
}
_ => util::unreachable()
}
state = FormatPattern(flags, fstate);
}
// conditionals
'?' => (),
't' => if stack.len() > 0 {
@ -288,17 +303,61 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables)
return Err(~"malformed character constant");
}
},
IntConstant => {
if cur == '}' {
stack.push(match int::parse_bytes(intstate, 10) {
Some(n) => Number(n),
None => return Err(~"bad int constant")
});
intstate.clear();
state = Nothing;
} else {
intstate.push(cur as u8);
old_state = Nothing;
IntConstant(i) => {
match cur {
'}' => {
stack.push(Number(i));
state = Nothing;
}
'0'..'9' => {
state = IntConstant(i*10 + ((cur - '0') as int));
old_state = Nothing;
}
_ => return Err(~"bad int constant")
}
}
FormatPattern(ref mut flags, ref mut fstate) => {
old_state = Nothing;
match (*fstate, cur) {
(_,'d')|(_,'o')|(_,'x')|(_,'X')|(_,'s') => if stack.len() > 0 {
let res = format(stack.pop(), FormatOp::from_char(cur), *flags);
if res.is_err() { return res }
output.push_all(res.unwrap());
old_state = state; // will cause state to go to Nothing
} else { return Err(~"stack is empty") },
(FormatStateFlags,'#') => {
flags.alternate = true;
}
(FormatStateFlags,'-') => {
flags.left = true;
}
(FormatStateFlags,'+') => {
flags.sign = true;
}
(FormatStateFlags,' ') => {
flags.space = true;
}
(FormatStateFlags,'0'..'9') => {
flags.width = (cur - '0') as uint;
*fstate = FormatStateWidth;
}
(FormatStateFlags,'.') => {
*fstate = FormatStatePrecision;
}
(FormatStateWidth,'0'..'9') => {
let old = flags.width;
flags.width = flags.width * 10 + ((cur - '0') as uint);
if flags.width < old { return Err(~"format width overflow") }
}
(FormatStateWidth,'.') => {
*fstate = FormatStatePrecision;
}
(FormatStatePrecision,'0'..'9') => {
let old = flags.precision;
flags.precision = flags.precision * 10 + ((cur - '0') as uint);
if flags.precision < old { return Err(~"format precision overflow") }
}
_ => return Err(~"invalid format specifier")
}
}
SeekIfElse(level) => {
@ -349,10 +408,153 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables)
Ok(output)
}
#[deriving(Eq)]
priv struct Flags {
width: uint,
precision: uint,
alternate: bool,
left: bool,
sign: bool,
space: bool
}
impl Flags {
priv fn new() -> Flags {
Flags{ width: 0, precision: 0, alternate: false,
left: false, sign: false, space: false }
}
}
priv enum FormatOp {
FormatDigit,
FormatOctal,
FormatHex,
FormatHEX,
FormatString
}
impl FormatOp {
priv fn from_char(c: char) -> FormatOp {
match c {
'd' => FormatDigit,
'o' => FormatOctal,
'x' => FormatHex,
'X' => FormatHEX,
's' => FormatString,
_ => fail!("bad FormatOp char")
}
}
priv fn to_char(self) -> char {
match self {
FormatDigit => 'd',
FormatOctal => 'o',
FormatHex => 'x',
FormatHEX => 'X',
FormatString => 's'
}
}
}
priv fn format(val: Param, op: FormatOp, flags: Flags) -> Result<~[u8],~str> {
let mut s = match val {
Number(d) => {
match op {
FormatString => {
return Err(~"non-number on stack with %s")
}
_ => {
let radix = match op {
FormatDigit => 10,
FormatOctal => 8,
FormatHex|FormatHEX => 16,
FormatString => util::unreachable()
};
let mut s = ~[];
match op {
FormatDigit => {
let sign = if flags.sign { SignAll } else { SignNeg };
do int_to_str_bytes_common(d, radix, sign) |c| {
s.push(c);
}
}
_ => {
do int_to_str_bytes_common(d as uint, radix, SignNone) |c| {
s.push(c);
}
}
};
if flags.precision > s.len() {
let mut s_ = vec::with_capacity(flags.precision);
let n = flags.precision - s.len();
s_.grow(n, &('0' as u8));
s_.push_all_move(s);
s = s_;
}
assert!(!s.is_empty(), "string conversion produced empty result");
match op {
FormatDigit => {
if flags.space && !(s[0] == '-' as u8 || s[0] == '+' as u8) {
s.unshift(' ' as u8);
}
}
FormatOctal => {
if flags.alternate && s[0] != '0' as u8 {
s.unshift('0' as u8);
}
}
FormatHex => {
if flags.alternate {
let s_ = util::replace(&mut s, ~['0' as u8, 'x' as u8]);
s.push_all_move(s_);
}
}
FormatHEX => {
s = s.into_ascii().to_upper().into_bytes();
if flags.alternate {
let s_ = util::replace(&mut s, ~['0' as u8, 'X' as u8]);
s.push_all_move(s_);
}
}
FormatString => util::unreachable()
}
s
}
}
}
String(s) => {
match op {
FormatString => {
let mut s = s.as_bytes_with_null_consume();
s.pop(); // remove the null
if flags.precision > 0 && flags.precision < s.len() {
s.truncate(flags.precision);
}
s
}
_ => {
return Err(fmt!("non-string on stack with %%%c", op.to_char()))
}
}
}
};
if flags.width > s.len() {
let n = flags.width - s.len();
if flags.left {
s.grow(n, &(' ' as u8));
} else {
let mut s_ = vec::with_capacity(flags.width);
s_.grow(n, &(' ' as u8));
s_.push_all_move(s);
s = s_;
}
}
Ok(s)
}
#[cfg(test)]
mod test {
use super::*;
use core::result::Ok;
use std::result::Ok;
#[test]
fn test_basic_setabf() {
@ -443,4 +645,20 @@ mod test {
assert!(res.is_ok(), res.unwrap_err());
assert_eq!(res.unwrap(), bytes!("\\E[38;5;42m").to_owned());
}
#[test]
fn test_format() {
let mut varstruct = Variables::new();
let vars = &mut varstruct;
assert_eq!(expand(bytes!("%p1%s%p2%2s%p3%2s%p4%.2s"),
[String(~"foo"), String(~"foo"), String(~"f"), String(~"foo")], vars),
Ok(bytes!("foofoo ffo").to_owned()));
assert_eq!(expand(bytes!("%p1%:-4.2s"), [String(~"foo")], vars),
Ok(bytes!("fo ").to_owned()));
assert_eq!(expand(bytes!("%p1%d%p1%.3d%p1%5d%p1%:+d"), [Number(1)], vars),
Ok(bytes!("1001 1+1").to_owned()));
assert_eq!(expand(bytes!("%p1%o%p1%#o%p2%6.4x%p2%#6.4X"), [Number(15), Number(27)], vars),
Ok(bytes!("17017 001b0X001B").to_owned()));
}
}

View file

@ -10,11 +10,10 @@
/// ncurses-compatible compiled terminfo format parsing (term(5))
use core::prelude::*;
use core::{vec, int, str};
use core::io::Reader;
use core::hashmap::HashMap;
use std::{vec, int, str};
use std::io::Reader;
use std::hashmap::HashMap;
use super::super::TermInfo;
// These are the orders ncurses uses in its compiled format (as of 5.9). Not sure if portable.
@ -271,7 +270,7 @@ pub fn parse(file: @Reader, longnames: bool) -> Result<~TermInfo, ~str> {
return Err(~"error: hit EOF before end of string table");
}
for string_offsets.eachi |i, v| {
for string_offsets.iter().enumerate().advance |(i, v)| {
let offset = *v;
if offset == 0xFFFF { // non-entry
loop;
@ -292,12 +291,13 @@ pub fn parse(file: @Reader, longnames: bool) -> Result<~TermInfo, ~str> {
// Find the offset of the NUL we want to go to
let nulpos = vec::position_between(string_table, offset as uint,
string_table_bytes as uint, |&b| b == 0);
let nulpos = string_table.slice(offset as uint, string_table_bytes as uint)
.iter().position_(|&b| b == 0);
match nulpos {
Some(x) => {
Some(len) => {
string_map.insert(name.to_owned(),
string_table.slice(offset as uint, x).to_owned())
string_table.slice(offset as uint,
offset as uint + len).to_owned())
},
None => {
return Err(~"invalid file: missing NUL in string_table");

View file

@ -11,11 +11,10 @@
/// Implement ncurses-compatible database discovery
/// Does not support hashed database, only filesystem!
use core::prelude::*;
use core::{os, str};
use core::os::getenv;
use core::io::{file_reader, Reader};
use path = core::path::Path;
use std::{os, str};
use std::os::getenv;
use std::io::{file_reader, Reader};
use path = std::path::Path;
/// Return path to database entry for `term`
pub fn get_dbpath_for_term(term: &str) -> Option<~path> {
@ -55,7 +54,7 @@ pub fn get_dbpath_for_term(term: &str) -> Option<~path> {
};
// Look for the terminal in all of the search directories
for dirs_to_search.each |p| {
for dirs_to_search.iter().advance |p| {
let newp = ~p.push_many(&[str::from_char(first_char), term.to_owned()]);
if os::path_exists(p) && os::path_exists(newp) {
return Some(newp);

View file

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use core::hashmap::HashMap;
use std::hashmap::HashMap;
/// A parsed terminfo entry.
pub struct TermInfo {

View file

@ -15,21 +15,26 @@
// simplest interface possible for representing and running tests
// while providing a base that other test frameworks may build off of.
use core::prelude::*;
use getopts;
use sort;
use stats::Stats;
use term;
use time::precise_time_ns;
use core::comm::{stream, SharedChan};
use core::either;
use core::io;
use core::option;
use core::result;
use core::task;
use core::to_str::ToStr;
use core::uint;
use core::vec;
use std::comm::{stream, SharedChan};
use std::either;
use std::io;
use std::num;
use std::option;
use std::rand::RngUtil;
use std::rand;
use std::result;
use std::task;
use std::to_str::ToStr;
use std::u64;
use std::uint;
use std::vec;
// The name of a test. By convention this follows the rules for rust
@ -131,7 +136,7 @@ type OptRes = Either<TestOpts, ~str>;
// Parses command line arguments into test options
pub fn parse_opts(args: &[~str]) -> OptRes {
let args_ = vec::tail(args);
let args_ = args.tail();
let opts = ~[getopts::optflag("ignored"),
getopts::optflag("test"),
getopts::optflag("bench"),
@ -318,33 +323,33 @@ pub fn run_tests_console(opts: &TestOpts,
}
fn write_ok(out: @io::Writer, use_color: bool) {
write_pretty(out, "ok", term::color_green, use_color);
write_pretty(out, "ok", term::color::green, use_color);
}
fn write_failed(out: @io::Writer, use_color: bool) {
write_pretty(out, "FAILED", term::color_red, use_color);
write_pretty(out, "FAILED", term::color::red, use_color);
}
fn write_ignored(out: @io::Writer, use_color: bool) {
write_pretty(out, "ignored", term::color_yellow, use_color);
write_pretty(out, "ignored", term::color::yellow, use_color);
}
fn write_bench(out: @io::Writer, use_color: bool) {
write_pretty(out, "bench", term::color_cyan, use_color);
write_pretty(out, "bench", term::color::cyan, use_color);
}
fn write_pretty(out: @io::Writer,
word: &str,
color: u8,
color: term::color::Color,
use_color: bool) {
let t = term::Terminal::new(out);
match t {
Ok(term) => {
if use_color && term.color_supported {
if use_color {
term.fg(color);
}
out.write_str(word);
if use_color && term.color_supported {
if use_color {
term.reset();
}
},
@ -361,7 +366,7 @@ fn print_failures(st: &ConsoleTestState) {
failures.push(name.to_str());
}
sort::tim_sort(failures);
for failures.each |name| {
for failures.iter().advance |name| {
st.out.write_line(fmt!(" %s", name.to_str()));
}
}
@ -415,7 +420,7 @@ type MonitorMsg = (TestDesc, TestResult);
fn run_tests(opts: &TestOpts,
tests: ~[TestDescAndFn],
callback: @fn(e: TestEvent)) {
callback: &fn(e: TestEvent)) {
let filtered_tests = filter_tests(opts, tests);
let filtered_descs = filtered_tests.map(|t| copy t.desc);
@ -423,7 +428,7 @@ fn run_tests(opts: &TestOpts,
callback(TeFiltered(filtered_descs));
let (filtered_tests, filtered_benchs) =
do vec::partition(filtered_tests) |e| {
do filtered_tests.partition |e| {
match e.testfn {
StaticTestFn(_) | DynTestFn(_) => true,
StaticBenchFn(_) | DynBenchFn(_) => false
@ -436,7 +441,7 @@ fn run_tests(opts: &TestOpts,
debug!("using %u test tasks", concurrency);
let mut remaining = filtered_tests;
vec::reverse(remaining);
remaining.reverse();
let mut pending = 0;
let (p, ch) = stream();
@ -480,7 +485,7 @@ static sched_overcommit : uint = 1;
static sched_overcommit : uint = 4u;
fn get_concurrency() -> uint {
use core::rt;
use std::rt;
let threads = rt::util::default_sched_threads();
if threads == 1 { 1 }
else { threads * sched_overcommit }
@ -558,7 +563,7 @@ pub fn run_test(force_ignore: bool,
fn run_test_inner(desc: TestDesc,
monitor_ch: SharedChan<MonitorMsg>,
testfn: ~fn()) {
let testfn_cell = ::core::cell::Cell::new(testfn);
let testfn_cell = ::std::cell::Cell::new(testfn);
do task::spawn {
let mut result_future = None; // task::future_result(builder);
@ -600,153 +605,144 @@ fn calc_result(desc: &TestDesc, task_succeeded: bool) -> TestResult {
}
}
pub mod bench {
use core::prelude::*;
use core::num;
use core::rand::RngUtil;
use core::rand;
use core::u64;
use core::vec;
use stats::Stats;
use test::{BenchHarness, BenchSamples};
use time::precise_time_ns;
impl BenchHarness {
/// Callback for benchmark functions to run in their body.
pub fn iter(&mut self, inner:&fn()) {
self.ns_start = precise_time_ns();
let k = self.iterations;
for u64::range(0, k) |_| {
inner();
}
self.ns_end = precise_time_ns();
impl BenchHarness {
/// Callback for benchmark functions to run in their body.
pub fn iter(&mut self, inner:&fn()) {
self.ns_start = precise_time_ns();
let k = self.iterations;
for u64::range(0, k) |_| {
inner();
}
self.ns_end = precise_time_ns();
}
pub fn ns_elapsed(&mut self) -> u64 {
if self.ns_start == 0 || self.ns_end == 0 {
0
} else {
self.ns_end - self.ns_start
}
}
pub fn ns_per_iter(&mut self) -> u64 {
if self.iterations == 0 {
0
} else {
self.ns_elapsed() / self.iterations
}
}
pub fn bench_n(&mut self, n: u64, f: &fn(&mut BenchHarness)) {
self.iterations = n;
debug!("running benchmark for %u iterations",
n as uint);
f(self);
}
// This is the Go benchmark algorithm. It produces a single
// datapoint and always tries to run for 1s.
pub fn go_bench(&mut self, f: &fn(&mut BenchHarness)) {
// Rounds a number down to the nearest power of 10.
fn round_down_10(n: u64) -> u64 {
let mut n = n;
let mut res = 1;
while n > 10 {
n = n / 10;
res *= 10;
}
res
}
// Rounds x up to a number of the form [1eX, 2eX, 5eX].
fn round_up(n: u64) -> u64 {
let base = round_down_10(n);
if n < (2 * base) {
2 * base
} else if n < (5 * base) {
5 * base
} else {
10 * base
}
}
// Initial bench run to get ballpark figure.
let mut n = 1_u64;
self.bench_n(n, f);
while n < 1_000_000_000 &&
self.ns_elapsed() < 1_000_000_000 {
let last = n;
// Try to estimate iter count for 1s falling back to 1bn
// iterations if first run took < 1ns.
if self.ns_per_iter() == 0 {
n = 1_000_000_000;
} else {
n = 1_000_000_000 / self.ns_per_iter();
}
n = u64::max(u64::min(n+n/2, 100*last), last+1);
n = round_up(n);
self.bench_n(n, f);
}
}
// This is a more statistics-driven benchmark algorithm.
// It stops as quickly as 50ms, so long as the statistical
// properties are satisfactory. If those properties are
// not met, it may run as long as the Go algorithm.
pub fn auto_bench(&mut self, f: &fn(&mut BenchHarness)) -> ~[f64] {
let mut rng = rand::rng();
let mut magnitude = 10;
let mut prev_madp = 0.0;
loop {
let n_samples = rng.gen_uint_range(50, 60);
let n_iter = rng.gen_uint_range(magnitude,
magnitude * 2);
let samples = do vec::from_fn(n_samples) |_| {
self.bench_n(n_iter as u64, f);
self.ns_per_iter() as f64
};
// Eliminate outliers
let med = samples.median();
let mad = samples.median_abs_dev();
let samples = do vec::filter(samples) |f| {
num::abs(*f - med) <= 3.0 * mad
};
debug!("%u samples, median %f, MAD=%f, %u survived filter",
n_samples, med as float, mad as float,
samples.len());
if samples.len() != 0 {
// If we have _any_ cluster of signal...
let curr_madp = samples.median_abs_dev_pct();
if self.ns_elapsed() > 1_000_000 &&
(curr_madp < 1.0 ||
num::abs(curr_madp - prev_madp) < 0.1) {
return samples;
}
prev_madp = curr_madp;
if n_iter > 20_000_000 ||
self.ns_elapsed() > 20_000_000 {
return samples;
}
}
magnitude *= 2;
}
pub fn ns_elapsed(&mut self) -> u64 {
if self.ns_start == 0 || self.ns_end == 0 {
0
} else {
self.ns_end - self.ns_start
}
}
pub fn ns_per_iter(&mut self) -> u64 {
if self.iterations == 0 {
0
} else {
self.ns_elapsed() / self.iterations
}
}
pub fn bench_n(&mut self, n: u64, f: &fn(&mut BenchHarness)) {
self.iterations = n;
debug!("running benchmark for %u iterations",
n as uint);
f(self);
}
// This is the Go benchmark algorithm. It produces a single
// datapoint and always tries to run for 1s.
pub fn go_bench(&mut self, f: &fn(&mut BenchHarness)) {
// Rounds a number down to the nearest power of 10.
fn round_down_10(n: u64) -> u64 {
let mut n = n;
let mut res = 1;
while n > 10 {
n = n / 10;
res *= 10;
}
res
}
// Rounds x up to a number of the form [1eX, 2eX, 5eX].
fn round_up(n: u64) -> u64 {
let base = round_down_10(n);
if n < (2 * base) {
2 * base
} else if n < (5 * base) {
5 * base
} else {
10 * base
}
}
// Initial bench run to get ballpark figure.
let mut n = 1_u64;
self.bench_n(n, |x| f(x));
while n < 1_000_000_000 &&
self.ns_elapsed() < 1_000_000_000 {
let last = n;
// Try to estimate iter count for 1s falling back to 1bn
// iterations if first run took < 1ns.
if self.ns_per_iter() == 0 {
n = 1_000_000_000;
} else {
n = 1_000_000_000 / self.ns_per_iter();
}
n = u64::max(u64::min(n+n/2, 100*last), last+1);
n = round_up(n);
self.bench_n(n, |x| f(x));
}
}
// This is a more statistics-driven benchmark algorithm.
// It stops as quickly as 50ms, so long as the statistical
// properties are satisfactory. If those properties are
// not met, it may run as long as the Go algorithm.
pub fn auto_bench(&mut self, f: &fn(&mut BenchHarness)) -> ~[f64] {
let mut rng = rand::rng();
let mut magnitude = 10;
let mut prev_madp = 0.0;
loop {
let n_samples = rng.gen_uint_range(50, 60);
let n_iter = rng.gen_uint_range(magnitude,
magnitude * 2);
let samples = do vec::from_fn(n_samples) |_| {
self.bench_n(n_iter as u64, |x| f(x));
self.ns_per_iter() as f64
};
// Eliminate outliers
let med = samples.median();
let mad = samples.median_abs_dev();
let samples = do vec::filter(samples) |f| {
num::abs(*f - med) <= 3.0 * mad
};
debug!("%u samples, median %f, MAD=%f, %u survived filter",
n_samples, med as float, mad as float,
samples.len());
if samples.len() != 0 {
// If we have _any_ cluster of signal...
let curr_madp = samples.median_abs_dev_pct();
if self.ns_elapsed() > 1_000_000 &&
(curr_madp < 1.0 ||
num::abs(curr_madp - prev_madp) < 0.1) {
return samples;
}
prev_madp = curr_madp;
if n_iter > 20_000_000 ||
self.ns_elapsed() > 20_000_000 {
return samples;
}
}
magnitude *= 2;
}
}
}
pub mod bench {
use test::{BenchHarness, BenchSamples};
pub fn benchmark(f: &fn(&mut BenchHarness)) -> BenchSamples {
let mut bs = BenchHarness {
@ -775,10 +771,10 @@ mod tests {
StaticTestName, DynTestName, DynTestFn};
use test::{TestOpts, run_test};
use core::either;
use core::comm::{stream, SharedChan};
use core::option;
use core::vec;
use std::either;
use std::comm::{stream, SharedChan};
use std::option;
use std::vec;
#[test]
pub fn do_not_run_ignored_tests() {
@ -938,7 +934,7 @@ mod tests {
{
fn testfn() { }
let mut tests = ~[];
for names.each |name| {
for names.iter().advance |name| {
let test = TestDescAndFn {
desc: TestDesc {
name: DynTestName(copy *name),
@ -964,7 +960,7 @@ mod tests {
let pairs = vec::zip(expected, filtered);
for pairs.each |p| {
for pairs.iter().advance |p| {
match *p {
(ref a, ref b) => {
assert!(*a == b.desc.name.to_str());

View file

@ -10,12 +10,11 @@
#[allow(missing_doc)];
use core::prelude::*;
use core::i32;
use core::int;
use core::io;
use core::str;
use std::i32;
use std::int;
use std::io;
use std::str;
static NSEC_PER_SEC: i32 = 1_000_000_000_i32;
@ -849,7 +848,7 @@ priv fn do_strftime(format: &str, tm: &Tm) -> ~str {
do io::with_str_reader(format) |rdr| {
while !rdr.eof() {
match rdr.read_char() {
'%' => buf += parse_type(rdr.read_char(), tm),
'%' => buf.push_str(parse_type(rdr.read_char(), tm)),
ch => buf.push_char(ch)
}
}
@ -862,11 +861,11 @@ priv fn do_strftime(format: &str, tm: &Tm) -> ~str {
mod tests {
use time::*;
use core::float;
use core::os;
use core::result;
use core::result::{Err, Ok};
use core::str;
use std::float;
use std::os;
use std::result;
use std::result::{Err, Ok};
use std::str;
fn test_get_time() {
static some_recent_date: i64 = 1325376000i64; // 2012-01-01T00:00:00Z
@ -1033,7 +1032,7 @@ mod tests {
}
}
for [
let days = [
~"Sunday",
~"Monday",
~"Tuesday",
@ -1041,11 +1040,12 @@ mod tests {
~"Thursday",
~"Friday",
~"Saturday"
].each |day| {
];
for days.iter().advance |day| {
assert!(test(*day, "%A"));
}
for [
let days = [
~"Sun",
~"Mon",
~"Tue",
@ -1053,11 +1053,12 @@ mod tests {
~"Thu",
~"Fri",
~"Sat"
].each |day| {
];
for days.iter().advance |day| {
assert!(test(*day, "%a"));
}
for [
let months = [
~"January",
~"February",
~"March",
@ -1070,11 +1071,12 @@ mod tests {
~"October",
~"November",
~"December"
].each |day| {
];
for months.iter().advance |day| {
assert!(test(*day, "%B"));
}
for [
let months = [
~"Jan",
~"Feb",
~"Mar",
@ -1087,7 +1089,8 @@ mod tests {
~"Oct",
~"Nov",
~"Dec"
].each |day| {
];
for months.iter().advance |day| {
assert!(test(*day, "%b"));
}
@ -1138,6 +1141,9 @@ mod tests {
assert!(result::unwrap(strptime("-0800", "%z")).tm_gmtoff ==
0);
assert!(test("%", "%%"));
// Test for #7256
assert_eq!(strptime("360", "%Y-%m-%d"), Err(~"Invalid year"))
}
fn test_ctime() {

View file

@ -10,18 +10,17 @@
//! Utilities that leverage libuv's `uv_timer_*` API
use core::prelude::*;
use uv;
use uv::iotask;
use uv::iotask::IoTask;
use core::cast::transmute;
use core::cast;
use core::comm::{stream, Chan, SharedChan, Port, select2i};
use core::either;
use core::libc::c_void;
use core::libc;
use std::cast::transmute;
use std::cast;
use std::comm::{stream, Chan, SharedChan, Port, select2i};
use std::either;
use std::libc::c_void;
use std::libc;
/**
* Wait for timeout period then send provided value over a channel
@ -39,7 +38,7 @@ use core::libc;
* * ch - a channel of type T to send a `val` on
* * val - a value of type T to send over the provided `ch`
*/
pub fn delayed_send<T:Owned>(iotask: &IoTask,
pub fn delayed_send<T:Send>(iotask: &IoTask,
msecs: uint,
ch: &Chan<T>,
val: T) {
@ -111,7 +110,7 @@ pub fn sleep(iotask: &IoTask, msecs: uint) {
*
* * `iotask' - `uv::iotask` that the tcp request will run on
* * msecs - an mount of time, in milliseconds, to wait to receive
* * wait_port - a `core::comm::port<T>` to receive on
* * wait_port - a `std::comm::port<T>` to receive on
*
* # Returns
*
@ -119,11 +118,12 @@ pub fn sleep(iotask: &IoTask, msecs: uint) {
* on the provided port in the allotted timeout period, then the result will
* be a `Some(T)`. If not, then `None` will be returned.
*/
pub fn recv_timeout<T:Copy + Owned>(iotask: &IoTask,
pub fn recv_timeout<T:Copy + Send>(iotask: &IoTask,
msecs: uint,
wait_po: &Port<T>)
-> Option<T> {
let mut (timeout_po, timeout_ch) = stream::<()>();
let (timeout_po, timeout_ch) = stream::<()>();
let mut timeout_po = timeout_po;
delayed_send(iotask, msecs, &timeout_ch, ());
// XXX: Workaround due to ports and channels not being &mut. They should
@ -175,16 +175,15 @@ extern fn delayed_send_close_cb(handle: *uv::ll::uv_timer_t) {
#[cfg(test)]
mod test {
use core::prelude::*;
use timer::*;
use uv;
use core::cell::Cell;
use core::pipes::{stream, SharedChan};
use core::rand::RngUtil;
use core::rand;
use core::task;
use std::cell::Cell;
use std::pipes::{stream, SharedChan};
use std::rand::RngUtil;
use std::rand;
use std::task;
#[test]
fn test_gl_timer_simple_sleep_test() {
@ -217,12 +216,12 @@ mod test {
for repeat.times {
let ch = ch.clone();
for spec.each |spec| {
for spec.iter().advance |spec| {
let (times, maxms) = *spec;
let ch = ch.clone();
let hl_loop_clone = hl_loop.clone();
do task::spawn {
use core::rand::*;
use std::rand::*;
let mut rng = rng();
for times.times {
sleep(&hl_loop_clone, rng.next() as uint % maxms);

View file

@ -12,10 +12,9 @@
//! trees. The only requirement for the types is that the key implements
//! `TotalOrd`.
use core::prelude::*;
use core::uint;
use core::util::{swap, replace};
use std::uint;
use std::util::{swap, replace};
// This is implemented as an AA tree, which is a simplified variation of
// a red-black tree where red (horizontal) nodes can only be added
@ -87,10 +86,10 @@ impl<K: Ord + TotalOrd, V> Ord for TreeMap<K, V> {
impl<K: TotalOrd, V> Container for TreeMap<K, V> {
/// Return the number of elements in the map
fn len(&const self) -> uint { self.length }
fn len(&self) -> uint { self.length }
/// Return true if the map contains no elements
fn is_empty(&const self) -> bool { self.root.is_none() }
fn is_empty(&self) -> bool { self.root.is_none() }
}
impl<K: TotalOrd, V> Mutable for TreeMap<K, V> {
@ -107,26 +106,6 @@ impl<K: TotalOrd, V> Map<K, V> for TreeMap<K, V> {
self.find(key).is_some()
}
/// Visit all key-value pairs in order
fn each<'a>(&'a self, f: &fn(&'a K, &'a V) -> bool) -> bool {
each(&self.root, f)
}
/// Visit all keys in order
fn each_key(&self, f: &fn(&K) -> bool) -> bool {
self.each(|k, _| f(k))
}
/// Visit all values in order
fn each_value<'a>(&'a self, f: &fn(&'a V) -> bool) -> bool {
self.each(|_, v| f(v))
}
/// Iterate over the map and mutate the contained values
fn mutate_values(&mut self, f: &fn(&K, &mut V) -> bool) -> bool {
mutate_values(&mut self.root, f)
}
/// Return a reference to the value corresponding to the key
fn find<'a>(&'a self, key: &K) -> Option<&'a V> {
let mut current: &'a Option<~TreeNode<K, V>> = &self.root;
@ -184,6 +163,21 @@ impl<K: TotalOrd, V> TreeMap<K, V> {
/// Create an empty TreeMap
pub fn new() -> TreeMap<K, V> { TreeMap{root: None, length: 0} }
/// Visit all keys in order
pub fn each_key(&self, f: &fn(&K) -> bool) -> bool {
self.iter().advance(|(k, _)| f(k))
}
/// Visit all values in order
pub fn each_value<'a>(&'a self, f: &fn(&'a V) -> bool) -> bool {
self.iter().advance(|(_, v)| f(v))
}
/// Iterate over the map and mutate the contained values
pub fn mutate_values(&mut self, f: &fn(&K, &mut V) -> bool) -> bool {
mutate_values(&mut self.root, f)
}
/// Visit all key-value pairs in reverse order
pub fn each_reverse<'a>(&'a self, f: &fn(&'a K, &'a V) -> bool) -> bool {
each_reverse(&self.root, f)
@ -249,22 +243,6 @@ pub struct TreeSet<T> {
priv map: TreeMap<T, ()>
}
impl<T: TotalOrd> BaseIter<T> for TreeSet<T> {
/// Visit all values in order
#[inline]
fn each(&self, f: &fn(&T) -> bool) -> bool { self.map.each_key(f) }
#[inline]
fn size_hint(&self) -> Option<uint> { Some(self.len()) }
}
impl<T: TotalOrd> ReverseIter<T> for TreeSet<T> {
/// Visit all values in reverse order
#[inline]
fn each_reverse(&self, f: &fn(&T) -> bool) -> bool {
self.map.each_key_reverse(f)
}
}
impl<T: Eq + TotalOrd> Eq for TreeSet<T> {
#[inline]
fn eq(&self, other: &TreeSet<T>) -> bool { self.map == other.map }
@ -286,11 +264,11 @@ impl<T: Ord + TotalOrd> Ord for TreeSet<T> {
impl<T: TotalOrd> Container for TreeSet<T> {
/// Return the number of elements in the set
#[inline]
fn len(&const self) -> uint { self.map.len() }
fn len(&self) -> uint { self.map.len() }
/// Return true if the set contains no elements
#[inline]
fn is_empty(&const self) -> bool { self.map.is_empty() }
fn is_empty(&self) -> bool { self.map.is_empty() }
}
impl<T: TotalOrd> Mutable for TreeSet<T> {
@ -499,6 +477,12 @@ impl<T: TotalOrd> TreeSet<T> {
pub fn iter<'a>(&'a self) -> TreeSetIterator<'a, T> {
TreeSetIterator{iter: self.map.iter()}
}
/// Visit all values in reverse order
#[inline]
pub fn each_reverse(&self, f: &fn(&T) -> bool) -> bool {
self.map.each_key_reverse(f)
}
}
/// Lazy forward iterator over a set
@ -526,14 +510,14 @@ impl<K: TotalOrd, V> TreeNode<K, V> {
fn each<'r, K: TotalOrd, V>(node: &'r Option<~TreeNode<K, V>>,
f: &fn(&'r K, &'r V) -> bool) -> bool {
node.iter().advance(|x| each(&x.left, f) && f(&x.key, &x.value) &&
each(&x.right, f))
node.iter().advance(|x| each(&x.left, |k,v| f(k,v)) && f(&x.key, &x.value) &&
each(&x.right, |k,v| f(k,v)))
}
fn each_reverse<'r, K: TotalOrd, V>(node: &'r Option<~TreeNode<K, V>>,
f: &fn(&'r K, &'r V) -> bool) -> bool {
node.iter().advance(|x| each_reverse(&x.right, f) && f(&x.key, &x.value) &&
each_reverse(&x.left, f))
node.iter().advance(|x| each_reverse(&x.right, |k,v| f(k,v)) && f(&x.key, &x.value) &&
each_reverse(&x.left, |k,v| f(k,v)))
}
fn mutate_values<'r, K: TotalOrd, V>(node: &'r mut Option<~TreeNode<K, V>>,
@ -542,9 +526,9 @@ fn mutate_values<'r, K: TotalOrd, V>(node: &'r mut Option<~TreeNode<K, V>>,
match *node {
Some(~TreeNode{key: ref key, value: ref mut value, left: ref mut left,
right: ref mut right, _}) => {
if !mutate_values(left, f) { return false }
if !mutate_values(left, |k,v| f(k,v)) { return false }
if !f(key, value) { return false }
if !mutate_values(right, f) { return false }
if !mutate_values(right, |k,v| f(k,v)) { return false }
}
None => return false
}
@ -704,13 +688,11 @@ fn remove<K: TotalOrd, V>(node: &mut Option<~TreeNode<K, V>>,
#[cfg(test)]
mod test_treemap {
use core::prelude::*;
use super::*;
use core::rand::RngUtil;
use core::rand;
use core::vec;
use std::rand::RngUtil;
use std::rand;
#[test]
fn find_empty() {
@ -781,13 +763,13 @@ mod test_treemap {
fn check_equal<K: Eq + TotalOrd, V: Eq>(ctrl: &[(K, V)],
map: &TreeMap<K, V>) {
assert_eq!(ctrl.is_empty(), map.is_empty());
for ctrl.each |x| {
for ctrl.iter().advance |x| {
let &(k, v) = x;
assert!(map.find(&k).unwrap() == &v)
}
for map.each |map_k, map_v| {
for map.iter().advance |(map_k, map_v)| {
let mut found = false;
for ctrl.each |x| {
for ctrl.iter().advance |x| {
let &(ctrl_k, ctrl_v) = x;
if *map_k == ctrl_k {
assert!(*map_v == ctrl_v);
@ -853,7 +835,7 @@ mod test_treemap {
for 90.times {
let k = rng.gen();
let v = rng.gen();
if !ctrl.contains(&(k, v)) {
if !ctrl.iter().any_(|x| x == &(k, v)) {
assert!(map.insert(k, v));
ctrl.push((k, v));
check_structure(&map);
@ -863,7 +845,7 @@ mod test_treemap {
for 30.times {
let r = rng.gen_uint_range(0, ctrl.len());
let (key, _) = vec::remove(&mut ctrl, r);
let (key, _) = ctrl.remove(r);
assert!(map.remove(&key));
check_structure(&map);
check_equal(ctrl, &map);
@ -891,7 +873,7 @@ mod test_treemap {
}
#[test]
fn test_each() {
fn test_iterator() {
let mut m = TreeMap::new();
assert!(m.insert(3, 6));
@ -901,7 +883,7 @@ mod test_treemap {
assert!(m.insert(1, 2));
let mut n = 0;
for m.each |k, v| {
for m.iter().advance |(k, v)| {
assert_eq!(*k, n);
assert_eq!(*v, n * 2);
n += 1;
@ -1026,7 +1008,6 @@ mod test_treemap {
#[cfg(test)]
mod test_set {
use core::prelude::*;
use super::*;
@ -1096,7 +1077,7 @@ mod test_set {
}
#[test]
fn test_each() {
fn test_iterator() {
let mut m = TreeSet::new();
assert!(m.insert(3));
@ -1106,7 +1087,7 @@ mod test_set {
assert!(m.insert(1));
let mut n = 0;
for m.each |x| {
for m.iter().advance |x| {
println(fmt!("%?", x));
assert_eq!(*x, n);
n += 1
@ -1135,8 +1116,8 @@ mod test_set {
let mut set_a = TreeSet::new();
let mut set_b = TreeSet::new();
for a.each |x| { assert!(set_a.insert(*x)) }
for b.each |y| { assert!(set_b.insert(*y)) }
for a.iter().advance |x| { assert!(set_a.insert(*x)) }
for b.iter().advance |y| { assert!(set_b.insert(*y)) }
let mut i = 0;
for f(&set_a, &set_b) |x| {

View file

@ -10,16 +10,15 @@
//! A process-wide libuv event loop for library use.
use core::prelude::*;
use iotask = uv_iotask;
use uv_iotask::{IoTask, spawn_iotask};
use core::comm::Chan;
use core::option::{Some, None};
use core::task::task;
use core::unstable::global::{global_data_clone_create, global_data_clone};
use core::unstable::weak_task::weaken_task;
use std::comm::Chan;
use std::option::{Some, None};
use std::task::task;
use std::unstable::global::{global_data_clone_create, global_data_clone};
use std::unstable::weak_task::weaken_task;
/**
* Race-free helper to get access to a global task where a libuv
@ -126,11 +125,11 @@ mod test {
use uv::ll;
use uv_iotask::IoTask;
use core::libc;
use core::task;
use core::cast::transmute;
use core::libc::c_void;
use core::comm::{stream, SharedChan, Chan};
use std::libc;
use std::task;
use std::cast::transmute;
use std::libc::c_void;
use std::comm::{stream, SharedChan, Chan};
extern fn simple_timer_close_cb(timer_ptr: *ll::uv_timer_t) {
unsafe {
@ -150,9 +149,7 @@ mod test {
let hl_loop = &get_gl();
do iotask::interact(hl_loop) |_loop_ptr| {
debug!(~"closing timer");
unsafe {
ll::close(timer_ptr, simple_timer_close_cb);
}
ll::close(timer_ptr, simple_timer_close_cb);
debug!(~"about to deref exit_ch_ptr");
debug!(~"after msg sent on deref'd exit_ch");
};
@ -169,24 +166,22 @@ mod test {
let timer_handle = ll::timer_t();
let timer_ptr: *ll::uv_timer_t = &timer_handle;
do iotask::interact(iotask) |loop_ptr| {
unsafe {
debug!(~"user code inside interact loop!!!");
let init_status = ll::timer_init(loop_ptr, timer_ptr);
if(init_status == 0i32) {
ll::set_data_for_uv_handle(
timer_ptr as *libc::c_void,
exit_ch_ptr);
let start_status = ll::timer_start(timer_ptr,
simple_timer_cb,
1u, 0u);
if(start_status != 0i32) {
fail!("failure on ll::timer_start()");
}
}
else {
fail!("failure on ll::timer_init()");
debug!(~"user code inside interact loop!!!");
let init_status = ll::timer_init(loop_ptr, timer_ptr);
if(init_status == 0i32) {
ll::set_data_for_uv_handle(
timer_ptr as *libc::c_void,
exit_ch_ptr);
let start_status = ll::timer_start(timer_ptr,
simple_timer_cb,
1u, 0u);
if(start_status != 0i32) {
fail!("failure on ll::timer_start()");
}
}
else {
fail!("failure on ll::timer_init()");
}
};
exit_po.recv();
debug!(

View file

@ -17,14 +17,13 @@
#[allow(missing_doc)];
use core::prelude::*;
use ll = uv_ll;
use core::comm::{stream, Port, Chan, SharedChan};
use core::libc::c_void;
use core::libc;
use core::task;
use std::comm::{stream, Port, Chan, SharedChan};
use std::libc::c_void;
use std::libc;
use std::task;
/// Used to abstract-away direct interaction with a libuv loop.
pub struct IoTask {
@ -226,7 +225,7 @@ struct AhData {
#[cfg(test)]
fn impl_uv_iotask_async(iotask: &IoTask) {
use core::ptr;
use std::ptr;
let async_handle = ll::async_t();
let ah_ptr: *ll::uv_async_t = &async_handle;

View file

@ -33,14 +33,13 @@
#[allow(non_camel_case_types)]; // C types
#[allow(missing_doc)];
use core::prelude::*;
use core::libc::{c_void, size_t};
use core::libc;
use core::ptr::to_unsafe_ptr;
use core::ptr;
use core::str;
use core::vec;
use std::libc::{c_void, size_t};
use std::libc;
use std::ptr::to_unsafe_ptr;
use std::ptr;
use std::str;
use std::vec;
pub type uv_handle_t = c_void;
pub type uv_loop_t = c_void;
@ -362,7 +361,7 @@ pub struct uv_getaddrinfo_t {
pub mod uv_ll_struct_stubgen {
use core::ptr;
use std::ptr;
use super::{
uv_async_t,
@ -1228,16 +1227,15 @@ pub unsafe fn addrinfo_as_sockaddr_in6(input: *addrinfo) -> *sockaddr_in6 {
#[cfg(test)]
mod test {
use core::prelude::*;
use super::*;
use core::comm::{SharedChan, stream, GenericChan, GenericPort};
use core::libc;
use core::str;
use core::sys;
use core::task;
use core::vec;
use std::comm::{SharedChan, stream, GenericChan, GenericPort};
use std::libc;
use std::str;
use std::sys;
use std::task;
use std::vec;
enum tcp_read_data {
tcp_read_eof,
@ -1767,9 +1765,7 @@ mod test {
mod impl64 {
#[test]
fn test_uv_ll_tcp_server_and_request() {
unsafe {
super::super::impl_uv_tcp_server_and_request();
}
super::super::impl_uv_tcp_server_and_request();
}
}
#[cfg(target_arch="x86")]

View file

@ -10,24 +10,24 @@
#[allow(missing_doc)];
use core::prelude::*;
use digest::DigestUtil;
use json;
use sha1;
use sha1::Sha1;
use serialize::{Encoder, Encodable, Decoder, Decodable};
use sort;
use core::cell::Cell;
use core::cmp;
use core::comm::{PortOne, oneshot, send_one, recv_one};
use core::either::{Either, Left, Right};
use core::hashmap::HashMap;
use core::io;
use core::result;
use core::run;
use core::task;
use core::to_bytes;
use core::util::replace;
use std::cell::Cell;
use std::cmp;
use std::comm::{PortOne, oneshot, send_one, recv_one};
use std::either::{Either, Left, Right};
use std::hashmap::HashMap;
use std::io;
use std::result;
use std::run;
use std::task;
use std::to_bytes;
use std::util::replace;
/**
*
@ -106,7 +106,7 @@ struct WorkKey {
impl to_bytes::IterBytes for WorkKey {
#[inline]
fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool {
self.kind.iter_bytes(lsb0, f) && self.name.iter_bytes(lsb0, f)
self.kind.iter_bytes(lsb0, |b| f(b)) && self.name.iter_bytes(lsb0, |b| f(b))
}
}
@ -145,7 +145,7 @@ impl WorkMap {
impl<S:Encoder> Encodable<S> for WorkMap {
fn encode(&self, s: &mut S) {
let mut d = ~[];
for self.each |k, v| {
for self.iter().advance |(k, v)| {
d.push((copy *k, copy *v))
}
sort::tim_sort(d);
@ -157,7 +157,7 @@ impl<D:Decoder> Decodable<D> for WorkMap {
fn decode(d: &mut D) -> WorkMap {
let v : ~[(WorkKey,~str)] = Decodable::decode(d);
let mut w = WorkMap::new();
for v.each |&(k, v)| {
for v.iter().advance |&(k, v)| {
w.insert(copy k, copy v);
}
w
@ -248,16 +248,16 @@ fn json_decode<T:Decodable<json::Decoder>>(s: &str) -> T {
}
fn digest<T:Encodable<json::Encoder>>(t: &T) -> ~str {
let mut sha = sha1::sha1();
sha.input_str(json_encode(t));
sha.result_str()
let mut sha = ~Sha1::new();
(*sha).input_str(json_encode(t));
(*sha).result_str()
}
fn digest_file(path: &Path) -> ~str {
let mut sha = sha1::sha1();
let mut sha = ~Sha1::new();
let s = io::read_whole_file_str(path);
sha.input_str(*s.get_ref());
sha.result_str()
(*sha).input_str(*s.get_ref());
(*sha).result_str()
}
impl Context {
@ -271,7 +271,7 @@ impl Context {
}
}
pub fn prep<T:Owned +
pub fn prep<T:Send +
Encodable<json::Encoder> +
Decodable<json::Decoder>>(@self, // FIXME(#5121)
fn_name:&str,
@ -291,7 +291,7 @@ trait TPrep {
fn declare_input(&mut self, kind:&str, name:&str, val:&str);
fn is_fresh(&self, cat:&str, kind:&str, name:&str, val:&str) -> bool;
fn all_fresh(&self, cat:&str, map:&WorkMap) -> bool;
fn exec<T:Owned +
fn exec<T:Send +
Encodable<json::Encoder> +
Decodable<json::Decoder>>( // FIXME(#5121)
&self, blk: ~fn(&Exec) -> T) -> Work<T>;
@ -319,7 +319,7 @@ impl TPrep for Prep {
}
fn all_fresh(&self, cat: &str, map: &WorkMap) -> bool {
for map.each |k, v| {
for map.iter().advance |(k, v)| {
if ! self.is_fresh(cat, k.kind, k.name, *v) {
return false;
}
@ -327,7 +327,7 @@ impl TPrep for Prep {
return true;
}
fn exec<T:Owned +
fn exec<T:Send +
Encodable<json::Encoder> +
Decodable<json::Decoder>>( // FIXME(#5121)
&self, blk: ~fn(&Exec) -> T) -> Work<T> {
@ -364,7 +364,7 @@ impl TPrep for Prep {
}
}
impl<T:Owned +
impl<T:Send +
Encodable<json::Encoder> +
Decodable<json::Decoder>> Work<T> { // FIXME(#5121)
pub fn new(p: @mut Prep, e: Either<T,PortOne<(Exec,T)>>) -> Work<T> {
@ -373,7 +373,7 @@ impl<T:Owned +
}
// FIXME (#3724): movable self. This should be in impl Work.
fn unwrap<T:Owned +
fn unwrap<T:Send +
Encodable<json::Encoder> +
Decodable<json::Decoder>>( // FIXME(#5121)
w: Work<T>) -> T {
@ -402,7 +402,7 @@ fn unwrap<T:Owned +
//#[test]
fn test() {
use core::io::WriterUtil;
use std::io::WriterUtil;
let db = @mut Database { db_filename: Path("db.json"),
db_cache: HashMap::new(),