<commit_before>//! A generic event loop for games and interactive applications

#![deny(missing_docs)]

extern crate time;
extern crate current;

use std::io::timer::sleep;
use std::time::duration::Duration;
use current::{ Modifier, Set };
use std::cmp;

/// Render arguments
#[deriving(Clone, PartialEq, Show)]
pub struct RenderArgs {
    /// Extrapolated time in seconds, used to do smooth animation.
    pub ext_dt: f64,
    /// The width of rendered area.
    pub width: u32,
    /// The height of rendered area.
    pub height: u32,
}

/// Update arguments, such as delta time in seconds
#[deriving(Clone, PartialEq, Show)]
pub struct UpdateArgs {
    /// Delta time in seconds.
    pub dt: f64,
}

/// Methods required to map from consumed event to emitted event.
pub trait EventMap<I> {
    /// Creates a render event.
    fn render(args: RenderArgs) -> Self;
    /// Creates an update event.
    fn update(args: UpdateArgs) -> Self;
    /// Creates an input event.
    fn input(args: I) -> Self;
}

#[deriving(Show)]
enum EventsState {
    RenderState,
    SwapBuffersState,
    UpdateLoopState,
    HandleEventsState,
    UpdateState,
}

/// The number of updates per second
///
/// This is the fixed update rate on average over time.
/// If the event loop lags, it will try to catch up.
pub struct Ups(pub u64);

impl<W> Modifier<Events<W>> for Ups {
    fn modify(self, events: &mut Events<W>) {
        let Ups(frames) = self;
        events.dt_update_in_ns = BILLION / frames;
    }
}

/// Wrapper trait for `Set<Ups>`
pub trait SetUps: Set<Ups> {
    /// Sets updates per second.
    fn set_ups(&mut self, val: Ups) {
        self.set_mut(val);
    }
}

impl<T: Set<Ups>> SetUps for T {}

/// The maximum number of frames per second
///
/// The frame rate can be lower because the
/// next frame is always scheduled from the previous frame.
/// This causes the frames to "slip" over time.
pub struct MaxFps(pub u64);

impl<W> Modifier<Events<W>> for MaxFps {
    fn modify(self, events: &mut Events<W>) {
        let MaxFps(frames) = self;
        events.dt_frame_in_ns = BILLION / frames;
    }
}

/// Wrapper trait for `Set<Fps>`
pub trait SetMaxFps: Set<MaxFps> {
    /// Sets frames per second.
    fn set_max_fps(&mut self, val: MaxFps) {
        self.set_mut(val);
    }
}

impl<T: Set<MaxFps>> SetMaxFps for T {}

/// Must be implemented by window.
pub trait EventWindow<I> {
    /// Polls event from window.
    fn poll_event(&mut self) -> Option<I>;
    /// Whether the window should close.
    fn should_close(&self) -> bool;
    /// The size of window.
    fn size(&self) -> [u32, ..2];
    /// Called when swapping buffers.
    fn swap_buffers(&mut self);
}

/// An event loop iterator
///
/// *Warning: Because the iterator polls events from the window back-end,
/// it must be used on the same thread as the window back-end (usually main thread),
/// unless the window back-end supports multi-thread event polling.*
///
/// Example:
///
/// ```Rust
/// fn main() {
///     let opengl = shader_version::opengl::OpenGL_3_2;
///     let window = Sdl2Window::new(
///         opengl,
///         WindowSettings {
///             title: "Example".to_string(),
///             size: [500, 500],
///             fullscreen: false,
///             exit_on_esc: true,
///             samples: 0,
///         }
///     )
///     let ref mut gl = Gl::new();
///     let window = RefCell::new(window);
///     for e in Events::new(&window)
///         .set(Ups(120))
///         .set(MaxFps(60)) {
///         use event::RenderEvent;
///         e.render(|args| {
///             // Set the viewport in window to render graphics.
///             gl.viewport(0, 0, args.width as i32, args.height as i32);
///             // Create graphics context with absolute coordinates.
///             let c = Context::abs(args.width as f64, args.height as f64);
///             // Do rendering here.
///         });
///     }
/// }
/// ```
pub struct Events<W> {
    /// The game window used by iterator.
    pub window: W,
    state: EventsState,
    last_update: u64,
    last_frame: u64,
    dt_update_in_ns: u64,
    dt_frame_in_ns: u64,
    dt: f64,
}

static BILLION: u64 = 1_000_000_000;

/// The default updates per second.
pub const DEFAULT_UPS: Ups = Ups(120);
/// The default maximum frames per second.
pub const DEFAULT_MAX_FPS: MaxFps = MaxFps(60);

impl<W: EventWindow<I>, I> Events<W> {
    /// Creates a new event iterator with default UPS and FPS settings.
    pub fn new(window: W) -> Events<W> {
        let start = time::precise_time_ns();
        let Ups(updates_per_second) = DEFAULT_UPS;
        let MaxFps(max_frames_per_second) = DEFAULT_MAX_FPS;
        Events {
            window: window,
            state: RenderState,
            last_update: start,
            last_frame: start,
            dt_update_in_ns: BILLION / updates_per_second,
            dt_frame_in_ns: BILLION / max_frames_per_second,
            dt: 1.0 / updates_per_second as f64,
        }
    }
}

impl<W: EventWindow<I>, I, E: EventMap<I>>
Iterator<E>
for Events<W> {
    /// Returns the next game event.
    fn next(&mut self) -> Option<E> {
        loop {
            self.state = match self.state {
                RenderState => {
                    let should_close = self.window.should_close();
                    if should_close { return None; }

                    let start_render = time::precise_time_ns();
                    self.last_frame = start_render;

                    let [w, h] = self.window.size();
                    if w != 0 && h != 0 {
                        // Swap buffers next time.
                        self.state = SwapBuffersState;
                        return Some(EventMap::render(RenderArgs {
                            // Extrapolate time forward to allow smooth motion.
                            ext_dt: (start_render - self.last_update) as f64
                                    / BILLION as f64,
                            width: w,
                            height: h,
                        }));
                    }

                    UpdateLoopState
                }
                SwapBuffersState => {
                    self.window.swap_buffers();
                    UpdateLoopState
                }
                UpdateLoopState => {
                    let current_time = time::precise_time_ns();
                    let next_frame = self.last_frame + self.dt_frame_in_ns;
                    let next_update = self.last_update + self.dt_update_in_ns;
                    let next_event = cmp::min(next_frame, next_update);
                    if next_event > current_time {
                        sleep( Duration::nanoseconds((next_event - current_time) as i64) );
                        UpdateLoopState
                    } else if next_event == next_frame {
                        RenderState
                    } else {
                        HandleEventsState
                    }
                }
                HandleEventsState => {
                    // Handle all events before updating.
                    match self.window.poll_event() {
                        None => UpdateState,
                        Some(x) => { return Some(EventMap::input(x)); },
                    }
                }
                UpdateState => {
                    self.state = UpdateLoopState;
                    self.last_update += self.dt_update_in_ns;
                    return Some(EventMap::update(UpdateArgs{ dt: self.dt }));
                }
            };
        }
    }
}
<commit_msg>Added property types to do correct type interference<commit_after>//! A generic event loop for games and interactive applications

#![deny(missing_docs)]

extern crate time;
extern crate current;

use std::io::timer::sleep;
use std::time::duration::Duration;
use current::{ Current, Get, Modifier, Set };
use std::cmp;
use std::cell::RefCell;

/// Whether window should close or not.
pub struct ShouldClose(pub bool);

/// Work-around trait for `Get<ShouldClose>`.
/// Used to support generic constraints.
pub trait GetShouldClose: Get<ShouldClose> {
    /// Returns whether window should close.
    fn get_should_close(&self) -> ShouldClose {
        self.get()
    }
}

impl<T: Get<ShouldClose>> GetShouldClose for T {}

/// Work-around trait for `Set<ShouldClose>`.
/// Used to support generic constraints.
pub trait SetShouldClose: Set<ShouldClose> {
    /// Sets whether window should close.
    fn set_should_close(&mut self, val: ShouldClose) {
        self.set_mut(val);
    }
}

impl<T: Set<ShouldClose>> SetShouldClose for T {}

/// The size of the window.
pub struct Size(pub [u32, ..2]);

/// Work-around trait for `Get<Size>`.
/// Used to support generic constraints.
pub trait GetSize: Get<Size> {
    /// Returns the size of window.
    fn get_size(&self) -> Size {
        self.get()
    }
}

impl<T: Get<Size>> GetSize for T {}

/// Work-around trait for `Set<Size>`.
/// Used to support generic constraints.
pub trait SetSize: Set<Size> {
    /// Sets size of window.
    fn set_size(&mut self, val: Size) {
        self.set_mut(val);
    }
}

impl<T: Set<Size>> SetSize for T {}

/// Implemented by windows that can swap buffers.
pub trait SwapBuffers {
    /// Swaps the buffers.
    fn swap_buffers(&mut self);
}

impl<W: SwapBuffers> SwapBuffers for Current<W> {
    #[inline(always)]
    fn swap_buffers(&mut self) {
        self.deref_mut().swap_buffers();
    }
}

impl<'a, W: 'a + SwapBuffers> SwapBuffers for &'a RefCell<W> {
    #[inline(always)]
    fn swap_buffers(&mut self) {
        self.borrow_mut().deref_mut().swap_buffers()
    }
}

/// Implemented by windows that can pull events.
pub trait PollEvent<E> {
    /// Polls event from window.
    fn poll_event(&mut self) -> Option<E>;
}

impl<W: PollEvent<I>, I> PollEvent<I> for Current<W> {
    fn poll_event(&mut self) -> Option<I> {
        self.deref_mut().poll_event()
    }
}

impl<'a, W: 'a + PollEvent<I>, I> PollEvent<I> for &'a RefCell<W> {
    #[inline(always)]
    fn poll_event(&mut self) -> Option<I> {
        self.borrow_mut().deref_mut().poll_event()
    }
}

/// Render arguments
#[deriving(Clone, PartialEq, Show)]
pub struct RenderArgs {
    /// Extrapolated time in seconds, used to do smooth animation.
    pub ext_dt: f64,
    /// The width of rendered area.
    pub width: u32,
    /// The height of rendered area.
    pub height: u32,
}

/// Update arguments, such as delta time in seconds
#[deriving(Clone, PartialEq, Show)]
pub struct UpdateArgs {
    /// Delta time in seconds.
    pub dt: f64,
}

/// Methods required to map from consumed event to emitted event.
pub trait EventMap<I> {
    /// Creates a render event.
    fn render(args: RenderArgs) -> Self;
    /// Creates an update event.
    fn update(args: UpdateArgs) -> Self;
    /// Creates an input event.
    fn input(args: I) -> Self;
}

#[deriving(Show)]
enum EventsState {
    RenderState,
    SwapBuffersState,
    UpdateLoopState,
    HandleEventsState,
    UpdateState,
}

/// The number of updates per second
///
/// This is the fixed update rate on average over time.
/// If the event loop lags, it will try to catch up.
pub struct Ups(pub u64);

impl<W> Modifier<Events<W>> for Ups {
    fn modify(self, events: &mut Events<W>) {
        let Ups(frames) = self;
        events.dt_update_in_ns = BILLION / frames;
    }
}

/// Wrapper trait for `Set<Ups>`
pub trait SetUps: Set<Ups> {
    /// Sets updates per second.
    fn set_ups(&mut self, val: Ups) {
        self.set_mut(val);
    }
}

impl<T: Set<Ups>> SetUps for T {}

/// The maximum number of frames per second
///
/// The frame rate can be lower because the
/// next frame is always scheduled from the previous frame.
/// This causes the frames to "slip" over time.
pub struct MaxFps(pub u64);

impl<W> Modifier<Events<W>> for MaxFps {
    fn modify(self, events: &mut Events<W>) {
        let MaxFps(frames) = self;
        events.dt_frame_in_ns = BILLION / frames;
    }
}

/// Wrapper trait for `Set<Fps>`
pub trait SetMaxFps: Set<MaxFps> {
    /// Sets frames per second.
    fn set_max_fps(&mut self, val: MaxFps) {
        self.set_mut(val);
    }
}

impl<T: Set<MaxFps>> SetMaxFps for T {}

/// Blanket impl for object that fulfill requirements.
pub trait EventWindow<I>:
    PollEvent<I>
  + GetShouldClose
  + GetSize
  + SwapBuffers {}

impl<T: PollEvent<I> + GetShouldClose + GetSize + SwapBuffers, I>
EventWindow<I> for T {}

/// An event loop iterator
///
/// *Warning: Because the iterator polls events from the window back-end,
/// it must be used on the same thread as the window back-end (usually main thread),
/// unless the window back-end supports multi-thread event polling.*
///
/// Example:
///
/// ```Rust
/// fn main() {
///     let opengl = shader_version::opengl::OpenGL_3_2;
///     let window = Sdl2Window::new(
///         opengl,
///         WindowSettings {
///             title: "Example".to_string(),
///             size: [500, 500],
///             fullscreen: false,
///             exit_on_esc: true,
///             samples: 0,
///         }
///     )
///     let ref mut gl = Gl::new();
///     let window = RefCell::new(window);
///     for e in Events::new(&window)
///         .set(Ups(120))
///         .set(MaxFps(60)) {
///         use event::RenderEvent;
///         e.render(|args| {
///             // Set the viewport in window to render graphics.
///             gl.viewport(0, 0, args.width as i32, args.height as i32);
///             // Create graphics context with absolute coordinates.
///             let c = Context::abs(args.width as f64, args.height as f64);
///             // Do rendering here.
///         });
///     }
/// }
/// ```
pub struct Events<W> {
    /// The game window used by iterator.
    pub window: W,
    state: EventsState,
    last_update: u64,
    last_frame: u64,
    dt_update_in_ns: u64,
    dt_frame_in_ns: u64,
    dt: f64,
}

static BILLION: u64 = 1_000_000_000;

/// The default updates per second.
pub const DEFAULT_UPS: Ups = Ups(120);
/// The default maximum frames per second.
pub const DEFAULT_MAX_FPS: MaxFps = MaxFps(60);

impl<W: EventWindow<I>, I> Events<W> {
    /// Creates a new event iterator with default UPS and FPS settings.
    pub fn new(window: W) -> Events<W> {
        let start = time::precise_time_ns();
        let Ups(updates_per_second) = DEFAULT_UPS;
        let MaxFps(max_frames_per_second) = DEFAULT_MAX_FPS;
        Events {
            window: window,
            state: RenderState,
            last_update: start,
            last_frame: start,
            dt_update_in_ns: BILLION / updates_per_second,
            dt_frame_in_ns: BILLION / max_frames_per_second,
            dt: 1.0 / updates_per_second as f64,
        }
    }
}

impl<W: EventWindow<I>, I, E: EventMap<I>>
Iterator<E>
for Events<W> {
    /// Returns the next game event.
    fn next(&mut self) -> Option<E> {
        loop {
            self.state = match self.state {
                RenderState => {
                    let ShouldClose(should_close) = self.window.get_should_close();
                    if should_close { return None; }

                    let start_render = time::precise_time_ns();
                    self.last_frame = start_render;

                    let Size([w, h]) = self.window.get_size();
                    if w != 0 && h != 0 {
                        // Swap buffers next time.
                        self.state = SwapBuffersState;
                        return Some(EventMap::render(RenderArgs {
                            // Extrapolate time forward to allow smooth motion.
                            ext_dt: (start_render - self.last_update) as f64
                                    / BILLION as f64,
                            width: w,
                            height: h,
                        }));
                    }

                    UpdateLoopState
                }
                SwapBuffersState => {
                    self.window.swap_buffers();
                    UpdateLoopState
                }
                UpdateLoopState => {
                    let current_time = time::precise_time_ns();
                    let next_frame = self.last_frame + self.dt_frame_in_ns;
                    let next_update = self.last_update + self.dt_update_in_ns;
                    let next_event = cmp::min(next_frame, next_update);
                    if next_event > current_time {
                        sleep( Duration::nanoseconds((next_event - current_time) as i64) );
                        UpdateLoopState
                    } else if next_event == next_frame {
                        RenderState
                    } else {
                        HandleEventsState
                    }
                }
                HandleEventsState => {
                    // Handle all events before updating.
                    match self.window.poll_event() {
                        None => UpdateState,
                        Some(x) => { return Some(EventMap::input(x)); },
                    }
                }
                UpdateState => {
                    self.state = UpdateLoopState;
                    self.last_update += self.dt_update_in_ns;
                    return Some(EventMap::update(UpdateArgs{ dt: self.dt }));
                }
            };
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Set up base directory, with test structure.<commit_after>#[cfg(test)]
#[allow(unused_imports)]
mod tests {
    use super::*;

    #[test]
    fn it_works() {
    }
}
<|endoftext|>


<commit_before><commit_msg>Rewrite Camera to use quaternions internally<commit_after><|endoftext|>


<commit_before><commit_msg>Add regression test<commit_after>// Copyright 2018 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 should not ICE
pub fn test() {
    macro_rules! foo {
        () => ()
    }
}
<|endoftext|>


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

use option::*;
use super::stack::StackSegment;
use libc::c_void;
use cast::{transmute, transmute_mut_unsafe,
           transmute_region, transmute_mut_region};

// XXX: Registers is boxed so that it is 16-byte aligned, for storing
// SSE regs.  It would be marginally better not to do this. In C++ we
// use an attribute on a struct.
// XXX: It would be nice to define regs as `~Option<Registers>` since
// the registers are sometimes empty, but the discriminant would
// then misalign the regs again.
pub struct Context {
    /// The context entry point, saved here for later destruction
    start: Option<~~fn()>,
    /// Hold the registers while the task or scheduler is suspended
    regs: ~Registers
}

pub impl Context {
    fn empty() -> Context {
        Context {
            start: None,
            regs: new_regs()
        }
    }

    /// Create a new context that will resume execution by running ~fn()
    fn new(start: ~fn(), stack: &mut StackSegment) -> Context {
        // XXX: Putting main into a ~ so it's a thin pointer and can
        // be passed to the spawn function.  Another unfortunate
        // allocation
        let start = ~start;

        // The C-ABI function that is the task entry point
        extern fn task_start_wrapper(f: &~fn()) { (*f)() }

        let fp: *c_void = task_start_wrapper as *c_void;
        let argp: *c_void = unsafe { transmute::<&~fn(), *c_void>(&*start) };
        let sp: *uint = stack.end();
        let sp: *mut uint = unsafe { transmute_mut_unsafe(sp) };

        // Save and then immediately load the current context,
        // which we will then modify to call the given function when restored
        let mut regs = new_regs();
        unsafe {
            swap_registers(transmute_mut_region(&mut *regs), transmute_region(&*regs))
        };

        initialize_call_frame(&mut *regs, fp, argp, sp);

        return Context {
            start: Some(start),
            regs: regs
        }
    }

    /* Switch contexts

    Suspend the current execution context and resume another by
    saving the registers values of the executing thread to a Context
    then loading the registers from a previously saved Context.
    */
    fn swap(out_context: &mut Context, in_context: &Context) {
        let out_regs: &mut Registers = match out_context {
            &Context { regs: ~ref mut r, _ } => r
        };
        let in_regs: &Registers = match in_context {
            &Context { regs: ~ref r, _ } => r
        };

        unsafe { swap_registers(out_regs, in_regs) };
    }
}

extern {
    fn swap_registers(out_regs: *mut Registers, in_regs: *Registers);
}

#[cfg(target_arch = "x86")]
struct Registers {
    eax: u32, ebx: u32, ecx: u32, edx: u32,
    ebp: u32, esi: u32, edi: u32, esp: u32,
    cs: u16, ds: u16, ss: u16, es: u16, fs: u16, gs: u16,
    eflags: u32, eip: u32
}

#[cfg(target_arch = "x86")]
fn new_regs() -> ~Registers {
    ~Registers {
        eax: 0, ebx: 0, ecx: 0, edx: 0,
        ebp: 0, esi: 0, edi: 0, esp: 0,
        cs: 0, ds: 0, ss: 0, es: 0, fs: 0, gs: 0,
        eflags: 0, eip: 0
    }
}

#[cfg(target_arch = "x86")]
fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) {

    let sp = align_down(sp);
    let sp = mut_offset(sp, -4);

    unsafe { *sp = arg as uint; }
    let sp = mut_offset(sp, -1);
    unsafe { *sp = 0; } // The final return address

    regs.esp = sp as u32;
    regs.eip = fptr as u32;

    // Last base pointer on the stack is 0
    regs.ebp = 0;
}

#[cfg(target_arch = "x86_64")]
type Registers = [uint, ..22];

#[cfg(target_arch = "x86_64")]
fn new_regs() -> ~Registers { ~([0, .. 22]) }

#[cfg(target_arch = "x86_64")]
fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) {

    // Redefinitions from regs.h
    static RUSTRT_ARG0: uint = 3;
    static RUSTRT_RSP: uint = 1;
    static RUSTRT_IP: uint = 8;
    static RUSTRT_RBP: uint = 2;

    let sp = align_down(sp);
    let sp = mut_offset(sp, -1);

    // The final return address. 0 indicates the bottom of the stack
    unsafe { *sp = 0; }

    rtdebug!("creating call frame");
    rtdebug!("fptr %x", fptr as uint);
    rtdebug!("arg %x", arg as uint);
    rtdebug!("sp %x", sp as uint);

    regs[RUSTRT_ARG0] = arg as uint;
    regs[RUSTRT_RSP] = sp as uint;
    regs[RUSTRT_IP] = fptr as uint;

    // Last base pointer on the stack should be 0
    regs[RUSTRT_RBP] = 0;
}

#[cfg(target_arch = "arm")]
type Registers = [uint, ..32];

#[cfg(target_arch = "arm")]
fn new_regs() -> ~Registers { ~[0, .. 32] }

#[cfg(target_arch = "arm")]
fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) {
    let sp = mut_offset(sp, -1);

    // The final return address. 0 indicates the bottom of the stack
    unsafe { *sp = 0; }

    regs[0] = arg as uint;   // r0
    regs[13] = sp as uint;   // #53 sp, r13
    regs[14] = fptr as uint; // #60 pc, r15 --> lr
}

#[cfg(target_arch = "mips")]
type Registers = [uint, ..32];

#[cfg(target_arch = "mips")]
fn new_regs() -> ~Registers { ~[0, .. 32] }

#[cfg(target_arch = "mips")]
fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) {
    let sp = mut_offset(sp, -1);

    // The final return address. 0 indicates the bottom of the stack
    unsafe { *sp = 0; }

    regs[4] = arg as uint;
    regs[29] = sp as uint;
    regs[31] = fptr as uint;
}

fn align_down(sp: *mut uint) -> *mut uint {
    unsafe {
        let sp = transmute::<*mut uint, uint>(sp);
        let sp = sp & !(16 - 1);
        transmute::<uint, *mut uint>(sp)
    }
}

// XXX: ptr::offset is positive ints only
#[inline(always)]
pub fn mut_offset<T>(ptr: *mut T, count: int) -> *mut T {
    use core::sys::size_of;
    unsafe {
        (ptr as int + count * (size_of::<T>() as int)) as *mut T
    }
}

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

use option::*;
use super::stack::StackSegment;
use libc::c_void;
use cast::{transmute, transmute_mut_unsafe,
           transmute_region, transmute_mut_region};

// XXX: Registers is boxed so that it is 16-byte aligned, for storing
// SSE regs.  It would be marginally better not to do this. In C++ we
// use an attribute on a struct.
// XXX: It would be nice to define regs as `~Option<Registers>` since
// the registers are sometimes empty, but the discriminant would
// then misalign the regs again.
pub struct Context {
    /// The context entry point, saved here for later destruction
    start: Option<~~fn()>,
    /// Hold the registers while the task or scheduler is suspended
    regs: ~Registers
}

pub impl Context {
    fn empty() -> Context {
        Context {
            start: None,
            regs: new_regs()
        }
    }

    /// Create a new context that will resume execution by running ~fn()
    fn new(start: ~fn(), stack: &mut StackSegment) -> Context {
        // XXX: Putting main into a ~ so it's a thin pointer and can
        // be passed to the spawn function.  Another unfortunate
        // allocation
        let start = ~start;

        // The C-ABI function that is the task entry point
        extern fn task_start_wrapper(f: &~fn()) { (*f)() }

        let fp: *c_void = task_start_wrapper as *c_void;
        let argp: *c_void = unsafe { transmute::<&~fn(), *c_void>(&*start) };
        let sp: *uint = stack.end();
        let sp: *mut uint = unsafe { transmute_mut_unsafe(sp) };

        // Save and then immediately load the current context,
        // which we will then modify to call the given function when restored
        let mut regs = new_regs();
        unsafe {
            swap_registers(transmute_mut_region(&mut *regs), transmute_region(&*regs))
        };

        initialize_call_frame(&mut *regs, fp, argp, sp);

        return Context {
            start: Some(start),
            regs: regs
        }
    }

    /* Switch contexts

    Suspend the current execution context and resume another by
    saving the registers values of the executing thread to a Context
    then loading the registers from a previously saved Context.
    */
    fn swap(out_context: &mut Context, in_context: &Context) {
        let out_regs: &mut Registers = match out_context {
            &Context { regs: ~ref mut r, _ } => r
        };
        let in_regs: &Registers = match in_context {
            &Context { regs: ~ref r, _ } => r
        };

        unsafe { swap_registers(out_regs, in_regs) };
    }
}

extern {
    fn swap_registers(out_regs: *mut Registers, in_regs: *Registers);
}

#[cfg(target_arch = "x86")]
struct Registers {
    eax: u32, ebx: u32, ecx: u32, edx: u32,
    ebp: u32, esi: u32, edi: u32, esp: u32,
    cs: u16, ds: u16, ss: u16, es: u16, fs: u16, gs: u16,
    eflags: u32, eip: u32
}

#[cfg(target_arch = "x86")]
fn new_regs() -> ~Registers {
    ~Registers {
        eax: 0, ebx: 0, ecx: 0, edx: 0,
        ebp: 0, esi: 0, edi: 0, esp: 0,
        cs: 0, ds: 0, ss: 0, es: 0, fs: 0, gs: 0,
        eflags: 0, eip: 0
    }
}

#[cfg(target_arch = "x86")]
fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) {

    let sp = align_down(sp);
    let sp = mut_offset(sp, -4);

    unsafe { *sp = arg as uint; }
    let sp = mut_offset(sp, -1);
    unsafe { *sp = 0; } // The final return address

    regs.esp = sp as u32;
    regs.eip = fptr as u32;

    // Last base pointer on the stack is 0
    regs.ebp = 0;
}

#[cfg(target_arch = "x86_64")]
type Registers = [uint, ..22];

#[cfg(target_arch = "x86_64")]
fn new_regs() -> ~Registers { ~([0, .. 22]) }

#[cfg(target_arch = "x86_64")]
fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) {

    // Redefinitions from regs.h
    static RUSTRT_ARG0: uint = 3;
    static RUSTRT_RSP: uint = 1;
    static RUSTRT_IP: uint = 8;
    static RUSTRT_RBP: uint = 2;

    let sp = align_down(sp);
    let sp = mut_offset(sp, -1);

    // The final return address. 0 indicates the bottom of the stack
    unsafe { *sp = 0; }

    rtdebug!("creating call frame");
    rtdebug!("fptr %x", fptr as uint);
    rtdebug!("arg %x", arg as uint);
    rtdebug!("sp %x", sp as uint);

    regs[RUSTRT_ARG0] = arg as uint;
    regs[RUSTRT_RSP] = sp as uint;
    regs[RUSTRT_IP] = fptr as uint;

    // Last base pointer on the stack should be 0
    regs[RUSTRT_RBP] = 0;
}

#[cfg(target_arch = "arm")]
type Registers = [uint, ..32];

#[cfg(target_arch = "arm")]
fn new_regs() -> ~Registers { ~([0, .. 32]) }

#[cfg(target_arch = "arm")]
fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) {
    let sp = mut_offset(sp, -1);

    // The final return address. 0 indicates the bottom of the stack
    unsafe { *sp = 0; }

    regs[0] = arg as uint;   // r0
    regs[13] = sp as uint;   // #53 sp, r13
    regs[14] = fptr as uint; // #60 pc, r15 --> lr
}

#[cfg(target_arch = "mips")]
type Registers = [uint, ..32];

#[cfg(target_arch = "mips")]
fn new_regs() -> ~Registers { ~([0, .. 32]) }

#[cfg(target_arch = "mips")]
fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) {
    let sp = mut_offset(sp, -1);

    // The final return address. 0 indicates the bottom of the stack
    unsafe { *sp = 0; }

    regs[4] = arg as uint;
    regs[29] = sp as uint;
    regs[31] = fptr as uint;
}

fn align_down(sp: *mut uint) -> *mut uint {
    unsafe {
        let sp = transmute::<*mut uint, uint>(sp);
        let sp = sp & !(16 - 1);
        transmute::<uint, *mut uint>(sp)
    }
}

// XXX: ptr::offset is positive ints only
#[inline(always)]
pub fn mut_offset<T>(ptr: *mut T, count: int) -> *mut T {
    use core::sys::size_of;
    unsafe {
        (ptr as int + count * (size_of::<T>() as int)) as *mut T
    }
}

<|endoftext|>


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

//! Temporary files and directories

use io::{fs, IoResult};
use io;
use libc;
use ops::Drop;
use option::Option;
use option::Option::{None, Some};
use os;
use path::{Path, GenericPath};
use result::Result::{Ok, Err};
use sync::atomic;

/// A wrapper for a path to temporary directory implementing automatic
/// scope-based deletion.
pub struct TempDir {
    path: Option<Path>,
    disarmed: bool
}

impl TempDir {
    /// Attempts to make a temporary directory inside of `tmpdir` whose name
    /// will have the suffix `suffix`. The directory will be automatically
    /// deleted once the returned wrapper is destroyed.
    ///
    /// If no directory can be created, `Err` is returned.
    pub fn new_in(tmpdir: &Path, suffix: &str) -> IoResult<TempDir> {
        if !tmpdir.is_absolute() {
            let abs_tmpdir = try!(os::make_absolute(tmpdir));
            return TempDir::new_in(&abs_tmpdir, suffix);
        }

        static CNT: atomic::AtomicUint = atomic::INIT_ATOMIC_UINT;

        let mut attempts = 0u;
        loop {
            let filename =
                format!("rs-{}-{}-{}",
                        unsafe { libc::getpid() },
                        CNT.fetch_add(1, atomic::SeqCst),
                        suffix);
            let p = tmpdir.join(filename);
            match fs::mkdir(&p, io::USER_RWX) {
                Err(error) => {
                    if attempts >= 1000 {
                        return Err(error)
                    }
                    attempts += 1;
                }
                Ok(()) => return Ok(TempDir { path: Some(p), disarmed: false })
            }
        }
    }

    /// Attempts to make a temporary directory inside of `os::tmpdir()` whose
    /// name will have the suffix `suffix`. The directory will be automatically
    /// deleted once the returned wrapper is destroyed.
    ///
    /// If no directory can be created, `Err` is returned.
    pub fn new(suffix: &str) -> IoResult<TempDir> {
        TempDir::new_in(&os::tmpdir(), suffix)
    }

    /// Unwrap the wrapped `std::path::Path` from the `TempDir` wrapper.
    /// This discards the wrapper so that the automatic deletion of the
    /// temporary directory is prevented.
    pub fn into_inner(self) -> Path {
        let mut tmpdir = self;
        tmpdir.path.take().unwrap()
    }

    /// Deprecated, use into_inner() instead
    #[deprecated = "renamed to into_inner()"]
    pub fn unwrap(self) -> Path { self.into_inner() }

    /// Access the wrapped `std::path::Path` to the temporary directory.
    pub fn path<'a>(&'a self) -> &'a Path {
        self.path.as_ref().unwrap()
    }

    /// Close and remove the temporary directory
    ///
    /// Although `TempDir` removes the directory on drop, in the destructor
    /// any errors are ignored. To detect errors cleaning up the temporary
    /// directory, call `close` instead.
    pub fn close(mut self) -> IoResult<()> {
        self.cleanup_dir()
    }

    fn cleanup_dir(&mut self) -> IoResult<()> {
        assert!(!self.disarmed);
        self.disarmed = true;
        match self.path {
            Some(ref p) => {
                fs::rmdir_recursive(p)
            }
            None => Ok(())
        }
    }
}

impl Drop for TempDir {
    fn drop(&mut self) {
        if !self.disarmed {
            let _ = self.cleanup_dir();
        }
    }
}

// the tests for this module need to change the path using change_dir,
// and this doesn't play nicely with other tests so these unit tests are located
// in src/test/run-pass/tempfile.rs
<commit_msg>Added example to TempDir<commit_after>// Copyright 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.

//! Temporary files and directories

use io::{fs, IoResult};
use io;
use libc;
use ops::Drop;
use option::Option;
use option::Option::{None, Some};
use os;
use path::{Path, GenericPath};
use result::Result::{Ok, Err};
use sync::atomic;

/// A wrapper for a path to temporary directory implementing automatic
/// scope-based deletion.
///
/// # Examples
///
/// ```
/// # fn main() {}
/// # fn foo () {
/// use std::io::TempDir;
///
/// {
///     // create a temporary directory
///     let tmpdir = match TempDir::new("mysuffix") {
///         Ok(dir) => dir,
///         Err(e) => panic!("couldn't create temporary directory: {}", e)
///     };
///
///     // get the path of the temporary directory without affecting the wrapper
///     let tmppath = tmpdir.path();
///
///     println!("The path of temporary directory is {}", tmppath.as_str().unwrap());
///
///     // the temporary directory is automatically removed when tmpdir goes
///     // out of scope at the end of the block
/// }
/// {
///     // create a temporary directory, this time using a custom path
///     let tmpdir = match TempDir::new_in(&Path::new("/tmp/best/custom/path"), "mysuffix") {
///         Ok(dir) => dir,
///         Err(e) => panic!("couldn't create temporary directory: {}", e)
///     };
///
///     // get the path of the temporary directory and disable automatic deletion in the wrapper
///     let tmppath = tmpdir.into_inner();
///
///     println!("The path of the not-so-temporary directory is {}", tmppath.as_str().unwrap());
///
///     // the temporary directory is not removed here
///     // because the directory is detached from the wrapper
/// }
/// {
///     // create a temporary directory
///     let tmpdir = match TempDir::new("mysuffix") {
///         Ok(dir) => dir,
///         Err(e) => panic!("couldn't create temporary directory: {}", e)
///     };
///
///     // close the temporary directory manually and check the result
///     match tmpdir.close() {
///         Ok(_) => println!("success!"),
///         Err(e) => panic!("couldn't remove temporary directory: {}", e)
///     };
/// }
/// # }
/// ```
pub struct TempDir {
    path: Option<Path>,
    disarmed: bool
}

impl TempDir {
    /// Attempts to make a temporary directory inside of `tmpdir` whose name
    /// will have the suffix `suffix`. The directory will be automatically
    /// deleted once the returned wrapper is destroyed.
    ///
    /// If no directory can be created, `Err` is returned.
    pub fn new_in(tmpdir: &Path, suffix: &str) -> IoResult<TempDir> {
        if !tmpdir.is_absolute() {
            let abs_tmpdir = try!(os::make_absolute(tmpdir));
            return TempDir::new_in(&abs_tmpdir, suffix);
        }

        static CNT: atomic::AtomicUint = atomic::INIT_ATOMIC_UINT;

        let mut attempts = 0u;
        loop {
            let filename =
                format!("rs-{}-{}-{}",
                        unsafe { libc::getpid() },
                        CNT.fetch_add(1, atomic::SeqCst),
                        suffix);
            let p = tmpdir.join(filename);
            match fs::mkdir(&p, io::USER_RWX) {
                Err(error) => {
                    if attempts >= 1000 {
                        return Err(error)
                    }
                    attempts += 1;
                }
                Ok(()) => return Ok(TempDir { path: Some(p), disarmed: false })
            }
        }
    }

    /// Attempts to make a temporary directory inside of `os::tmpdir()` whose
    /// name will have the suffix `suffix`. The directory will be automatically
    /// deleted once the returned wrapper is destroyed.
    ///
    /// If no directory can be created, `Err` is returned.
    pub fn new(suffix: &str) -> IoResult<TempDir> {
        TempDir::new_in(&os::tmpdir(), suffix)
    }

    /// Unwrap the wrapped `std::path::Path` from the `TempDir` wrapper.
    /// This discards the wrapper so that the automatic deletion of the
    /// temporary directory is prevented.
    pub fn into_inner(self) -> Path {
        let mut tmpdir = self;
        tmpdir.path.take().unwrap()
    }

    /// Deprecated, use into_inner() instead
    #[deprecated = "renamed to into_inner()"]
    pub fn unwrap(self) -> Path { self.into_inner() }

    /// Access the wrapped `std::path::Path` to the temporary directory.
    pub fn path<'a>(&'a self) -> &'a Path {
        self.path.as_ref().unwrap()
    }

    /// Close and remove the temporary directory
    ///
    /// Although `TempDir` removes the directory on drop, in the destructor
    /// any errors are ignored. To detect errors cleaning up the temporary
    /// directory, call `close` instead.
    pub fn close(mut self) -> IoResult<()> {
        self.cleanup_dir()
    }

    fn cleanup_dir(&mut self) -> IoResult<()> {
        assert!(!self.disarmed);
        self.disarmed = true;
        match self.path {
            Some(ref p) => {
                fs::rmdir_recursive(p)
            }
            None => Ok(())
        }
    }
}

impl Drop for TempDir {
    fn drop(&mut self) {
        if !self.disarmed {
            let _ = self.cleanup_dir();
        }
    }
}

// the tests for this module need to change the path using change_dir,
// and this doesn't play nicely with other tests so these unit tests are located
// in src/test/run-pass/tempfile.rs
<|endoftext|>


<commit_before><commit_msg>concatenating a string to string reference<commit_after><|endoftext|>


<commit_before><commit_msg>Fix compilation on Rust 1.3 beta.<commit_after><|endoftext|>


<commit_before><commit_msg>(fix) Derive Copy where possible.<commit_after><|endoftext|>


<commit_before><commit_msg>Fix Tabbing<commit_after><|endoftext|>


<commit_before><commit_msg>Fix compilation errors when PCI is disabled<commit_after><|endoftext|>


<commit_before><commit_msg>Add test for the Mail model<commit_after><|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.

/*!
Message passing
*/

#[allow(missing_doc)];

use clone::Clone;
use kinds::Send;
use option::Option;
use rtcomm = rt::comm;

/// A trait for things that can send multiple messages.
pub trait GenericChan<T> {
    /// Sends a message.
    fn send(&self, x: T);
}

/// Things that can send multiple messages and can detect when the receiver
/// is closed
pub trait GenericSmartChan<T> {
    /// Sends a message, or report if the receiver has closed the connection.
    fn try_send(&self, x: T) -> bool;
}

/// Trait for non-rescheduling send operations, similar to `send_deferred` on ChanOne.
pub trait SendDeferred<T> {
    fn send_deferred(&self, val: T);
    fn try_send_deferred(&self, val: T) -> bool;
}

/// A trait for things that can receive multiple messages.
pub trait GenericPort<T> {
    /// Receives a message, or fails if the connection closes.
    fn recv(&self) -> T;

    /** Receives a message, or returns `none` if
    the connection is closed or closes.
    */
    fn try_recv(&self) -> Option<T>;
}

/// Ports that can `peek`
pub trait Peekable<T> {
    /// Returns true if a message is available
    fn peek(&self) -> bool;
}

pub struct PortOne<T> { priv x: rtcomm::PortOne<T> }
pub struct ChanOne<T> { priv x: rtcomm::ChanOne<T> }

pub fn oneshot<T: Send>() -> (PortOne<T>, ChanOne<T>) {
    let (p, c) = rtcomm::oneshot();
    (PortOne { x: p }, ChanOne { x: c })
}

pub struct Port<T> { priv x: rtcomm::Port<T> }
pub struct Chan<T> { priv x: rtcomm::Chan<T> }

pub fn stream<T: Send>() -> (Port<T>, Chan<T>) {
    let (p, c) = rtcomm::stream();
    (Port { x: p }, Chan { x: c })
}

impl<T: Send> ChanOne<T> {
    pub fn send(self, val: T) {
        let ChanOne { x: c } = self;
        c.send(val)
    }

    pub fn try_send(self, val: T) -> bool {
        let ChanOne { x: c } = self;
        c.try_send(val)
    }

    pub fn send_deferred(self, val: T) {
        let ChanOne { x: c } = self;
        c.send_deferred(val)
    }

    pub fn try_send_deferred(self, val: T) -> bool {
        let ChanOne{ x: c } = self;
        c.try_send_deferred(val)
    }
}

impl<T: Send> PortOne<T> {
    pub fn recv(self) -> T {
        let PortOne { x: p } = self;
        p.recv()
    }

    pub fn try_recv(self) -> Option<T> {
        let PortOne { x: p } = self;
        p.try_recv()
    }
}

impl<T: Send> Peekable<T>  for PortOne<T> {
    fn peek(&self) -> bool {
        let &PortOne { x: ref p } = self;
        p.peek()
    }
}

impl<T: Send> GenericChan<T> for Chan<T> {
    fn send(&self, val: T) {
        let &Chan { x: ref c } = self;
        c.send(val)
    }
}

impl<T: Send> GenericSmartChan<T> for Chan<T> {
    fn try_send(&self, val: T) -> bool {
        let &Chan { x: ref c } = self;
        c.try_send(val)
    }
}

impl<T: Send> SendDeferred<T> for Chan<T> {
    fn send_deferred(&self, val: T) {
        let &Chan { x: ref c } = self;
        c.send_deferred(val)
    }

    fn try_send_deferred(&self, val: T) -> bool {
        let &Chan { x: ref c } = self;
        c.try_send_deferred(val)
    }
}

impl<T: Send> GenericPort<T> for Port<T> {
    fn recv(&self) -> T {
        let &Port { x: ref p } = self;
        p.recv()
    }

    fn try_recv(&self) -> Option<T> {
        let &Port { x: ref p } = self;
        p.try_recv()
    }
}

impl<T: Send> Peekable<T> for Port<T> {
    fn peek(&self) -> bool {
        let &Port { x: ref p } = self;
        p.peek()
    }
}

pub struct SharedChan<T> { priv x: rtcomm::SharedChan<T> }

impl<T: Send> SharedChan<T> {
    pub fn new(c: Chan<T>) -> SharedChan<T> {
        let Chan { x: c } = c;
        SharedChan { x: rtcomm::SharedChan::new(c) }
    }
}

impl<T: Send> GenericChan<T> for SharedChan<T> {
    fn send(&self, val: T) {
        let &SharedChan { x: ref c } = self;
        c.send(val)
    }
}

impl<T: Send> GenericSmartChan<T> for SharedChan<T> {
    fn try_send(&self, val: T) -> bool {
        let &SharedChan { x: ref c } = self;
        c.try_send(val)
    }
}

impl<T: Send> SendDeferred<T> for SharedChan<T> {
    fn send_deferred(&self, val: T) {
        let &SharedChan { x: ref c } = self;
        c.send_deferred(val)
    }

    fn try_send_deferred(&self, val: T) -> bool {
        let &SharedChan { x: ref c } = self;
        c.try_send_deferred(val)
    }
}

impl<T: Send> Clone for SharedChan<T> {
    fn clone(&self) -> SharedChan<T> {
        let &SharedChan { x: ref c } = self;
        SharedChan { x: c.clone() }
    }
}

pub struct SharedPort<T> { priv x: rtcomm::SharedPort<T> }

impl<T: Send> SharedPort<T> {
    pub fn new(p: Port<T>) -> SharedPort<T> {
        let Port { x: p } = p;
        SharedPort { x: rtcomm::SharedPort::new(p) }
    }
}

impl<T: Send> GenericPort<T> for SharedPort<T> {
    fn recv(&self) -> T {
        let &SharedPort { x: ref p } = self;
        p.recv()
    }

    fn try_recv(&self) -> Option<T> {
        let &SharedPort { x: ref p } = self;
        p.try_recv()
    }
}

impl<T: Send> Clone for SharedPort<T> {
    fn clone(&self) -> SharedPort<T> {
        let &SharedPort { x: ref p } = self;
        SharedPort { x: p.clone() }
    }
}
<commit_msg>Disable priv in std::comm::Port, etc<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.

/*!
Message passing
*/

#[allow(missing_doc)];

use clone::Clone;
use kinds::Send;
use option::Option;
use rtcomm = rt::comm;

/// A trait for things that can send multiple messages.
pub trait GenericChan<T> {
    /// Sends a message.
    fn send(&self, x: T);
}

/// Things that can send multiple messages and can detect when the receiver
/// is closed
pub trait GenericSmartChan<T> {
    /// Sends a message, or report if the receiver has closed the connection.
    fn try_send(&self, x: T) -> bool;
}

/// Trait for non-rescheduling send operations, similar to `send_deferred` on ChanOne.
pub trait SendDeferred<T> {
    fn send_deferred(&self, val: T);
    fn try_send_deferred(&self, val: T) -> bool;
}

/// A trait for things that can receive multiple messages.
pub trait GenericPort<T> {
    /// Receives a message, or fails if the connection closes.
    fn recv(&self) -> T;

    /** Receives a message, or returns `none` if
    the connection is closed or closes.
    */
    fn try_recv(&self) -> Option<T>;
}

/// Ports that can `peek`
pub trait Peekable<T> {
    /// Returns true if a message is available
    fn peek(&self) -> bool;
}

/* priv is disabled to allow users to get at traits like Select. */
pub struct PortOne<T> { /* priv */ x: rtcomm::PortOne<T> }
pub struct ChanOne<T> { /* priv */ x: rtcomm::ChanOne<T> }

pub fn oneshot<T: Send>() -> (PortOne<T>, ChanOne<T>) {
    let (p, c) = rtcomm::oneshot();
    (PortOne { x: p }, ChanOne { x: c })
}

pub struct Port<T> { /* priv */ x: rtcomm::Port<T> }
pub struct Chan<T> { /* priv */ x: rtcomm::Chan<T> }

pub fn stream<T: Send>() -> (Port<T>, Chan<T>) {
    let (p, c) = rtcomm::stream();
    (Port { x: p }, Chan { x: c })
}

impl<T: Send> ChanOne<T> {
    pub fn send(self, val: T) {
        let ChanOne { x: c } = self;
        c.send(val)
    }

    pub fn try_send(self, val: T) -> bool {
        let ChanOne { x: c } = self;
        c.try_send(val)
    }

    pub fn send_deferred(self, val: T) {
        let ChanOne { x: c } = self;
        c.send_deferred(val)
    }

    pub fn try_send_deferred(self, val: T) -> bool {
        let ChanOne{ x: c } = self;
        c.try_send_deferred(val)
    }
}

impl<T: Send> PortOne<T> {
    pub fn recv(self) -> T {
        let PortOne { x: p } = self;
        p.recv()
    }

    pub fn try_recv(self) -> Option<T> {
        let PortOne { x: p } = self;
        p.try_recv()
    }
}

impl<T: Send> Peekable<T>  for PortOne<T> {
    fn peek(&self) -> bool {
        let &PortOne { x: ref p } = self;
        p.peek()
    }
}

impl<T: Send> GenericChan<T> for Chan<T> {
    fn send(&self, val: T) {
        let &Chan { x: ref c } = self;
        c.send(val)
    }
}

impl<T: Send> GenericSmartChan<T> for Chan<T> {
    fn try_send(&self, val: T) -> bool {
        let &Chan { x: ref c } = self;
        c.try_send(val)
    }
}

impl<T: Send> SendDeferred<T> for Chan<T> {
    fn send_deferred(&self, val: T) {
        let &Chan { x: ref c } = self;
        c.send_deferred(val)
    }

    fn try_send_deferred(&self, val: T) -> bool {
        let &Chan { x: ref c } = self;
        c.try_send_deferred(val)
    }
}

impl<T: Send> GenericPort<T> for Port<T> {
    fn recv(&self) -> T {
        let &Port { x: ref p } = self;
        p.recv()
    }

    fn try_recv(&self) -> Option<T> {
        let &Port { x: ref p } = self;
        p.try_recv()
    }
}

impl<T: Send> Peekable<T> for Port<T> {
    fn peek(&self) -> bool {
        let &Port { x: ref p } = self;
        p.peek()
    }
}

pub struct SharedChan<T> { /* priv */ x: rtcomm::SharedChan<T> }

impl<T: Send> SharedChan<T> {
    pub fn new(c: Chan<T>) -> SharedChan<T> {
        let Chan { x: c } = c;
        SharedChan { x: rtcomm::SharedChan::new(c) }
    }
}

impl<T: Send> GenericChan<T> for SharedChan<T> {
    fn send(&self, val: T) {
        let &SharedChan { x: ref c } = self;
        c.send(val)
    }
}

impl<T: Send> GenericSmartChan<T> for SharedChan<T> {
    fn try_send(&self, val: T) -> bool {
        let &SharedChan { x: ref c } = self;
        c.try_send(val)
    }
}

impl<T: Send> SendDeferred<T> for SharedChan<T> {
    fn send_deferred(&self, val: T) {
        let &SharedChan { x: ref c } = self;
        c.send_deferred(val)
    }

    fn try_send_deferred(&self, val: T) -> bool {
        let &SharedChan { x: ref c } = self;
        c.try_send_deferred(val)
    }
}

impl<T: Send> Clone for SharedChan<T> {
    fn clone(&self) -> SharedChan<T> {
        let &SharedChan { x: ref c } = self;
        SharedChan { x: c.clone() }
    }
}

pub struct SharedPort<T> { /* priv */ x: rtcomm::SharedPort<T> }

impl<T: Send> SharedPort<T> {
    pub fn new(p: Port<T>) -> SharedPort<T> {
        let Port { x: p } = p;
        SharedPort { x: rtcomm::SharedPort::new(p) }
    }
}

impl<T: Send> GenericPort<T> for SharedPort<T> {
    fn recv(&self) -> T {
        let &SharedPort { x: ref p } = self;
        p.recv()
    }

    fn try_recv(&self) -> Option<T> {
        let &SharedPort { x: ref p } = self;
        p.try_recv()
    }
}

impl<T: Send> Clone for SharedPort<T> {
    fn clone(&self) -> SharedPort<T> {
        let &SharedPort { x: ref p } = self;
        SharedPort { x: p.clone() }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add example demonstrating min/max window dimension constraints.<commit_after>#[cfg(target_os = "android")]
#[macro_use]
extern crate android_glue;

extern crate winit;

#[cfg(target_os = "android")]
android_start!(main);

fn resize_callback(width: u32, height: u32) {
    println!("Window resized to {}x{}", width, height);
}

fn main() {
    let window = winit::WindowBuilder::new()
        .with_title("A fantastic window!")
        .with_window_resize_callback(resize_callback)
        .with_min_dimensions(400, 200)
        .with_max_dimensions(800, 400)
        .build()
        .unwrap();

    for event in window.wait_events() {
        println!("{:?}", event);

        match event {
            winit::Event::Closed => break,
            _ => ()
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Added "Hello world!" example<commit_after>extern crate piston_meta;
extern crate range;

use std::rc::Rc;
use piston_meta::*;

fn main() {
    let text = "foo \"Hello world!\"";
    let chars: Vec<char> = text.chars().collect();
    let mut tokenizer = Tokenizer::new();
    let s = TokenizerState::new();
    let foo: Rc<String> = Rc::new("foo".into());
    let text = Text {
        allow_empty: true,
        property: Some(foo.clone())
    };
    let _ = text.parse(&mut tokenizer, &s, &chars[4..], 4);
    assert_eq!(tokenizer.tokens.len(), 1);
    if let &MetaData::String(_, ref hello) = &tokenizer.tokens[0].0 {
        println!("{}", hello);
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2015, Nathan Zadoks <nathan@nathan7.eu>
// See the LICENSE file included in this distribution.
extern crate libc;
use core::prelude::*;
use self::libc::{c_void, c_int, size_t};
use self::libc::{mmap, mprotect, munmap};
use self::libc::MAP_FAILED;
use super::page_size;

use core::ptr;

#[cold]
#[inline(never)]
pub fn sys_page_size() -> usize {
  unsafe {
    libc::sysconf(libc::_SC_PAGESIZE) as usize
  }
}

const GUARD_PROT:  c_int = libc::PROT_NONE;
const STACK_PROT:  c_int = libc::PROT_READ
                         | libc::PROT_WRITE;
const STACK_FLAGS: c_int = libc::MAP_STACK
                         | libc::MAP_PRIVATE
                         | libc::MAP_ANON;

pub unsafe fn map_stack(len: usize) -> Option<*mut u8> {
  let ptr = mmap(ptr::null_mut(), len as size_t,
                 STACK_PROT, STACK_FLAGS, -1, 0);
  if ptr != MAP_FAILED {
    Some(ptr as *mut u8)
  }
  else {
    None
  }
}

pub unsafe fn protect_stack(ptr: *mut u8) -> bool {
  mprotect(ptr as *mut c_void, page_size() as size_t, GUARD_PROT) == 0
}

pub unsafe fn unmap_stack(ptr: *mut u8, len: usize) -> bool {
  munmap(ptr as *mut c_void, len as size_t) == 0
}
<commit_msg>add FreeBSD + DragonFlyBSD MAP_STACK workaround<commit_after>// Copyright (c) 2015, Nathan Zadoks <nathan@nathan7.eu>
// See the LICENSE file included in this distribution.
extern crate libc;
use core::prelude::*;
use self::libc::{c_void, c_int, size_t};
use self::libc::{mmap, mprotect, munmap};
use self::libc::MAP_FAILED;
use super::page_size;

use core::ptr;

#[cold]
#[inline(never)]
pub fn sys_page_size() -> usize {
  unsafe {
    libc::sysconf(libc::_SC_PAGESIZE) as usize
  }
}

const GUARD_PROT:  c_int = libc::PROT_NONE;
const STACK_PROT:  c_int = libc::PROT_READ
                         | libc::PROT_WRITE;
#[cfg(not(any(target_os = "freebsd", target_os = "dragonfly")))]
const STACK_FLAGS: c_int = libc::MAP_STACK
                         | libc::MAP_PRIVATE
                         | libc::MAP_ANON;
// workaround for http://lists.freebsd.org/pipermail/freebsd-bugs/2011-July/044840.html
// according to libgreen, DragonFlyBSD suffers from this too
#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
const STACK_FLAGS: c_int = libc::MAP_PRIVATE
                         | libc::MAP_ANON;

pub unsafe fn map_stack(len: usize) -> Option<*mut u8> {
  let ptr = mmap(ptr::null_mut(), len as size_t,
                 STACK_PROT, STACK_FLAGS, -1, 0);
  if ptr != MAP_FAILED {
    Some(ptr as *mut u8)
  }
  else {
    None
  }
}

pub unsafe fn protect_stack(ptr: *mut u8) -> bool {
  mprotect(ptr as *mut c_void, page_size() as size_t, GUARD_PROT) == 0
}

pub unsafe fn unmap_stack(ptr: *mut u8, len: usize) -> bool {
  munmap(ptr as *mut c_void, len as size_t) == 0
}
<|endoftext|>


<commit_before>use collections::VecDeque;
// Temporary hack until libredox get hashmaps
use redox::*;

#[derive(Clone, PartialEq, Copy, Hash)]
pub enum InsertMode {
    Append,
    Insert,
    Replace,
}

#[derive(Clone, PartialEq, Copy, Hash)]
pub struct InsertOptions {
    mode: InsertMode,
}

/// A mode
#[derive(Clone, PartialEq, Copy, Hash)]
pub enum Mode {
    /// A primitive mode (no repeat, no delimiters, no preprocessing)
    Primitive(PrimitiveMode),
    /// Command mode
    Command(CommandMode),
}

#[derive(Clone, PartialEq, Copy, Hash)]
/// A command mode
pub enum CommandMode {
//    Visual(VisualOptions),
    /// Normal mode
    Normal,
}

#[derive(Clone, PartialEq, Copy, Hash)]
/// A primitive mode
pub enum PrimitiveMode {
    /// Insert mode
    Insert(InsertOptions),
}

#[derive(Clone, PartialEq, Hash)]
pub enum Unit {
    /// Single [repeated] instruction
    Inst(u16, char),
    /// Multiple instructions
    Block(u16, Vec<Unit>),
}

#[derive(Clone, PartialEq, Hash)]
/// The state of the editor
pub struct State {
    /// The current cursor
    pub current_cursor: u8,
    /// The cursors
    pub cursors: Vec<Cursor>,
    /// The text (document)
    pub text: VecDeque<VecDeque<char>>,
    /// The x coordinate of the scroll
    pub scroll_x: u32,
    /// The y coordinate of the scroll
    pub scroll_y: u32,
}

impl State {
    fn insert(&mut self, c: char) {

    }
    fn new() -> State {
        State {
            current_cursor: 0,
            cursors: Vec::new(),
            text: VecDeque::new(),
            scroll_x: 0,
            scroll_y: 0,
        }
    }
}

/// A command char
#[derive(Clone, Copy, Hash, PartialEq)]
pub enum CommandChar {
    /// A char
    Char(char),
    /// A wildcard
    Wildcard,
}

/// The editor
pub struct Editor {
    /// The state of the editor
    pub state: State,
}

impl Editor {
    pub fn new() -> Self {
        Editor {
            state: State::new(),
        }
    }

    pub fn exec(&mut self, cmd: &Unit) {

        match *cmd {
            Unit::Inst(n, ref c) => {
                // Execute commands
            },
            Unit::Block(n, ref units) => {
                for _ in 1..n {
                    for i in units {
                        self.exec(&i);
                    }
                }
            },
        }
    }
}

#[derive(Clone, PartialEq, Hash)]
/// A cursor
pub struct Cursor {
    /// The x coordinate of the cursor
    pub x: u32,
    /// The y coordinate of the cursor
    pub y: u32,
    /// The mode of the cursor
    pub mode: Mode,
    /// The history of the cursor
    pub history: Vec<Unit>,
}

/// An iterator over units
pub struct UnitIterator<'a, I: Iterator<Item = char> + 'a> {
    /// The iterator over the chars
    char_iter: &'a mut I,
    /// The state
    state: &'a mut State,
}

impl<'a, I: Iterator<Item = char> + 'a> Iterator for UnitIterator<'a, I> {
    type Item = Unit;

    fn next(&mut self) -> Option<Unit> {
        match self.state.cursors[self.state.current_cursor as usize].mode {
            Mode::Primitive(_) => Some(Unit::Inst(1, match self.char_iter.next() {
                Some(c) => c,
                None => return None,
            })),
            Mode::Command(_) => {
                let mut ch = self.char_iter.next().unwrap_or('\0');
                let mut n = 1;

                let mut unset = true;
                for c in *self.char_iter {
                    n = match c {
                        '0' if n != 0 => n * 10,
                        '1'           => n * 10 + 1,
                        '2'           => n * 10 + 2,
                        '3'           => n * 10 + 3,
                        '4'           => n * 10 + 4,
                        '5'           => n * 10 + 5,
                        '6'           => n * 10 + 6,
                        '7'           => n * 10 + 7,
                        '8'           => n * 10 + 8,
                        '9'           => n * 10 + 9,
                        _             => {
                            ch = c;
                            break;
                        },
                    };

                    if unset {
                        unset = false;
                        n     = 0;
                    }
                }

                if ch == '(' {
                    let mut level = 0;
                    let mut vec = self.char_iter.take_while(|c| {
                        level = match *c {
                            '(' => level + 1,
                            ')' => level - 1,
                            ';' => 0,
                            _ => level,
                        };
                        level != 0
                    }).skip(1).collect::<Vec<_>>();
                    vec.pop();
                    Some(Unit::Block(n, vec.into_iter().unit_iter(&mut self.state).collect()))
                } else if let Some(ch) = self.char_iter.next() {
                    Some(Unit::Inst(n, ch))
                } else {
                    None
                }
            }
        }
    }
}

pub trait ToUnitIterator<'a>: Iterator<Item = char> + 'a {
    /// Create a iterator of the unit given by the chars
    fn unit_iter(&'a mut self, state: &'a mut State) -> UnitIterator<'a, Self>;
}

impl<'a, I: Iterator<Item = char> + 'a> ToUnitIterator<'a> for I {
    fn unit_iter(&'a mut self, state: &'a mut State) -> UnitIterator<'a, I> {
        UnitIterator {
            char_iter: self,
            state: state,
        }
    }
}
<commit_msg>Die errors die<commit_after>use collections::VecDeque;
// Temporary hack until libredox get hashmaps
use redox::*;

#[derive(Clone, PartialEq, Copy, Hash)]
pub enum InsertMode {
    Append,
    Insert,
    Replace,
}

#[derive(Clone, PartialEq, Copy, Hash)]
pub struct InsertOptions {
    mode: InsertMode,
}

/// A mode
#[derive(Clone, PartialEq, Copy, Hash)]
pub enum Mode {
    /// A primitive mode (no repeat, no delimiters, no preprocessing)
    Primitive(PrimitiveMode),
    /// Command mode
    Command(CommandMode),
}

#[derive(Clone, PartialEq, Copy, Hash)]
/// A command mode
pub enum CommandMode {
//    Visual(VisualOptions),
    /// Normal mode
    Normal,
}

#[derive(Clone, PartialEq, Copy, Hash)]
/// A primitive mode
pub enum PrimitiveMode {
    /// Insert mode
    Insert(InsertOptions),
}

#[derive(Clone, PartialEq, Hash)]
pub enum Unit {
    /// Single [repeated] instruction
    Inst(u16, char),
    /// Multiple instructions
    Block(u16, Vec<Unit>),
}

#[derive(Clone, PartialEq, Hash)]
/// The state of the editor
pub struct State {
    /// The current cursor
    pub current_cursor: u8,
    /// The cursors
    pub cursors: Vec<Cursor>,
    /// The text (document)
    pub text: VecDeque<VecDeque<char>>,
    /// The x coordinate of the scroll
    pub scroll_x: u32,
    /// The y coordinate of the scroll
    pub scroll_y: u32,
}

impl State {
    fn insert(&mut self, c: char) {

    }
    fn new() -> State {
        State {
            current_cursor: 0,
            cursors: Vec::new(),
            text: VecDeque::new(),
            scroll_x: 0,
            scroll_y: 0,
        }
    }
}

/// A command char
#[derive(Clone, Copy, Hash, PartialEq)]
pub enum CommandChar {
    /// A char
    Char(char),
    /// A wildcard
    Wildcard,
}

/// The editor
pub struct Editor {
    /// The state of the editor
    pub state: State,
}

impl Editor {
    pub fn new() -> Self {
        Editor {
            state: State::new(),
        }
    }

    pub fn exec(&mut self, cmd: &Unit) {

        match *cmd {
            Unit::Inst(n, ref c) => {
                // Execute commands
            },
            Unit::Block(n, ref units) => {
                for _ in 1..n {
                    for i in units {
                        self.exec(&i);
                    }
                }
            },
        }
    }
}

#[derive(Clone, PartialEq, Hash)]
/// A cursor
pub struct Cursor {
    /// The x coordinate of the cursor
    pub x: u32,
    /// The y coordinate of the cursor
    pub y: u32,
    /// The mode of the cursor
    pub mode: Mode,
    /// The history of the cursor
    pub history: Vec<Unit>,
}

/// An iterator over units
pub struct UnitIterator<'a, I: Iterator<Item = char> + 'a> {
    /// The iterator over the chars
    char_iter: &'a mut I,
    /// The state
    state: &'a mut State,
}

impl<'a, I: Iterator<Item = char> + 'a> Iterator for UnitIterator<'a, I> {
    type Item = Unit;

    fn next(&mut self) -> Option<Unit> {
        match self.state.cursors[self.state.current_cursor as usize].mode {
            Mode::Primitive(_) => Some(Unit::Inst(1, match self.char_iter.next() {
                Some(c) => c,
                None => return None,
            })),
            Mode::Command(_) => {
                let mut ch = self.char_iter.next().unwrap_or('\0');
                let mut n = 1;

                let mut unset = true;
                for c in self.char_iter {
                    n = match c {
                        '0' if n != 0 => n * 10,
                        '1'           => n * 10 + 1,
                        '2'           => n * 10 + 2,
                        '3'           => n * 10 + 3,
                        '4'           => n * 10 + 4,
                        '5'           => n * 10 + 5,
                        '6'           => n * 10 + 6,
                        '7'           => n * 10 + 7,
                        '8'           => n * 10 + 8,
                        '9'           => n * 10 + 9,
                        r             => {
                            ch = r;
                            break;
                        },
                    };

                    if unset {
                        unset = false;
                        n     = 0;
                    }
                }

                if ch == '(' {
                    let mut level = 0;
                    let mut vec = self.char_iter.take_while(|c| {
                        level = match *c {
                            '(' => level + 1,
                            ')' => level - 1,
                            ';' => 0,
                            _ => level,
                        };
                        level != 0
                    }).skip(1).collect::<Vec<_>>();
                    vec.pop();
                    Some(Unit::Block(n, vec.into_iter().unit_iter(&mut self.state).collect()))
                } else if let Some(ch) = self.char_iter.next() {
                    Some(Unit::Inst(n, ch))
                } else {
                    None
                }
            }
        }
    }
}

pub trait ToUnitIterator<'a>: Iterator<Item = char> + 'a {
    /// Create a iterator of the unit given by the chars
    fn unit_iter(&'a mut self, state: &'a mut State) -> UnitIterator<'a, Self>;
}

impl<'a, I: Iterator<Item = char> + 'a> ToUnitIterator<'a> for I {
    fn unit_iter(&'a mut self, state: &'a mut State) -> UnitIterator<'a, I> {
        UnitIterator {
            char_iter: self,
            state: state,
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>add multi consumers example<commit_after>extern crate env_logger;
extern crate lapin_futures as lapin;
#[macro_use]
extern crate log;
extern crate futures;
extern crate tokio;

use futures::future::Future;
use futures::Stream;
use tokio::io::{AsyncRead, AsyncWrite};
use tokio::net::TcpStream;
use lapin::types::FieldTable;
use lapin::client::{Client, ConnectionOptions};
use lapin::channel::{BasicConsumeOptions, BasicProperties, BasicPublishOptions, ConfirmSelectOptions, QueueDeclareOptions};

fn create_consumer<T: AsyncRead + AsyncWrite + Sync + Send + 'static>(client: &Client<T>, n: u8) -> Box<Future<Item = (), Error = ()> + Send + 'static> {
    info!("will create consumer {}", n);

    let queue = format!("test-queue-{}", n);

    Box::new(
        client.create_confirm_channel(ConfirmSelectOptions::default()).and_then(move |channel| {
            channel.queue_declare(&queue, &QueueDeclareOptions::default(), &FieldTable::new()).map(move |_| (channel, queue.clone()))
        }).and_then(move |(channel, queue)| {
            info!("creating consumer {}", n);
            channel.basic_consume(&queue, "", &BasicConsumeOptions::default(), &FieldTable::new()).map(move |stream| (channel, stream))
        }).and_then(move |(channel, stream)| {
            info!("got stream for consumer {}", n);
            stream.for_each(move |message| {
                println!("consumer '{}' got '{}'", n, std::str::from_utf8(&message.data).unwrap());
                channel.basic_ack(message.delivery_tag)
            })
        }).map_err(move |err| {
            eprintln!("got error in consumer '{}': {:?}", n, err)
        })
    )
}

fn main() {
    env_logger::init();

    let addr = "127.0.0.1:5672".parse().unwrap();

    tokio::run(
        TcpStream::connect(&addr).and_then(|stream| {
            Client::connect(stream, &ConnectionOptions {
                frame_max: 65535,
                ..Default::default()
            })
        }).and_then(|(client, heartbeat)| {
            tokio::spawn(heartbeat.map_err(|e| eprintln!("heartbeat error: {:?}", e)));

            for n in 1..9 {
                tokio::spawn(create_consumer(&client, n));
            }

            client.create_confirm_channel(ConfirmSelectOptions::default()).and_then(move |channel| {
                futures::stream::iter_ok((1..9).flat_map(|c| {
                    (1..6).map(move |m| (c, m))
                })).for_each(move |(c, m)| {
                    let queue   = format!("test-queue-{}", c);
                    let message = format!("message {} for consumer {}", m, c);
                    let channel = channel.clone();

                    info!("will publish {}", message);

                    channel.queue_declare(&queue, &QueueDeclareOptions::default(), &FieldTable::new()).and_then(move |_| {
                        channel.basic_publish("", &queue, message.as_str().as_bytes(), &BasicPublishOptions::default(), BasicProperties::default()).map(move |confirmation| {
                            println!("got confirmation (consumer {}, message {}): {:?}", c, m, confirmation);
                        })
                    })
                })
            })
        }).map_err(|err| {
            eprintln!("error: {:?}", err)
        })
    );
}
<|endoftext|>


<commit_before><commit_msg>Add coordinates module file.<commit_after>use std::convert::From;

//use smallvec::SmallVec;

pub trait Coordinate {

    // type CoordinateSmallVec;
    // type CoordinateOptionSmallVec;

    fn as_cartesian_2d(&self) -> Cartesian2DCoordinate;
}

#[derive(Hash, Eq, PartialEq, Copy, Clone, Debug, Ord, PartialOrd)]
pub struct Cartesian2DCoordinate {
    pub x: u32,
    pub y: u32,
}
impl Cartesian2DCoordinate {
    pub fn new(x: u32, y: u32) -> Cartesian2DCoordinate {
        Cartesian2DCoordinate { x: x, y: y }
    }
}
impl Coordinate for Cartesian2DCoordinate {

    // type CoordinateSmallVec = SmallVec<[Cartesian2DCoordinate; 4]>;
    // type CoordinateOptionSmallVec = SmallVec<[Option<Cartesian2DCoordinate>; 4]>;

    fn as_cartesian_2d(&self) -> Cartesian2DCoordinate {
        self.clone()
    }
}
impl From<(u32, u32)> for Cartesian2DCoordinate {
    fn from(x_y_pair: (u32, u32)) -> Cartesian2DCoordinate {
        Cartesian2DCoordinate::new(x_y_pair.0, x_y_pair.1)
    }
}
<|endoftext|>


<commit_before><commit_msg>Add regression test<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.

#![allow(unused)]

fn main() {
    let x = 0;
    macro_rules! foo { () => {
        assert_eq!(x, 0);
    } }

    let x = 1;
    foo!();
}
<|endoftext|>


<commit_before>// -*- rust -*-

use std;
import std::map;
import std::str;
import std::uint;
import std::util;

fn test_simple() {
  log "*** starting test_simple";

  fn eq_uint(&uint x, &uint y) -> bool { ret x == y; }
  fn hash_uint(&uint u) -> uint {
    // FIXME: can't use std::util::id since we'd be capturing a type param,
    // and presently we can't close items over type params.
    ret u;
  }

  let map::hashfn[uint] hasher_uint = hash_uint;
  let map::eqfn[uint] eqer_uint = eq_uint;

  let map::hashfn[str] hasher_str = str::hash;
  let map::eqfn[str] eqer_str = str::eq;

  log "uint -> uint";

  let map::hashmap[uint, uint] hm_uu =
      map::mk_hashmap[uint, uint](hasher_uint, eqer_uint);

  assert (hm_uu.insert(10u, 12u));
  assert (hm_uu.insert(11u, 13u));
  assert (hm_uu.insert(12u, 14u));

  assert (hm_uu.get(11u) == 13u);
  assert (hm_uu.get(12u) == 14u);
  assert (hm_uu.get(10u) == 12u);

  assert (!hm_uu.insert(12u, 14u));
  assert (hm_uu.get(12u) == 14u);

  assert (!hm_uu.insert(12u, 12u));
  assert (hm_uu.get(12u) == 12u);

  let str ten = "ten";
  let str eleven = "eleven";
  let str twelve = "twelve";

  log "str -> uint";

  let map::hashmap[str, uint] hm_su = map::mk_hashmap[str, uint](hasher_str,
                                                               eqer_str);
  assert (hm_su.insert("ten", 12u));
  assert (hm_su.insert(eleven, 13u));
  assert (hm_su.insert("twelve", 14u));

  assert (hm_su.get(eleven) == 13u);

  assert (hm_su.get("eleven") == 13u);
  assert (hm_su.get("twelve") == 14u);
  assert (hm_su.get("ten") == 12u);

  assert (!hm_su.insert("twelve", 14u));
  assert (hm_su.get("twelve") == 14u);

  assert (!hm_su.insert("twelve", 12u));
  assert (hm_su.get("twelve") == 12u);

  log "uint -> str";

  let map::hashmap[uint, str] hm_us = map::mk_hashmap[uint, str](hasher_uint,
                                                               eqer_uint);

  assert (hm_us.insert(10u, "twelve"));
  assert (hm_us.insert(11u, "thirteen"));
  assert (hm_us.insert(12u, "fourteen"));

  assert (str::eq(hm_us.get(11u), "thirteen"));
  assert (str::eq(hm_us.get(12u), "fourteen"));
  assert (str::eq(hm_us.get(10u), "twelve"));

  assert (!hm_us.insert(12u, "fourteen"));
  assert (str::eq(hm_us.get(12u), "fourteen"));

  assert (!hm_us.insert(12u, "twelve"));
  assert (str::eq(hm_us.get(12u), "twelve"));

  log "str -> str";

  let map::hashmap[str, str] hm_ss = map::mk_hashmap[str, str](hasher_str,
                                                             eqer_str);

  assert (hm_ss.insert(ten, "twelve"));
  assert (hm_ss.insert(eleven, "thirteen"));
  assert (hm_ss.insert(twelve, "fourteen"));

  assert (str::eq(hm_ss.get("eleven"), "thirteen"));
  assert (str::eq(hm_ss.get("twelve"), "fourteen"));
  assert (str::eq(hm_ss.get("ten"), "twelve"));

  assert (!hm_ss.insert("twelve", "fourteen"));
  assert (str::eq(hm_ss.get("twelve"), "fourteen"));

  assert (!hm_ss.insert("twelve", "twelve"));
  assert (str::eq(hm_ss.get("twelve"), "twelve"));

  log "*** finished test_simple";
}

/**
 * Force map growth and rehashing.
 */
fn test_growth() {
  log "*** starting test_growth";

  let uint num_to_insert = 64u;

  fn eq_uint(&uint x, &uint y) -> bool { ret x == y; }
  fn hash_uint(&uint u) -> uint {
    // FIXME: can't use std::util::id since we'd be capturing a type param,
    // and presently we can't close items over type params.
    ret u;
  }

  log "uint -> uint";

  let map::hashfn[uint] hasher_uint = hash_uint;
  let map::eqfn[uint] eqer_uint = eq_uint;
  let map::hashmap[uint, uint] hm_uu =
      map::mk_hashmap[uint, uint](hasher_uint, eqer_uint);

  let uint i = 0u;
  while (i < num_to_insert) {
    assert (hm_uu.insert(i, i * i));
    log "inserting " + uint::to_str(i, 10u)
      + " -> " + uint::to_str(i * i, 10u);
    i += 1u;
  }

  log "-----";

  i = 0u;
  while (i < num_to_insert) {
    log "get(" + uint::to_str(i, 10u) + ") = "
      + uint::to_str(hm_uu.get(i), 10u);
    assert (hm_uu.get(i) == i * i);
    i += 1u;
  }

  assert (hm_uu.insert(num_to_insert, 17u));
  assert (hm_uu.get(num_to_insert) == 17u);

  log "-----";

  hm_uu.rehash();

  i = 0u;
  while (i < num_to_insert) {
    log "get(" + uint::to_str(i, 10u) + ") = "
      + uint::to_str(hm_uu.get(i), 10u);
    assert (hm_uu.get(i) == i * i);
    i += 1u;
  }

  log "str -> str";

  let map::hashfn[str] hasher_str = str::hash;
  let map::eqfn[str] eqer_str = str::eq;
  let map::hashmap[str, str] hm_ss = map::mk_hashmap[str, str](hasher_str,
                                                             eqer_str);

  i = 0u;
  while (i < num_to_insert) {
    assert (hm_ss.insert(uint::to_str(i, 2u), uint::to_str(i * i, 2u)));
    log "inserting \"" + uint::to_str(i, 2u)
      + "\" -> \"" + uint::to_str(i * i, 2u) + "\"";
    i += 1u;
  }

  log "-----";

  i = 0u;
  while (i < num_to_insert) {
    log "get(\""
      + uint::to_str(i, 2u)
      + "\") = \""
      + hm_ss.get(uint::to_str(i, 2u)) + "\"";

    assert (str::eq(hm_ss.get(uint::to_str(i, 2u)),
                   uint::to_str(i * i, 2u)));
    i += 1u;
  }

  assert (hm_ss.insert(uint::to_str(num_to_insert, 2u),
                      uint::to_str(17u, 2u)));

  assert (str::eq(hm_ss.get(uint::to_str(num_to_insert, 2u)),
                 uint::to_str(17u, 2u)));

  log "-----";

  hm_ss.rehash();

  i = 0u;
  while (i < num_to_insert) {
    log "get(\"" + uint::to_str(i, 2u) + "\") = \""
      + hm_ss.get(uint::to_str(i, 2u)) + "\"";
    assert (str::eq(hm_ss.get(uint::to_str(i, 2u)),
                   uint::to_str(i * i, 2u)));
    i += 1u;
  }

  log "*** finished test_growth";
}

fn test_removal() {
  log "*** starting test_removal";

  let uint num_to_insert = 64u;

  fn eq(&uint x, &uint y) -> bool { ret x == y; }
  fn hash(&uint u) -> uint {
    // This hash function intentionally causes collisions between
    // consecutive integer pairs.
    ret (u / 2u) * 2u;
  }

  assert (hash(0u) == hash(1u));
  assert (hash(2u) == hash(3u));
  assert (hash(0u) != hash(2u));

  let map::hashfn[uint] hasher = hash;
  let map::eqfn[uint] eqer = eq;
  let map::hashmap[uint, uint] hm = map::mk_hashmap[uint, uint](hasher, eqer);

  let uint i = 0u;
  while (i < num_to_insert) {
    assert (hm.insert(i, i * i));
    log "inserting " + uint::to_str(i, 10u)
      + " -> " + uint::to_str(i * i, 10u);
    i += 1u;
  }

  assert (hm.size() == num_to_insert);

  log "-----";
  log "removing evens";

  i = 0u;
  while (i < num_to_insert) {
    /**
     * FIXME (issue #150): we want to check the removed value as in the
     * following:

    let util.option[uint] v = hm.remove(i);
    alt (v) {
      case (util.some[uint](u)) {
        assert (u == (i * i));
      }
      case (util.none[uint]()) { fail; }
    }

     * but we util.option is a tag type so util.some and util.none are
     * off limits until we parse the dwarf for tag types.
     */

    hm.remove(i);
    i += 2u;
  }

  assert (hm.size() == (num_to_insert / 2u));

  log "-----";

  i = 1u;
  while (i < num_to_insert) {
    log "get(" + uint::to_str(i, 10u) + ") = "
      + uint::to_str(hm.get(i), 10u);
    assert (hm.get(i) == i * i);
    i += 2u;
  }

  log "-----";
  log "rehashing";

  hm.rehash();

  log "-----";

  i = 1u;
  while (i < num_to_insert) {
    log "get(" + uint::to_str(i, 10u) + ") = "
      + uint::to_str(hm.get(i), 10u);
    assert (hm.get(i) == i * i);
    i += 2u;
  }

  log "-----";

  i = 0u;
  while (i < num_to_insert) {
    assert (hm.insert(i, i * i));
    log "inserting " + uint::to_str(i, 10u)
      + " -> " + uint::to_str(i * i, 10u);
    i += 2u;
  }

  assert (hm.size() == num_to_insert);

  log "-----";

  i = 0u;
  while (i < num_to_insert) {
    log "get(" + uint::to_str(i, 10u) + ") = "
      + uint::to_str(hm.get(i), 10u);
    assert (hm.get(i) == i * i);
    i += 1u;
  }

  log "-----";
  log "rehashing";

  hm.rehash();

  log "-----";

  assert (hm.size() == num_to_insert);

  i = 0u;
  while (i < num_to_insert) {
    log "get(" + uint::to_str(i, 10u) + ") = "
      + uint::to_str(hm.get(i), 10u);
    assert (hm.get(i) == i * i);
    i += 1u;
  }

  log "*** finished test_removal";
}

fn main() {
  test_simple();
  test_growth();
  test_removal();
}
<commit_msg>stdlib: Add regression tests for std::map<commit_after>// -*- rust -*-

use std;
import std::map;
import std::str;
import std::uint;
import std::util;

fn test_simple() {
  log "*** starting test_simple";

  fn eq_uint(&uint x, &uint y) -> bool { ret x == y; }
  fn hash_uint(&uint u) -> uint {
    // FIXME: can't use std::util::id since we'd be capturing a type param,
    // and presently we can't close items over type params.
    ret u;
  }

  let map::hashfn[uint] hasher_uint = hash_uint;
  let map::eqfn[uint] eqer_uint = eq_uint;

  let map::hashfn[str] hasher_str = str::hash;
  let map::eqfn[str] eqer_str = str::eq;

  log "uint -> uint";

  let map::hashmap[uint, uint] hm_uu =
      map::mk_hashmap[uint, uint](hasher_uint, eqer_uint);

  assert (hm_uu.insert(10u, 12u));
  assert (hm_uu.insert(11u, 13u));
  assert (hm_uu.insert(12u, 14u));

  assert (hm_uu.get(11u) == 13u);
  assert (hm_uu.get(12u) == 14u);
  assert (hm_uu.get(10u) == 12u);

  assert (!hm_uu.insert(12u, 14u));
  assert (hm_uu.get(12u) == 14u);

  assert (!hm_uu.insert(12u, 12u));
  assert (hm_uu.get(12u) == 12u);

  let str ten = "ten";
  let str eleven = "eleven";
  let str twelve = "twelve";

  log "str -> uint";

  let map::hashmap[str, uint] hm_su = map::mk_hashmap[str, uint](hasher_str,
                                                               eqer_str);
  assert (hm_su.insert("ten", 12u));
  assert (hm_su.insert(eleven, 13u));
  assert (hm_su.insert("twelve", 14u));

  assert (hm_su.get(eleven) == 13u);

  assert (hm_su.get("eleven") == 13u);
  assert (hm_su.get("twelve") == 14u);
  assert (hm_su.get("ten") == 12u);

  assert (!hm_su.insert("twelve", 14u));
  assert (hm_su.get("twelve") == 14u);

  assert (!hm_su.insert("twelve", 12u));
  assert (hm_su.get("twelve") == 12u);

  log "uint -> str";

  let map::hashmap[uint, str] hm_us = map::mk_hashmap[uint, str](hasher_uint,
                                                               eqer_uint);

  assert (hm_us.insert(10u, "twelve"));
  assert (hm_us.insert(11u, "thirteen"));
  assert (hm_us.insert(12u, "fourteen"));

  assert (str::eq(hm_us.get(11u), "thirteen"));
  assert (str::eq(hm_us.get(12u), "fourteen"));
  assert (str::eq(hm_us.get(10u), "twelve"));

  assert (!hm_us.insert(12u, "fourteen"));
  assert (str::eq(hm_us.get(12u), "fourteen"));

  assert (!hm_us.insert(12u, "twelve"));
  assert (str::eq(hm_us.get(12u), "twelve"));

  log "str -> str";

  let map::hashmap[str, str] hm_ss = map::mk_hashmap[str, str](hasher_str,
                                                             eqer_str);

  assert (hm_ss.insert(ten, "twelve"));
  assert (hm_ss.insert(eleven, "thirteen"));
  assert (hm_ss.insert(twelve, "fourteen"));

  assert (str::eq(hm_ss.get("eleven"), "thirteen"));
  assert (str::eq(hm_ss.get("twelve"), "fourteen"));
  assert (str::eq(hm_ss.get("ten"), "twelve"));

  assert (!hm_ss.insert("twelve", "fourteen"));
  assert (str::eq(hm_ss.get("twelve"), "fourteen"));

  assert (!hm_ss.insert("twelve", "twelve"));
  assert (str::eq(hm_ss.get("twelve"), "twelve"));

  log "*** finished test_simple";
}

/**
 * Force map growth and rehashing.
 */
fn test_growth() {
  log "*** starting test_growth";

  let uint num_to_insert = 64u;

  fn eq_uint(&uint x, &uint y) -> bool { ret x == y; }
  fn hash_uint(&uint u) -> uint {
    // FIXME: can't use std::util::id since we'd be capturing a type param,
    // and presently we can't close items over type params.
    ret u;
  }

  log "uint -> uint";

  let map::hashfn[uint] hasher_uint = hash_uint;
  let map::eqfn[uint] eqer_uint = eq_uint;
  let map::hashmap[uint, uint] hm_uu =
      map::mk_hashmap[uint, uint](hasher_uint, eqer_uint);

  let uint i = 0u;
  while (i < num_to_insert) {
    assert (hm_uu.insert(i, i * i));
    log "inserting " + uint::to_str(i, 10u)
      + " -> " + uint::to_str(i * i, 10u);
    i += 1u;
  }

  log "-----";

  i = 0u;
  while (i < num_to_insert) {
    log "get(" + uint::to_str(i, 10u) + ") = "
      + uint::to_str(hm_uu.get(i), 10u);
    assert (hm_uu.get(i) == i * i);
    i += 1u;
  }

  assert (hm_uu.insert(num_to_insert, 17u));
  assert (hm_uu.get(num_to_insert) == 17u);

  log "-----";

  hm_uu.rehash();

  i = 0u;
  while (i < num_to_insert) {
    log "get(" + uint::to_str(i, 10u) + ") = "
      + uint::to_str(hm_uu.get(i), 10u);
    assert (hm_uu.get(i) == i * i);
    i += 1u;
  }

  log "str -> str";

  let map::hashfn[str] hasher_str = str::hash;
  let map::eqfn[str] eqer_str = str::eq;
  let map::hashmap[str, str] hm_ss = map::mk_hashmap[str, str](hasher_str,
                                                             eqer_str);

  i = 0u;
  while (i < num_to_insert) {
    assert (hm_ss.insert(uint::to_str(i, 2u), uint::to_str(i * i, 2u)));
    log "inserting \"" + uint::to_str(i, 2u)
      + "\" -> \"" + uint::to_str(i * i, 2u) + "\"";
    i += 1u;
  }

  log "-----";

  i = 0u;
  while (i < num_to_insert) {
    log "get(\""
      + uint::to_str(i, 2u)
      + "\") = \""
      + hm_ss.get(uint::to_str(i, 2u)) + "\"";

    assert (str::eq(hm_ss.get(uint::to_str(i, 2u)),
                   uint::to_str(i * i, 2u)));
    i += 1u;
  }

  assert (hm_ss.insert(uint::to_str(num_to_insert, 2u),
                      uint::to_str(17u, 2u)));

  assert (str::eq(hm_ss.get(uint::to_str(num_to_insert, 2u)),
                 uint::to_str(17u, 2u)));

  log "-----";

  hm_ss.rehash();

  i = 0u;
  while (i < num_to_insert) {
    log "get(\"" + uint::to_str(i, 2u) + "\") = \""
      + hm_ss.get(uint::to_str(i, 2u)) + "\"";
    assert (str::eq(hm_ss.get(uint::to_str(i, 2u)),
                   uint::to_str(i * i, 2u)));
    i += 1u;
  }

  log "*** finished test_growth";
}

fn test_removal() {
  log "*** starting test_removal";

  let uint num_to_insert = 64u;

  fn eq(&uint x, &uint y) -> bool { ret x == y; }
  fn hash(&uint u) -> uint {
    // This hash function intentionally causes collisions between
    // consecutive integer pairs.
    ret (u / 2u) * 2u;
  }

  assert (hash(0u) == hash(1u));
  assert (hash(2u) == hash(3u));
  assert (hash(0u) != hash(2u));

  let map::hashfn[uint] hasher = hash;
  let map::eqfn[uint] eqer = eq;
  let map::hashmap[uint, uint] hm = map::mk_hashmap[uint, uint](hasher, eqer);

  let uint i = 0u;
  while (i < num_to_insert) {
    assert (hm.insert(i, i * i));
    log "inserting " + uint::to_str(i, 10u)
      + " -> " + uint::to_str(i * i, 10u);
    i += 1u;
  }

  assert (hm.size() == num_to_insert);

  log "-----";
  log "removing evens";

  i = 0u;
  while (i < num_to_insert) {
    /**
     * FIXME (issue #150): we want to check the removed value as in the
     * following:

    let util.option[uint] v = hm.remove(i);
    alt (v) {
      case (util.some[uint](u)) {
        assert (u == (i * i));
      }
      case (util.none[uint]()) { fail; }
    }

     * but we util.option is a tag type so util.some and util.none are
     * off limits until we parse the dwarf for tag types.
     */

    hm.remove(i);
    i += 2u;
  }

  assert (hm.size() == (num_to_insert / 2u));

  log "-----";

  i = 1u;
  while (i < num_to_insert) {
    log "get(" + uint::to_str(i, 10u) + ") = "
      + uint::to_str(hm.get(i), 10u);
    assert (hm.get(i) == i * i);
    i += 2u;
  }

  log "-----";
  log "rehashing";

  hm.rehash();

  log "-----";

  i = 1u;
  while (i < num_to_insert) {
    log "get(" + uint::to_str(i, 10u) + ") = "
      + uint::to_str(hm.get(i), 10u);
    assert (hm.get(i) == i * i);
    i += 2u;
  }

  log "-----";

  i = 0u;
  while (i < num_to_insert) {
    assert (hm.insert(i, i * i));
    log "inserting " + uint::to_str(i, 10u)
      + " -> " + uint::to_str(i * i, 10u);
    i += 2u;
  }

  assert (hm.size() == num_to_insert);

  log "-----";

  i = 0u;
  while (i < num_to_insert) {
    log "get(" + uint::to_str(i, 10u) + ") = "
      + uint::to_str(hm.get(i), 10u);
    assert (hm.get(i) == i * i);
    i += 1u;
  }

  log "-----";
  log "rehashing";

  hm.rehash();

  log "-----";

  assert (hm.size() == num_to_insert);

  i = 0u;
  while (i < num_to_insert) {
    log "get(" + uint::to_str(i, 10u) + ") = "
      + uint::to_str(hm.get(i), 10u);
    assert (hm.get(i) == i * i);
    i += 1u;
  }

  log "*** finished test_removal";
}

fn test_contains_key() {
  auto key = "k";
  auto map = map::mk_hashmap[str, str](str::hash, str::eq);
  assert (!map.contains_key(key));
  map.insert(key, "val");
  assert (map.contains_key(key));
}

fn test_find() {
  auto key = "k";
  auto map = map::mk_hashmap[str, str](str::hash, str::eq);
  assert (std::option::is_none(map.find(key)));
  map.insert(key, "val");
  assert (std::option::get(map.find(key)) == "val");
}

fn main() {
  test_simple();
  test_growth();
  test_removal();
  test_contains_key();
  test_find();
}
<|endoftext|>