<commit_before>
import util.common.option;
import std.map.hashmap;
import util.common.span;
import util.common.spanned;
import util.common.option;
import util.common.some;
import util.common.none;

type ident = str;

type name_ = rec(ident ident, vec[@ty] types);
type name = spanned[name_];
type path = vec[name];

type crate_num = int;
type slot_num = int;
type item_num = int;

tag slot_id {
    id_slot(crate_num, slot_num);
}

tag item_id {
    id_item(crate_num, slot_num);
}

tag referent {
    ref_slot(slot_id);
    ref_item(item_id);
}

type crate = spanned[crate_];
type crate_ = rec(_mod module);

type block = spanned[block_];
type block_ = vec[@stmt];

tag binop {
    add;
    sub;
    mul;
    div;
    rem;
    and;
    or;
    bitxor;
    bitand;
    bitor;
    lsl;
    lsr;
    asr;
    eq;
    lt;
    le;
    ne;
    ge;
    gt;
}

tag unop {
    box;
    deref;
    bitnot;
    not;
    neg;
}

type stmt = spanned[stmt_];
tag stmt_ {
    stmt_decl(@decl);
    stmt_ret(option[@expr]);
    stmt_log(@expr);
    stmt_expr(@expr);
}

type decl = spanned[decl_];
tag decl_ {
    decl_local(ident, option[@ty], option[@expr]);
    decl_item(name, @item);
}

type expr = spanned[expr_];
tag expr_ {
    expr_vec(vec[@expr]);
    expr_tup(vec[@expr]);
    expr_rec(vec[tup(ident,@expr)]);
    expr_call(@expr, vec[@expr]);
    expr_binary(binop, @expr, @expr);
    expr_unary(unop, @expr);
    expr_lit(@lit);
    expr_name(name, option[referent]);
    expr_field(@expr, ident);
    expr_index(@expr, @expr);
    expr_cast(@expr, @ty);
    expr_if(@expr, block, option[block]);
    expr_block(block);
}

type lit = spanned[lit_];
tag lit_ {
    lit_str(str);
    lit_char(char);
    lit_int(int);
    lit_uint(uint);
    lit_nil;
    lit_bool(bool);
}

type ty = spanned[ty_];
tag ty_ {
    ty_nil;
    ty_bool;
    ty_int;
    ty_uint;
    ty_machine(util.common.ty_mach);
    ty_char;
    ty_str;
    ty_box(@ty);
    ty_path(path, option[referent]);
}

tag mode {
    val;
    alias;
}

type slot = rec(@ty ty, mode mode, option[slot_id] id);
type input = rec(slot slot, ident ident);

type _fn = rec(vec[input] inputs,
               ty output,
               block body);

type _mod = hashmap[ident,@item];

type item = spanned[item_];
tag item_ {
    item_fn(_fn, item_id);
    item_mod(_mod);
    item_ty(@ty, item_id);
}

//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C ../.. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
//
<commit_msg>rustc: Add the tuple type to the AST<commit_after>
import util.common.option;
import std.map.hashmap;
import util.common.span;
import util.common.spanned;
import util.common.option;
import util.common.some;
import util.common.none;

type ident = str;

type name_ = rec(ident ident, vec[@ty] types);
type name = spanned[name_];
type path = vec[name];

type crate_num = int;
type slot_num = int;
type item_num = int;

tag slot_id {
    id_slot(crate_num, slot_num);
}

tag item_id {
    id_item(crate_num, slot_num);
}

tag referent {
    ref_slot(slot_id);
    ref_item(item_id);
}

type crate = spanned[crate_];
type crate_ = rec(_mod module);

type block = spanned[block_];
type block_ = vec[@stmt];

tag binop {
    add;
    sub;
    mul;
    div;
    rem;
    and;
    or;
    bitxor;
    bitand;
    bitor;
    lsl;
    lsr;
    asr;
    eq;
    lt;
    le;
    ne;
    ge;
    gt;
}

tag unop {
    box;
    deref;
    bitnot;
    not;
    neg;
}

type stmt = spanned[stmt_];
tag stmt_ {
    stmt_decl(@decl);
    stmt_ret(option[@expr]);
    stmt_log(@expr);
    stmt_expr(@expr);
}

type decl = spanned[decl_];
tag decl_ {
    decl_local(ident, option[@ty], option[@expr]);
    decl_item(name, @item);
}

type expr = spanned[expr_];
tag expr_ {
    expr_vec(vec[@expr]);
    expr_tup(vec[@expr]);
    expr_rec(vec[tup(ident,@expr)]);
    expr_call(@expr, vec[@expr]);
    expr_binary(binop, @expr, @expr);
    expr_unary(unop, @expr);
    expr_lit(@lit);
    expr_name(name, option[referent]);
    expr_field(@expr, ident);
    expr_index(@expr, @expr);
    expr_cast(@expr, @ty);
    expr_if(@expr, block, option[block]);
    expr_block(block);
}

type lit = spanned[lit_];
tag lit_ {
    lit_str(str);
    lit_char(char);
    lit_int(int);
    lit_uint(uint);
    lit_nil;
    lit_bool(bool);
}

type ty = spanned[ty_];
tag ty_ {
    ty_nil;
    ty_bool;
    ty_int;
    ty_uint;
    ty_machine(util.common.ty_mach);
    ty_char;
    ty_str;
    ty_box(@ty);
    ty_tup(vec[tup(bool /* mutability */, @ty)]);
    ty_path(path, option[referent]);
}

tag mode {
    val;
    alias;
}

type slot = rec(@ty ty, mode mode, option[slot_id] id);
type input = rec(slot slot, ident ident);

type _fn = rec(vec[input] inputs,
               ty output,
               block body);

type _mod = hashmap[ident,@item];

type item = spanned[item_];
tag item_ {
    item_fn(_fn, item_id);
    item_mod(_mod);
    item_ty(@ty, item_id);
}

//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C ../.. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
//
<|endoftext|>


<commit_before><commit_msg>A simple example for iterating over the array<commit_after>extern crate mudi;
use mudi::Array;

fn main() {
    let mut array = Array::from_element(0.0, (5, 2, 9));

    // Iterations using the size of the array
    let (nx, ny, nz) = array.shape();
    for i in 0..nx {
        for j in 0..ny {
            for k in 0..nz {
                array[(i, j, k)] = (i + j + k) as f64;
            }
        }
    }

    // Linear iteration over the array
    for value in array.flat_iter() {
         print!("{} ", value);
    }
}
<|endoftext|>


<commit_before><commit_msg>docs(examples): add example of using the `Polynomial` basis<commit_after>extern crate rsrl;
#[macro_use] extern crate slog;

use rsrl::{run, logging, Parameter, SerialExperiment, Evaluation};
use rsrl::agents::memory::Trace;
use rsrl::agents::control::td::SARSALambda;
use rsrl::domains::{Domain, MountainCar};
use rsrl::fa::{Linear, Projector};
use rsrl::fa::projection::Polynomial;
use rsrl::geometry::Space;
use rsrl::policies::EpsilonGreedy;

fn main() {
    let domain = MountainCar::default();
    let mut agent = {
        let n_actions = domain.action_space().span().into();

        // Build the linear value function using a polynomial basis projection and the appropriate
        // eligibility trace.
        let bases = Polynomial::from_space(5, domain.state_space());
        let trace = Trace::replacing(0.7, bases.activation());
        let q_func = Linear::new(bases, n_actions);

        // Build a stochastic behaviour policy with exponential epsilon.
        let eps = Parameter::exponential(0.99, 0.05, 0.99);
        let policy = EpsilonGreedy::new(eps);

        SARSALambda::new(trace, q_func, policy, 0.1, 0.99)
    };

    let logger = logging::root(logging::stdout());
    let domain_builder = Box::new(MountainCar::default);

    // Training phase:
    let _training_result = {
        // Start a serial learning experiment up to 1000 steps per episode.
        let e = SerialExperiment::new(&mut agent, domain_builder.clone(), 1000);

        // Realise 1000 episodes of the experiment generator.
        run(e, 1000, Some(logger.clone()))
    };

    // Testing phase:
    let testing_result =
        Evaluation::new(&mut agent, domain_builder).next().unwrap();

    info!(logger, "solution"; testing_result);
}
<|endoftext|>


<commit_before>// Copyright 2015 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.

//! Routines for manipulating the control-flow graph.

use build::CFG;
use rustc::mir::*;

impl<'tcx> CFG<'tcx> {
    pub fn block_data(&self, blk: BasicBlock) -> &BasicBlockData<'tcx> {
        &self.basic_blocks[blk]
    }

    pub fn block_data_mut(&mut self, blk: BasicBlock) -> &mut BasicBlockData<'tcx> {
        &mut self.basic_blocks[blk]
    }

    pub fn start_new_block(&mut self) -> BasicBlock {
        self.basic_blocks.push(BasicBlockData::new(None))
    }

    pub fn start_new_cleanup_block(&mut self) -> BasicBlock {
        let bb = self.start_new_block();
        self.block_data_mut(bb).is_cleanup = true;
        bb
    }

    pub fn push(&mut self, block: BasicBlock, statement: Statement<'tcx>) {
        debug!("push({:?}, {:?})", block, statement);
        self.block_data_mut(block).statements.push(statement);
    }

    pub fn push_assign(&mut self,
                       block: BasicBlock,
                       source_info: SourceInfo,
                       lvalue: &Lvalue<'tcx>,
                       rvalue: Rvalue<'tcx>) {
        self.push(block, Statement {
            source_info: source_info,
            kind: StatementKind::Assign(lvalue.clone(), rvalue)
        });
    }

    pub fn push_assign_constant(&mut self,
                                block: BasicBlock,
                                source_info: SourceInfo,
                                temp: &Lvalue<'tcx>,
                                constant: Constant<'tcx>) {
        self.push_assign(block, source_info, temp,
                         Rvalue::Use(Operand::Constant(constant)));
    }

    pub fn push_assign_unit(&mut self,
                            block: BasicBlock,
                            source_info: SourceInfo,
                            lvalue: &Lvalue<'tcx>) {
        self.push_assign(block, source_info, lvalue, Rvalue::Aggregate(
            AggregateKind::Tuple, vec![]
        ));
    }

    pub fn terminate(&mut self,
                     block: BasicBlock,
                     source_info: SourceInfo,
                     kind: TerminatorKind<'tcx>) {
        debug!("terminating block {:?} <- {:?}", block, kind);
        debug_assert!(self.block_data(block).terminator.is_none(),
                      "terminate: block {:?}={:?} already has a terminator set",
                      block,
                      self.block_data(block));
        self.block_data_mut(block).terminator = Some(Terminator {
            source_info: source_info,
            kind: kind,
        });
    }
}
<commit_msg>mark build::cfg::start_new_block as inline(never)<commit_after>// Copyright 2015 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.

//! Routines for manipulating the control-flow graph.

use build::CFG;
use rustc::mir::*;

impl<'tcx> CFG<'tcx> {
    pub fn block_data(&self, blk: BasicBlock) -> &BasicBlockData<'tcx> {
        &self.basic_blocks[blk]
    }

    pub fn block_data_mut(&mut self, blk: BasicBlock) -> &mut BasicBlockData<'tcx> {
        &mut self.basic_blocks[blk]
    }

    // llvm.org/PR32488 makes this function use an excess of stack space. Mark
    // it as #[inline(never)] to keep rustc's stack use in check.
    #[inline(never)]
    pub fn start_new_block(&mut self) -> BasicBlock {
        self.basic_blocks.push(BasicBlockData::new(None))
    }

    pub fn start_new_cleanup_block(&mut self) -> BasicBlock {
        let bb = self.start_new_block();
        self.block_data_mut(bb).is_cleanup = true;
        bb
    }

    pub fn push(&mut self, block: BasicBlock, statement: Statement<'tcx>) {
        debug!("push({:?}, {:?})", block, statement);
        self.block_data_mut(block).statements.push(statement);
    }

    pub fn push_assign(&mut self,
                       block: BasicBlock,
                       source_info: SourceInfo,
                       lvalue: &Lvalue<'tcx>,
                       rvalue: Rvalue<'tcx>) {
        self.push(block, Statement {
            source_info: source_info,
            kind: StatementKind::Assign(lvalue.clone(), rvalue)
        });
    }

    pub fn push_assign_constant(&mut self,
                                block: BasicBlock,
                                source_info: SourceInfo,
                                temp: &Lvalue<'tcx>,
                                constant: Constant<'tcx>) {
        self.push_assign(block, source_info, temp,
                         Rvalue::Use(Operand::Constant(constant)));
    }

    pub fn push_assign_unit(&mut self,
                            block: BasicBlock,
                            source_info: SourceInfo,
                            lvalue: &Lvalue<'tcx>) {
        self.push_assign(block, source_info, lvalue, Rvalue::Aggregate(
            AggregateKind::Tuple, vec![]
        ));
    }

    pub fn terminate(&mut self,
                     block: BasicBlock,
                     source_info: SourceInfo,
                     kind: TerminatorKind<'tcx>) {
        debug!("terminating block {:?} <- {:?}", block, kind);
        debug_assert!(self.block_data(block).terminator.is_none(),
                      "terminate: block {:?}={:?} already has a terminator set",
                      block,
                      self.block_data(block));
        self.block_data_mut(block).terminator = Some(Terminator {
            source_info: source_info,
            kind: kind,
        });
    }
}
<|endoftext|>


<commit_before>// NB: transitionary, de-mode-ing.
// tjc: allowing deprecated modes due to function issue.
// can re-forbid them after snapshot
#[forbid(deprecated_pattern)];

/*!
 * A type representing values that may be computed concurrently and
 * operations for working with them.
 *
 * # Example
 *
 * ~~~
 * let delayed_fib = future::spawn {|| fib(5000) };
 * make_a_sandwich();
 * io::println(fmt!("fib(5000) = %?", delayed_fib.get()))
 * ~~~
 */

use either::Either;
use pipes::recv;
use cast::copy_lifetime;

#[doc = "The future type"]
pub struct Future<A> {
    /*priv*/ mut state: FutureState<A>,

    // FIXME(#2829) -- futures should not be copyable, because they close
    // over fn~'s that have pipes and so forth within!
    drop {}
}

priv enum FutureState<A> {
    Pending(fn~() -> A),
    Evaluating,
    Forced(~A)
}

/// Methods on the `future` type
impl<A:Copy> Future<A> {
    fn get() -> A {
        //! Get the value of the future

        get(&self)
    }
}

impl<A> Future<A> {
    fn get_ref(&self) -> &self/A {
        get_ref(self)
    }

    fn with<B>(blk: fn((&A)) -> B) -> B {
        //! Work with the value without copying it

        with(&self, blk)
    }
}

pub fn from_value<A>(val: A) -> Future<A> {
    /*!
     * Create a future from a value
     *
     * The value is immediately available and calling `get` later will
     * not block.
     */

    Future {state: Forced(~(move val))}
}

pub fn from_port<A:Send>(port: future_pipe::client::waiting<A>) ->
        Future<A> {
    /*!
     * Create a future from a port
     *
     * The first time that the value is requested the task will block
     * waiting for the result to be received on the port.
     */

    let port = ~mut Some(move port);
    do from_fn |move port| {
        let mut port_ = None;
        port_ <-> *port;
        let port = option::unwrap(move port_);
        match recv(move port) {
            future_pipe::completed(move data) => move data
        }
    }
}

pub fn from_fn<A>(f: ~fn() -> A) -> Future<A> {
    /*!
     * Create a future from a function.
     *
     * The first time that the value is requested it will be retreived by
     * calling the function.  Note that this function is a local
     * function. It is not spawned into another task.
     */

    Future {state: Pending(move f)}
}

pub fn spawn<A:Send>(blk: fn~() -> A) -> Future<A> {
    /*!
     * Create a future from a unique closure.
     *
     * The closure will be run in a new task and its result used as the
     * value of the future.
     */

    from_port(pipes::spawn_service_recv(future_pipe::init, |move blk, ch| {
        future_pipe::server::completed(move ch, blk());
    }))
}

pub fn get_ref<A>(future: &r/Future<A>) -> &r/A {
    /*!
     * Executes the future's closure and then returns a borrowed
     * pointer to the result.  The borrowed pointer lasts as long as
     * the future.
     */

    // The unsafety here is to hide the aliases from borrowck, which
    // would otherwise be concerned that someone might reassign
    // `future.state` and cause the value of the future to be freed.
    // But *we* know that once `future.state` is `Forced()` it will
    // never become "unforced"---so we can safely return a pointer
    // into the interior of the Forced() variant which will last as
    // long as the future itself.

    match future.state {
      Forced(ref v) => { // v here has type &A, but with a shorter lifetime.
        return unsafe{ copy_lifetime(future, &**v) }; // ...extend it.
      }
      Evaluating => {
        fail ~"Recursive forcing of future!";
      }
      Pending(_) => {}
    }

    let mut state = Evaluating;
    state <-> future.state;
    match move state {
      Forced(_) | Evaluating => {
        fail ~"Logic error.";
      }
      Pending(move f) => {
        future.state = Forced(~f());
        return get_ref(future);
      }
    }
}

pub fn get<A:Copy>(future: &Future<A>) -> A {
    //! Get the value of the future

    *get_ref(future)
}

pub fn with<A,B>(future: &Future<A>, blk: fn((&A)) -> B) -> B {
    //! Work with the value without copying it

    blk(get_ref(future))
}

proto! future_pipe (
    waiting:recv<T:Send> {
        completed(T) -> !
    }
)

#[allow(non_implicitly_copyable_typarams)]
pub mod test {
    #[test]
    pub fn test_from_value() {
        let f = from_value(~"snail");
        assert get(&f) == ~"snail";
    }

    #[test]
    pub fn test_from_port() {
        let (po, ch) = future_pipe::init();
        future_pipe::server::completed(move ch, ~"whale");
        let f = from_port(move po);
        assert get(&f) == ~"whale";
    }

    #[test]
    pub fn test_from_fn() {
        let f = from_fn(|| ~"brail");
        assert get(&f) == ~"brail";
    }

    #[test]
    pub fn test_interface_get() {
        let f = from_value(~"fail");
        assert f.get() == ~"fail";
    }

    #[test]
    pub fn test_with() {
        let f = from_value(~"nail");
        assert with(&f, |v| copy *v) == ~"nail";
    }

    #[test]
    pub fn test_get_ref_method() {
        let f = from_value(22);
        assert *f.get_ref() == 22;
    }

    #[test]
    pub fn test_get_ref_fn() {
        let f = from_value(22);
        assert *get_ref(&f) == 22;
    }

    #[test]
    pub fn test_interface_with() {
        let f = from_value(~"kale");
        assert f.with(|v| copy *v) == ~"kale";
    }

    #[test]
    pub fn test_spawn() {
        let f = spawn(|| ~"bale");
        assert get(&f) == ~"bale";
    }

    #[test]
    #[should_fail]
    #[ignore(cfg(target_os = "win32"))]
    pub fn test_futurefail() {
        let f = spawn(|| fail);
        let _x: ~str = get(&f);
    }

    #[test]
    pub fn test_sendable_future() {
        let expected = ~"schlorf";
        let f = do spawn |copy expected| { copy expected };
        do task::spawn |move f, move expected| {
            let actual = get(&f);
            assert actual == expected;
        }
    }
}
<commit_msg>core: Give future_pipe the same definition as pipes::oneshot<commit_after>// NB: transitionary, de-mode-ing.
// tjc: allowing deprecated modes due to function issue.
// can re-forbid them after snapshot
#[forbid(deprecated_pattern)];

/*!
 * A type representing values that may be computed concurrently and
 * operations for working with them.
 *
 * # Example
 *
 * ~~~
 * let delayed_fib = future::spawn {|| fib(5000) };
 * make_a_sandwich();
 * io::println(fmt!("fib(5000) = %?", delayed_fib.get()))
 * ~~~
 */

use either::Either;
use pipes::recv;
use cast::copy_lifetime;

#[doc = "The future type"]
pub struct Future<A> {
    /*priv*/ mut state: FutureState<A>,

    // FIXME(#2829) -- futures should not be copyable, because they close
    // over fn~'s that have pipes and so forth within!
    drop {}
}

priv enum FutureState<A> {
    Pending(fn~() -> A),
    Evaluating,
    Forced(~A)
}

/// Methods on the `future` type
impl<A:Copy> Future<A> {
    fn get() -> A {
        //! Get the value of the future

        get(&self)
    }
}

impl<A> Future<A> {
    fn get_ref(&self) -> &self/A {
        get_ref(self)
    }

    fn with<B>(blk: fn((&A)) -> B) -> B {
        //! Work with the value without copying it

        with(&self, blk)
    }
}

pub fn from_value<A>(val: A) -> Future<A> {
    /*!
     * Create a future from a value
     *
     * The value is immediately available and calling `get` later will
     * not block.
     */

    Future {state: Forced(~(move val))}
}

pub fn from_port<A:Send>(port: future_pipe::server::waiting<A>) ->
        Future<A> {
    /*!
     * Create a future from a port
     *
     * The first time that the value is requested the task will block
     * waiting for the result to be received on the port.
     */

    let port = ~mut Some(move port);
    do from_fn |move port| {
        let mut port_ = None;
        port_ <-> *port;
        let port = option::unwrap(move port_);
        match recv(move port) {
            future_pipe::completed(move data) => move data
        }
    }
}

pub fn from_fn<A>(f: ~fn() -> A) -> Future<A> {
    /*!
     * Create a future from a function.
     *
     * The first time that the value is requested it will be retreived by
     * calling the function.  Note that this function is a local
     * function. It is not spawned into another task.
     */

    Future {state: Pending(move f)}
}

pub fn spawn<A:Send>(blk: fn~() -> A) -> Future<A> {
    /*!
     * Create a future from a unique closure.
     *
     * The closure will be run in a new task and its result used as the
     * value of the future.
     */

    let (chan, port) = future_pipe::init();

    let chan = ~mut Some(move chan);
    do task::spawn |move blk, move chan| {
        let chan = option::swap_unwrap(&mut *chan);
        future_pipe::client::completed(move chan, blk());
    }

    return from_port(move port);
}

pub fn get_ref<A>(future: &r/Future<A>) -> &r/A {
    /*!
     * Executes the future's closure and then returns a borrowed
     * pointer to the result.  The borrowed pointer lasts as long as
     * the future.
     */

    // The unsafety here is to hide the aliases from borrowck, which
    // would otherwise be concerned that someone might reassign
    // `future.state` and cause the value of the future to be freed.
    // But *we* know that once `future.state` is `Forced()` it will
    // never become "unforced"---so we can safely return a pointer
    // into the interior of the Forced() variant which will last as
    // long as the future itself.

    match future.state {
      Forced(ref v) => { // v here has type &A, but with a shorter lifetime.
        return unsafe{ copy_lifetime(future, &**v) }; // ...extend it.
      }
      Evaluating => {
        fail ~"Recursive forcing of future!";
      }
      Pending(_) => {}
    }

    let mut state = Evaluating;
    state <-> future.state;
    match move state {
      Forced(_) | Evaluating => {
        fail ~"Logic error.";
      }
      Pending(move f) => {
        future.state = Forced(~f());
        return get_ref(future);
      }
    }
}

pub fn get<A:Copy>(future: &Future<A>) -> A {
    //! Get the value of the future

    *get_ref(future)
}

pub fn with<A,B>(future: &Future<A>, blk: fn((&A)) -> B) -> B {
    //! Work with the value without copying it

    blk(get_ref(future))
}

proto! future_pipe (
    waiting:send<T:Send> {
        completed(T) -> !
    }
)

#[allow(non_implicitly_copyable_typarams)]
pub mod test {
    #[test]
    pub fn test_from_value() {
        let f = from_value(~"snail");
        assert get(&f) == ~"snail";
    }

    #[test]
    pub fn test_from_port() {
        let (ch, po) = future_pipe::init();
        future_pipe::client::completed(move ch, ~"whale");
        let f = from_port(move po);
        assert get(&f) == ~"whale";
    }

    #[test]
    pub fn test_from_fn() {
        let f = from_fn(|| ~"brail");
        assert get(&f) == ~"brail";
    }

    #[test]
    pub fn test_interface_get() {
        let f = from_value(~"fail");
        assert f.get() == ~"fail";
    }

    #[test]
    pub fn test_with() {
        let f = from_value(~"nail");
        assert with(&f, |v| copy *v) == ~"nail";
    }

    #[test]
    pub fn test_get_ref_method() {
        let f = from_value(22);
        assert *f.get_ref() == 22;
    }

    #[test]
    pub fn test_get_ref_fn() {
        let f = from_value(22);
        assert *get_ref(&f) == 22;
    }

    #[test]
    pub fn test_interface_with() {
        let f = from_value(~"kale");
        assert f.with(|v| copy *v) == ~"kale";
    }

    #[test]
    pub fn test_spawn() {
        let f = spawn(|| ~"bale");
        assert get(&f) == ~"bale";
    }

    #[test]
    #[should_fail]
    #[ignore(cfg(target_os = "win32"))]
    pub fn test_futurefail() {
        let f = spawn(|| fail);
        let _x: ~str = get(&f);
    }

    #[test]
    pub fn test_sendable_future() {
        let expected = ~"schlorf";
        let f = do spawn |copy expected| { copy expected };
        do task::spawn |move f, move expected| {
            let actual = get(&f);
            assert actual == expected;
        }
    }
}
<|endoftext|>


<commit_before>/*!

Operations on the ubiquitous `Option` type.

Type `Option` represents an optional value.

Every `Option<T>` value can either be `Some(T)` or `None`. Where in other
languages you might use a nullable type, in Rust you would use an option
type.

Options are most commonly used with pattern matching to query the presence
of a value and take action, always accounting for the `None` case.

# Example

~~~
let msg = Some(~"howdy");

// Take a reference to the contained string
match msg {
    Some(ref m) => io::println(m),
    None => ()
}

// Remove the contained string, destroying the Option
let unwrapped_msg = match move msg {
    Some(move m) => m,
    None => ~"default message"
};
~~~

*/

#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];

use cmp::Eq;

/// The option type
pub enum Option<T> {
    None,
    Some(T),
}

pub pure fn get<T: Copy>(opt: Option<T>) -> T {
    /*!
    Gets the value out of an option

    # Failure

    Fails if the value equals `None`

    # Safety note

    In general, because this function may fail, its use is discouraged
    (calling `get` on `None` is akin to dereferencing a null pointer).
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
    */

    match opt {
      Some(copy x) => return x,
      None => fail ~"option::get none"
    }
}

pub pure fn get_ref<T>(opt: &r/Option<T>) -> &r/T {
    /*!
    Gets an immutable reference to the value inside an option.

    # Failure

    Fails if the value equals `None`

    # Safety note

    In general, because this function may fail, its use is discouraged
    (calling `get` on `None` is akin to dereferencing a null pointer).
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
     */
    match *opt {
        Some(ref x) => x,
        None => fail ~"option::get_ref none"
    }
}

pub pure fn expect<T>(opt: Option<T>, reason: ~str) -> T {
    /*!
     * Gets the value out of an option without copying, printing a
     * specified message on failure.
     *
     * # Failure
     *
     * Fails if the value equals `none`
     */
    if opt.is_some() { move option::unwrap(move opt) }
    else { fail reason }
}

pub pure fn map<T, U>(opt: &Option<T>, f: fn(x: &T) -> U) -> Option<U> {
    //! Maps a `some` value by reference from one type to another

    match *opt { Some(ref x) => Some(f(x)), None => None }
}

pub pure fn map_consume<T, U>(opt: Option<T>,
                              f: fn(v: T) -> U) -> Option<U> {
    /*!
     * As `map`, but consumes the option and gives `f` ownership to avoid
     * copying.
     */
    if opt.is_some() { Some(f(option::unwrap(move opt))) } else { None }
}

pub pure fn chain<T, U>(opt: Option<T>,
                        f: fn(t: T) -> Option<U>) -> Option<U> {
    /*!
     * Update an optional value by optionally running its content through a
     * function that returns an option.
     */

    match move opt {
        Some(move t) => f(move t),
        None => None
    }
}

pub pure fn chain_ref<T, U>(opt: &Option<T>,
                            f: fn(x: &T) -> Option<U>) -> Option<U> {
    /*!
     * Update an optional value by optionally running its content by reference
     * through a function that returns an option.
     */

    match *opt { Some(ref x) => f(x), None => None }
}

pub pure fn or<T>(opta: Option<T>, optb: Option<T>) -> Option<T> {
    /*!
     * Returns the leftmost some() value, or none if both are none.
     */
    match opta {
        Some(_) => move opta,
        _ => move optb
    }
}

#[inline(always)]
pub pure fn while_some<T>(x: Option<T>, blk: fn(v: T) -> Option<T>) {
    //! Applies a function zero or more times until the result is none.

    let mut opt = move x;
    while opt.is_some() {
        opt = blk(unwrap(move opt));
    }
}

pub pure fn is_none<T>(opt: &Option<T>) -> bool {
    //! Returns true if the option equals `none`

    match *opt { None => true, Some(_) => false }
}

pub pure fn is_some<T>(opt: &Option<T>) -> bool {
    //! Returns true if the option contains some value

    !is_none(opt)
}

pub pure fn get_default<T: Copy>(opt: Option<T>, def: T) -> T {
    //! Returns the contained value or a default

    match opt { Some(copy x) => x, None => def }
}

pub pure fn map_default<T, U>(opt: &Option<T>, def: U,
                              f: fn(x: &T) -> U) -> U {
    //! Applies a function to the contained value or returns a default

    match *opt { None => move def, Some(ref t) => f(t) }
}

pub pure fn iter<T>(opt: &Option<T>, f: fn(x: &T)) {
    //! Performs an operation on the contained value by reference
    match *opt { None => (), Some(ref t) => f(t) }
}

#[inline(always)]
pub pure fn unwrap<T>(opt: Option<T>) -> T {
    /*!
    Moves a value out of an option type and returns it.

    Useful primarily for getting strings, vectors and unique pointers out
    of option types without copying them.

    # Failure

    Fails if the value equals `None`.

    # Safety note

    In general, because this function may fail, its use is discouraged.
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
     */
    match move opt {
        Some(move x) => move x,
        None => fail ~"option::unwrap none"
    }
}

#[inline(always)]
pub fn swap_unwrap<T>(opt: &mut Option<T>) -> T {
    /*!
    The option dance. Moves a value out of an option type and returns it,
    replacing the original with `None`.

    # Failure

    Fails if the value equals `None`.
     */
    if opt.is_none() { fail ~"option::swap_unwrap none" }
    unwrap(util::replace(opt, None))
}

pub pure fn unwrap_expect<T>(opt: Option<T>, reason: &str) -> T {
    //! As unwrap, but with a specified failure message.
    if opt.is_none() { fail reason.to_owned(); }
    unwrap(move opt)
}

// Some of these should change to be &Option<T>, some should not. See below.
impl<T> Option<T> {
    /// Returns true if the option equals `none`
    pure fn is_none() -> bool { is_none(&self) }
    /// Returns true if the option contains some value
    pure fn is_some() -> bool { is_some(&self) }
}

impl<T> &Option<T> {
    /**
     * Update an optional value by optionally running its content by reference
     * through a function that returns an option.
     */
    pure fn chain_ref<U>(f: fn(x: &T) -> Option<U>) -> Option<U> {
        chain_ref(self, f)
    }
    /// Applies a function to the contained value or returns a default
    pure fn map_default<U>(def: U, f: fn(x: &T) -> U) -> U
        { map_default(self, move def, f) }
    /// Performs an operation on the contained value by reference
    pure fn iter(f: fn(x: &T)) { iter(self, f) }
    /// Maps a `some` value from one type to another by reference
    pure fn map<U>(f: fn(x: &T) -> U) -> Option<U> { map(self, f) }
    /**
    Gets an immutable reference to the value inside an option.

    # Failure

    Fails if the value equals `None`

    # Safety note

    In general, because this function may fail, its use is discouraged
    (calling `get` on `None` is akin to dereferencing a null pointer).
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
     */
    pure fn get_ref() -> &self/T { get_ref(self) }
}

impl<T: Copy> Option<T> {
    /**
    Gets the value out of an option

    # Failure

    Fails if the value equals `None`

    # Safety note

    In general, because this function may fail, its use is discouraged
    (calling `get` on `None` is akin to dereferencing a null pointer).
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
    */
    pure fn get() -> T { get(self) }
    pure fn get_default(def: T) -> T { get_default(self, def) }
    /**
     * Gets the value out of an option, printing a specified message on
     * failure
     *
     * # Failure
     *
     * Fails if the value equals `none`
     */
    pure fn expect(reason: ~str) -> T { expect(self, move reason) }
    /// Applies a function zero or more times until the result is none.
    pure fn while_some(blk: fn(v: T) -> Option<T>) { while_some(self, blk) }
}

impl<T: Eq> Option<T> : Eq {
    pure fn eq(other: &Option<T>) -> bool {
        match self {
            None => {
                match (*other) {
                    None => true,
                    Some(_) => false
                }
            }
            Some(ref self_contents) => {
                match (*other) {
                    None => false,
                    Some(ref other_contents) =>
                        (*self_contents).eq(other_contents)
                }
            }
        }
    }
    pure fn ne(other: &Option<T>) -> bool { !self.eq(other) }
}

#[test]
fn test_unwrap_ptr() {
    let x = ~0;
    let addr_x = ptr::addr_of(&(*x));
    let opt = Some(move x);
    let y = unwrap(move opt);
    let addr_y = ptr::addr_of(&(*y));
    assert addr_x == addr_y;
}

#[test]
fn test_unwrap_str() {
    let x = ~"test";
    let addr_x = str::as_buf(x, |buf, _len| buf);
    let opt = Some(move x);
    let y = unwrap(move opt);
    let addr_y = str::as_buf(y, |buf, _len| buf);
    assert addr_x == addr_y;
}

#[test]
fn test_unwrap_resource() {
    struct R {
       i: @mut int,
       drop { *(self.i) += 1; }
    }

    fn R(i: @mut int) -> R {
        R {
            i: i
        }
    }

    let i = @mut 0;
    {
        let x = R(i);
        let opt = Some(move x);
        let _y = unwrap(move opt);
    }
    assert *i == 1;
}

#[test]
fn test_option_dance() {
    let x = Some(());
    let mut y = Some(5);
    let mut y2 = 0;
    do x.iter |_x| {
        y2 = swap_unwrap(&mut y);
    }
    assert y2 == 5;
    assert y.is_none();
}
#[test] #[should_fail] #[ignore(cfg(windows))]
fn test_option_too_much_dance() {
    let mut y = Some(util::NonCopyable());
    let _y2 = swap_unwrap(&mut y);
    let _y3 = swap_unwrap(&mut y);
}

#[test]
fn test_option_while_some() {
    let mut i = 0;
    do Some(10).while_some |j| {
        i += 1;
        if (j > 0) {
            Some(j-1)
        } else {
            None
        }
    }
    assert i == 11;
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
<commit_msg>Whitespace<commit_after>/*!

Operations on the ubiquitous `Option` type.

Type `Option` represents an optional value.

Every `Option<T>` value can either be `Some(T)` or `None`. Where in other
languages you might use a nullable type, in Rust you would use an option
type.

Options are most commonly used with pattern matching to query the presence
of a value and take action, always accounting for the `None` case.

# Example

~~~
let msg = Some(~"howdy");

// Take a reference to the contained string
match msg {
    Some(ref m) => io::println(m),
    None => ()
}

// Remove the contained string, destroying the Option
let unwrapped_msg = match move msg {
    Some(move m) => m,
    None => ~"default message"
};
~~~

*/

#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];

use cmp::Eq;

/// The option type
pub enum Option<T> {
    None,
    Some(T),
}

pub pure fn get<T: Copy>(opt: Option<T>) -> T {
    /*!
    Gets the value out of an option

    # Failure

    Fails if the value equals `None`

    # Safety note

    In general, because this function may fail, its use is discouraged
    (calling `get` on `None` is akin to dereferencing a null pointer).
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
    */

    match opt {
      Some(copy x) => return x,
      None => fail ~"option::get none"
    }
}

pub pure fn get_ref<T>(opt: &r/Option<T>) -> &r/T {
    /*!
    Gets an immutable reference to the value inside an option.

    # Failure

    Fails if the value equals `None`

    # Safety note

    In general, because this function may fail, its use is discouraged
    (calling `get` on `None` is akin to dereferencing a null pointer).
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
     */
    match *opt {
        Some(ref x) => x,
        None => fail ~"option::get_ref none"
    }
}

pub pure fn expect<T>(opt: Option<T>, reason: ~str) -> T {
    /*!
     * Gets the value out of an option without copying, printing a
     * specified message on failure.
     *
     * # Failure
     *
     * Fails if the value equals `none`
     */
    if opt.is_some() { move option::unwrap(move opt) }
    else { fail reason }
}

pub pure fn map<T, U>(opt: &Option<T>, f: fn(x: &T) -> U) -> Option<U> {
    //! Maps a `some` value by reference from one type to another

    match *opt { Some(ref x) => Some(f(x)), None => None }
}

pub pure fn map_consume<T, U>(opt: Option<T>,
                              f: fn(v: T) -> U) -> Option<U> {
    /*!
     * As `map`, but consumes the option and gives `f` ownership to avoid
     * copying.
     */
    if opt.is_some() { Some(f(option::unwrap(move opt))) } else { None }
}

pub pure fn chain<T, U>(opt: Option<T>,
                        f: fn(t: T) -> Option<U>) -> Option<U> {
    /*!
     * Update an optional value by optionally running its content through a
     * function that returns an option.
     */

    match move opt {
        Some(move t) => f(move t),
        None => None
    }
}

pub pure fn chain_ref<T, U>(opt: &Option<T>,
                            f: fn(x: &T) -> Option<U>) -> Option<U> {
    /*!
     * Update an optional value by optionally running its content by reference
     * through a function that returns an option.
     */

    match *opt { Some(ref x) => f(x), None => None }
}

pub pure fn or<T>(opta: Option<T>, optb: Option<T>) -> Option<T> {
    /*!
     * Returns the leftmost some() value, or none if both are none.
     */
    match opta {
        Some(_) => move opta,
        _ => move optb
    }
}

#[inline(always)]
pub pure fn while_some<T>(x: Option<T>, blk: fn(v: T) -> Option<T>) {
    //! Applies a function zero or more times until the result is none.

    let mut opt = move x;
    while opt.is_some() {
        opt = blk(unwrap(move opt));
    }
}

pub pure fn is_none<T>(opt: &Option<T>) -> bool {
    //! Returns true if the option equals `none`

    match *opt { None => true, Some(_) => false }
}

pub pure fn is_some<T>(opt: &Option<T>) -> bool {
    //! Returns true if the option contains some value

    !is_none(opt)
}

pub pure fn get_default<T: Copy>(opt: Option<T>, def: T) -> T {
    //! Returns the contained value or a default

    match opt { Some(copy x) => x, None => def }
}

pub pure fn map_default<T, U>(opt: &Option<T>, def: U,
                              f: fn(x: &T) -> U) -> U {
    //! Applies a function to the contained value or returns a default

    match *opt { None => move def, Some(ref t) => f(t) }
}

pub pure fn iter<T>(opt: &Option<T>, f: fn(x: &T)) {
    //! Performs an operation on the contained value by reference
    match *opt { None => (), Some(ref t) => f(t) }
}

#[inline(always)]
pub pure fn unwrap<T>(opt: Option<T>) -> T {
    /*!
    Moves a value out of an option type and returns it.

    Useful primarily for getting strings, vectors and unique pointers out
    of option types without copying them.

    # Failure

    Fails if the value equals `None`.

    # Safety note

    In general, because this function may fail, its use is discouraged.
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
     */
    match move opt {
        Some(move x) => move x,
        None => fail ~"option::unwrap none"
    }
}

#[inline(always)]
pub fn swap_unwrap<T>(opt: &mut Option<T>) -> T {
    /*!
    The option dance. Moves a value out of an option type and returns it,
    replacing the original with `None`.

    # Failure

    Fails if the value equals `None`.
     */
    if opt.is_none() { fail ~"option::swap_unwrap none" }
    unwrap(util::replace(opt, None))
}

pub pure fn unwrap_expect<T>(opt: Option<T>, reason: &str) -> T {
    //! As unwrap, but with a specified failure message.
    if opt.is_none() { fail reason.to_owned(); }
    unwrap(move opt)
}

// Some of these should change to be &Option<T>, some should not. See below.
impl<T> Option<T> {
    /// Returns true if the option equals `none`
    pure fn is_none() -> bool { is_none(&self) }
    /// Returns true if the option contains some value
    pure fn is_some() -> bool { is_some(&self) }
}

impl<T> &Option<T> {
    /**
     * Update an optional value by optionally running its content by reference
     * through a function that returns an option.
     */
    pure fn chain_ref<U>(f: fn(x: &T) -> Option<U>) -> Option<U> {
        chain_ref(self, f)
    }
    /// Applies a function to the contained value or returns a default
    pure fn map_default<U>(def: U, f: fn(x: &T) -> U) -> U
        { map_default(self, move def, f) }
    /// Performs an operation on the contained value by reference
    pure fn iter(f: fn(x: &T)) { iter(self, f) }
    /// Maps a `some` value from one type to another by reference
    pure fn map<U>(f: fn(x: &T) -> U) -> Option<U> { map(self, f) }
    /**
    Gets an immutable reference to the value inside an option.

    # Failure

    Fails if the value equals `None`

    # Safety note

    In general, because this function may fail, its use is discouraged
    (calling `get` on `None` is akin to dereferencing a null pointer).
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
     */
    pure fn get_ref() -> &self/T { get_ref(self) }
}

impl<T: Copy> Option<T> {
    /**
    Gets the value out of an option

    # Failure

    Fails if the value equals `None`

    # Safety note

    In general, because this function may fail, its use is discouraged
    (calling `get` on `None` is akin to dereferencing a null pointer).
    Instead, prefer to use pattern matching and handle the `None`
    case explicitly.
    */
    pure fn get() -> T { get(self) }
    pure fn get_default(def: T) -> T { get_default(self, def) }
    /**
     * Gets the value out of an option, printing a specified message on
     * failure
     *
     * # Failure
     *
     * Fails if the value equals `none`
     */
    pure fn expect(reason: ~str) -> T { expect(self, move reason) }
    /// Applies a function zero or more times until the result is none.
    pure fn while_some(blk: fn(v: T) -> Option<T>) { while_some(self, blk) }
}

impl<T: Eq> Option<T> : Eq {
    pure fn eq(other: &Option<T>) -> bool {
        match self {
            None => {
                match (*other) {
                    None => true,
                    Some(_) => false
                }
            }
            Some(ref self_contents) => {
                match (*other) {
                    None => false,
                    Some(ref other_contents) =>
                        (*self_contents).eq(other_contents)
                }
            }
        }
    }
    pure fn ne(other: &Option<T>) -> bool { !self.eq(other) }
}

#[test]
fn test_unwrap_ptr() {
    let x = ~0;
    let addr_x = ptr::addr_of(&(*x));
    let opt = Some(move x);
    let y = unwrap(move opt);
    let addr_y = ptr::addr_of(&(*y));
    assert addr_x == addr_y;
}

#[test]
fn test_unwrap_str() {
    let x = ~"test";
    let addr_x = str::as_buf(x, |buf, _len| buf);
    let opt = Some(move x);
    let y = unwrap(move opt);
    let addr_y = str::as_buf(y, |buf, _len| buf);
    assert addr_x == addr_y;
}

#[test]
fn test_unwrap_resource() {
    struct R {
       i: @mut int,
       drop { *(self.i) += 1; }
    }

    fn R(i: @mut int) -> R {
        R {
            i: i
        }
    }

    let i = @mut 0;
    {
        let x = R(i);
        let opt = Some(move x);
        let _y = unwrap(move opt);
    }
    assert *i == 1;
}

#[test]
fn test_option_dance() {
    let x = Some(());
    let mut y = Some(5);
    let mut y2 = 0;
    do x.iter |_x| {
        y2 = swap_unwrap(&mut y);
    }
    assert y2 == 5;
    assert y.is_none();
}
#[test] #[should_fail] #[ignore(cfg(windows))]
fn test_option_too_much_dance() {
    let mut y = Some(util::NonCopyable());
    let _y2 = swap_unwrap(&mut y);
    let _y3 = swap_unwrap(&mut y);
}

#[test]
fn test_option_while_some() {
    let mut i = 0;
    do Some(10).while_some |j| {
        i += 1;
        if (j > 0) {
            Some(j-1)
        } else {
            None
        }
    }
    assert i == 11;
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
<|endoftext|>


<commit_before><commit_msg>Implementando busca binaria em Rust<commit_after>/*
    Crontibuidores
        - Dromedario de Chapéu

        O que é busca Binaria -
    "A busca binária é um eficiente algoritmo para encontrar um item em uma lista
    ordenada de itens. Ela funciona dividindo repetidamente pela metade a porção da
    lista que deve conter o item, até reduzir as localizações possíveis a apenas uma.
    Nós usamos a busca binária em um jogo de adivinhação no tutorial introdutório."
        - Khan Academy : https://pt.khanacademy.org/computing/computer-science/algorithms/binary-search/a/binary-search
*/

// O <T> em Rust indica que não se espera tipo especifico e sim qualquer tipo
// no caso o T é usado para indicar o tipo dos valores da lista e o valor a ser
// procurado.
fn busca_binaria<T>(lista: &[T], valor: T) -> (bool, usize)
where
    // É preciso especificar que T implementa as Traits PartialEq e PartialOrd para
    // indicar que T pode ser comparado T e que possui uma ordem de maior e menor
    T: PartialEq,
    T: PartialOrd,
{
    // Centro indica o centro a lista ou sublista
    let mut centro = lista.len() / 2;

    // Limite_r representa o maior indice possivel, referente ao extremo direito
    // da lista atual, serve para dividir a lista original sem precisar ficar
    // clonando ou literalmente dividindo. Seria o [-1] da sublista
    let mut limite_r = lista.len() - 1;

    // Limite_l representa o mesmo que Limite_r porem para o extremo esquerdo,
    // ou sejá, o [0] da sub lista.
    let mut limite_l = 0;

    loop {
        // O valor esta sendo passado por referencia e depois acessado pelo seu
        // ponteiro pelo sistema de owenrship o Rust, isso pode feito com atribuição
        // simples como `valor_p = lista[centro]` em um Python por exemplo
        let valor_p = &lista[centro];

        // O primeiro bloco de if se responsabiliza em verificar se o valor que estamos
        // buscado foi encontrado, caso não ele verifica da ultima operação para esta
        // o centro não mudou de posição, ou sejá, não ha mais valores para verificar
        // e o item não existe
        if *valor_p == valor {
            return (true, centro)
        } else if centro == limite_l && centro == limite_r {
            return (false, 0)
        }

        // O segundo bloco se responsabiliza em verificar a distancia entre o valor recebido
        // e o atual valor_p, caso sejá valor_p sejá maior, significa que o valor procurado
        // esta mais para tras, e o centro é movido para o centro da sub lista anterior.
        // Porem caso valor sejá maior qe o valor_p, significa que precisamos mover o centro
        // para o centro da sub lista superiors
        if *valor_p > valor {
            limite_r = centro;
            centro = centro / 2;
        } else if *valor_p < valor {
            limite_l = centro;
            // O If esta verificando se o espaço entre limite_r e limite_l é igual a 1
            // pois a operação de padrão usada daria o resultado de 0 nesse caso, pos
            // Rust aredonda os valores para baixo, logo 0.5 é jogado para 0
            // Poderia ser feito em uma linha utilizado conversõ de tipos e arredondamento
            // porem eu pessoalmente acredito que a performance ganha não vale compensa

            centro = if (limite_r - limite_l) == 1 { centro + 1 }
                     else { centro + (limite_r - limite_l) / 2 };
            // Forma em uma linha -
            //     centro = centro + (((limite_r - limite_l) as f32 / 2.0).ceil() as usize);
        }
    }
}

fn main() {
    let lista = vec![-5, -4, -3, -2, -1];
    let (existe, centro) = busca_binaria(&lista, 6);
    println!("{}, {}", existe, centro);
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn busca() {
        let lista = vec![-3, -2, -1, 0, 1, 2, 3];
        assert_eq!(busca_binaria(&lista, -7), (false, 0));
        assert_eq!(busca_binaria(&lista, -2), (true, 1));
        assert_eq!(busca_binaria(&lista, 0), (true, 3));
        assert_eq!(busca_binaria(&lista, 2), (true, 5));
        assert_eq!(busca_binaria(&lista, 7), (false, 0));
    }
}<|endoftext|>


<commit_before>// 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.

/*! Condition handling */

#[allow(missing_doc)];

use local_data;
use prelude::*;

// helper for transmutation, shown below.
type RustClosure = (int, int);

pub struct Handler<T, U> {
    handle: RustClosure,
    prev: Option<@Handler<T, U>>,
}

pub struct Condition<T, U> {
    name: &'static str,
    key: local_data::Key<@Handler<T, U>>
}

impl<T, U> Condition<T, U> {
    pub fn trap<'a>(&'a self, h: &'a fn(T) -> U) -> Trap<'a, T, U> {
        unsafe {
            let p : *RustClosure = ::cast::transmute(&h);
            let prev = local_data::get(self.key, |k| k.map(|&x| *x));
            let h = @Handler { handle: *p, prev: prev };
            Trap { cond: self, handler: h }
        }
    }

    pub fn raise(&self, t: T) -> U {
        let msg = fmt!("Unhandled condition: %s: %?", self.name, t);
        self.raise_default(t, || fail!(msg.clone()))
    }

    pub fn raise_default(&self, t: T, default: &fn() -> U) -> U {
        unsafe {
            match local_data::pop(self.key) {
                None => {
                    debug!("Condition.raise: found no handler");
                    default()
                }
                Some(handler) => {
                    debug!("Condition.raise: found handler");
                    match handler.prev {
                        None => {}
                        Some(hp) => local_data::set(self.key, hp)
                    }
                    let handle : &fn(T) -> U =
                        ::cast::transmute(handler.handle);
                    let u = handle(t);
                    local_data::set(self.key, handler);
                    u
                }
            }
        }
    }
}

struct Trap<'self, T, U> {
    cond: &'self Condition<T, U>,
    handler: @Handler<T, U>
}

impl<'self, T, U> Trap<'self, T, U> {
    pub fn inside<V>(&self, inner: &'self fn() -> V) -> V {
        let _g = Guard { cond: self.cond };
        debug!("Trap: pushing handler to TLS");
        local_data::set(self.cond.key, self.handler);
        inner()
    }
}

struct Guard<'self, T, U> {
    cond: &'self Condition<T, U>
}

#[unsafe_destructor]
impl<'self, T, U> Drop for Guard<'self, T, U> {
    fn drop(&self) {
        debug!("Guard: popping handler from TLS");
        let curr = local_data::pop(self.cond.key);
        match curr {
            None => {}
            Some(h) => match h.prev {
                None => {}
                Some(hp) => local_data::set(self.cond.key, hp)
            }
        }
    }
}

#[cfg(test)]
mod test {
    condition! {
        sadness: int -> int;
    }

    fn trouble(i: int) {
        debug!("trouble: raising condition");
        let j = sadness::cond.raise(i);
        debug!("trouble: handler recovered with %d", j);
    }

    fn nested_trap_test_inner() {
        let mut inner_trapped = false;

        do sadness::cond.trap(|_j| {
            debug!("nested_trap_test_inner: in handler");
            inner_trapped = true;
            0
        }).inside {
            debug!("nested_trap_test_inner: in protected block");
            trouble(1);
        }

        assert!(inner_trapped);
    }

    #[test]
    fn nested_trap_test_outer() {
        let mut outer_trapped = false;

        do sadness::cond.trap(|_j| {
            debug!("nested_trap_test_outer: in handler");
            outer_trapped = true; 0
        }).inside {
            debug!("nested_guard_test_outer: in protected block");
            nested_trap_test_inner();
            trouble(1);
        }

        assert!(outer_trapped);
    }

    fn nested_reraise_trap_test_inner() {
        let mut inner_trapped = false;

        do sadness::cond.trap(|_j| {
            debug!("nested_reraise_trap_test_inner: in handler");
            inner_trapped = true;
            let i = 10;
            debug!("nested_reraise_trap_test_inner: handler re-raising");
            sadness::cond.raise(i)
        }).inside {
            debug!("nested_reraise_trap_test_inner: in protected block");
            trouble(1);
        }

        assert!(inner_trapped);
    }

    #[test]
    fn nested_reraise_trap_test_outer() {
        let mut outer_trapped = false;

        do sadness::cond.trap(|_j| {
            debug!("nested_reraise_trap_test_outer: in handler");
            outer_trapped = true; 0
        }).inside {
            debug!("nested_reraise_trap_test_outer: in protected block");
            nested_reraise_trap_test_inner();
        }

        assert!(outer_trapped);
    }

    #[test]
    fn test_default() {
        let mut trapped = false;

        do sadness::cond.trap(|j| {
            debug!("test_default: in handler");
            sadness::cond.raise_default(j, || { trapped=true; 5 })
        }).inside {
            debug!("test_default: in protected block");
            trouble(1);
        }

        assert!(trapped);
    }

    // Issue #6009
    mod m {
        condition! {
            sadness: int -> int;
        }

        mod n {
            use super::sadness;

            #[test]
            fn test_conditions_are_public() {
                let mut trapped = false;
                do sadness::cond.trap(|_| {
                    trapped = true;
                    0
                }).inside {
                    sadness::cond.raise(0);
                }
                assert!(trapped);
            }
        }
    }
}
<commit_msg>Another followup on #6009.<commit_after>// 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.

/*! Condition handling */

#[allow(missing_doc)];

use local_data;
use prelude::*;

// helper for transmutation, shown below.
type RustClosure = (int, int);

pub struct Handler<T, U> {
    handle: RustClosure,
    prev: Option<@Handler<T, U>>,
}

pub struct Condition<T, U> {
    name: &'static str,
    key: local_data::Key<@Handler<T, U>>
}

impl<T, U> Condition<T, U> {
    pub fn trap<'a>(&'a self, h: &'a fn(T) -> U) -> Trap<'a, T, U> {
        unsafe {
            let p : *RustClosure = ::cast::transmute(&h);
            let prev = local_data::get(self.key, |k| k.map(|&x| *x));
            let h = @Handler { handle: *p, prev: prev };
            Trap { cond: self, handler: h }
        }
    }

    pub fn raise(&self, t: T) -> U {
        let msg = fmt!("Unhandled condition: %s: %?", self.name, t);
        self.raise_default(t, || fail!(msg.clone()))
    }

    pub fn raise_default(&self, t: T, default: &fn() -> U) -> U {
        unsafe {
            match local_data::pop(self.key) {
                None => {
                    debug!("Condition.raise: found no handler");
                    default()
                }
                Some(handler) => {
                    debug!("Condition.raise: found handler");
                    match handler.prev {
                        None => {}
                        Some(hp) => local_data::set(self.key, hp)
                    }
                    let handle : &fn(T) -> U =
                        ::cast::transmute(handler.handle);
                    let u = handle(t);
                    local_data::set(self.key, handler);
                    u
                }
            }
        }
    }
}

struct Trap<'self, T, U> {
    cond: &'self Condition<T, U>,
    handler: @Handler<T, U>
}

impl<'self, T, U> Trap<'self, T, U> {
    pub fn inside<V>(&self, inner: &'self fn() -> V) -> V {
        let _g = Guard { cond: self.cond };
        debug!("Trap: pushing handler to TLS");
        local_data::set(self.cond.key, self.handler);
        inner()
    }
}

struct Guard<'self, T, U> {
    cond: &'self Condition<T, U>
}

#[unsafe_destructor]
impl<'self, T, U> Drop for Guard<'self, T, U> {
    fn drop(&self) {
        debug!("Guard: popping handler from TLS");
        let curr = local_data::pop(self.cond.key);
        match curr {
            None => {}
            Some(h) => match h.prev {
                None => {}
                Some(hp) => local_data::set(self.cond.key, hp)
            }
        }
    }
}

#[cfg(test)]
mod test {
    condition! {
        sadness: int -> int;
    }

    fn trouble(i: int) {
        debug!("trouble: raising condition");
        let j = sadness::cond.raise(i);
        debug!("trouble: handler recovered with %d", j);
    }

    fn nested_trap_test_inner() {
        let mut inner_trapped = false;

        do sadness::cond.trap(|_j| {
            debug!("nested_trap_test_inner: in handler");
            inner_trapped = true;
            0
        }).inside {
            debug!("nested_trap_test_inner: in protected block");
            trouble(1);
        }

        assert!(inner_trapped);
    }

    #[test]
    fn nested_trap_test_outer() {
        let mut outer_trapped = false;

        do sadness::cond.trap(|_j| {
            debug!("nested_trap_test_outer: in handler");
            outer_trapped = true; 0
        }).inside {
            debug!("nested_guard_test_outer: in protected block");
            nested_trap_test_inner();
            trouble(1);
        }

        assert!(outer_trapped);
    }

    fn nested_reraise_trap_test_inner() {
        let mut inner_trapped = false;

        do sadness::cond.trap(|_j| {
            debug!("nested_reraise_trap_test_inner: in handler");
            inner_trapped = true;
            let i = 10;
            debug!("nested_reraise_trap_test_inner: handler re-raising");
            sadness::cond.raise(i)
        }).inside {
            debug!("nested_reraise_trap_test_inner: in protected block");
            trouble(1);
        }

        assert!(inner_trapped);
    }

    #[test]
    fn nested_reraise_trap_test_outer() {
        let mut outer_trapped = false;

        do sadness::cond.trap(|_j| {
            debug!("nested_reraise_trap_test_outer: in handler");
            outer_trapped = true; 0
        }).inside {
            debug!("nested_reraise_trap_test_outer: in protected block");
            nested_reraise_trap_test_inner();
        }

        assert!(outer_trapped);
    }

    #[test]
    fn test_default() {
        let mut trapped = false;

        do sadness::cond.trap(|j| {
            debug!("test_default: in handler");
            sadness::cond.raise_default(j, || { trapped=true; 5 })
        }).inside {
            debug!("test_default: in protected block");
            trouble(1);
        }

        assert!(trapped);
    }

    // Issue #6009
    mod m {
        condition! {
            // #6009, #8215: should this truly need a `pub` for access from n?
            pub sadness: int -> int;
        }

        mod n {
            use super::sadness;

            #[test]
            fn test_conditions_are_public() {
                let mut trapped = false;
                do sadness::cond.trap(|_| {
                    trapped = true;
                    0
                }).inside {
                    sadness::cond.raise(0);
                }
                assert!(trapped);
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Implement Pred for positive bin nats<commit_after><|endoftext|>


<commit_before><commit_msg>Problem 22<commit_after>fn rang(from: int, to: int) -> ~[int] {
    if to >= from {
        range(from, to+1).to_owned_vec()
    } else {
        range(to, from+1).rev().to_owned_vec()
    }
}

fn main() {
    println!("{:?}", rang(4, 9));
    println!("{:?}", rang(9, 4));
}

<|endoftext|>


<commit_before><commit_msg>15 - tuple<commit_after>// Tuples can be used as function arguments and as return values
fn reverse(pair: (int, bool)) -> (bool, int) {
    // `let` can be used to bind the members of a tuple to variables
    let (integer, boolean) = pair;

    (boolean, integer)
}

fn main() {
    // A tuple with a bunch of different types
    let long_tuple = (1u8, 2u16, 3u32, 4u64,
                      -1i8, -2i16, -3i32, -4i64,
                      0.1f32, 0.2f64,
                      'a', true);

    // Values can be extracted from the tuple using the `valN` methods
    println!("long tuple first value: {}", long_tuple.0);
    println!("long tuple second value: {}", long_tuple.1);

    // Tuples can be tuple members
    let tuple_of_tuples = ((1u8, 2u16, 2u32), (4u64, -1i8), -2i16);

    // Tuples are printable
    println!("tuple of tuples: {}", tuple_of_tuples);

    let pair = (1, true);
    println!("pair is {}", pair);

    println!("the reversed pair is {}", reverse(pair));

    // To create one element tuples, the comma is required to tell them apart
    // from a literal surrounded by parentheses
    println!("one element tuple: {}", (5u,));
    println!("just an integer: {}", (5u));
}
<|endoftext|>


<commit_before><commit_msg>Add linked_list implementation in Rust<commit_after>use List::{Item, Nil};

// linked list implementation in rust

fn main() {
    let mut list = List::new();
    list = list.prepend(1);
    list = list.prepend(2);
    list = list.prepend(3);
    list = list.prepend(4);

    println!("len of final linked list {}", list.len());
    println!("{}", list.stringify());
}

enum List {
    Item(u32, Box<List>),
    Nil,
}

impl List {
    fn new() -> List {
        Nil
    }
    fn prepend(self, elem: u32) -> List {
        Item(elem, Box::new(self))
    }
    fn len(&self) -> u32 {
        match *self {
            Item(_, ref tail) => 1 + tail.len(),
            Nil => 0
        }
    }
    fn stringify(&self) -> String {
        match *self {
            Item(head, ref tail) => {
                format!("{}, {}", head, tail.stringify())
            },
            Nil => {
                format!("Nil")
            }
        }
    }
}

<|endoftext|>


<commit_before><commit_msg>Fix typo in 'NotFound' docs: 404, not 400.<commit_after><|endoftext|>


<commit_before><commit_msg>Rust adts updates<commit_after><|endoftext|>


<commit_before><commit_msg>Added Rust version<commit_after>// Copyright (C) 2017 Chris Liebert

#[allow(unused_assignments)]

pub fn print_conglomerates(x0: i32, y0: i32, z0: i32) {
    let mut x = x0;
    let mut y = y0;
    let mut z = z0;
    let xbackup = x0;
    let ybackup = y0;
    let zbackup = z0;
    let mut collections: Vec<[i32; 8]> = vec!();
    let mut a: i32 = 0;
    let mut b: i32 = 0;
    let mut c: i32 = 0;
    let mut d: i32 = 0;
    let mut e: i32 = 0;
    let mut f: i32 = 0;
    let mut g: i32 = 0;
    let mut h: i32 = 0;
    a = 0;
    while (x >= 0) && (y >= 0) && (z >= 0) {
        b = 0;
        let bx = x;
        let by = y;
        let bz = z;
        while (x >= 0) && (y >= 0) && (z >= 0) {
            c = 0;
            let cx = x;
            let cy = y;
            let cz = z;
            while (x >= 0) && (y >= 0) && (z >= 0) {
                d = 0;
                let dx = x;
                let dy = y;
                let dz = z;
                while (x >= 0) && (y >= 0) && (z >= 0) {
                    e = 0;
                    let ex = x;
                    let ey = y;
                    let ez = z;
                    while (x >= 0) && (y >= 0) && (z >= 0) {
                        f = 0;
                        let fx = x;
                        let fy = y;
                        let fz = z;
                        while (x >= 0) && (y >= 0) && (z >= 0) {
                            g = 0;
                            let gx = x;
                            let gy = y;
                            let gz = z;
                            while (x >= 0) && (y >= 0) && (z >= 0) {
                                h = 0;
                                let hx = x;
                                let hy = y;
                                let hz = z;
                                while (x >= 0) && (y >= 0) && (z >= 0) {
                                    if (x == 0) && (y == 0) && (z == 0) {
                                        let collection: [i32; 8] = [a, b, c, d, e, f, g, h];
                                        collections.push(collection);
                                    }
                                    y -= 1;
                                    z -= 2;
                                    h += 1;
                                }
                                x = hx - 2;
                                y = hy - 6;
                                z = hz - 1;
                                g += 1;
                            }
                            x = gx - 6;
                            y = gy;
                            z = gz - 2;
                            f += 1;
                        }
                        x = fx;
                        y = fy - 2;
                        z = fz - 5;
                        e += 1;
                    }
                    x = ex - 3;
                    y = ey - 3;
                    z = ez - 1;
                    d += 1;
                }
                x = dx;
                y = dy;
                z = dz - 1;
                c += 1;
            }
            x = cx;
            y = cy - 1;
            z = cz;
            b += 1;
        }
        x = bx - 1;
        y = by;
        z = bz;
        a += 1;
    }

    let mut min_card = 0;
    let mut min_card_index: i32 = -1;

    for i in 0..collections.len() {
        let mut card = 0;
        for j in 0..8 {
            card += collections[i][j];
        }

        if min_card == 0 || card < min_card {
            min_card = card;
            min_card_index = i as i32;
        }
    }

    if min_card_index == -1 {
        println!("No conglomerates found");
    }

    let conglomerats: [i32; 8] = collections[min_card_index as usize];

    println!("Alphium\tBetium\tCetium\tDeltium\tEtium\tFerium\tGatium\tHerium\t|CRD|\t X\t Y\t Z\n");

    let mut s = String::from("");
    for i in 0..8 {
        s.push_str(&format!(" {}\t", conglomerats[i]));
    }
    s.push_str(&format!("{}\t{}\t{}\t{}", min_card, xbackup, ybackup, zbackup));
    println!("{}", &s);
}

pub fn main() {
    print_conglomerates(70, 73, 77);
}
<|endoftext|>


<commit_before><commit_msg>Added linked list example.<commit_after>use List::*;

enum List {
    // Cons: Tuple struct that wraps an element and a pointer to the next node
    Cons(u32, Box<List>),
    // Nil: A node that signifies the end of the linked list
    Nil,
}

// Methods can be attached to an enum
impl List {
    // Create an empty list
    fn new() -> List {
        // `Nil` has type `List`
        Nil
    }

    // Consume a list, and return the same list with a new element at its front
    fn prepend(self, elem: u32) -> List {
        // `Cons` also has type List
        Cons(elem, Box::new(self))
    }

    // Return the length of the list
    fn len(&self) -> u32 {
        // `self` has to be matched, because the behavior of this method
        // depends on the variant of `self`
        // `self` has type `&List`, and `*self` has type `List`, matching on a
        // concrete type `T` is preferred over a match on a reference `&T`
        match *self {
            // Can't take ownership of the tail, because `self` is borrowed;
            // instead take a reference to the tail
            Cons(_, ref tail) => 1 + tail.len(),
            // Base Case: An empty list has zero length
            Nil => 0
        }
    }

    // Return representation of the list as a (heap allocated) string
    fn stringify(&self) -> String {
        match *self {
            Cons(head, ref tail) => {
                // `format!` is similar to `print!`, but returns a heap
                // allocated string instead of printing to the console
                format!("{}, {}", head, tail.stringify())
            },
            Nil => {
                format!("Nil")
            },
        }
    }

    fn reverse(&self) -> List {
        self.reverse2(Nil)
    }

    fn reverse2(&self, list: List) -> List {
        match *self {
            Cons(head, ref tail) => {
                tail.reverse2(list.prepend(head))
            },
            Nil => list
        }
    }
}

fn main() {
    // Create an empty linked list
    let mut list = List::new();

    // Append some elements
    list = list.prepend(1);
    list = list.prepend(2);
    list = list.prepend(3);

    // Show the final state of the list
    println!("linked list has length: {}", list.len());
    println!("{}", list.stringify());
    println!("{}", list.reverse().stringify());
}
<|endoftext|>


<commit_before><commit_msg>Add address stability test for matches<commit_after>// Check that `ref mut` variables don't change address between the match guard
// and the arm expression.

// run-pass

#![feature(nll, bind_by_move_pattern_guards)]

// Test that z always point to the same temporary.
fn referent_stability() {
    let p;
    match 0 {
        ref mut z if { p = z as *const _; true } => assert_eq!(p, z as *const _),
        _ => unreachable!(),
    };
}

// Test that z is always effectively the same variable.
fn variable_stability() {
    let p;
    match 0 {
        ref mut z if { p = &z as *const _; true } => assert_eq!(p, &z as *const _),
        _ => unreachable!(),
    };
}

// Test that a borrow of *z can cross from the guard to the arm.
fn persist_borrow() {
    let r;
    match 0 {
        ref mut z if { r = z as &_; true } => assert_eq!(*r, 0),
        _ => unreachable!(),
    }
}

fn main() {
    referent_stability();
    variable_stability();
    persist_borrow();
}
<|endoftext|>


<commit_before><commit_msg>bench: Add shootout-spectralnorm<commit_after>// Based on spectalnorm.gcc by Sebastien Loisel

use std;

fn eval_A(i: uint, j: uint) -> float {
    1.0/(((i+j)*(i+j+1u)/2u+i+1u) as float)
}

fn eval_A_times_u(u: [const float], Au: [mutable float]) {
    let N = vec::len(u);
    let i = 0u;
    while i < N {
        Au[i] = 0.0;
        let j = 0u;
        while j < N {
            Au[i] += eval_A(i, j) * u[j];
            j += 1u;
        }
        i += 1u;
    }
}

fn eval_At_times_u(u: [const float], Au: [mutable float]) {
    let N = vec::len(u);
    let i = 0u;
    while i < N {
        Au[i] = 0.0;
        let j = 0u;
        while j < N {
            Au[i] += eval_A(j, i) * u[j];
            j += 1u;
        }
        i += 1u;
    }
}

fn eval_AtA_times_u(u: [const float], AtAu: [mutable float]) {
    let v = vec::init_elt_mut(vec::len(u), 0.0);
    eval_A_times_u(u, v);
    eval_At_times_u(v, AtAu);
}

fn main(args: [str]) {

    let N = if vec::len(args) == 2u {
        uint::from_str(args[1])
    } else {
        1000u
    };

    let u = vec::init_elt_mut(N, 1.0);
    let v = vec::init_elt_mut(N, 0.0);
    let i = 0u;
    while i < 10u {
        eval_AtA_times_u(u, v);
        eval_AtA_times_u(v, u);
        i += 1u;
    }

    let vBv = 0.0;
    let vv = 0.0;
    let i = 0u;
    while i < N {
        vBv += u[i] * v[i];
        vv += v[i] * v[i];
        i += 1u;
    }

    std::io::println(#fmt("%0.9f\n", float::sqrt(vBv / vv)));
}
<|endoftext|>


<commit_before><commit_msg>blank message<commit_after><|endoftext|>


<commit_before><commit_msg>initial implementation, works w/ rust 0.10<commit_after>extern crate rand;

#[cfg(test)]
extern crate test;

use std::vec;
use std::str;
use std::fmt;
use std::option;
use rand::{task_rng, Rng};

#[cfg(test)]
use test::BenchHarness;

static LIVE_CELL: char = '@';
static DEAD_CELL: char = '.';

fn main() {
  let mut brd = Board::new(65,250).random();
  loop {
    println!("\x1b[H\x1b[2J{}", brd);
    brd = brd.next_generation();
  }
}

#[deriving(Eq)]
struct Board {
  board: Vec<Vec<bool>>,
  rows: uint,
  cols: uint
}

impl Board {
  fn new(rows: uint, cols: uint) -> Board {
    let new_board = Vec::from_elem(rows, Vec::from_elem(cols, false));
    Board { board: new_board, rows: rows, cols: cols }
  }

  fn random(&self) -> Board {
    let mut rng = task_rng();
    let board = Vec::from_fn(self.rows, |_| {
      Vec::from_slice(task_rng().gen_vec(self.cols))
    });

    Board { board: board, rows: self.rows, cols: self.cols }
  }

  fn next_generation(&self) -> Board {
    let new_brd = Vec::from_fn(self.rows, |row| {
      Vec::from_fn(self.cols, |col| self.successor(col, row))
    });
    Board { board: new_brd, rows: self.rows, cols: self.cols }
  }

  fn cell_live(&self, x: uint, y: uint) -> bool {
    if x >= self.cols || y >= self.rows {
      false
    } else {
      *self.board.get(y).get(x)
    }
  }

  fn living_neighbors(&self, x: uint, y: uint) -> uint {
    let neighbors = [
      self.cell_live(x-1, y-1), self.cell_live(x, y-1), self.cell_live(x+1, y-1),
      self.cell_live(x-1, y+0),                         self.cell_live(x+1, y+0),
      self.cell_live(x-1, y+1), self.cell_live(x, y+1), self.cell_live(x+1, y+1),
    ];
    neighbors.iter().count(|x| *x)
  }

  fn successor(&self, x:uint, y:uint) -> bool {
    let neighbors = self.living_neighbors(x, y);
    if self.cell_live(x, y) {
      neighbors == 2 || neighbors == 3
    } else {
      neighbors == 3
    }
  }

  fn from_str(string: &str) -> Option<Board> {
    fn process_rows(string: &str) -> Option<Vec<Vec<bool>>> {
      let mut rows = string.split_terminator('\n').peekable();
      let col_count = match rows.peek() {
        Some(cols) => Some(cols.len()),
        None       => None
      };
      col_count.and(option::collect(rows.map(|row| {
        let len = row.len();
        if len != 0 && Some(len) == col_count {
          process_cells(row)
        } else {
          None
        }
      })))
    }

    fn process_cells(row: &str) -> Option<Vec<bool>> {
      option::collect(row.chars().map(process_cell))
    }

    fn process_cell(cell: char) -> Option<bool> {
      match cell {
        LIVE_CELL => Some(true),
        DEAD_CELL => Some(false),
        _         => None
      }
    }

    let board = process_rows(string);
    match board {
      Some(brd) => Some(Board { board: brd.clone(),
                                rows : brd.len(),
                                cols : brd.get(0).len() }),
      None      => None
    }
  }
}

impl fmt::Show for Board {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {

    fn row_to_str(row: &Vec<bool>) -> ~str {
      let chars: ~[char] = row.iter().map(|cell|
        if *cell {LIVE_CELL} else {DEAD_CELL}
      ).collect();
      str::from_chars(chars)
    }

    let rows: ~[~str] = self.board.iter().map(|row|
      row_to_str(row)
    ).collect();

    write!(f.buf, "{}", rows.connect("\n"))
  }
}

#[cfg(test)]
fn testing_board(n: int) -> Board {
  let brds = [
    ".@.\n" +
    ".@@\n" +
    ".@@\n"
    ,
    "...\n" +
    "@@@\n" +
    "...\n"
    ,
    ".@.\n" +
    ".@.\n" +
    ".@.\n" ];
  Board::from_str(brds[n]).unwrap()
}

#[test]
fn test_cell_live() {
  let brd = testing_board(0);
  assert!(!brd.cell_live(0, 0));
  assert!(brd.cell_live(2, 2));
}

#[test]
fn test_live_count() {
  let brd = testing_board(0);
  assert!(brd.living_neighbors(0, 0) == 2);
  assert!(brd.living_neighbors(2, 2) == 3);
}

#[test]
fn test_next_generation() {
  assert!(testing_board(1).next_generation() == testing_board(2))
}

#[bench]
fn bench_random(b: &mut BenchHarness) {
  let brd = Board::new(200,200);
  b.iter(|| {brd.random();})
}

#[bench]
fn bench_hundred_generations(b: &mut BenchHarness) {
  let mut brd = Board::new(200,200).random();
  b.iter(|| {
    for _ in range(0,100) { brd = brd.next_generation() }
  });
}
<|endoftext|>