Merge pull request #7897 from thestinger/double
rollup of small pull requests 404de4f r=huonw 0cdb0a2 r=pcwalton b082302 r=sanxiyn b6a0138 r=huonw 8d64fa3 r=graydon ddd8c15 r=thestinger eb74f0c r=thestinger
This commit is contained in:
commit
8d97c905dd
@ -249,7 +249,7 @@ endef
|
||||
|
||||
# Same interface as above, but deletes rather than just listing the files.
|
||||
define REMOVE_ALL_OLD_GLOB_MATCHES_EXCEPT
|
||||
$(Q)MATCHES="$(filter-out %$(3),$(wildcard $(1)/$(2)))"; if [ -n "$$MATCHES" ] ; then echo "Warning: removing previous" \'$(2)\' "libraries:" $$MATCHES; rm -v $$MATCHES ; fi
|
||||
$(Q)MATCHES="$(filter-out %$(3),$(wildcard $(1)/$(2)))"; if [ -n "$$MATCHES" ] ; then echo "Warning: removing previous" \'$(2)\' "libraries:" $$MATCHES; rm $$MATCHES ; fi
|
||||
endef
|
||||
|
||||
# We use a different strategy for LIST_ALL_OLD_GLOB_MATCHES_EXCEPT
|
||||
|
115
README.md
115
README.md
@ -3,18 +3,72 @@
|
||||
This is a compiler for Rust, including standard libraries, tools and
|
||||
documentation.
|
||||
|
||||
## Quick Start
|
||||
|
||||
## Installation
|
||||
### Windows
|
||||
|
||||
The Rust compiler currently must be built from a [tarball], unless you
|
||||
are on Windows, in which case using the [installer][win-exe] is
|
||||
recommended.
|
||||
1. Download and use the [installer][win-exe].
|
||||
2. Read the [tutorial].
|
||||
2. Enjoy!
|
||||
|
||||
Since the Rust compiler is written in Rust, it must be built by
|
||||
a precompiled "snapshot" version of itself (made in an earlier state
|
||||
of development). As such, source builds require a connection to
|
||||
the Internet, to fetch snapshots, and an OS that can execute the
|
||||
available snapshot binaries.
|
||||
> ***Note:*** Windows users should read the detailed
|
||||
> [getting started][wiki-start] notes on the wiki. Even when using
|
||||
> the binary installer the Windows build requires a MinGW installation,
|
||||
> the precise details of which are not discussed here.
|
||||
|
||||
[tutorial]: http://static.rust-lang.org/doc/tutorial.html
|
||||
[wiki-start]: https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust
|
||||
[win-exe]: http://static.rust-lang.org/dist/rust-0.7-install.exe
|
||||
|
||||
### Linux / OS X
|
||||
|
||||
1. Install the prerequisites (if not already installed)
|
||||
* g++ 4.4 or clang++ 3.x
|
||||
* python 2.6 or later (but not 3.x)
|
||||
* perl 5.0 or later
|
||||
* gnu make 3.81 or later
|
||||
* curl
|
||||
2. Download and build Rust
|
||||
You can either download a [tarball] or build directly from the [repo].
|
||||
|
||||
To build from the [tarball] do:
|
||||
|
||||
$ curl -O http://static.rust-lang.org/dist/rust-0.7.tar.gz
|
||||
$ tar -xzf rust-0.7.tar.gz
|
||||
$ cd rust-0.7
|
||||
|
||||
Or to build from the [repo] do:
|
||||
|
||||
$ git clone https://github.com/mozilla/rust.git
|
||||
$ cd rust
|
||||
|
||||
Now that you have Rust's source code, you can configure and build it:
|
||||
|
||||
$ ./configure
|
||||
$ make && make install
|
||||
|
||||
You may need to use `sudo make install` if you do not normally have
|
||||
permission to modify the destination directory. The install locations can
|
||||
be adjusted by passing a `--prefix` argument to `configure`. Various other
|
||||
options are also supported, pass `--help` for more information on them.
|
||||
|
||||
When complete, `make install` will place several programs into
|
||||
`/usr/local/bin`: `rustc`, the Rust compiler; `rustdoc`, the
|
||||
API-documentation tool, and `rustpkg`, the Rust package manager and build
|
||||
system.
|
||||
3. Read the [tutorial].
|
||||
4. Enjoy!
|
||||
|
||||
[repo]: https://github.com/mozilla/rust
|
||||
[tarball]: http://static.rust-lang.org/dist/rust-0.7.tar.gz
|
||||
[tutorial]: http://static.rust-lang.org/doc/tutorial.html
|
||||
|
||||
## Notes
|
||||
|
||||
Since the Rust compiler is written in Rust, it must be built by a
|
||||
precompiled "snapshot" version of itself (made in an earlier state of
|
||||
development). As such, source builds require a connection to the Internet, to
|
||||
fetch snapshots, and an OS that can execute the available snapshot binaries.
|
||||
|
||||
Snapshot binaries are currently built and tested on several platforms:
|
||||
|
||||
@ -25,42 +79,12 @@ Snapshot binaries are currently built and tested on several platforms:
|
||||
You may find that other platforms work, but these are our "tier 1"
|
||||
supported build environments that are most likely to work.
|
||||
|
||||
> ***Note:*** Windows users should read the detailed
|
||||
> [getting started][wiki-start] notes on the wiki. Even when using
|
||||
> the binary installer the Windows build requires a MinGW installation,
|
||||
> the precise details of which are not discussed here.
|
||||
Rust currently needs about 1.8G of RAM to build without swapping; if it hits
|
||||
swap, it will take a very long time to build.
|
||||
|
||||
To build from source you will also need the following prerequisite
|
||||
packages:
|
||||
There is lots more documentation in the [wiki].
|
||||
|
||||
* g++ 4.4 or clang++ 3.x
|
||||
* python 2.6 or later (but not 3.x)
|
||||
* perl 5.0 or later
|
||||
* gnu make 3.81 or later
|
||||
* curl
|
||||
|
||||
Assuming you're on a relatively modern *nix system and have met the
|
||||
prerequisites, something along these lines should work.
|
||||
|
||||
$ curl -O http://static.rust-lang.org/dist/rust-0.7.tar.gz
|
||||
$ tar -xzf rust-0.7.tar.gz
|
||||
$ cd rust-0.7
|
||||
$ ./configure
|
||||
$ make && make install
|
||||
|
||||
You may need to use `sudo make install` if you do not normally have
|
||||
permission to modify the destination directory. The install locations
|
||||
can be adjusted by passing a `--prefix` argument to
|
||||
`configure`. Various other options are also supported, pass `--help`
|
||||
for more information on them.
|
||||
|
||||
When complete, `make install` will place several programs into
|
||||
`/usr/local/bin`: `rustc`, the Rust compiler; `rustdoc`, the
|
||||
API-documentation tool, and `rustpkg`, the Rust package manager and build system.
|
||||
|
||||
[wiki-start]: https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust
|
||||
[tarball]: http://static.rust-lang.org/dist/rust-0.7.tar.gz
|
||||
[win-exe]: http://static.rust-lang.org/dist/rust-0.7-install.exe
|
||||
[wiki]: https://github.com/mozilla/rust/wiki
|
||||
|
||||
|
||||
## License
|
||||
@ -71,8 +95,3 @@ BSD-like licenses.
|
||||
|
||||
See LICENSE-APACHE, LICENSE-MIT, and COPYRIGHT for details.
|
||||
|
||||
## More help
|
||||
|
||||
The [tutorial] is a good starting point.
|
||||
|
||||
[tutorial]: http://static.rust-lang.org/doc/tutorial.html
|
||||
|
@ -573,8 +573,7 @@ The top level of this tree is a module that is anonymous (from the point of view
|
||||
|
||||
The Rust compiler is always invoked with a single source file as input, and always produces a single output crate.
|
||||
The processing of that source file may result in other source files being loaded as modules.
|
||||
Source files typically have the extension `.rs` but, by convention,
|
||||
source files that represent crates have the extension `.rc`, called *crate files*.
|
||||
Source files have the extension `.rs`.
|
||||
|
||||
A Rust source file describes a module, the name and
|
||||
location of which -- in the module tree of the current crate -- are defined
|
||||
@ -3286,7 +3285,7 @@ As an example, to see all the logs generated by the compiler, you would set
|
||||
you would set it to `rustc::metadata::creader`. To see just error logging
|
||||
use `rustc=0`.
|
||||
|
||||
Note that when compiling either `.rs` or `.rc` files that don't specify a
|
||||
Note that when compiling source files that don't specify a
|
||||
crate name the crate is given a default name that matches the source file,
|
||||
with the extension removed. In that case, to turn on logging for a program
|
||||
compiled from, e.g. `helloworld.rs`, `RUST_LOG` should be set to `helloworld`.
|
||||
|
@ -60,6 +60,19 @@ impl<A:Clone> Future<A> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A> Future<A> {
|
||||
/// Gets the value from this future, forcing evaluation.
|
||||
pub fn unwrap(self) -> A {
|
||||
let mut this = self;
|
||||
this.get_ref();
|
||||
let state = replace(&mut this.state, Evaluating);
|
||||
match state {
|
||||
Forced(v) => v,
|
||||
_ => fail!( "Logic error." ),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A> Future<A> {
|
||||
pub fn get_ref<'a>(&'a mut self) -> &'a A {
|
||||
/*!
|
||||
@ -179,6 +192,12 @@ mod test {
|
||||
assert_eq!(f.get(), ~"fail");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_interface_unwrap() {
|
||||
let mut f = from_value(~"fail");
|
||||
assert_eq!(f.unwrap(), ~"fail");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_ref_method() {
|
||||
let mut f = from_value(22);
|
||||
|
@ -13,15 +13,12 @@ use back::abi;
|
||||
use back::link::{mangle_internal_name_by_path_and_seq};
|
||||
use lib::llvm::{llvm, ValueRef};
|
||||
use middle::moves;
|
||||
use middle::lang_items::ClosureExchangeMallocFnLangItem;
|
||||
use middle::trans::base::*;
|
||||
use middle::trans::build::*;
|
||||
use middle::trans::callee;
|
||||
use middle::trans::common::*;
|
||||
use middle::trans::datum::{Datum, INIT, ByRef, ZeroMem};
|
||||
use middle::trans::expr;
|
||||
use middle::trans::glue;
|
||||
use middle::trans::machine;
|
||||
use middle::trans::type_of::*;
|
||||
use middle::ty;
|
||||
use util::ppaux::ty_to_str;
|
||||
@ -508,52 +505,9 @@ pub fn make_opaque_cbox_take_glue(
|
||||
return bcx;
|
||||
}
|
||||
ast::OwnedSigil => {
|
||||
/* hard case: fallthrough to code below */
|
||||
fail!("unique closures are not copyable")
|
||||
}
|
||||
}
|
||||
|
||||
// ~fn requires a deep copy.
|
||||
let ccx = bcx.ccx();
|
||||
let tcx = ccx.tcx;
|
||||
let llopaquecboxty = Type::opaque_box(ccx).ptr_to();
|
||||
let cbox_in = Load(bcx, cboxptr);
|
||||
do with_cond(bcx, IsNotNull(bcx, cbox_in)) |bcx| {
|
||||
// Load the size from the type descr found in the cbox
|
||||
let cbox_in = PointerCast(bcx, cbox_in, llopaquecboxty);
|
||||
let tydescptr = GEPi(bcx, cbox_in, [0u, abi::box_field_tydesc]);
|
||||
let tydesc = Load(bcx, tydescptr);
|
||||
let tydesc = PointerCast(bcx, tydesc, ccx.tydesc_type.ptr_to());
|
||||
let sz = Load(bcx, GEPi(bcx, tydesc, [0u, abi::tydesc_field_size]));
|
||||
|
||||
// Adjust sz to account for the rust_opaque_box header fields
|
||||
let sz = Add(bcx, sz, machine::llsize_of(ccx, Type::box_header(ccx)));
|
||||
|
||||
// Allocate memory, update original ptr, and copy existing data
|
||||
let opaque_tydesc = PointerCast(bcx, tydesc, Type::i8p());
|
||||
let mut bcx = bcx;
|
||||
let alloc_fn = langcall(bcx, None,
|
||||
fmt!("allocation of type with sigil `%s`",
|
||||
sigil.to_str()),
|
||||
ClosureExchangeMallocFnLangItem);
|
||||
let llresult = unpack_result!(bcx, callee::trans_lang_call(
|
||||
bcx,
|
||||
alloc_fn,
|
||||
[opaque_tydesc, sz],
|
||||
None));
|
||||
let cbox_out = PointerCast(bcx, llresult, llopaquecboxty);
|
||||
call_memcpy(bcx, cbox_out, cbox_in, sz, 1);
|
||||
Store(bcx, cbox_out, cboxptr);
|
||||
|
||||
// Take the (deeply cloned) type descriptor
|
||||
let tydesc_out = GEPi(bcx, cbox_out, [0u, abi::box_field_tydesc]);
|
||||
let bcx = glue::take_ty(bcx, tydesc_out, ty::mk_type(tcx));
|
||||
|
||||
// Take the data in the tuple
|
||||
let cdata_out = GEPi(bcx, cbox_out, [0u, abi::box_field_body]);
|
||||
glue::call_tydesc_glue_full(bcx, cdata_out, tydesc,
|
||||
abi::tydesc_field_take_glue, None);
|
||||
bcx
|
||||
}
|
||||
}
|
||||
|
||||
pub fn make_opaque_cbox_drop_glue(
|
||||
|
@ -93,26 +93,6 @@ pub fn drop_ty_immediate(bcx: block, v: ValueRef, t: ty::t) -> block {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn take_ty_immediate(bcx: block, v: ValueRef, t: ty::t) -> Result {
|
||||
let _icx = push_ctxt("take_ty_immediate");
|
||||
match ty::get(t).sty {
|
||||
ty::ty_box(_) | ty::ty_opaque_box |
|
||||
ty::ty_evec(_, ty::vstore_box) |
|
||||
ty::ty_estr(ty::vstore_box) => {
|
||||
incr_refcnt_of_boxed(bcx, v);
|
||||
rslt(bcx, v)
|
||||
}
|
||||
ty::ty_uniq(_) => {
|
||||
uniq::duplicate(bcx, v, t)
|
||||
}
|
||||
ty::ty_evec(_, ty::vstore_uniq) |
|
||||
ty::ty_estr(ty::vstore_uniq) => {
|
||||
tvec::duplicate_uniq(bcx, v, t)
|
||||
}
|
||||
_ => rslt(bcx, v)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn free_ty(cx: block, v: ValueRef, t: ty::t) -> block {
|
||||
// NB: v is an *alias* of type t here, not a direct value.
|
||||
let _icx = push_ctxt("free_ty");
|
||||
@ -589,23 +569,15 @@ pub fn make_take_glue(bcx: block, v: ValueRef, t: ty::t) -> block {
|
||||
ty::ty_evec(_, ty::vstore_box) | ty::ty_estr(ty::vstore_box) => {
|
||||
incr_refcnt_of_boxed(bcx, Load(bcx, v)); bcx
|
||||
}
|
||||
ty::ty_uniq(_) => {
|
||||
let Result {bcx, val} = uniq::duplicate(bcx, Load(bcx, v), t);
|
||||
Store(bcx, val, v);
|
||||
bcx
|
||||
}
|
||||
ty::ty_evec(_, ty::vstore_uniq) | ty::ty_estr(ty::vstore_uniq) => {
|
||||
let Result {bcx, val} = tvec::duplicate_uniq(bcx, Load(bcx, v), t);
|
||||
Store(bcx, val, v);
|
||||
bcx
|
||||
}
|
||||
ty::ty_evec(_, ty::vstore_slice(_))
|
||||
| ty::ty_estr(ty::vstore_slice(_)) => {
|
||||
bcx
|
||||
}
|
||||
ty::ty_closure(_) => {
|
||||
ty::ty_closure(ty::ClosureTy { sigil: ast::BorrowedSigil, _ }) |
|
||||
ty::ty_closure(ty::ClosureTy { sigil: ast::ManagedSigil, _ }) => {
|
||||
closure::make_closure_glue(bcx, v, t, take_ty)
|
||||
}
|
||||
ty::ty_closure(ty::ClosureTy { sigil: ast::OwnedSigil, _ }) => bcx,
|
||||
ty::ty_trait(_, _, ty::BoxTraitStore, _, _) => {
|
||||
let llbox = Load(bcx, GEPi(bcx, v, [0u, abi::trt_field_box]));
|
||||
incr_refcnt_of_boxed(bcx, llbox);
|
||||
|
@ -130,23 +130,6 @@ pub fn alloc_vec(bcx: block,
|
||||
return rslt(bcx, vptr);
|
||||
}
|
||||
|
||||
pub fn duplicate_uniq(bcx: block, vptr: ValueRef, vec_ty: ty::t) -> Result {
|
||||
let _icx = push_ctxt("tvec::duplicate_uniq");
|
||||
|
||||
let fill = get_fill(bcx, get_bodyptr(bcx, vptr, vec_ty));
|
||||
let unit_ty = ty::sequence_element_type(bcx.tcx(), vec_ty);
|
||||
let Result {bcx, val: newptr} = alloc_uniq_raw(bcx, unit_ty, fill, fill);
|
||||
|
||||
let data_ptr = get_dataptr(bcx, get_bodyptr(bcx, vptr, vec_ty));
|
||||
let new_data_ptr = get_dataptr(bcx, get_bodyptr(bcx, newptr, vec_ty));
|
||||
base::call_memcpy(bcx, new_data_ptr, data_ptr, fill, 1);
|
||||
|
||||
let bcx = if ty::type_needs_drop(bcx.tcx(), unit_ty) {
|
||||
iter_vec_raw(bcx, new_data_ptr, vec_ty, fill, glue::take_ty)
|
||||
} else { bcx };
|
||||
return rslt(bcx, newptr);
|
||||
}
|
||||
|
||||
pub fn make_drop_glue_unboxed(bcx: block, vptr: ValueRef, vec_ty: ty::t) ->
|
||||
block {
|
||||
let _icx = push_ctxt("tvec::make_drop_glue_unboxed");
|
||||
|
@ -14,11 +14,8 @@ use middle::trans::base::*;
|
||||
use middle::trans::build::*;
|
||||
use middle::trans::common::*;
|
||||
use middle::trans::datum::immediate_rvalue;
|
||||
use middle::trans::datum;
|
||||
use middle::trans::glue;
|
||||
use middle::ty;
|
||||
use middle::trans::machine::llsize_of;
|
||||
use middle::trans::type_of;
|
||||
|
||||
pub fn make_free_glue(bcx: block, vptrptr: ValueRef, box_ty: ty::t)
|
||||
-> block {
|
||||
@ -37,30 +34,3 @@ pub fn make_free_glue(bcx: block, vptrptr: ValueRef, box_ty: ty::t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn duplicate(bcx: block, src_box: ValueRef, src_ty: ty::t) -> Result {
|
||||
let _icx = push_ctxt("uniq::duplicate");
|
||||
|
||||
// Load the body of the source (*src)
|
||||
let src_datum = immediate_rvalue(src_box, src_ty);
|
||||
let body_datum = src_datum.box_body(bcx);
|
||||
|
||||
// Malloc space in exchange heap and copy src into it
|
||||
if ty::type_contents(bcx.tcx(), src_ty).contains_managed() {
|
||||
let MallocResult {
|
||||
bcx: bcx,
|
||||
box: dst_box,
|
||||
body: dst_body
|
||||
} = malloc_general(bcx, body_datum.ty, heap_managed_unique);
|
||||
body_datum.copy_to(bcx, datum::INIT, dst_body);
|
||||
|
||||
rslt(bcx, dst_box)
|
||||
} else {
|
||||
let body_datum = body_datum.to_value_datum(bcx);
|
||||
let llty = type_of(bcx.ccx(), body_datum.ty);
|
||||
let size = llsize_of(bcx.ccx(), llty);
|
||||
let Result { bcx: bcx, val: val } = malloc_raw_dyn(bcx, body_datum.ty, heap_exchange, size);
|
||||
body_datum.copy_to(bcx, datum::INIT, val);
|
||||
Result { bcx: bcx, val: val }
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ the `clone` method.
|
||||
|
||||
*/
|
||||
|
||||
use core::kinds::Freeze;
|
||||
use std::kinds::Freeze;
|
||||
|
||||
/// A common trait for cloning an object.
|
||||
pub trait Clone {
|
||||
|
@ -382,19 +382,19 @@ mod pipesy {
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub mod oneshot {
|
||||
priv use core::kinds::Send;
|
||||
priv use std::kinds::Send;
|
||||
use ptr::to_mut_unsafe_ptr;
|
||||
|
||||
pub fn init<T: Send>() -> (server::Oneshot<T>, client::Oneshot<T>) {
|
||||
pub use core::pipes::HasBuffer;
|
||||
pub use std::pipes::HasBuffer;
|
||||
|
||||
let buffer = ~::core::pipes::Buffer {
|
||||
header: ::core::pipes::BufferHeader(),
|
||||
let buffer = ~::std::pipes::Buffer {
|
||||
header: ::std::pipes::BufferHeader(),
|
||||
data: __Buffer {
|
||||
Oneshot: ::core::pipes::mk_packet::<Oneshot<T>>()
|
||||
Oneshot: ::std::pipes::mk_packet::<Oneshot<T>>()
|
||||
},
|
||||
};
|
||||
do ::core::pipes::entangle_buffer(buffer) |buffer, data| {
|
||||
do ::std::pipes::entangle_buffer(buffer) |buffer, data| {
|
||||
data.Oneshot.set_buffer(buffer);
|
||||
to_mut_unsafe_ptr(&mut data.Oneshot)
|
||||
}
|
||||
@ -403,23 +403,23 @@ mod pipesy {
|
||||
pub enum Oneshot<T> { pub send(T), }
|
||||
#[allow(non_camel_case_types)]
|
||||
pub struct __Buffer<T> {
|
||||
Oneshot: ::core::pipes::Packet<Oneshot<T>>,
|
||||
Oneshot: ::std::pipes::Packet<Oneshot<T>>,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub mod client {
|
||||
|
||||
priv use core::kinds::Send;
|
||||
priv use std::kinds::Send;
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub fn try_send<T: Send>(pipe: Oneshot<T>, x_0: T) ->
|
||||
::core::option::Option<()> {
|
||||
::std::option::Option<()> {
|
||||
{
|
||||
use super::send;
|
||||
let message = send(x_0);
|
||||
if ::core::pipes::send(pipe, message) {
|
||||
::core::pipes::rt::make_some(())
|
||||
} else { ::core::pipes::rt::make_none() }
|
||||
if ::std::pipes::send(pipe, message) {
|
||||
::std::pipes::rt::make_some(())
|
||||
} else { ::std::pipes::rt::make_none() }
|
||||
}
|
||||
}
|
||||
|
||||
@ -428,13 +428,13 @@ mod pipesy {
|
||||
{
|
||||
use super::send;
|
||||
let message = send(x_0);
|
||||
::core::pipes::send(pipe, message);
|
||||
::std::pipes::send(pipe, message);
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type Oneshot<T> =
|
||||
::core::pipes::SendPacketBuffered<super::Oneshot<T>,
|
||||
::std::pipes::SendPacketBuffered<super::Oneshot<T>,
|
||||
super::__Buffer<T>>;
|
||||
}
|
||||
|
||||
@ -442,7 +442,7 @@ mod pipesy {
|
||||
pub mod server {
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type Oneshot<T> =
|
||||
::core::pipes::RecvPacketBuffered<super::Oneshot<T>,
|
||||
::std::pipes::RecvPacketBuffered<super::Oneshot<T>,
|
||||
super::__Buffer<T>>;
|
||||
}
|
||||
}
|
||||
@ -557,11 +557,11 @@ mod pipesy {
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub mod streamp {
|
||||
priv use core::kinds::Send;
|
||||
priv use std::kinds::Send;
|
||||
|
||||
pub fn init<T: Send>() -> (server::Open<T>, client::Open<T>) {
|
||||
pub use core::pipes::HasBuffer;
|
||||
::core::pipes::entangle()
|
||||
pub use std::pipes::HasBuffer;
|
||||
::std::pipes::entangle()
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
@ -569,18 +569,18 @@ mod pipesy {
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub mod client {
|
||||
priv use core::kinds::Send;
|
||||
priv use std::kinds::Send;
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub fn try_data<T: Send>(pipe: Open<T>, x_0: T) ->
|
||||
::core::option::Option<Open<T>> {
|
||||
::std::option::Option<Open<T>> {
|
||||
{
|
||||
use super::data;
|
||||
let (s, c) = ::core::pipes::entangle();
|
||||
let (s, c) = ::std::pipes::entangle();
|
||||
let message = data(x_0, s);
|
||||
if ::core::pipes::send(pipe, message) {
|
||||
::core::pipes::rt::make_some(c)
|
||||
} else { ::core::pipes::rt::make_none() }
|
||||
if ::std::pipes::send(pipe, message) {
|
||||
::std::pipes::rt::make_some(c)
|
||||
} else { ::std::pipes::rt::make_none() }
|
||||
}
|
||||
}
|
||||
|
||||
@ -588,21 +588,21 @@ mod pipesy {
|
||||
pub fn data<T: Send>(pipe: Open<T>, x_0: T) -> Open<T> {
|
||||
{
|
||||
use super::data;
|
||||
let (s, c) = ::core::pipes::entangle();
|
||||
let (s, c) = ::std::pipes::entangle();
|
||||
let message = data(x_0, s);
|
||||
::core::pipes::send(pipe, message);
|
||||
::std::pipes::send(pipe, message);
|
||||
c
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type Open<T> = ::core::pipes::SendPacket<super::Open<T>>;
|
||||
pub type Open<T> = ::std::pipes::SendPacket<super::Open<T>>;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub mod server {
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type Open<T> = ::core::pipes::RecvPacket<super::Open<T>>;
|
||||
pub type Open<T> = ::std::pipes::RecvPacket<super::Open<T>>;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -773,6 +773,17 @@ impl<A, T: Iterator<A>, U: Iterator<A>> Iterator<A> for ChainIterator<A, T, U> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<A, T: DoubleEndedIterator<A>, U: DoubleEndedIterator<A>> DoubleEndedIterator<A>
|
||||
for ChainIterator<A, T, U> {
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<A> {
|
||||
match self.b.next_back() {
|
||||
Some(x) => Some(x),
|
||||
None => self.a.next_back()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator which iterates two other iterators simultaneously
|
||||
// FIXME #6967: Dummy A & B parameters to get around type inference bug
|
||||
pub struct ZipIterator<A, T, B, U> {
|
||||
@ -828,6 +839,17 @@ impl<'self, A, B, T: Iterator<A>> Iterator<B> for MapIterator<'self, A, B, T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'self, A, B, T: DoubleEndedIterator<A>> DoubleEndedIterator<B>
|
||||
for MapIterator<'self, A, B, T> {
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<B> {
|
||||
match self.iter.next_back() {
|
||||
Some(a) => Some((self.f)(a)),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator which filters the elements of `iter` with `predicate`
|
||||
pub struct FilterIterator<'self, A, T> {
|
||||
priv iter: T,
|
||||
@ -854,6 +876,24 @@ impl<'self, A, T: Iterator<A>> Iterator<A> for FilterIterator<'self, A, T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'self, A, T: DoubleEndedIterator<A>> DoubleEndedIterator<A> for FilterIterator<'self, A, T> {
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<A> {
|
||||
loop {
|
||||
match self.iter.next_back() {
|
||||
None => return None,
|
||||
Some(x) => {
|
||||
if (self.predicate)(&x) {
|
||||
return Some(x);
|
||||
} else {
|
||||
loop
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator which uses `f` to both filter and map elements from `iter`
|
||||
pub struct FilterMapIterator<'self, A, B, T> {
|
||||
priv iter: T,
|
||||
@ -879,6 +919,24 @@ impl<'self, A, B, T: Iterator<A>> Iterator<B> for FilterMapIterator<'self, A, B,
|
||||
}
|
||||
}
|
||||
|
||||
impl<'self, A, B, T: DoubleEndedIterator<A>> DoubleEndedIterator<B>
|
||||
for FilterMapIterator<'self, A, B, T> {
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<B> {
|
||||
loop {
|
||||
match self.iter.next_back() {
|
||||
None => return None,
|
||||
Some(x) => {
|
||||
match (self.f)(x) {
|
||||
Some(y) => return Some(y),
|
||||
None => ()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator which yields the current count and the element during iteration
|
||||
// FIXME #6967: Dummy A parameter to get around type inference bug
|
||||
pub struct EnumerateIterator<A, T> {
|
||||
@ -1135,6 +1193,20 @@ impl<'self, A, T: Iterator<A>> Iterator<A> for PeekIterator<'self, A, T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'self, A, T: DoubleEndedIterator<A>> DoubleEndedIterator<A> for PeekIterator<'self, A, T> {
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<A> {
|
||||
let next = self.iter.next_back();
|
||||
|
||||
match next {
|
||||
Some(ref a) => (self.f)(a),
|
||||
None => ()
|
||||
}
|
||||
|
||||
next
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator which just modifies the contained state throughout iteration.
|
||||
pub struct UnfoldrIterator<'self, A, St> {
|
||||
priv f: &'self fn(&mut St) -> Option<A>,
|
||||
@ -1526,4 +1598,53 @@ mod tests {
|
||||
it.next();
|
||||
assert_eq!(it.invert().transform(|&x| x).collect::<~[int]>(), ~[16, 14, 12, 10, 8, 6]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_double_ended_map() {
|
||||
let xs = [1, 2, 3, 4, 5, 6];
|
||||
let mut it = xs.iter().transform(|&x| x * -1);
|
||||
assert_eq!(it.next(), Some(-1));
|
||||
assert_eq!(it.next(), Some(-2));
|
||||
assert_eq!(it.next_back(), Some(-6));
|
||||
assert_eq!(it.next_back(), Some(-5));
|
||||
assert_eq!(it.next(), Some(-3));
|
||||
assert_eq!(it.next_back(), Some(-4));
|
||||
assert_eq!(it.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_double_ended_filter() {
|
||||
let xs = [1, 2, 3, 4, 5, 6];
|
||||
let mut it = xs.iter().filter(|&x| *x & 1 == 0);
|
||||
assert_eq!(it.next_back().unwrap(), &6);
|
||||
assert_eq!(it.next_back().unwrap(), &4);
|
||||
assert_eq!(it.next().unwrap(), &2);
|
||||
assert_eq!(it.next_back(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_double_ended_filter_map() {
|
||||
let xs = [1, 2, 3, 4, 5, 6];
|
||||
let mut it = xs.iter().filter_map(|&x| if x & 1 == 0 { Some(x * 2) } else { None });
|
||||
assert_eq!(it.next_back().unwrap(), 12);
|
||||
assert_eq!(it.next_back().unwrap(), 8);
|
||||
assert_eq!(it.next().unwrap(), 4);
|
||||
assert_eq!(it.next_back(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_double_ended_chain() {
|
||||
let xs = [1, 2, 3, 4, 5];
|
||||
let ys = ~[7, 9, 11];
|
||||
let mut it = xs.iter().chain_(ys.iter()).invert();
|
||||
assert_eq!(it.next().unwrap(), &11)
|
||||
assert_eq!(it.next().unwrap(), &9)
|
||||
assert_eq!(it.next_back().unwrap(), &1)
|
||||
assert_eq!(it.next_back().unwrap(), &2)
|
||||
assert_eq!(it.next_back().unwrap(), &3)
|
||||
assert_eq!(it.next_back().unwrap(), &4)
|
||||
assert_eq!(it.next_back().unwrap(), &5)
|
||||
assert_eq!(it.next_back().unwrap(), &7)
|
||||
assert_eq!(it.next_back(), None)
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
use clone::Clone;
|
||||
use container::Container;
|
||||
use core::cmp::{Ord, Eq};
|
||||
use std::cmp::{Ord, Eq};
|
||||
use ops::{Add, Sub, Mul, Div, Rem, Neg};
|
||||
use option::{None, Option, Some};
|
||||
use char;
|
||||
|
@ -209,6 +209,6 @@ fn align_down(sp: *mut uint) -> *mut uint {
|
||||
// XXX: ptr::offset is positive ints only
|
||||
#[inline]
|
||||
pub fn mut_offset<T>(ptr: *mut T, count: int) -> *mut T {
|
||||
use core::sys::size_of;
|
||||
use std::sys::size_of;
|
||||
(ptr as int + count * (size_of::<T>() as int)) as *mut T
|
||||
}
|
||||
|
@ -206,16 +206,6 @@ pub mod rt;
|
||||
// 'std' so that macro-expanded references to std::error and such
|
||||
// can be resolved within libstd.
|
||||
#[doc(hidden)]
|
||||
mod core {
|
||||
pub use clone;
|
||||
pub use cmp;
|
||||
pub use condition;
|
||||
pub use option;
|
||||
pub use kinds;
|
||||
pub use sys;
|
||||
pub use pipes;
|
||||
}
|
||||
#[doc(hidden)]
|
||||
mod std {
|
||||
pub use clone;
|
||||
pub use cmp;
|
||||
|
@ -411,7 +411,7 @@ pub fn check_integrity<T>(trie: &TrieNode<T>) {
|
||||
#[cfg(test)]
|
||||
mod test_map {
|
||||
use super::*;
|
||||
use core::option::{Some, None};
|
||||
use option::{Some, None};
|
||||
use uint;
|
||||
|
||||
#[test]
|
||||
|
Loading…
x
Reference in New Issue
Block a user