<commit_before>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/// An exclusive access primitive
///
/// This primitive is used to gain exclusive access to read() and write() in uv.
/// It is assumed that all invocations of this struct happen on the same thread
/// (the uv event loop).

use alloc::arc::Arc;
use std::mem;
use std::rt::local::Local;
use std::rt::task::{BlockedTask, Task};
use std::cell::UnsafeCell;

use homing::HomingMissile;

pub struct Access<T> {
    inner: Arc<UnsafeCell<Inner<T>>>,
}

pub struct Guard<'a, T:'static> {
    access: &'a mut Access<T>,
    missile: Option<HomingMissile>,
}

struct Inner<T> {
    queue: Vec<(BlockedTask, uint)>,
    held: bool,
    closed: bool,
    data: T,
}

impl<T: Send> Access<T> {
    pub fn new(data: T) -> Access<T> {
        Access {
            inner: Arc::new(UnsafeCell::new(Inner {
                queue: vec![],
                held: false,
                closed: false,
                data: data,
            }))
        }
    }

    pub fn grant<'a>(&'a mut self, token: uint,
                     missile: HomingMissile) -> Guard<'a, T> {
        // This unsafety is actually OK because the homing missile argument
        // guarantees that we're on the same event loop as all the other objects
        // attempting to get access granted.
        let inner = unsafe { &mut *self.inner.get() };

        if inner.held {
            let t: Box<Task> = Local::take();
            t.deschedule(1, |task| {
                inner.queue.push((task, token));
                Ok(())
            });
            assert!(inner.held);
        } else {
            inner.held = true;
        }

        Guard { access: self, missile: Some(missile) }
    }

    pub fn unsafe_get(&self) -> *mut T {
        unsafe { &mut (*self.inner.get()).data  as *mut _ }
    }

    // Safe version which requires proof that you are on the home scheduler.
    pub fn get_mut<'a>(&'a mut self, _missile: &HomingMissile) -> &'a mut T {
        unsafe { &mut *self.unsafe_get() }
    }

    pub fn close(&self, _missile: &HomingMissile) {
        // This unsafety is OK because with a homing missile we're guaranteed to
        // be the only task looking at the `closed` flag (and are therefore
        // allowed to modify it). Additionally, no atomics are necessary because
        // everyone's running on the same thread and has already done the
        // necessary synchronization to be running on this thread.
        unsafe { (*self.inner.get()).closed = true; }
    }

    // Dequeue a blocked task with a specified token. This is unsafe because it
    // is only safe to invoke while on the home event loop, and there is no
    // guarantee that this i being invoked on the home event loop.
    pub unsafe fn dequeue(&mut self, token: uint) -> Option<BlockedTask> {
        let inner = &mut *self.inner.get();
        match inner.queue.iter().position(|&(_, t)| t == token) {
            Some(i) => Some(inner.queue.remove(i).unwrap().val0()),
            None => None,
        }
    }

    /// Test whether this access is closed, using a homing missile to prove
    /// that it's safe
    pub fn is_closed(&self, _missile: &HomingMissile) -> bool {
        unsafe { (*self.inner.get()).closed }
    }
}

impl<T: Send> Clone for Access<T> {
    fn clone(&self) -> Access<T> {
        Access { inner: self.inner.clone() }
    }
}

impl<'a, T: Send> Guard<'a, T> {
    pub fn is_closed(&self) -> bool {
        // See above for why this unsafety is ok, it just applies to the read
        // instead of the write.
        unsafe { (*self.access.inner.get()).closed }
    }
}

impl<'a, T: Send> Deref<T> for Guard<'a, T> {
    fn deref<'a>(&'a self) -> &'a T {
        // A guard represents exclusive access to a piece of data, so it's safe
        // to hand out shared and mutable references
        unsafe { &(*self.access.inner.get()).data }
    }
}

impl<'a, T: Send> DerefMut<T> for Guard<'a, T> {
    fn deref_mut<'a>(&'a mut self) -> &'a mut T {
        unsafe { &mut (*self.access.inner.get()).data }
    }
}

#[unsafe_destructor]
impl<'a, T> Drop for Guard<'a, T> {
    fn drop(&mut self) {
        // This guard's homing missile is still armed, so we're guaranteed to be
        // on the same I/O event loop, so this unsafety should be ok.
        assert!(self.missile.is_some());
        let inner: &mut Inner<T> = unsafe {
            mem::transmute(self.access.inner.get())
        };

        match inner.queue.remove(0) {
            // Here we have found a task that was waiting for access, and we
            // current have the "access lock" we need to relinquish access to
            // this sleeping task.
            //
            // To do so, we first drop out homing missile and we then reawaken
            // the task. In reawakening the task, it will be immediately
            // scheduled on this scheduler. Because we might be woken up on some
            // other scheduler, we drop our homing missile before we reawaken
            // the task.
            Some((task, _)) => {
                drop(self.missile.take());
                task.reawaken();
            }
            None => { inner.held = false; }
        }
    }
}

#[unsafe_destructor]
impl<T> Drop for Inner<T> {
    fn drop(&mut self) {
        assert!(!self.held);
        assert_eq!(self.queue.len(), 0);
    }
}
<commit_msg>add Send bound on impl because stricter trait checking requires it<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/// An exclusive access primitive
///
/// This primitive is used to gain exclusive access to read() and write() in uv.
/// It is assumed that all invocations of this struct happen on the same thread
/// (the uv event loop).

use alloc::arc::Arc;
use std::mem;
use std::rt::local::Local;
use std::rt::task::{BlockedTask, Task};
use std::cell::UnsafeCell;

use homing::HomingMissile;

pub struct Access<T> {
    inner: Arc<UnsafeCell<Inner<T>>>,
}

pub struct Guard<'a, T:'static> {
    access: &'a mut Access<T>,
    missile: Option<HomingMissile>,
}

struct Inner<T> {
    queue: Vec<(BlockedTask, uint)>,
    held: bool,
    closed: bool,
    data: T,
}

impl<T: Send> Access<T> {
    pub fn new(data: T) -> Access<T> {
        Access {
            inner: Arc::new(UnsafeCell::new(Inner {
                queue: vec![],
                held: false,
                closed: false,
                data: data,
            }))
        }
    }

    pub fn grant<'a>(&'a mut self, token: uint,
                     missile: HomingMissile) -> Guard<'a, T> {
        // This unsafety is actually OK because the homing missile argument
        // guarantees that we're on the same event loop as all the other objects
        // attempting to get access granted.
        let inner = unsafe { &mut *self.inner.get() };

        if inner.held {
            let t: Box<Task> = Local::take();
            t.deschedule(1, |task| {
                inner.queue.push((task, token));
                Ok(())
            });
            assert!(inner.held);
        } else {
            inner.held = true;
        }

        Guard { access: self, missile: Some(missile) }
    }

    pub fn unsafe_get(&self) -> *mut T {
        unsafe { &mut (*self.inner.get()).data  as *mut _ }
    }

    // Safe version which requires proof that you are on the home scheduler.
    pub fn get_mut<'a>(&'a mut self, _missile: &HomingMissile) -> &'a mut T {
        unsafe { &mut *self.unsafe_get() }
    }

    pub fn close(&self, _missile: &HomingMissile) {
        // This unsafety is OK because with a homing missile we're guaranteed to
        // be the only task looking at the `closed` flag (and are therefore
        // allowed to modify it). Additionally, no atomics are necessary because
        // everyone's running on the same thread and has already done the
        // necessary synchronization to be running on this thread.
        unsafe { (*self.inner.get()).closed = true; }
    }

    // Dequeue a blocked task with a specified token. This is unsafe because it
    // is only safe to invoke while on the home event loop, and there is no
    // guarantee that this i being invoked on the home event loop.
    pub unsafe fn dequeue(&mut self, token: uint) -> Option<BlockedTask> {
        let inner = &mut *self.inner.get();
        match inner.queue.iter().position(|&(_, t)| t == token) {
            Some(i) => Some(inner.queue.remove(i).unwrap().val0()),
            None => None,
        }
    }

    /// Test whether this access is closed, using a homing missile to prove
    /// that it's safe
    pub fn is_closed(&self, _missile: &HomingMissile) -> bool {
        unsafe { (*self.inner.get()).closed }
    }
}

impl<T: Send> Clone for Access<T> {
    fn clone(&self) -> Access<T> {
        Access { inner: self.inner.clone() }
    }
}

impl<'a, T: Send> Guard<'a, T> {
    pub fn is_closed(&self) -> bool {
        // See above for why this unsafety is ok, it just applies to the read
        // instead of the write.
        unsafe { (*self.access.inner.get()).closed }
    }
}

impl<'a, T: Send> Deref<T> for Guard<'a, T> {
    fn deref<'a>(&'a self) -> &'a T {
        // A guard represents exclusive access to a piece of data, so it's safe
        // to hand out shared and mutable references
        unsafe { &(*self.access.inner.get()).data }
    }
}

impl<'a, T: Send> DerefMut<T> for Guard<'a, T> {
    fn deref_mut<'a>(&'a mut self) -> &'a mut T {
        unsafe { &mut (*self.access.inner.get()).data }
    }
}

#[unsafe_destructor]
impl<'a, T:Send> Drop for Guard<'a, T> {
    fn drop(&mut self) {
        // This guard's homing missile is still armed, so we're guaranteed to be
        // on the same I/O event loop, so this unsafety should be ok.
        assert!(self.missile.is_some());
        let inner: &mut Inner<T> = unsafe {
            mem::transmute(self.access.inner.get())
        };

        match inner.queue.remove(0) {
            // Here we have found a task that was waiting for access, and we
            // current have the "access lock" we need to relinquish access to
            // this sleeping task.
            //
            // To do so, we first drop out homing missile and we then reawaken
            // the task. In reawakening the task, it will be immediately
            // scheduled on this scheduler. Because we might be woken up on some
            // other scheduler, we drop our homing missile before we reawaken
            // the task.
            Some((task, _)) => {
                drop(self.missile.take());
                task.reawaken();
            }
            None => { inner.held = false; }
        }
    }
}

#[unsafe_destructor]
impl<T> Drop for Inner<T> {
    fn drop(&mut self) {
        assert!(!self.held);
        assert_eq!(self.queue.len(), 0);
    }
}
<|endoftext|>


<commit_before><commit_msg>Shrinking appears to be working.<commit_after>use std::iter::Unfold;
use std::rand;
use std::vec;

trait Arbitrary {
    fn arbitrary<R: rand::Rng>(rng: &mut R) -> Self;
}

trait Shrink<T: Iterator<Self>> {
    fn shrink(&self) -> T;
}

impl<T: rand::Rand> Arbitrary for T {
    fn arbitrary<R: rand::Rng>(rng: &mut R) -> T { rng.gen() }
}

impl Shrink<vec::MoveItems<()>> for () {
    fn shrink(&self) -> vec::MoveItems<()> { (~[]).move_iter() }
}

impl Shrink<vec::MoveItems<bool>> for bool {
    fn shrink(&self) -> vec::MoveItems<bool> {
        match *self {
            true => (~[false]).move_iter(),
            false => (~[]).move_iter(),
        }
    }
}

struct OptionState<T> {
    state: Option<T>,
    started: bool,
}

impl<A: Shrink<Ia>, Ia: Iterator<A>>
    Shrink<Unfold<'static, Option<A>, OptionState<Ia>>>
    for Option<A>
{
    fn shrink(&self) -> Unfold<'static, Option<A>, OptionState<Ia>> {
        let init = match *self {
            None => None,
            Some(ref x) => Some(x.shrink()),
        };
        let st = OptionState{
            state: init,
            started: false,
        };
        Unfold::new(st, |st: &mut OptionState<Ia>| -> Option<Option<A>> {
            match st.state {
                None => return None,
                Some(ref mut x) => {
                    if !st.started {
                        st.started = true;
                        return Some(None)
                    }
                    match x.next() {
                        None => None,
                        Some(it) => Some(Some(it)),
                    }
                }
            }
        })
    }
}

impl<A: Shrink<Ia>, B: Shrink<Ib>, Ia: Iterator<A>, Ib: Iterator<B>>
    Shrink<Unfold<'static, Result<A, B>, Result<Ia, Ib>>>
    for Result<A, B>
{
    fn shrink(&self) -> Unfold<'static, Result<A, B>, Result<Ia, Ib>> {
        let init = match *self {
            Ok(ref a) => Ok(a.shrink()),
            Err(ref b) => Err(b.shrink()),
        };
        Unfold::new(init, |st: &mut Result<Ia, Ib>| -> Option<Result<A, B>> {
            match *st {
                Ok(ref mut a) => match a.next() {
                    None => return None,
                    Some(a) => Some(Ok(a)),
                },
                Err(ref mut b) => match b.next() {
                    None => return None,
                    Some(b) => Some(Err(b)),
                },
            }
        })
    }
}

fn main() {
    // let mut rng = ~rand::rng();
    let r: Option<Result<Option<bool>, ()>> = Some(Ok(Some(true)));
    println!("{}", Some(true).shrink().to_owned_vec());
    println!("{}", r.shrink().to_owned_vec());
}
<|endoftext|>


<commit_before><commit_msg>Add regression test for write_primval bug.<commit_after>// PrimVals in Miri are represented with 8 bytes (u64) and at the time of writing, the `-x`
// will sign extend into the entire 8 bytes. Then, if you tried to write the `-x` into
// something smaller than 8 bytes, like a 4 byte pointer, it would crash in byteorder crate
// code that assumed only the low 4 bytes would be set. Actually, we were masking properly for
// everything except pointers before I fixed it, so this was probably impossible to reproduce on
// 64-bit.
//
// This is just intended as a regression test to make sure we don't reintroduce this problem.

#[cfg(target_pointer_width = "32")]
fn main() {
    use std::mem::transmute;

    // Make the weird PrimVal.
    let x = 1i32;
    let bad = unsafe { transmute::<i32, *const u8>(-x) };

    // Force it through the Memory::write_primval code.
    Box::new(bad);
}

#[cfg(not(target_pointer_width = "32"))]
fn main() {}
<|endoftext|>


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

fn main() {
    let args: Vec<String> = std::env::args().collect();
    if args.len() > 1 && args[1] == "run_test" {
        let _ = std::thread::spawn(|| {
            panic!();
        }).join();

        panic!();
    } else {
        let test = std::process::Command::new(&args[0]).arg("run_test").output().unwrap();
        assert!(!test.status.success());
        let err = String::from_utf8_lossy(&test.stderr);
        let mut it = err.lines();

        assert_eq!(it.next().map(|l| l.starts_with("thread '<unnamed>' panicked at")), Some(true));
        assert_eq!(it.next(), Some("note: Run with `RUST_BACKTRACE=1` for a backtrace."));
        assert_eq!(it.next().map(|l| l.starts_with("thread '<main>' panicked at")), Some(true));
        assert_eq!(it.next(), None);
    }
}
<commit_msg>don't leak RUST_BACKTRACE into test process<commit_after>// Copyright 2016 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.

fn main() {
    let args: Vec<String> = std::env::args().collect();
    if args.len() > 1 && args[1] == "run_test" {
        let _ = std::thread::spawn(|| {
            panic!();
        }).join();

        panic!();
    } else {
        let test = std::process::Command::new(&args[0]).arg("run_test")
                                                       .env_remove("RUST_BACKTRACE")
                                                       .output()
                                                       .unwrap();
        assert!(!test.status.success());
        let err = String::from_utf8_lossy(&test.stderr);
        let mut it = err.lines();

        assert_eq!(it.next().map(|l| l.starts_with("thread '<unnamed>' panicked at")), Some(true));
        assert_eq!(it.next(), Some("note: Run with `RUST_BACKTRACE=1` for a backtrace."));
        assert_eq!(it.next().map(|l| l.starts_with("thread '<main>' panicked at")), Some(true));
        assert_eq!(it.next(), None);
    }
}
<|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.

// compile-flags: -Z borrowck=compare

use std::cell::Cell;
use std::mem::swap;

// Just a grab bag of stuff that you wouldn't want to actually write.

fn strange() -> bool { let _x: bool = return true; }

fn funny() {
    fn f(_x: ()) { }
    f(return);
}

fn what() {
    fn the(x: &Cell<bool>) {
        return while !x.get() { x.set(true); };
    }
    let i = &Cell::new(false);
    let dont = {||the(i)};
    dont();
    assert!((i.get()));
}

fn zombiejesus() {
    loop {
        while (return) {
            if (return) {
                match (return) {
                    1 => {
                        if (return) {
                            return
                        } else {
                            return
                        }
                    }
                    _ => { return }
                };
            } else if (return) {
                return;
            }
        }
        if (return) { break; }
    }
}

fn notsure() {
    let mut _x: isize;
    let mut _y = (_x = 0) == (_x = 0);
    let mut _z = (_x = 0) < (_x = 0);
    let _a = (_x += 0) == (_x = 0);
    let _b = swap(&mut _y, &mut _z) == swap(&mut _y, &mut _z);
}

fn canttouchthis() -> usize {
    fn p() -> bool { true }
    let _a = (assert!((true)) == (assert!(p())));
    let _c = (assert!((p())) == ());
    let _b: bool = (println!("{}", 0) == (return 0));
}

fn angrydome() {
    loop { if break { } }
    let mut i = 0;
    loop { i += 1; if i == 1 { match (continue) { 1 => { }, _ => panic!("wat") } }
      break; }
}

fn evil_lincoln() { let _evil = println!("lincoln"); }

fn dots() {
    assert_eq!(String::from(".................................................."),
               format!("{:?}", .. .. .. .. .. .. .. .. .. .. .. .. ..
                               .. .. .. .. .. .. .. .. .. .. .. ..));
}

fn u8(u8: u8) {
    if u8 != 0u8 {
        assert_eq!(8u8, {
            macro_rules! u8 {
                (u8) => {
                    mod u8 {
                        pub fn u8<'u8: 'u8 + 'u8>(u8: &'u8 u8) -> &'u8 u8 {
                            "u8";
                            u8
                        }
                    }
                };
            }

            u8!(u8);
            let &u8: &u8 = u8::u8(&8u8);
            ::u8(0u8);
            u8
        });
    }
}

fn fishy() {
    assert_eq!(String::from("><>"),
               String::<>::from::<>("><>").chars::<>().rev::<>().collect::<String>());
}

fn union() {
    union union<'union> { union: &'union union<'union>, }
}

fn special_characters() {
    let val = !((|(..):(_,_),__@_|__)((&*"\\",'🤔')/**/,{})=={&[..=..][..];})//
    ;
    assert!(!val);
}

pub fn main() {
    strange();
    funny();
    what();
    zombiejesus();
    notsure();
    canttouchthis();
    angrydome();
    evil_lincoln();
    dots();
    u8(8u8);
    fishy();
    union();
    special_characters();
}
<commit_msg>Rollup merge of #52073 - xfix:patch-7, r=oli-obk<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.

// compile-flags: -Z borrowck=compare

#![recursion_limit = "128"]

use std::cell::Cell;
use std::mem::swap;

// Just a grab bag of stuff that you wouldn't want to actually write.

fn strange() -> bool { let _x: bool = return true; }

fn funny() {
    fn f(_x: ()) { }
    f(return);
}

fn what() {
    fn the(x: &Cell<bool>) {
        return while !x.get() { x.set(true); };
    }
    let i = &Cell::new(false);
    let dont = {||the(i)};
    dont();
    assert!((i.get()));
}

fn zombiejesus() {
    loop {
        while (return) {
            if (return) {
                match (return) {
                    1 => {
                        if (return) {
                            return
                        } else {
                            return
                        }
                    }
                    _ => { return }
                };
            } else if (return) {
                return;
            }
        }
        if (return) { break; }
    }
}

fn notsure() {
    let mut _x: isize;
    let mut _y = (_x = 0) == (_x = 0);
    let mut _z = (_x = 0) < (_x = 0);
    let _a = (_x += 0) == (_x = 0);
    let _b = swap(&mut _y, &mut _z) == swap(&mut _y, &mut _z);
}

fn canttouchthis() -> usize {
    fn p() -> bool { true }
    let _a = (assert!((true)) == (assert!(p())));
    let _c = (assert!((p())) == ());
    let _b: bool = (println!("{}", 0) == (return 0));
}

fn angrydome() {
    loop { if break { } }
    let mut i = 0;
    loop { i += 1; if i == 1 { match (continue) { 1 => { }, _ => panic!("wat") } }
      break; }
}

fn evil_lincoln() { let _evil = println!("lincoln"); }

fn dots() {
    assert_eq!(String::from(".................................................."),
               format!("{:?}", .. .. .. .. .. .. .. .. .. .. .. .. ..
                               .. .. .. .. .. .. .. .. .. .. .. ..));
}

fn u8(u8: u8) {
    if u8 != 0u8 {
        assert_eq!(8u8, {
            macro_rules! u8 {
                (u8) => {
                    mod u8 {
                        pub fn u8<'u8: 'u8 + 'u8>(u8: &'u8 u8) -> &'u8 u8 {
                            "u8";
                            u8
                        }
                    }
                };
            }

            u8!(u8);
            let &u8: &u8 = u8::u8(&8u8);
            ::u8(0u8);
            u8
        });
    }
}

fn fishy() {
    assert_eq!(String::from("><>"),
               String::<>::from::<>("><>").chars::<>().rev::<>().collect::<String>());
}

fn union() {
    union union<'union> { union: &'union union<'union>, }
}

fn special_characters() {
    let val = !((|(..):(_,_),__@_|__)((&*"\\",'🤔')/**/,{})=={&[..=..][..];})//
    ;
    assert!(!val);
}

fn punch_card() -> impl std::fmt::Debug {
    ..=..=.. ..    .. .. .. ..    .. .. .. ..    .. ..=.. ..
    ..=.. ..=..    .. .. .. ..    .. .. .. ..    ..=..=..=..
    ..=.. ..=..    ..=.. ..=..    .. ..=..=..    .. ..=.. ..
    ..=..=.. ..    ..=.. ..=..    ..=.. .. ..    .. ..=.. ..
    ..=.. ..=..    ..=.. ..=..    .. ..=.. ..    .. ..=.. ..
    ..=.. ..=..    ..=.. ..=..    .. .. ..=..    .. ..=.. ..
    ..=.. ..=..    .. ..=..=..    ..=..=.. ..    .. ..=.. ..
}

pub fn main() {
    strange();
    funny();
    what();
    zombiejesus();
    notsure();
    canttouchthis();
    angrydome();
    evil_lincoln();
    dots();
    u8(8u8);
    fishy();
    union();
    special_characters();
    punch_card();
}
<|endoftext|>


<commit_before><commit_msg>Add gpio example<commit_after>// Copyright (c) 2017-2018 Rene van der Meer
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// gpio_status.rs
//
// Retrieves the mode and logic level for each of the pins on the standard
// 40-pin GPIO header, and displays the results in an ASCII table.

use std::fmt;
use std::process::exit;

use rppal::gpio::Gpio;
use rppal::system::{DeviceInfo, Model};

enum PinType {
    Gpio(u8),
    Ground,
    Power3v3,
    Power5v,
}

impl fmt::Display for PinType {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match *self {
            PinType::Gpio(pin) => write!(f, "GPIO{}", pin),
            PinType::Ground => write!(f, "{:<5}", "GND"),
            PinType::Power3v3 => write!(f, "{:<5}", "3.3 V"),
            PinType::Power5v => write!(f, "{:<5}", "5 V"),
        }
    }
}

const HEADER_40: [PinType; 40] = [
    PinType::Power3v3, // Physical pin 1
    PinType::Power5v,  // Physical pin 2
    PinType::Gpio(2),  // Physical pin 3
    PinType::Power5v,  // Physical pin 4
    PinType::Gpio(3),  // Physical pin 5
    PinType::Ground,   // Physical pin 6
    PinType::Gpio(4),  // Physical pin 7
    PinType::Gpio(14), // Physical pin 8
    PinType::Ground,   // Physical pin 9
    PinType::Gpio(15), // Physical pin 10
    PinType::Gpio(17), // Physical pin 11
    PinType::Gpio(18), // Physical pin 12
    PinType::Gpio(27), // Physical pin 13
    PinType::Ground,   // Physical pin 14
    PinType::Gpio(22), // Physical pin 15
    PinType::Gpio(23), // Physical pin 16
    PinType::Power3v3, // Physical pin 17
    PinType::Gpio(24), // Physical pin 18
    PinType::Gpio(10), // Physical pin 19
    PinType::Ground,   // Physical pin 20
    PinType::Gpio(9),  // Physical pin 21
    PinType::Gpio(25), // Physical pin 22
    PinType::Gpio(11), // Physical pin 23
    PinType::Gpio(8),  // Physical pin 24
    PinType::Ground,   // Physical pin 25
    PinType::Gpio(7),  // Physical pin 26
    PinType::Gpio(0),  // Physical pin 27
    PinType::Gpio(1),  // Physical pin 28
    PinType::Gpio(5),  // Physical pin 29
    PinType::Ground,   // Physical pin 30
    PinType::Gpio(6),  // Physical pin 31
    PinType::Gpio(12), // Physical pin 32
    PinType::Gpio(13), // Physical pin 33
    PinType::Ground,   // Physical pin 34
    PinType::Gpio(19), // Physical pin 35
    PinType::Gpio(16), // Physical pin 36
    PinType::Gpio(26), // Physical pin 37
    PinType::Gpio(20), // Physical pin 38
    PinType::Ground,   // Physical pin 39
    PinType::Gpio(21), // Physical pin 40
];

fn print_gpio_status() {
    let gpio = Gpio::new().unwrap_or_else(|e| {
        println!("Error: Can't access GPIO peripheral ({})", e);
        exit(1);
    });

    println!("+------+-------+-------+-----------+-------+-------+------+");
    println!("| GPIO | Mode  | Level |    Pin    | Level | Mode  | GPIO |");
    println!("+------+-------+-------+-----+-----+-------+-------+------+");

    for (idx, pin_type) in HEADER_40.iter().enumerate() {
        match pin_type {
            PinType::Gpio(bcm) => {
                let pin = gpio.get(*bcm).unwrap_or_else(|| {
                    println!("\nError: Can't access GPIO pin {}", *bcm);;
                    exit(1);
                });

                if idx % 2 == 0 {
                    print!(
                        "| {:>4} | {:<5} | {:<5} | {:>3} |",
                        bcm,
                        format!("{}", pin.mode()).to_uppercase(),
                        format!("{}", pin.read()),
                        idx + 1
                    );
                } else {
                    println!(
                        " {:>3} | {:<5} | {:<5} | {:>4} |",
                        idx + 1,
                        format!("{:?}", pin.read()),
                        format!("{}", pin.mode()).to_uppercase(),
                        bcm,
                    );
                }
            }
            _ => {
                if idx % 2 == 0 {
                    print!("|      | {} |       | {:>3} |", pin_type, idx + 1);
                } else {
                    println!(" {:>3} |       | {} |      |", idx + 1, pin_type);
                }
            }
        };
    }

    println!("+------+-------+-------+-----+-----+-------+-------+------+");
}

fn main() {
    match DeviceInfo::new()
        .unwrap_or_else(|e| {
            println!("Error: Can't identify Raspberry Pi model ({})", e);
            exit(1);
        })
        .model()
    {
        Model::RaspberryPiAPlus
        | Model::RaspberryPiBPlus
        | Model::RaspberryPi2B
        | Model::RaspberryPi3APlus
        | Model::RaspberryPi3B
        | Model::RaspberryPi3BPlus
        | Model::RaspberryPiZero
        | Model::RaspberryPiZeroW => print_gpio_status(),
        model => {
            println!("No GPIO header information available for the {}.", model);
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>add basic weston-info example<commit_after>// Copyright (c) <2015> <lummax>
// Licensed under MIT (http://opensource.org/licenses/MIT)

extern crate wayland_client;
use wayland_client::client::{FromPrimitive, Display,
                             Registry, RegistryEventHandler,
                             Seat, SeatEventHandler, SeatCapability,
                             Shm, ShmEventHandler, ShmFormat,
                             Output, OutputEventHandler, OutputSubpixel,
                             OutputTransform, OutputMode};

#[derive(Debug)]
struct MyRegistry {
    registry: Registry,
    seat: Option<MySeat>,
    shm: Option<MyShm>,
    output: Option<MyOutput>,
    pub roundtrip: bool,
}

impl MyRegistry {
    fn new(registry: Registry) -> MyRegistry {
        return MyRegistry {
            registry: registry,
            seat: None,
            shm: None,
            output: None,
            roundtrip: true,
        };
    }
}

impl RegistryEventHandler for MyRegistry {
    fn get_registry(&mut self) -> &mut Registry {
        return &mut self.registry;
    }

    fn on_global(&mut self, name: u32, interface: String, version: u32) {
        println!("interface: '{}', version: {}, name: {}", interface, version, name);
        if interface == "wl_seat" {
            self.roundtrip = true;
            let mut seat = MySeat::new(self.registry.bind(name, version).unwrap());
            seat.connect_dispatcher();
            self.seat = Some(seat);
        } else if interface == "wl_shm" {
            self.roundtrip = true;
            let mut shm = MyShm::new(self.registry.bind(name, version).unwrap());
            shm.connect_dispatcher();
            self.shm = Some(shm);
        } else if interface == "wl_output" {
            self.roundtrip = true;
            let mut output = MyOutput::new(self.registry.bind(name, version).unwrap());
            output.connect_dispatcher();
            self.output = Some(output);
        }
    }

    fn on_global_remove(&mut self, name: u32) {
        println!("on_global_remove({})", name);
    }
}

#[derive(Debug)]
struct MySeat {
    seat: Seat,
}

impl MySeat {
    fn new(seat: Seat) -> MySeat {
        return MySeat { seat: seat };
    }
}

impl SeatEventHandler for MySeat {
    fn get_seat(&mut self) -> &mut Seat {
        return &mut self.seat;
    }

    fn on_capabilities(&mut self, capabilities: u32) {
        println!("on_capabilities({})", capabilities);
    }

    fn on_name(&mut self, name: String) {
        println!("on_name({})", name);
    }
}

#[derive(Debug)]
struct MyShm {
    shm: Shm,
}

impl MyShm {
    fn new(shm: Shm) -> MyShm {
        return MyShm { shm: shm };
    }
}

impl ShmEventHandler for MyShm {
    fn get_shm(&mut self) -> &mut Shm {
        return &mut self.shm;
    }

    fn on_format(&mut self, format: u32) {
        println!("on_format({:?})", ShmFormat::from_u32(format).unwrap());
    }
}

#[derive(Debug)]
struct MyOutput {
    output: Output,
}

impl MyOutput {
    fn new(output: Output) -> MyOutput {
        return MyOutput { output: output };
    }
}

impl OutputEventHandler for MyOutput {
    fn get_output(&mut self) -> &mut Output {
        return &mut self.output;
    }

    fn on_geometry(&mut self, x: i32, y: i32, physical_width: i32,
                   physical_height: i32, subpixel: i32, make: String, model:
                   String, transform: i32) {
        println!("on_geometry({}, {}, {}, {}, {:?}, {}, {}, {:?})", x, y,
            physical_width, physical_height,
            OutputSubpixel::from_u32(subpixel as u32).unwrap(), make, model,
            OutputTransform::from_u32(transform as u32).unwrap());
    }

    fn on_mode(&mut self, flags: u32, width: i32, height: i32, refresh: i32) {
        println!("on_mode({}, {}, {}, {})", flags, width, height, refresh);
    }

    fn on_done(&mut self) {
        println!("on_done()");
    }

    fn on_scale(&mut self, factor: i32) {
        println!("on_scale({})", factor);
    }
}

fn main() {
    let mut display = Display::connect("wayland-0").unwrap();
    let mut registry = MyRegistry::new(display.get_registry().unwrap());
    registry.connect_dispatcher();

    while registry.roundtrip {
        registry.roundtrip = false;
        display.roundtrip();
    }
}
<|endoftext|>


<commit_before><commit_msg>Implement if..then..else..<commit_after><|endoftext|>


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

//! This module implements the `Any` trait, which enables dynamic typing
//! of any `'static` type through runtime reflection.
//!
//! `Any` itself can be used to get a `TypeId`, and has more features when used
//! as a trait object. As `&Any` (a borrowed trait object), it has the `is` and
//! `downcast_ref` methods, to test if the contained value is of a given type,
//! and to get a reference to the inner value as a type. As `&mut Any`, there
//! is also the `downcast_mut` method, for getting a mutable reference to the
//! inner value. `Box<Any>` adds the `downcast` method, which attempts to
//! convert to a `Box<T>`. See the [`Box`] documentation for the full details.
//!
//! Note that &Any is limited to testing whether a value is of a specified
//! concrete type, and cannot be used to test whether a type implements a trait.
//!
//! [`Box`]: ../../std/boxed/struct.Box.html
//!
//! # Examples
//!
//! Consider a situation where we want to log out a value passed to a function.
//! We know the value we're working on implements Debug, but we don't know its
//! concrete type.  We want to give special treatment to certain types: in this
//! case printing out the length of String values prior to their value.
//! We don't know the concrete type of our value at compile time, so we need to
//! use runtime reflection instead.
//!
//! ```rust
//! use std::fmt::Debug;
//! use std::any::Any;
//!
//! // Logger function for any type that implements Debug.
//! fn log<T: Any + Debug>(value: &T) {
//!     let value_any = value as &Any;
//!
//!     // try to convert our value to a String.  If successful, we want to
//!     // output the String's length as well as its value.  If not, it's a
//!     // different type: just print it out unadorned.
//!     match value_any.downcast_ref::<String>() {
//!         Some(as_string) => {
//!             println!("String ({}): {}", as_string.len(), as_string);
//!         }
//!         None => {
//!             println!("{:?}", value);
//!         }
//!     }
//! }
//!
//! // This function wants to log its parameter out prior to doing work with it.
//! fn do_work<T: Any + Debug>(value: &T) {
//!     log(value);
//!     // ...do some other work
//! }
//!
//! fn main() {
//!     let my_string = "Hello World".to_string();
//!     do_work(&my_string);
//!
//!     let my_i8: i8 = 100;
//!     do_work(&my_i8);
//! }
//! ```

#![stable(feature = "rust1", since = "1.0.0")]

use fmt;
use marker::Send;
use mem::transmute;
use option::Option::{self, Some, None};
use raw::TraitObject;
use intrinsics;
use marker::{Reflect, Sized};

///////////////////////////////////////////////////////////////////////////////
// Any trait
///////////////////////////////////////////////////////////////////////////////

/// A type to emulate dynamic typing.
///
/// Every type with no non-`'static` references implements `Any`.
/// See the [module-level documentation][mod] for more details.
///
/// [mod]: index.html
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Any: Reflect + 'static {
    /// Gets the `TypeId` of `self`.
    #[unstable(feature = "get_type_id",
               reason = "this method will likely be replaced by an associated static",
               issue = "27745")]
    fn get_type_id(&self) -> TypeId;
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Reflect + 'static + ?Sized > Any for T {
    fn get_type_id(&self) -> TypeId { TypeId::of::<T>() }
}

///////////////////////////////////////////////////////////////////////////////
// Extension methods for Any trait objects.
///////////////////////////////////////////////////////////////////////////////

#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Debug for Any {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.pad("Any")
    }
}

// Ensure that the result of e.g. joining a thread can be printed and
// hence used with `unwrap`. May eventually no longer be needed if
// dispatch works with upcasting.
#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Debug for Any + Send {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.pad("Any")
    }
}

impl Any {
    /// Returns true if the boxed type is the same as `T`
    #[stable(feature = "rust1", since = "1.0.0")]
    #[inline]
    pub fn is<T: Any>(&self) -> bool {
        // Get TypeId of the type this function is instantiated with
        let t = TypeId::of::<T>();

        // Get TypeId of the type in the trait object
        let boxed = self.get_type_id();

        // Compare both TypeIds on equality
        t == boxed
    }

    /// Returns some reference to the boxed value if it is of type `T`, or
    /// `None` if it isn't.
    #[stable(feature = "rust1", since = "1.0.0")]
    #[inline]
    pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
        if self.is::<T>() {
            unsafe {
                // Get the raw representation of the trait object
                let to: TraitObject = transmute(self);

                // Extract the data pointer
                Some(&*(to.data as *const T))
            }
        } else {
            None
        }
    }

    /// Returns some mutable reference to the boxed value if it is of type `T`, or
    /// `None` if it isn't.
    #[stable(feature = "rust1", since = "1.0.0")]
    #[inline]
    pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
        if self.is::<T>() {
            unsafe {
                // Get the raw representation of the trait object
                let to: TraitObject = transmute(self);

                // Extract the data pointer
                Some(&mut *(to.data as *const T as *mut T))
            }
        } else {
            None
        }
    }
}

impl Any+Send {
    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "rust1", since = "1.0.0")]
    #[inline]
    pub fn is<T: Any>(&self) -> bool {
        Any::is::<T>(self)
    }

    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "rust1", since = "1.0.0")]
    #[inline]
    pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
        Any::downcast_ref::<T>(self)
    }

    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "rust1", since = "1.0.0")]
    #[inline]
    pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
        Any::downcast_mut::<T>(self)
    }
}

///////////////////////////////////////////////////////////////////////////////
// TypeID and its methods
///////////////////////////////////////////////////////////////////////////////

/// A `TypeId` represents a globally unique identifier for a type.
///
/// Each `TypeId` is an opaque object which does not allow inspection of what's
/// inside but does allow basic operations such as cloning, comparison,
/// printing, and showing.
///
/// A `TypeId` is currently only available for types which ascribe to `'static`,
/// but this limitation may be removed in the future.
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct TypeId {
    t: u64,
}

impl TypeId {
    /// Returns the `TypeId` of the type this generic function has been
    /// instantiated with
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn of<T: ?Sized + Reflect + 'static>() -> TypeId {
        TypeId {
            t: unsafe { intrinsics::type_id::<T>() },
        }
    }
}
<commit_msg>Rollup merge of #34145 - matklad:any-docs, r=steveklabnik<commit_after>// Copyright 2013-2014 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.

//! This module implements the `Any` trait, which enables dynamic typing
//! of any `'static` type through runtime reflection.
//!
//! `Any` itself can be used to get a `TypeId`, and has more features when used
//! as a trait object. As `&Any` (a borrowed trait object), it has the `is` and
//! `downcast_ref` methods, to test if the contained value is of a given type,
//! and to get a reference to the inner value as a type. As `&mut Any`, there
//! is also the `downcast_mut` method, for getting a mutable reference to the
//! inner value. `Box<Any>` adds the `downcast` method, which attempts to
//! convert to a `Box<T>`. See the [`Box`] documentation for the full details.
//!
//! Note that &Any is limited to testing whether a value is of a specified
//! concrete type, and cannot be used to test whether a type implements a trait.
//!
//! [`Box`]: ../../std/boxed/struct.Box.html
//!
//! # Examples
//!
//! Consider a situation where we want to log out a value passed to a function.
//! We know the value we're working on implements Debug, but we don't know its
//! concrete type.  We want to give special treatment to certain types: in this
//! case printing out the length of String values prior to their value.
//! We don't know the concrete type of our value at compile time, so we need to
//! use runtime reflection instead.
//!
//! ```rust
//! use std::fmt::Debug;
//! use std::any::Any;
//!
//! // Logger function for any type that implements Debug.
//! fn log<T: Any + Debug>(value: &T) {
//!     let value_any = value as &Any;
//!
//!     // try to convert our value to a String.  If successful, we want to
//!     // output the String's length as well as its value.  If not, it's a
//!     // different type: just print it out unadorned.
//!     match value_any.downcast_ref::<String>() {
//!         Some(as_string) => {
//!             println!("String ({}): {}", as_string.len(), as_string);
//!         }
//!         None => {
//!             println!("{:?}", value);
//!         }
//!     }
//! }
//!
//! // This function wants to log its parameter out prior to doing work with it.
//! fn do_work<T: Any + Debug>(value: &T) {
//!     log(value);
//!     // ...do some other work
//! }
//!
//! fn main() {
//!     let my_string = "Hello World".to_string();
//!     do_work(&my_string);
//!
//!     let my_i8: i8 = 100;
//!     do_work(&my_i8);
//! }
//! ```

#![stable(feature = "rust1", since = "1.0.0")]

use fmt;
use marker::Send;
use mem::transmute;
use option::Option::{self, Some, None};
use raw::TraitObject;
use intrinsics;
use marker::{Reflect, Sized};

///////////////////////////////////////////////////////////////////////////////
// Any trait
///////////////////////////////////////////////////////////////////////////////

/// A type to emulate dynamic typing.
///
/// Most types implement `Any`. However, any type which contains a non-`'static` reference does not.
/// See the [module-level documentation][mod] for more details.
///
/// [mod]: index.html
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Any: Reflect + 'static {
    /// Gets the `TypeId` of `self`.
    #[unstable(feature = "get_type_id",
               reason = "this method will likely be replaced by an associated static",
               issue = "27745")]
    fn get_type_id(&self) -> TypeId;
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Reflect + 'static + ?Sized > Any for T {
    fn get_type_id(&self) -> TypeId { TypeId::of::<T>() }
}

///////////////////////////////////////////////////////////////////////////////
// Extension methods for Any trait objects.
///////////////////////////////////////////////////////////////////////////////

#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Debug for Any {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.pad("Any")
    }
}

// Ensure that the result of e.g. joining a thread can be printed and
// hence used with `unwrap`. May eventually no longer be needed if
// dispatch works with upcasting.
#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Debug for Any + Send {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.pad("Any")
    }
}

impl Any {
    /// Returns true if the boxed type is the same as `T`
    #[stable(feature = "rust1", since = "1.0.0")]
    #[inline]
    pub fn is<T: Any>(&self) -> bool {
        // Get TypeId of the type this function is instantiated with
        let t = TypeId::of::<T>();

        // Get TypeId of the type in the trait object
        let boxed = self.get_type_id();

        // Compare both TypeIds on equality
        t == boxed
    }

    /// Returns some reference to the boxed value if it is of type `T`, or
    /// `None` if it isn't.
    #[stable(feature = "rust1", since = "1.0.0")]
    #[inline]
    pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
        if self.is::<T>() {
            unsafe {
                // Get the raw representation of the trait object
                let to: TraitObject = transmute(self);

                // Extract the data pointer
                Some(&*(to.data as *const T))
            }
        } else {
            None
        }
    }

    /// Returns some mutable reference to the boxed value if it is of type `T`, or
    /// `None` if it isn't.
    #[stable(feature = "rust1", since = "1.0.0")]
    #[inline]
    pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
        if self.is::<T>() {
            unsafe {
                // Get the raw representation of the trait object
                let to: TraitObject = transmute(self);

                // Extract the data pointer
                Some(&mut *(to.data as *const T as *mut T))
            }
        } else {
            None
        }
    }
}

impl Any+Send {
    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "rust1", since = "1.0.0")]
    #[inline]
    pub fn is<T: Any>(&self) -> bool {
        Any::is::<T>(self)
    }

    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "rust1", since = "1.0.0")]
    #[inline]
    pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
        Any::downcast_ref::<T>(self)
    }

    /// Forwards to the method defined on the type `Any`.
    #[stable(feature = "rust1", since = "1.0.0")]
    #[inline]
    pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
        Any::downcast_mut::<T>(self)
    }
}

///////////////////////////////////////////////////////////////////////////////
// TypeID and its methods
///////////////////////////////////////////////////////////////////////////////

/// A `TypeId` represents a globally unique identifier for a type.
///
/// Each `TypeId` is an opaque object which does not allow inspection of what's
/// inside but does allow basic operations such as cloning, comparison,
/// printing, and showing.
///
/// A `TypeId` is currently only available for types which ascribe to `'static`,
/// but this limitation may be removed in the future.
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct TypeId {
    t: u64,
}

impl TypeId {
    /// Returns the `TypeId` of the type this generic function has been
    /// instantiated with
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn of<T: ?Sized + Reflect + 'static>() -> TypeId {
        TypeId {
            t: unsafe { intrinsics::type_id::<T>() },
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*!

The `ToStr` trait for converting to strings

*/

use str;

pub trait ToStr {
    fn to_str(&self) -> ~str;
}

/// Trait for converting a type to a string, consuming it in the process.
pub trait ToStrConsume {
    // Cosume and convert to a string.
    fn to_str_consume(self) -> ~str;
}

impl ToStr for bool {
    #[inline(always)]
    fn to_str(&self) -> ~str { ::bool::to_str(*self) }
}
impl ToStr for () {
    #[inline(always)]
    fn to_str(&self) -> ~str { ~"()" }
}

impl<A:ToStr> ToStr for (A,) {
    #[inline(always)]
    fn to_str(&self) -> ~str {
        match *self {
            (ref a,) => {
                ~"(" + a.to_str() + ~", " + ~")"
            }
        }
    }
}

impl<A:ToStr,B:ToStr> ToStr for (A, B) {
    #[inline(always)]
    fn to_str(&self) -> ~str {
        // FIXME(#4760): this causes an llvm assertion
        //let &(ref a, ref b) = self;
        match *self {
            (ref a, ref b) => {
                ~"(" + a.to_str() + ~", " + b.to_str() + ~")"
            }
        }
    }
}
impl<A:ToStr,B:ToStr,C:ToStr> ToStr for (A, B, C) {
    #[inline(always)]
    fn to_str(&self) -> ~str {
        // FIXME(#4760): this causes an llvm assertion
        //let &(ref a, ref b, ref c) = self;
        match *self {
            (ref a, ref b, ref c) => {
                fmt!("(%s, %s, %s)",
                    (*a).to_str(),
                    (*b).to_str(),
                    (*c).to_str()
                )
            }
        }
    }
}

impl<'self,A:ToStr> ToStr for &'self [A] {
    #[inline(always)]
    fn to_str(&self) -> ~str {
        let mut acc = ~"[", first = true;
        for self.each |elt| {
            if first { first = false; }
            else { str::push_str(&mut acc, ~", "); }
            str::push_str(&mut acc, elt.to_str());
        }
        str::push_char(&mut acc, ']');
        acc
    }
}

impl<A:ToStr> ToStr for ~[A] {
    #[inline(always)]
    fn to_str(&self) -> ~str {
        let mut acc = ~"[", first = true;
        for self.each |elt| {
            if first { first = false; }
            else { str::push_str(&mut acc, ~", "); }
            str::push_str(&mut acc, elt.to_str());
        }
        str::push_char(&mut acc, ']');
        acc
    }
}

impl<A:ToStr> ToStr for @[A] {
    #[inline(always)]
    fn to_str(&self) -> ~str {
        let mut acc = ~"[", first = true;
        for self.each |elt| {
            if first { first = false; }
            else { str::push_str(&mut acc, ~", "); }
            str::push_str(&mut acc, elt.to_str());
        }
        str::push_char(&mut acc, ']');
        acc
    }
}

#[cfg(test)]
#[allow(non_implicitly_copyable_typarams)]
mod tests {
    #[test]
    fn test_simple_types() {
        assert!(1i.to_str() == ~"1");
        assert!((-1i).to_str() == ~"-1");
        assert!(200u.to_str() == ~"200");
        assert!(2u8.to_str() == ~"2");
        assert!(true.to_str() == ~"true");
        assert!(false.to_str() == ~"false");
        assert!(().to_str() == ~"()");
        assert!((~"hi").to_str() == ~"hi");
        assert!((@"hi").to_str() == ~"hi");
    }

    #[test]
    fn test_tuple_types() {
        assert!((1, 2).to_str() == ~"(1, 2)");
        assert!((~"a", ~"b", false).to_str() == ~"(a, b, false)");
        assert!(((), ((), 100)).to_str() == ~"((), ((), 100))");
    }

    #[test]
    fn test_vectors() {
        let x: ~[int] = ~[];
        assert!(x.to_str() == ~"[]");
        assert!((~[1]).to_str() == ~"[1]");
        assert!((~[1, 2, 3]).to_str() == ~"[1, 2, 3]");
        assert!((~[~[], ~[1], ~[1, 1]]).to_str() ==
               ~"[[], [1], [1, 1]]");
    }
}
<commit_msg>Add to_str() for HashMaps, and some basic tests as well.<commit_after>// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/*!

The `ToStr` trait for converting to strings

*/

use str;
use hashmap::HashMap;
use container::Map;
use hash::Hash;
use cmp::Eq;

pub trait ToStr {
    fn to_str(&self) -> ~str;
}

/// Trait for converting a type to a string, consuming it in the process.
pub trait ToStrConsume {
    // Cosume and convert to a string.
    fn to_str_consume(self) -> ~str;
}

impl ToStr for bool {
    #[inline(always)]
    fn to_str(&self) -> ~str { ::bool::to_str(*self) }
}
impl ToStr for () {
    #[inline(always)]
    fn to_str(&self) -> ~str { ~"()" }
}

impl<A:ToStr> ToStr for (A,) {
    #[inline(always)]
    fn to_str(&self) -> ~str {
        match *self {
            (ref a,) => {
                ~"(" + a.to_str() + ~", " + ~")"
            }
        }
    }
}

impl<A:ToStr+Hash+Eq, B:ToStr+Hash+Eq> ToStr for HashMap<A, B> {
    #[inline(always)]
    fn to_str(&self) -> ~str {
        let mut acc = ~"{", first = true;
        for self.each |key, value| {
            if first {
                first = false;
            }
            else {
                str::push_str(&mut acc, ~", ");
            }
            str::push_str(&mut acc, key.to_str());
            str::push_str(&mut acc, ~" : ");
            str::push_str(&mut acc, value.to_str());
        }
        str::push_char(&mut acc, '}');
        acc
    }
}

impl<A:ToStr,B:ToStr> ToStr for (A, B) {
    #[inline(always)]
    fn to_str(&self) -> ~str {
        // FIXME(#4760): this causes an llvm assertion
        //let &(ref a, ref b) = self;
        match *self {
            (ref a, ref b) => {
                ~"(" + a.to_str() + ~", " + b.to_str() + ~")"
            }
        }
    }
}
impl<A:ToStr,B:ToStr,C:ToStr> ToStr for (A, B, C) {
    #[inline(always)]
    fn to_str(&self) -> ~str {
        // FIXME(#4760): this causes an llvm assertion
        //let &(ref a, ref b, ref c) = self;
        match *self {
            (ref a, ref b, ref c) => {
                fmt!("(%s, %s, %s)",
                    (*a).to_str(),
                    (*b).to_str(),
                    (*c).to_str()
                )
            }
        }
    }
}

impl<'self,A:ToStr> ToStr for &'self [A] {
    #[inline(always)]
    fn to_str(&self) -> ~str {
        let mut acc = ~"[", first = true;
        for self.each |elt| {
            if first { first = false; }
            else { str::push_str(&mut acc, ~", "); }
            str::push_str(&mut acc, elt.to_str());
        }
        str::push_char(&mut acc, ']');
        acc
    }
}

impl<A:ToStr> ToStr for ~[A] {
    #[inline(always)]
    fn to_str(&self) -> ~str {
        let mut acc = ~"[", first = true;
        for self.each |elt| {
            if first { first = false; }
            else { str::push_str(&mut acc, ~", "); }
            str::push_str(&mut acc, elt.to_str());
        }
        str::push_char(&mut acc, ']');
        acc
    }
}

impl<A:ToStr> ToStr for @[A] {
    #[inline(always)]
    fn to_str(&self) -> ~str {
        let mut acc = ~"[", first = true;
        for self.each |elt| {
            if first { first = false; }
            else { str::push_str(&mut acc, ~", "); }
            str::push_str(&mut acc, elt.to_str());
        }
        str::push_char(&mut acc, ']');
        acc
    }
}

#[cfg(test)]
#[allow(non_implicitly_copyable_typarams)]
mod tests {
    #[test]
    fn test_simple_types() {
        assert!(1i.to_str() == ~"1");
        assert!((-1i).to_str() == ~"-1");
        assert!(200u.to_str() == ~"200");
        assert!(2u8.to_str() == ~"2");
        assert!(true.to_str() == ~"true");
        assert!(false.to_str() == ~"false");
        assert!(().to_str() == ~"()");
        assert!((~"hi").to_str() == ~"hi");
        assert!((@"hi").to_str() == ~"hi");
    }

    #[test]
    fn test_tuple_types() {
        assert!((1, 2).to_str() == ~"(1, 2)");
        assert!((~"a", ~"b", false).to_str() == ~"(a, b, false)");
        assert!(((), ((), 100)).to_str() == ~"((), ((), 100))");
    }

    #[test]
    fn test_vectors() {
        let x: ~[int] = ~[];
        assert!(x.to_str() == ~"[]");
        assert!((~[1]).to_str() == ~"[1]");
        assert!((~[1, 2, 3]).to_str() == ~"[1, 2, 3]");
        assert!((~[~[], ~[1], ~[1, 1]]).to_str() ==
               ~"[[], [1], [1, 1]]");
    }

    #[test]
    fn test_hashmap() {
        let mut table: HashMap<int, int> = HashMap::new();
        let mut empty: HashMap<int, int> = HashMap::new();

        table.insert(3, 4);
        table.insert(1, 2);

        assert!(table.to_str() == ~"{1 : 2, 3 : 4}");
        assert!(empty.to_str() == ~"{}");
    }
}
<|endoftext|>


<commit_before>// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! A double-ended queue implemented as a circular buffer

use core::prelude::*;

use core::util::replace;

static initial_capacity: uint = 32u; // 2^5

pub struct Deque<T> {
    priv nelts: uint,
    priv lo: uint,
    priv hi: uint,
    priv elts: ~[Option<T>]
}

impl<T> Container for Deque<T> {
    /// Return the number of elements in the deque
    fn len(&const self) -> uint { self.nelts }

    /// Return true if the deque contains no elements
    fn is_empty(&const self) -> bool { self.len() == 0 }
}

impl<T> Mutable for Deque<T> {
    /// Clear the deque, removing all values.
    fn clear(&mut self) {
        for self.elts.each_mut |x| { *x = None }
        self.nelts = 0;
        self.lo = 0;
        self.hi = 0;
    }
}

pub impl<T> Deque<T> {
    /// Create an empty Deque
    fn new() -> Deque<T> {
        Deque{nelts: 0, lo: 0, hi: 0,
              elts: vec::from_fn(initial_capacity, |_| None)}
    }

    /// Return a reference to the first element in the deque
    ///
    /// Fails if the deque is empty
    fn peek_front<'a>(&'a self) -> &'a T { get(self.elts, self.lo) }

    /// Return a reference to the last element in the deque
    ///
    /// Fails if the deque is empty
    fn peek_back<'a>(&'a self) -> &'a T { get(self.elts, self.hi - 1u) }

    /// Retrieve an element in the deque by index
    ///
    /// Fails if there is no element with the given index
    fn get<'a>(&'a self, i: int) -> &'a T {
        let idx = (self.lo + (i as uint)) % self.elts.len();
        get(self.elts, idx)
    }

    /// Iterate over the elements in the deque
    fn each(&self, f: &fn(&T) -> bool) -> bool {
        self.eachi(|_i, e| f(e))
    }

    /// Iterate over the elements in the deque by index
    fn eachi(&self, f: &fn(uint, &T) -> bool) -> bool {
        uint::range(0, self.nelts, |i| f(i, self.get(i as int)))
    }

    /// Remove and return the first element in the deque
    ///
    /// Fails if the deque is empty
    fn pop_front(&mut self) -> T {
        let result = self.elts[self.lo].swap_unwrap();
        self.lo = (self.lo + 1u) % self.elts.len();
        self.nelts -= 1u;
        result
    }

    /// Remove and return the last element in the deque
    ///
    /// Fails if the deque is empty
    fn pop_back(&mut self) -> T {
        if self.hi == 0u {
            self.hi = self.elts.len() - 1u;
        } else { self.hi -= 1u; }
        let result = self.elts[self.hi].swap_unwrap();
        self.elts[self.hi] = None;
        self.nelts -= 1u;
        result
    }

    /// Prepend an element to the deque
    fn add_front(&mut self, t: T) {
        let oldlo = self.lo;
        if self.lo == 0u {
            self.lo = self.elts.len() - 1u;
        } else { self.lo -= 1u; }
        if self.lo == self.hi {
            self.elts = grow(self.nelts, oldlo, self.elts);
            self.lo = self.elts.len() - 1u;
            self.hi = self.nelts;
        }
        self.elts[self.lo] = Some(t);
        self.nelts += 1u;
    }

    /// Append an element to the deque
    fn add_back(&mut self, t: T) {
        if self.lo == self.hi && self.nelts != 0u {
            self.elts = grow(self.nelts, self.lo, self.elts);
            self.lo = 0u;
            self.hi = self.nelts;
        }
        self.elts[self.hi] = Some(t);
        self.hi = (self.hi + 1u) % self.elts.len();
        self.nelts += 1u;
    }
}

/// Grow is only called on full elts, so nelts is also len(elts), unlike
/// elsewhere.
fn grow<T>(nelts: uint, lo: uint, elts: &mut [Option<T>]) -> ~[Option<T>] {
    assert_eq!(nelts, elts.len());
    let mut rv = ~[];

    do rv.grow_fn(nelts + 1) |i| {
        replace(&mut elts[(lo + i) % nelts], None)
    }

    rv
}

fn get<'r, T>(elts: &'r [Option<T>], i: uint) -> &'r T {
    match elts[i] { Some(ref t) => t, _ => fail!() }
}

#[cfg(test)]
mod tests {
    use super::*;
    use core::cmp::Eq;
    use core::kinds::Copy;

    #[test]
    fn test_simple() {
        let mut d = Deque::new();
        assert_eq!(d.len(), 0u);
        d.add_front(17);
        d.add_front(42);
        d.add_back(137);
        assert_eq!(d.len(), 3u);
        d.add_back(137);
        assert_eq!(d.len(), 4u);
        debug!(d.peek_front());
        assert_eq!(*d.peek_front(), 42);
        debug!(d.peek_back());
        assert_eq!(*d.peek_back(), 137);
        let mut i: int = d.pop_front();
        debug!(i);
        assert_eq!(i, 42);
        i = d.pop_back();
        debug!(i);
        assert_eq!(i, 137);
        i = d.pop_back();
        debug!(i);
        assert_eq!(i, 137);
        i = d.pop_back();
        debug!(i);
        assert_eq!(i, 17);
        assert_eq!(d.len(), 0u);
        d.add_back(3);
        assert_eq!(d.len(), 1u);
        d.add_front(2);
        assert_eq!(d.len(), 2u);
        d.add_back(4);
        assert_eq!(d.len(), 3u);
        d.add_front(1);
        assert_eq!(d.len(), 4u);
        debug!(d.get(0));
        debug!(d.get(1));
        debug!(d.get(2));
        debug!(d.get(3));
        assert_eq!(*d.get(0), 1);
        assert_eq!(*d.get(1), 2);
        assert_eq!(*d.get(2), 3);
        assert_eq!(*d.get(3), 4);
    }

    #[test]
    fn test_boxes() {
        let a: @int = @5;
        let b: @int = @72;
        let c: @int = @64;
        let d: @int = @175;

        let mut deq = Deque::new();
        assert_eq!(deq.len(), 0);
        deq.add_front(a);
        deq.add_front(b);
        deq.add_back(c);
        assert_eq!(deq.len(), 3);
        deq.add_back(d);
        assert_eq!(deq.len(), 4);
        assert_eq!(*deq.peek_front(), b);
        assert_eq!(*deq.peek_back(), d);
        assert_eq!(deq.pop_front(), b);
        assert_eq!(deq.pop_back(), d);
        assert_eq!(deq.pop_back(), c);
        assert_eq!(deq.pop_back(), a);
        assert_eq!(deq.len(), 0);
        deq.add_back(c);
        assert_eq!(deq.len(), 1);
        deq.add_front(b);
        assert_eq!(deq.len(), 2);
        deq.add_back(d);
        assert_eq!(deq.len(), 3);
        deq.add_front(a);
        assert_eq!(deq.len(), 4);
        assert_eq!(*deq.get(0), a);
        assert_eq!(*deq.get(1), b);
        assert_eq!(*deq.get(2), c);
        assert_eq!(*deq.get(3), d);
    }

    #[cfg(test)]
    fn test_parameterized<T:Copy + Eq>(a: T, b: T, c: T, d: T) {
        let mut deq = Deque::new();
        assert_eq!(deq.len(), 0);
        deq.add_front(a);
        deq.add_front(b);
        deq.add_back(c);
        assert_eq!(deq.len(), 3);
        deq.add_back(d);
        assert_eq!(deq.len(), 4);
        assert_eq!(*deq.peek_front(), b);
        assert_eq!(*deq.peek_back(), d);
        assert_eq!(deq.pop_front(), b);
        assert_eq!(deq.pop_back(), d);
        assert_eq!(deq.pop_back(), c);
        assert_eq!(deq.pop_back(), a);
        assert_eq!(deq.len(), 0);
        deq.add_back(c);
        assert_eq!(deq.len(), 1);
        deq.add_front(b);
        assert_eq!(deq.len(), 2);
        deq.add_back(d);
        assert_eq!(deq.len(), 3);
        deq.add_front(a);
        assert_eq!(deq.len(), 4);
        assert_eq!(*deq.get(0), a);
        assert_eq!(*deq.get(1), b);
        assert_eq!(*deq.get(2), c);
        assert_eq!(*deq.get(3), d);
    }

    #[deriving(Eq)]
    enum Taggy { One(int), Two(int, int), Three(int, int, int), }

    #[deriving(Eq)]
    enum Taggypar<T> {
        Onepar(int), Twopar(int, int), Threepar(int, int, int),
    }

    #[deriving(Eq)]
    struct RecCy {
        x: int,
        y: int,
        t: Taggy
    }

    #[test]
    fn test_param_int() {
        test_parameterized::<int>(5, 72, 64, 175);
    }

    #[test]
    fn test_param_at_int() {
        test_parameterized::<@int>(@5, @72, @64, @175);
    }

    #[test]
    fn test_param_taggy() {
        test_parameterized::<Taggy>(One(1), Two(1, 2), Three(1, 2, 3),
                                    Two(17, 42));
    }

    #[test]
    fn test_param_taggypar() {
        test_parameterized::<Taggypar<int>>(Onepar::<int>(1),
                                            Twopar::<int>(1, 2),
                                            Threepar::<int>(1, 2, 3),
                                            Twopar::<int>(17, 42));
    }

    #[test]
    fn test_param_reccy() {
        let reccy1 = RecCy { x: 1, y: 2, t: One(1) };
        let reccy2 = RecCy { x: 345, y: 2, t: Two(1, 2) };
        let reccy3 = RecCy { x: 1, y: 777, t: Three(1, 2, 3) };
        let reccy4 = RecCy { x: 19, y: 252, t: Two(17, 42) };
        test_parameterized::<RecCy>(reccy1, reccy2, reccy3, reccy4);
    }

    #[test]
    fn test_eachi() {
        let mut deq = Deque::new();
        deq.add_back(1);
        deq.add_back(2);
        deq.add_back(3);

        for deq.eachi |i, e| {
            assert_eq!(*e, i + 1);
        }

        deq.pop_front();

        for deq.eachi |i, e| {
            assert_eq!(*e, i + 2);
        }

    }
}
<commit_msg>auto merge of #6769 : catamorphism/rust/issue-4994, r=thestinger<commit_after>// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! A double-ended queue implemented as a circular buffer

use core::prelude::*;

use core::util::replace;

static initial_capacity: uint = 32u; // 2^5

pub struct Deque<T> {
    priv nelts: uint,
    priv lo: uint,
    priv hi: uint,
    priv elts: ~[Option<T>]
}

impl<T> Container for Deque<T> {
    /// Return the number of elements in the deque
    fn len(&const self) -> uint { self.nelts }

    /// Return true if the deque contains no elements
    fn is_empty(&const self) -> bool { self.len() == 0 }
}

impl<T> Mutable for Deque<T> {
    /// Clear the deque, removing all values.
    fn clear(&mut self) {
        for self.elts.each_mut |x| { *x = None }
        self.nelts = 0;
        self.lo = 0;
        self.hi = 0;
    }
}

pub impl<T> Deque<T> {
    /// Create an empty Deque
    fn new() -> Deque<T> {
        Deque{nelts: 0, lo: 0, hi: 0,
              elts: vec::from_fn(initial_capacity, |_| None)}
    }

    /// Return a reference to the first element in the deque
    ///
    /// Fails if the deque is empty
    fn peek_front<'a>(&'a self) -> &'a T { get(self.elts, self.lo) }

    /// Return a reference to the last element in the deque
    ///
    /// Fails if the deque is empty
    fn peek_back<'a>(&'a self) -> &'a T { get(self.elts, self.hi - 1u) }

    /// Retrieve an element in the deque by index
    ///
    /// Fails if there is no element with the given index
    fn get<'a>(&'a self, i: int) -> &'a T {
        let idx = (self.lo + (i as uint)) % self.elts.len();
        get(self.elts, idx)
    }

    /// Iterate over the elements in the deque
    fn each(&self, f: &fn(&T) -> bool) -> bool {
        self.eachi(|_i, e| f(e))
    }

    /// Iterate over the elements in the deque by index
    fn eachi(&self, f: &fn(uint, &T) -> bool) -> bool {
        uint::range(0, self.nelts, |i| f(i, self.get(i as int)))
    }

    /// Remove and return the first element in the deque
    ///
    /// Fails if the deque is empty
    fn pop_front(&mut self) -> T {
        let result = self.elts[self.lo].swap_unwrap();
        self.lo = (self.lo + 1u) % self.elts.len();
        self.nelts -= 1u;
        result
    }

    /// Remove and return the last element in the deque
    ///
    /// Fails if the deque is empty
    fn pop_back(&mut self) -> T {
        if self.hi == 0u {
            self.hi = self.elts.len() - 1u;
        } else { self.hi -= 1u; }
        let result = self.elts[self.hi].swap_unwrap();
        self.elts[self.hi] = None;
        self.nelts -= 1u;
        result
    }

    /// Prepend an element to the deque
    fn add_front(&mut self, t: T) {
        let oldlo = self.lo;
        if self.lo == 0u {
            self.lo = self.elts.len() - 1u;
        } else { self.lo -= 1u; }
        if self.lo == self.hi {
            self.elts = grow(self.nelts, oldlo, self.elts);
            self.lo = self.elts.len() - 1u;
            self.hi = self.nelts;
        }
        self.elts[self.lo] = Some(t);
        self.nelts += 1u;
    }

    /// Append an element to the deque
    fn add_back(&mut self, t: T) {
        if self.lo == self.hi && self.nelts != 0u {
            self.elts = grow(self.nelts, self.lo, self.elts);
            self.lo = 0u;
            self.hi = self.nelts;
        }
        self.elts[self.hi] = Some(t);
        self.hi = (self.hi + 1u) % self.elts.len();
        self.nelts += 1u;
    }

    /// Reserve capacity for exactly `n` elements in the given deque,
    /// doing nothing if `self`'s capacity is already equal to or greater
    /// than the requested capacity
    ///
    /// # Arguments
    ///
    /// * n - The number of elements to reserve space for
    fn reserve(&mut self, n: uint) {
        vec::reserve(&mut self.elts, n);
    }

    /// Reserve capacity for at least `n` elements in the given deque,
    /// over-allocating in case the caller needs to reserve additional
    /// space.
    ///
    /// Do nothing if `self`'s capacity is already equal to or greater
    /// than the requested capacity.
    ///
    /// # Arguments
    ///
    /// * n - The number of elements to reserve space for
    fn reserve_at_least(&mut self, n: uint) {
        vec::reserve_at_least(&mut self.elts, n);
    }
}

/// Grow is only called on full elts, so nelts is also len(elts), unlike
/// elsewhere.
fn grow<T>(nelts: uint, lo: uint, elts: &mut [Option<T>]) -> ~[Option<T>] {
    assert_eq!(nelts, elts.len());
    let mut rv = ~[];

    do rv.grow_fn(nelts + 1) |i| {
        replace(&mut elts[(lo + i) % nelts], None)
    }

    rv
}

fn get<'r, T>(elts: &'r [Option<T>], i: uint) -> &'r T {
    match elts[i] { Some(ref t) => t, _ => fail!() }
}

#[cfg(test)]
mod tests {
    use super::*;
    use core::cmp::Eq;
    use core::kinds::Copy;
    use core::vec::capacity;

    #[test]
    fn test_simple() {
        let mut d = Deque::new();
        assert_eq!(d.len(), 0u);
        d.add_front(17);
        d.add_front(42);
        d.add_back(137);
        assert_eq!(d.len(), 3u);
        d.add_back(137);
        assert_eq!(d.len(), 4u);
        debug!(d.peek_front());
        assert_eq!(*d.peek_front(), 42);
        debug!(d.peek_back());
        assert_eq!(*d.peek_back(), 137);
        let mut i: int = d.pop_front();
        debug!(i);
        assert_eq!(i, 42);
        i = d.pop_back();
        debug!(i);
        assert_eq!(i, 137);
        i = d.pop_back();
        debug!(i);
        assert_eq!(i, 137);
        i = d.pop_back();
        debug!(i);
        assert_eq!(i, 17);
        assert_eq!(d.len(), 0u);
        d.add_back(3);
        assert_eq!(d.len(), 1u);
        d.add_front(2);
        assert_eq!(d.len(), 2u);
        d.add_back(4);
        assert_eq!(d.len(), 3u);
        d.add_front(1);
        assert_eq!(d.len(), 4u);
        debug!(d.get(0));
        debug!(d.get(1));
        debug!(d.get(2));
        debug!(d.get(3));
        assert_eq!(*d.get(0), 1);
        assert_eq!(*d.get(1), 2);
        assert_eq!(*d.get(2), 3);
        assert_eq!(*d.get(3), 4);
    }

    #[test]
    fn test_boxes() {
        let a: @int = @5;
        let b: @int = @72;
        let c: @int = @64;
        let d: @int = @175;

        let mut deq = Deque::new();
        assert_eq!(deq.len(), 0);
        deq.add_front(a);
        deq.add_front(b);
        deq.add_back(c);
        assert_eq!(deq.len(), 3);
        deq.add_back(d);
        assert_eq!(deq.len(), 4);
        assert_eq!(*deq.peek_front(), b);
        assert_eq!(*deq.peek_back(), d);
        assert_eq!(deq.pop_front(), b);
        assert_eq!(deq.pop_back(), d);
        assert_eq!(deq.pop_back(), c);
        assert_eq!(deq.pop_back(), a);
        assert_eq!(deq.len(), 0);
        deq.add_back(c);
        assert_eq!(deq.len(), 1);
        deq.add_front(b);
        assert_eq!(deq.len(), 2);
        deq.add_back(d);
        assert_eq!(deq.len(), 3);
        deq.add_front(a);
        assert_eq!(deq.len(), 4);
        assert_eq!(*deq.get(0), a);
        assert_eq!(*deq.get(1), b);
        assert_eq!(*deq.get(2), c);
        assert_eq!(*deq.get(3), d);
    }

    #[cfg(test)]
    fn test_parameterized<T:Copy + Eq>(a: T, b: T, c: T, d: T) {
        let mut deq = Deque::new();
        assert_eq!(deq.len(), 0);
        deq.add_front(a);
        deq.add_front(b);
        deq.add_back(c);
        assert_eq!(deq.len(), 3);
        deq.add_back(d);
        assert_eq!(deq.len(), 4);
        assert_eq!(*deq.peek_front(), b);
        assert_eq!(*deq.peek_back(), d);
        assert_eq!(deq.pop_front(), b);
        assert_eq!(deq.pop_back(), d);
        assert_eq!(deq.pop_back(), c);
        assert_eq!(deq.pop_back(), a);
        assert_eq!(deq.len(), 0);
        deq.add_back(c);
        assert_eq!(deq.len(), 1);
        deq.add_front(b);
        assert_eq!(deq.len(), 2);
        deq.add_back(d);
        assert_eq!(deq.len(), 3);
        deq.add_front(a);
        assert_eq!(deq.len(), 4);
        assert_eq!(*deq.get(0), a);
        assert_eq!(*deq.get(1), b);
        assert_eq!(*deq.get(2), c);
        assert_eq!(*deq.get(3), d);
    }

    #[deriving(Eq)]
    enum Taggy { One(int), Two(int, int), Three(int, int, int), }

    #[deriving(Eq)]
    enum Taggypar<T> {
        Onepar(int), Twopar(int, int), Threepar(int, int, int),
    }

    #[deriving(Eq)]
    struct RecCy {
        x: int,
        y: int,
        t: Taggy
    }

    #[test]
    fn test_param_int() {
        test_parameterized::<int>(5, 72, 64, 175);
    }

    #[test]
    fn test_param_at_int() {
        test_parameterized::<@int>(@5, @72, @64, @175);
    }

    #[test]
    fn test_param_taggy() {
        test_parameterized::<Taggy>(One(1), Two(1, 2), Three(1, 2, 3),
                                    Two(17, 42));
    }

    #[test]
    fn test_param_taggypar() {
        test_parameterized::<Taggypar<int>>(Onepar::<int>(1),
                                            Twopar::<int>(1, 2),
                                            Threepar::<int>(1, 2, 3),
                                            Twopar::<int>(17, 42));
    }

    #[test]
    fn test_param_reccy() {
        let reccy1 = RecCy { x: 1, y: 2, t: One(1) };
        let reccy2 = RecCy { x: 345, y: 2, t: Two(1, 2) };
        let reccy3 = RecCy { x: 1, y: 777, t: Three(1, 2, 3) };
        let reccy4 = RecCy { x: 19, y: 252, t: Two(17, 42) };
        test_parameterized::<RecCy>(reccy1, reccy2, reccy3, reccy4);
    }

    #[test]
    fn test_eachi() {
        let mut deq = Deque::new();
        deq.add_back(1);
        deq.add_back(2);
        deq.add_back(3);

        for deq.eachi |i, e| {
            assert_eq!(*e, i + 1);
        }

        deq.pop_front();

        for deq.eachi |i, e| {
            assert_eq!(*e, i + 2);
        }

    }

    #[test]
    fn test_reserve() {
        let mut d = Deque::new();
        d.add_back(0u64);
        d.reserve(50);
        assert_eq!(capacity(&mut d.elts), 50);
        let mut d = Deque::new();
        d.add_back(0u32);
        d.reserve(50);
        assert_eq!(capacity(&mut d.elts), 50);
    }

    #[test]
    fn test_reserve_at_least() {
        let mut d = Deque::new();
        d.add_back(0u64);
        d.reserve_at_least(50);
        assert_eq!(capacity(&mut d.elts), 64);
        let mut d = Deque::new();
        d.add_back(0u32);
        d.reserve_at_least(50);
        assert_eq!(capacity(&mut d.elts), 64);
    }

}
<|endoftext|>