<commit_before>use std::kinds::marker::ContravariantLifetime;
use std::ptr;
use std::sync::Arc;

use texture::{mod, Texture};
use uniforms::Uniforms;
use {DisplayImpl, VertexBuffer, IndexBuffer, Program, DrawParameters, Surface};
use {FrameBufferObject};

use {vertex_buffer, index_buffer, program};
use {gl, context, libc};

/// Creates a framebuffer that allows you to draw on something.
pub struct FrameBuffer<'a> {
    display: Arc<DisplayImpl>,
    attachments: FramebufferAttachments,
    marker: ContravariantLifetime<'a>,
}

impl<'a> FrameBuffer<'a> {
    pub fn new<'a>(display: &::Display) -> FrameBuffer<'a> {
        FrameBuffer {
            display: display.context.clone(),
            attachments: FramebufferAttachments {
                colors: Vec::new(),
                depth: None,
                stencil: None
            },
            marker: ContravariantLifetime
        }
    }

    pub fn with_texture<T: 'a>(mut self, texture: &'a mut T) -> FrameBuffer<'a> where T: Texture {
        self.attachments.colors.push(texture::get_id(texture.get_implementation()));
        self
    }
}

impl<'a> Surface for FrameBuffer<'a> {
    fn clear_color(&mut self, red: f32, green: f32, blue: f32, alpha: f32) {
        clear_color(&self.display, Some(&self.attachments), red, green, blue, alpha)
    }

    fn clear_depth(&mut self, value: f32) {
        clear_depth(&self.display, Some(&self.attachments), value)
    }

    fn clear_stencil(&mut self, value: int) {
        clear_stencil(&self.display, Some(&self.attachments), value)
    }

    fn get_dimensions(&self) -> (uint, uint) {
        unimplemented!()
    }

    fn draw<V, U>(&mut self, vb: &::VertexBuffer<V>, ib: &::IndexBuffer, program: &::Program,
        uniforms: &U, draw_parameters: &::DrawParameters) where U: ::uniforms::Uniforms
    {
        draw(&self.display, Some(&self.attachments), vb, ib, program, uniforms, draw_parameters)
    }
}

#[deriving(Hash, Clone, PartialEq, Eq)]
pub struct FramebufferAttachments {
    colors: Vec<gl::types::GLuint>,
    depth: Option<gl::types::GLuint>,
    stencil: Option<gl::types::GLuint>,
}

/// Draws everything.
pub fn draw<V, U: Uniforms>(display: &Arc<DisplayImpl>,
    framebuffer: Option<&FramebufferAttachments>, vertex_buffer: &VertexBuffer<V>,
    index_buffer: &IndexBuffer, program: &Program, uniforms: &U, draw_parameters: &DrawParameters)
{
    let fbo_id = get_framebuffer(display, framebuffer);

    let (vb_id, vb_elementssize, vb_bindingsclone) = vertex_buffer::get_clone(vertex_buffer);
    let (ib_id, ib_elemcounts, ib_datatype, ib_primitives) =
        index_buffer::get_clone(index_buffer);
    let program_id = program::get_program_id(program);
    let uniforms = uniforms.to_binder();
    let uniforms_locations = program::get_uniforms_locations(program);
    let draw_parameters = draw_parameters.clone();

    let (tx, rx) = channel();

    display.context.exec(proc(gl, state, version, _) {
        unsafe {
            if state.draw_framebuffer != fbo_id {
                if version >= &context::GlVersion(3, 0) {
                    gl.BindFramebuffer(gl::DRAW_FRAMEBUFFER, fbo_id.unwrap_or(0));
                    state.draw_framebuffer = fbo_id.clone();
                } else {
                    gl.BindFramebufferEXT(gl::FRAMEBUFFER_EXT, fbo_id.unwrap_or(0));
                    state.draw_framebuffer = fbo_id.clone();
                    state.read_framebuffer = fbo_id.clone();
                }
            }

            // binding program
            if state.program != program_id {
                gl.UseProgram(program_id);
                state.program = program_id;
            }

            // binding program uniforms
            uniforms.0(gl, |name| {
                uniforms_locations
                    .find_equiv(name)
                    .map(|val| val.0)
            });

            // binding vertex buffer
            if state.array_buffer_binding != Some(vb_id) {
                gl.BindBuffer(gl::ARRAY_BUFFER, vb_id);
                state.array_buffer_binding = Some(vb_id);
            }

            // binding index buffer
            if state.element_array_buffer_binding != Some(ib_id) {
                gl.BindBuffer(gl::ELEMENT_ARRAY_BUFFER, ib_id);
                state.element_array_buffer_binding = Some(ib_id);
            }

            // binding vertex buffer
            let mut locations = Vec::new();
            for &(ref name, vertex_buffer::VertexAttrib { offset, data_type, elements_count })
                in vb_bindingsclone.iter()
            {
                let loc = gl.GetAttribLocation(program_id, name.to_c_str().unwrap());
                locations.push(loc);

                if loc != -1 {
                    match data_type {
                        gl::BYTE | gl::UNSIGNED_BYTE | gl::SHORT | gl::UNSIGNED_SHORT |
                        gl::INT | gl::UNSIGNED_INT =>
                            gl.VertexAttribIPointer(loc as u32,
                                elements_count as gl::types::GLint, data_type,
                                vb_elementssize as i32, offset as *const libc::c_void),

                        _ => gl.VertexAttribPointer(loc as u32,
                                elements_count as gl::types::GLint, data_type, 0,
                                vb_elementssize as i32, offset as *const libc::c_void)
                    }

                    gl.EnableVertexAttribArray(loc as u32);
                }
            }

            // sync-ing parameters
            draw_parameters.sync(gl, state);

            // drawing
            gl.DrawElements(ib_primitives, ib_elemcounts as i32, ib_datatype, ptr::null());

            // disable vertex attrib array
            for l in locations.iter() {
                gl.DisableVertexAttribArray(l.clone() as u32);
            }
        }

        tx.send(());
    });

    // synchronizing with the end of the draw
    // TODO: remove that after making sure that everything is ok
    rx.recv();
}

pub fn clear_color(display: &Arc<DisplayImpl>, framebuffer: Option<&FramebufferAttachments>,
    red: f32, green: f32, blue: f32, alpha: f32)
{
    // FIXME: use framebuffer

    let (red, green, blue, alpha) = (
        red as gl::types::GLclampf,
        green as gl::types::GLclampf,
        blue as gl::types::GLclampf,
        alpha as gl::types::GLclampf
    );

    display.context.exec(proc(gl, state, _, _) {
        if state.clear_color != (red, green, blue, alpha) {
            gl.ClearColor(red, green, blue, alpha);
            state.clear_color = (red, green, blue, alpha);
        }

        gl.Clear(gl::COLOR_BUFFER_BIT);
    });
}

pub fn clear_depth(display: &Arc<DisplayImpl>, framebuffer: Option<&FramebufferAttachments>,
    value: f32)
{
    // FIXME: use framebuffer

    let value = value as gl::types::GLclampf;

    display.context.exec(proc(gl, state, _, _) {
        if state.clear_depth != value {
            gl.ClearDepth(value as f64);        // TODO: find out why this needs "as"
            state.clear_depth = value;
        }

        gl.Clear(gl::DEPTH_BUFFER_BIT);
    });
}

pub fn clear_stencil(display: &Arc<DisplayImpl>, framebuffer: Option<&FramebufferAttachments>,
    value: int)
{
    // FIXME: use framebuffer

    let value = value as gl::types::GLint;

    display.context.exec(proc(gl, state, _, _) {
        if state.clear_stencil != value {
            gl.ClearStencil(value);
            state.clear_stencil = value;
        }

        gl.Clear(gl::STENCIL_BUFFER_BIT);
    });
}

fn get_framebuffer(display: &Arc<DisplayImpl>, framebuffer: Option<&FramebufferAttachments>)
    -> Option<gl::types::GLuint>
{
    if let Some(framebuffer) = framebuffer {
        let mut framebuffers = display.framebuffer_objects.lock();

        if let Some(value) = framebuffers.find(framebuffer) {
            return Some(value.id);
        }

        let mut new_fbo = FrameBufferObject::new(display.clone());
        let new_fbo_id = new_fbo.id.clone();
        initialize_fbo(display, &mut new_fbo, framebuffer);
        framebuffers.insert(framebuffer.clone(), new_fbo);
        Some(new_fbo_id)

    } else {
        None
    }
}

fn initialize_fbo(display: &Arc<DisplayImpl>, fbo: &mut FrameBufferObject,
    content: &FramebufferAttachments)
{
    // TODO: missing implementation
}
<commit_msg>clear_* functions now bind the correct framebuffer<commit_after>use std::kinds::marker::ContravariantLifetime;
use std::ptr;
use std::sync::Arc;

use texture::{mod, Texture};
use uniforms::Uniforms;
use {DisplayImpl, VertexBuffer, IndexBuffer, Program, DrawParameters, Surface};
use {FrameBufferObject};

use {vertex_buffer, index_buffer, program};
use {gl, context, libc};

/// Creates a framebuffer that allows you to draw on something.
pub struct FrameBuffer<'a> {
    display: Arc<DisplayImpl>,
    attachments: FramebufferAttachments,
    marker: ContravariantLifetime<'a>,
}

impl<'a> FrameBuffer<'a> {
    pub fn new<'a>(display: &::Display) -> FrameBuffer<'a> {
        FrameBuffer {
            display: display.context.clone(),
            attachments: FramebufferAttachments {
                colors: Vec::new(),
                depth: None,
                stencil: None
            },
            marker: ContravariantLifetime
        }
    }

    pub fn with_texture<T: 'a>(mut self, texture: &'a mut T) -> FrameBuffer<'a> where T: Texture {
        self.attachments.colors.push(texture::get_id(texture.get_implementation()));
        self
    }
}

impl<'a> Surface for FrameBuffer<'a> {
    fn clear_color(&mut self, red: f32, green: f32, blue: f32, alpha: f32) {
        clear_color(&self.display, Some(&self.attachments), red, green, blue, alpha)
    }

    fn clear_depth(&mut self, value: f32) {
        clear_depth(&self.display, Some(&self.attachments), value)
    }

    fn clear_stencil(&mut self, value: int) {
        clear_stencil(&self.display, Some(&self.attachments), value)
    }

    fn get_dimensions(&self) -> (uint, uint) {
        unimplemented!()
    }

    fn draw<V, U>(&mut self, vb: &::VertexBuffer<V>, ib: &::IndexBuffer, program: &::Program,
        uniforms: &U, draw_parameters: &::DrawParameters) where U: ::uniforms::Uniforms
    {
        draw(&self.display, Some(&self.attachments), vb, ib, program, uniforms, draw_parameters)
    }
}

#[deriving(Hash, Clone, PartialEq, Eq)]
pub struct FramebufferAttachments {
    colors: Vec<gl::types::GLuint>,
    depth: Option<gl::types::GLuint>,
    stencil: Option<gl::types::GLuint>,
}

/// Draws everything.
pub fn draw<V, U: Uniforms>(display: &Arc<DisplayImpl>,
    framebuffer: Option<&FramebufferAttachments>, vertex_buffer: &VertexBuffer<V>,
    index_buffer: &IndexBuffer, program: &Program, uniforms: &U, draw_parameters: &DrawParameters)
{
    let fbo_id = get_framebuffer(display, framebuffer);

    let (vb_id, vb_elementssize, vb_bindingsclone) = vertex_buffer::get_clone(vertex_buffer);
    let (ib_id, ib_elemcounts, ib_datatype, ib_primitives) =
        index_buffer::get_clone(index_buffer);
    let program_id = program::get_program_id(program);
    let uniforms = uniforms.to_binder();
    let uniforms_locations = program::get_uniforms_locations(program);
    let draw_parameters = draw_parameters.clone();

    let (tx, rx) = channel();

    display.context.exec(proc(gl, state, version, extensions) {
        unsafe {
            bind_framebuffer(gl, state, version, extensions, fbo_id, true, false);

            // binding program
            if state.program != program_id {
                gl.UseProgram(program_id);
                state.program = program_id;
            }

            // binding program uniforms
            uniforms.0(gl, |name| {
                uniforms_locations
                    .find_equiv(name)
                    .map(|val| val.0)
            });

            // binding vertex buffer
            if state.array_buffer_binding != Some(vb_id) {
                gl.BindBuffer(gl::ARRAY_BUFFER, vb_id);
                state.array_buffer_binding = Some(vb_id);
            }

            // binding index buffer
            if state.element_array_buffer_binding != Some(ib_id) {
                gl.BindBuffer(gl::ELEMENT_ARRAY_BUFFER, ib_id);
                state.element_array_buffer_binding = Some(ib_id);
            }

            // binding vertex buffer
            let mut locations = Vec::new();
            for &(ref name, vertex_buffer::VertexAttrib { offset, data_type, elements_count })
                in vb_bindingsclone.iter()
            {
                let loc = gl.GetAttribLocation(program_id, name.to_c_str().unwrap());
                locations.push(loc);

                if loc != -1 {
                    match data_type {
                        gl::BYTE | gl::UNSIGNED_BYTE | gl::SHORT | gl::UNSIGNED_SHORT |
                        gl::INT | gl::UNSIGNED_INT =>
                            gl.VertexAttribIPointer(loc as u32,
                                elements_count as gl::types::GLint, data_type,
                                vb_elementssize as i32, offset as *const libc::c_void),

                        _ => gl.VertexAttribPointer(loc as u32,
                                elements_count as gl::types::GLint, data_type, 0,
                                vb_elementssize as i32, offset as *const libc::c_void)
                    }

                    gl.EnableVertexAttribArray(loc as u32);
                }
            }

            // sync-ing parameters
            draw_parameters.sync(gl, state);

            // drawing
            gl.DrawElements(ib_primitives, ib_elemcounts as i32, ib_datatype, ptr::null());

            // disable vertex attrib array
            for l in locations.iter() {
                gl.DisableVertexAttribArray(l.clone() as u32);
            }
        }

        tx.send(());
    });

    // synchronizing with the end of the draw
    // TODO: remove that after making sure that everything is ok
    rx.recv();
}

pub fn clear_color(display: &Arc<DisplayImpl>, framebuffer: Option<&FramebufferAttachments>,
    red: f32, green: f32, blue: f32, alpha: f32)
{
    let fbo_id = get_framebuffer(display, framebuffer);

    let (red, green, blue, alpha) = (
        red as gl::types::GLclampf,
        green as gl::types::GLclampf,
        blue as gl::types::GLclampf,
        alpha as gl::types::GLclampf
    );

    display.context.exec(proc(gl, state, version, extensions) {
        bind_framebuffer(gl, state, version, extensions, fbo_id, true, false);

        if state.clear_color != (red, green, blue, alpha) {
            gl.ClearColor(red, green, blue, alpha);
            state.clear_color = (red, green, blue, alpha);
        }

        gl.Clear(gl::COLOR_BUFFER_BIT);
    });
}

pub fn clear_depth(display: &Arc<DisplayImpl>, framebuffer: Option<&FramebufferAttachments>,
    value: f32)
{
    let value = value as gl::types::GLclampf;
    let fbo_id = get_framebuffer(display, framebuffer);

    display.context.exec(proc(gl, state, version, extensions) {
        bind_framebuffer(gl, state, version, extensions, fbo_id, true, false);

        if state.clear_depth != value {
            gl.ClearDepth(value as f64);        // TODO: find out why this needs "as"
            state.clear_depth = value;
        }

        gl.Clear(gl::DEPTH_BUFFER_BIT);
    });
}

pub fn clear_stencil(display: &Arc<DisplayImpl>, framebuffer: Option<&FramebufferAttachments>,
    value: int)
{
    let value = value as gl::types::GLint;
    let fbo_id = get_framebuffer(display, framebuffer);

    display.context.exec(proc(gl, state, version, extensions) {
        bind_framebuffer(gl, state, version, extensions, fbo_id, true, false);

        if state.clear_stencil != value {
            gl.ClearStencil(value);
            state.clear_stencil = value;
        }

        gl.Clear(gl::STENCIL_BUFFER_BIT);
    });
}

fn get_framebuffer(display: &Arc<DisplayImpl>, framebuffer: Option<&FramebufferAttachments>)
    -> Option<gl::types::GLuint>
{
    if let Some(framebuffer) = framebuffer {
        let mut framebuffers = display.framebuffer_objects.lock();

        if let Some(value) = framebuffers.find(framebuffer) {
            return Some(value.id);
        }

        let mut new_fbo = FrameBufferObject::new(display.clone());
        let new_fbo_id = new_fbo.id.clone();
        initialize_fbo(display, &mut new_fbo, framebuffer);
        framebuffers.insert(framebuffer.clone(), new_fbo);
        Some(new_fbo_id)

    } else {
        None
    }
}

fn initialize_fbo(display: &Arc<DisplayImpl>, fbo: &mut FrameBufferObject,
    content: &FramebufferAttachments)
{
    // TODO: missing implementation
}

fn bind_framebuffer(gl: &gl::Gl, state: &mut context::GLState, version: &context::GlVersion,
    _: &context::ExtensionsList, fbo_id: Option<gl::types::GLuint>, draw: bool, read: bool)
{
    if draw && state.draw_framebuffer != fbo_id {
        if version >= &context::GlVersion(3, 0) {
            gl.BindFramebuffer(gl::DRAW_FRAMEBUFFER, fbo_id.unwrap_or(0));
            state.draw_framebuffer = fbo_id.clone();
        } else {
            gl.BindFramebufferEXT(gl::FRAMEBUFFER_EXT, fbo_id.unwrap_or(0));
            state.draw_framebuffer = fbo_id.clone();
            state.read_framebuffer = fbo_id.clone();
        }
    }

    if read && state.read_framebuffer != fbo_id {
        if version >= &context::GlVersion(3, 0) {
            gl.BindFramebuffer(gl::READ_FRAMEBUFFER, fbo_id.unwrap_or(0));
            state.read_framebuffer = fbo_id.clone();
        } else {
            gl.BindFramebufferEXT(gl::FRAMEBUFFER_EXT, fbo_id.unwrap_or(0));
            state.draw_framebuffer = fbo_id.clone();
            state.read_framebuffer = fbo_id.clone();
        }
    }
}
<|endoftext|>


<commit_before>#[doc = "An atomically reference counted wrapper that can be used to
share immutable data between tasks."]

import comm::{port, chan, methods};
import sys::methods;

export arc, get, clone, shared_arc, get_arc;

export exclusive, methods;

#[abi = "cdecl"]
native mod rustrt {
    #[rust_stack]
    fn rust_atomic_increment(p: &mut libc::intptr_t)
        -> libc::intptr_t;

    #[rust_stack]
    fn rust_atomic_decrement(p: &mut libc::intptr_t)
        -> libc::intptr_t;
}

type arc_data<T> = {
    mut count: libc::intptr_t,
    data: T
};

class arc_destruct<T> {
  let data: *libc::c_void;
  new(data: *libc::c_void) { self.data = data; }
  drop unsafe {
     let data: ~arc_data<T> = unsafe::reinterpret_cast(self.data);
     let new_count = rustrt::rust_atomic_decrement(&mut data.count);
     assert new_count >= 0;
     if new_count == 0 {
         // drop glue takes over.
     } else {
       unsafe::forget(data);
     }
  }
}

type arc<T: const> = arc_destruct<T>;

#[doc="Create an atomically reference counted wrapper."]
fn arc<T: const>(-data: T) -> arc<T> {
    let data = ~{mut count: 1, data: data};
    unsafe {
        let ptr = unsafe::transmute(data);
        arc_destruct(ptr)
    }
}

#[doc="Access the underlying data in an atomically reference counted
 wrapper."]
fn get<T: const>(rc: &a.arc<T>) -> &a.T {
    unsafe {
        let ptr: ~arc_data<T> = unsafe::reinterpret_cast((*rc).data);
        // Cast us back into the correct region
        let r = unsafe::reinterpret_cast(&ptr.data);
        unsafe::forget(ptr);
        ret r;
    }
}

#[doc="Duplicate an atomically reference counted wrapper.

The resulting two `arc` objects will point to the same underlying data
object. However, one of the `arc` objects can be sent to another task,
allowing them to share the underlying data."]
fn clone<T: const>(rc: &arc<T>) -> arc<T> {
    unsafe {
        let ptr: ~arc_data<T> = unsafe::reinterpret_cast((*rc).data);
        let new_count = rustrt::rust_atomic_increment(&mut ptr.count);
        assert new_count >= 2;
        unsafe::forget(ptr);
    }
    arc_destruct((*rc).data)
}

// An arc over mutable data that is protected by a lock.
type ex_data<T: send> = {lock: sys::lock_and_signal, data: T};
type exclusive<T: send> = arc_destruct<ex_data<T>>;

fn exclusive<T:send >(-data: T) -> exclusive<T> {
    let data = ~{mut count: 1, data: {lock: sys::create_lock(),
                                      data: data}};
    unsafe {
        let ptr = unsafe::reinterpret_cast(data);
        unsafe::forget(data);
        arc_destruct(ptr)
    }
}

impl methods<T: send> for exclusive<T> {
    fn clone() -> exclusive<T> {
        unsafe {
            // this makes me nervous...
            let ptr: ~arc_data<ex_data<T>> =
                  unsafe::reinterpret_cast(self.data);
            let new_count = rustrt::rust_atomic_increment(&mut ptr.count);
            assert new_count > 1;
            unsafe::forget(ptr);
        }
        arc_destruct(self.data)
    }

    unsafe fn with<U>(f: fn(sys::condition, x: &T) -> U) -> U {
        let ptr: ~arc_data<ex_data<T>> =
            unsafe::reinterpret_cast(self.data);
        let r = {
            let rec: &ex_data<T> = &(*ptr).data;
            rec.lock.lock_cond(|c| f(c, &rec.data))
        };
        unsafe::forget(ptr);
        r
    }
}

// Convenience code for sharing arcs between tasks

type get_chan<T: const send> = chan<chan<arc<T>>>;

// (terminate, get)
type shared_arc<T: const send> = (shared_arc_res, get_chan<T>);

class shared_arc_res {
   let c: comm::chan<()>;
   new(c: comm::chan<()>) { self.c = c; }
   drop { self.c.send(()); }
}

fn shared_arc<T: send const>(-data: T) -> shared_arc<T> {
    let a = arc::arc(data);
    let p = port();
    let c = chan(p);
    do task::spawn() |move a| {
        let mut live = true;
        let terminate = port();
        let get = port();

        c.send((chan(terminate), chan(get)));

        while live {
            alt comm::select2(terminate, get) {
              either::left(()) { live = false; }
              either::right(cc) {
                comm::send(cc, arc::clone(&a));
              }
            }
        }
    };
    let (terminate, get) = p.recv();
    (shared_arc_res(terminate), get)
}

fn get_arc<T: send const>(c: get_chan<T>) -> arc::arc<T> {
    let p = port();
    c.send(chan(p));
    p.recv()
}

#[cfg(test)]
mod tests {
    import comm::*;
    import future::future;

    #[test]
    fn manually_share_arc() {
        let v = ~[1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
        let arc_v = arc::arc(v);

        let p = port();
        let c = chan(p);

        do task::spawn() || {
            let p = port();
            c.send(chan(p));

            let arc_v = p.recv();

            let v = *arc::get::<~[int]>(&arc_v);
            assert v[3] == 4;
        };

        let c = p.recv();
        c.send(arc::clone(&arc_v));

        assert (*arc::get(&arc_v))[2] == 3;

        log(info, arc_v);
    }

    #[test]
    fn auto_share_arc() {
        let v = ~[1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
        let (_res, arc_c) = shared_arc(v);

        let p = port();
        let c = chan(p);

        do task::spawn() || {
            let arc_v = get_arc(arc_c);
            let v = *get(&arc_v);
            assert v[2] == 3;

            c.send(());
        };

        assert p.recv() == ();
    }

    #[test]
    #[ignore] // this can probably infinite loop too.
    fn exclusive_arc() {
        let mut futures = ~[];

        let num_tasks = 10u;
        let count = 1000u;

        let total = exclusive(~mut 0u);

        for uint::range(0u, num_tasks) |_i| {
            let total = total.clone();
            futures += ~[future::spawn(|| {
                for uint::range(0u, count) |_i| {
                    do total.with |_cond, count| {
                        **count += 1u;
                    }
                }
            })];
        };

        for futures.each |f| { f.get() }

        do total.with |_cond, total| {
            assert **total == num_tasks * count
        };
    }
}
<commit_msg>core: Import future::extensions<commit_after>#[doc = "An atomically reference counted wrapper that can be used to
share immutable data between tasks."]

import comm::{port, chan, methods};
import sys::methods;

export arc, get, clone, shared_arc, get_arc;

export exclusive, methods;

#[abi = "cdecl"]
native mod rustrt {
    #[rust_stack]
    fn rust_atomic_increment(p: &mut libc::intptr_t)
        -> libc::intptr_t;

    #[rust_stack]
    fn rust_atomic_decrement(p: &mut libc::intptr_t)
        -> libc::intptr_t;
}

type arc_data<T> = {
    mut count: libc::intptr_t,
    data: T
};

class arc_destruct<T> {
  let data: *libc::c_void;
  new(data: *libc::c_void) { self.data = data; }
  drop unsafe {
     let data: ~arc_data<T> = unsafe::reinterpret_cast(self.data);
     let new_count = rustrt::rust_atomic_decrement(&mut data.count);
     assert new_count >= 0;
     if new_count == 0 {
         // drop glue takes over.
     } else {
       unsafe::forget(data);
     }
  }
}

type arc<T: const> = arc_destruct<T>;

#[doc="Create an atomically reference counted wrapper."]
fn arc<T: const>(-data: T) -> arc<T> {
    let data = ~{mut count: 1, data: data};
    unsafe {
        let ptr = unsafe::transmute(data);
        arc_destruct(ptr)
    }
}

#[doc="Access the underlying data in an atomically reference counted
 wrapper."]
fn get<T: const>(rc: &a.arc<T>) -> &a.T {
    unsafe {
        let ptr: ~arc_data<T> = unsafe::reinterpret_cast((*rc).data);
        // Cast us back into the correct region
        let r = unsafe::reinterpret_cast(&ptr.data);
        unsafe::forget(ptr);
        ret r;
    }
}

#[doc="Duplicate an atomically reference counted wrapper.

The resulting two `arc` objects will point to the same underlying data
object. However, one of the `arc` objects can be sent to another task,
allowing them to share the underlying data."]
fn clone<T: const>(rc: &arc<T>) -> arc<T> {
    unsafe {
        let ptr: ~arc_data<T> = unsafe::reinterpret_cast((*rc).data);
        let new_count = rustrt::rust_atomic_increment(&mut ptr.count);
        assert new_count >= 2;
        unsafe::forget(ptr);
    }
    arc_destruct((*rc).data)
}

// An arc over mutable data that is protected by a lock.
type ex_data<T: send> = {lock: sys::lock_and_signal, data: T};
type exclusive<T: send> = arc_destruct<ex_data<T>>;

fn exclusive<T:send >(-data: T) -> exclusive<T> {
    let data = ~{mut count: 1, data: {lock: sys::create_lock(),
                                      data: data}};
    unsafe {
        let ptr = unsafe::reinterpret_cast(data);
        unsafe::forget(data);
        arc_destruct(ptr)
    }
}

impl methods<T: send> for exclusive<T> {
    fn clone() -> exclusive<T> {
        unsafe {
            // this makes me nervous...
            let ptr: ~arc_data<ex_data<T>> =
                  unsafe::reinterpret_cast(self.data);
            let new_count = rustrt::rust_atomic_increment(&mut ptr.count);
            assert new_count > 1;
            unsafe::forget(ptr);
        }
        arc_destruct(self.data)
    }

    unsafe fn with<U>(f: fn(sys::condition, x: &T) -> U) -> U {
        let ptr: ~arc_data<ex_data<T>> =
            unsafe::reinterpret_cast(self.data);
        let r = {
            let rec: &ex_data<T> = &(*ptr).data;
            rec.lock.lock_cond(|c| f(c, &rec.data))
        };
        unsafe::forget(ptr);
        r
    }
}

// Convenience code for sharing arcs between tasks

type get_chan<T: const send> = chan<chan<arc<T>>>;

// (terminate, get)
type shared_arc<T: const send> = (shared_arc_res, get_chan<T>);

class shared_arc_res {
   let c: comm::chan<()>;
   new(c: comm::chan<()>) { self.c = c; }
   drop { self.c.send(()); }
}

fn shared_arc<T: send const>(-data: T) -> shared_arc<T> {
    let a = arc::arc(data);
    let p = port();
    let c = chan(p);
    do task::spawn() |move a| {
        let mut live = true;
        let terminate = port();
        let get = port();

        c.send((chan(terminate), chan(get)));

        while live {
            alt comm::select2(terminate, get) {
              either::left(()) { live = false; }
              either::right(cc) {
                comm::send(cc, arc::clone(&a));
              }
            }
        }
    };
    let (terminate, get) = p.recv();
    (shared_arc_res(terminate), get)
}

fn get_arc<T: send const>(c: get_chan<T>) -> arc::arc<T> {
    let p = port();
    c.send(chan(p));
    p.recv()
}

#[cfg(test)]
mod tests {
    import comm::*;
    import future::extensions;

    #[test]
    fn manually_share_arc() {
        let v = ~[1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
        let arc_v = arc::arc(v);

        let p = port();
        let c = chan(p);

        do task::spawn() || {
            let p = port();
            c.send(chan(p));

            let arc_v = p.recv();

            let v = *arc::get::<~[int]>(&arc_v);
            assert v[3] == 4;
        };

        let c = p.recv();
        c.send(arc::clone(&arc_v));

        assert (*arc::get(&arc_v))[2] == 3;

        log(info, arc_v);
    }

    #[test]
    fn auto_share_arc() {
        let v = ~[1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
        let (_res, arc_c) = shared_arc(v);

        let p = port();
        let c = chan(p);

        do task::spawn() || {
            let arc_v = get_arc(arc_c);
            let v = *get(&arc_v);
            assert v[2] == 3;

            c.send(());
        };

        assert p.recv() == ();
    }

    #[test]
    #[ignore] // this can probably infinite loop too.
    fn exclusive_arc() {
        let mut futures = ~[];

        let num_tasks = 10u;
        let count = 1000u;

        let total = exclusive(~mut 0u);

        for uint::range(0u, num_tasks) |_i| {
            let total = total.clone();
            futures += ~[future::spawn(|| {
                for uint::range(0u, count) |_i| {
                    do total.with |_cond, count| {
                        **count += 1u;
                    }
                }
            })];
        };

        for futures.each |f| { f.get() }

        do total.with |_cond, total| {
            assert **total == num_tasks * count
        };
    }
}
<|endoftext|>


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

//! Basic functions for dealing with memory
//!
//! This module contains functions for querying the size and alignment of
//! types, initializing and manipulating memory.

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

use marker::Sized;
use intrinsics;
use ptr;

#[stable(feature = "rust1", since = "1.0.0")]
pub use intrinsics::transmute;

/// Moves a thing into the void.
///
/// The forget function will take ownership of the provided value but neglect
/// to run any required cleanup or memory management operations on it.
///
/// This function is the unsafe version of the `drop` function because it does
/// not run any destructors.
#[stable(feature = "rust1", since = "1.0.0")]
pub use intrinsics::forget;

/// Returns the size of a type in bytes.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// assert_eq!(4, mem::size_of::<i32>());
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn size_of<T>() -> uint {
    unsafe { intrinsics::size_of::<T>() }
}

/// Returns the size of the type that `_val` points to in bytes.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// assert_eq!(4, mem::size_of_val(&5i32));
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn size_of_val<T>(_val: &T) -> uint {
    size_of::<T>()
}

/// Returns the ABI-required minimum alignment of a type
///
/// This is the alignment used for struct fields. It may be smaller than the preferred alignment.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// assert_eq!(4, mem::min_align_of::<i32>());
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn min_align_of<T>() -> uint {
    unsafe { intrinsics::min_align_of::<T>() }
}

/// Returns the ABI-required minimum alignment of the type of the value that `_val` points to
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// assert_eq!(4, mem::min_align_of_val(&5i32));
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn min_align_of_val<T>(_val: &T) -> uint {
    min_align_of::<T>()
}

/// Returns the alignment in memory for a type.
///
/// This function will return the alignment, in bytes, of a type in memory. If the alignment
/// returned is adhered to, then the type is guaranteed to function properly.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// assert_eq!(4, mem::align_of::<i32>());
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn align_of<T>() -> uint {
    // We use the preferred alignment as the default alignment for a type. This
    // appears to be what clang migrated towards as well:
    //
    // http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20110725/044411.html
    unsafe { intrinsics::pref_align_of::<T>() }
}

/// Returns the alignment of the type of the value that `_val` points to.
///
/// This is similar to `align_of`, but function will properly handle types such as trait objects
/// (in the future), returning the alignment for an arbitrary value at runtime.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// assert_eq!(4, mem::align_of_val(&5i32));
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn align_of_val<T>(_val: &T) -> uint {
    align_of::<T>()
}

/// Create a value initialized to zero.
///
/// This function is similar to allocating space for a local variable and zeroing it out (an unsafe
/// operation).
///
/// Care must be taken when using this function, if the type `T` has a destructor and the value
/// falls out of scope (due to unwinding or returning) before being initialized, then the
/// destructor will run on zeroed data, likely leading to crashes.
///
/// This is useful for FFI functions sometimes, but should generally be avoided.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// let x: int = unsafe { mem::zeroed() };
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn zeroed<T>() -> T {
    intrinsics::init()
}

/// Create an uninitialized value.
///
/// Care must be taken when using this function, if the type `T` has a destructor and the value
/// falls out of scope (due to unwinding or returning) before being initialized, then the
/// destructor will run on uninitialized data, likely leading to crashes.
///
/// This is useful for FFI functions sometimes, but should generally be avoided.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// let x: int = unsafe { mem::uninitialized() };
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn uninitialized<T>() -> T {
    intrinsics::uninit()
}

/// Swap the values at two mutable locations of the same type, without deinitialising or copying
/// either one.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// let x = &mut 5;
/// let y = &mut 42;
///
/// mem::swap(x, y);
///
/// assert_eq!(42, *x);
/// assert_eq!(5, *y);
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn swap<T>(x: &mut T, y: &mut T) {
    unsafe {
        // Give ourselves some scratch space to work with
        let mut t: T = uninitialized();

        // Perform the swap, `&mut` pointers never alias
        ptr::copy_nonoverlapping_memory(&mut t, &*x, 1);
        ptr::copy_nonoverlapping_memory(x, &*y, 1);
        ptr::copy_nonoverlapping_memory(y, &t, 1);

        // y and t now point to the same thing, but we need to completely forget `t`
        // because it's no longer relevant.
        forget(t);
    }
}

/// Replace the value at a mutable location with a new one, returning the old value, without
/// deinitialising or copying either one.
///
/// This is primarily used for transferring and swapping ownership of a value in a mutable
/// location.
///
/// # Examples
///
/// A simple example:
///
/// ```
/// use std::mem;
///
/// let mut v: Vec<i32> = Vec::new();
///
/// mem::replace(&mut v, Vec::new());
/// ```
///
/// This function allows consumption of one field of a struct by replacing it with another value.
/// The normal approach doesn't always work:
///
/// ```rust,ignore
/// struct Buffer<T> { buf: Vec<T> }
///
/// impl<T> Buffer<T> {
///     fn get_and_reset(&mut self) -> Vec<T> {
///         // error: cannot move out of dereference of `&mut`-pointer
///         let buf = self.buf;
///         self.buf = Vec::new();
///         buf
///     }
/// }
/// ```
///
/// Note that `T` does not necessarily implement `Clone`, so it can't even clone and reset
/// `self.buf`. But `replace` can be used to disassociate the original value of `self.buf` from
/// `self`, allowing it to be returned:
///
/// ```rust
/// use std::mem;
/// # struct Buffer<T> { buf: Vec<T> }
/// impl<T> Buffer<T> {
///     fn get_and_reset(&mut self) -> Vec<T> {
///         mem::replace(&mut self.buf, Vec::new())
///     }
/// }
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn replace<T>(dest: &mut T, mut src: T) -> T {
    swap(dest, &mut src);
    src
}

/// Disposes of a value.
///
/// This function can be used to destroy any value by allowing `drop` to take ownership of its
/// argument.
///
/// # Examples
///
/// ```
/// use std::cell::RefCell;
///
/// let x = RefCell::new(1);
///
/// let mut mutable_borrow = x.borrow_mut();
/// *mutable_borrow = 1;
///
/// drop(mutable_borrow); // relinquish the mutable borrow on this slot
///
/// let borrow = x.borrow();
/// println!("{}", *borrow);
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn drop<T>(_x: T) { }

/// Interprets `src` as `&U`, and then reads `src` without moving the contained value.
///
/// This function will unsafely assume the pointer `src` is valid for `sizeof(U)` bytes by
/// transmuting `&T` to `&U` and then reading the `&U`. It will also unsafely create a copy of the
/// contained value instead of moving out of `src`.
///
/// It is not a compile-time error if `T` and `U` have different sizes, but it is highly encouraged
/// to only invoke this function where `T` and `U` have the same size. This function triggers
/// undefined behavior if `U` is larger than `T`.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// let one = unsafe { mem::transmute_copy(&1) };
///
/// assert_eq!(1, one);
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
    ptr::read(src as *const T as *const U)
}

/// Transforms lifetime of the second pointer to match the first.
#[inline]
#[unstable(feature = "core",
           reason = "this function may be removed in the future due to its \
                     questionable utility")]
pub unsafe fn copy_lifetime<'a, S: ?Sized, T: ?Sized + 'a>(_ptr: &'a S,
                                                        ptr: &T) -> &'a T {
    transmute(ptr)
}

/// Transforms lifetime of the second mutable pointer to match the first.
#[inline]
#[unstable(feature = "core",
           reason = "this function may be removed in the future due to its \
                     questionable utility")]
pub unsafe fn copy_mut_lifetime<'a, S: ?Sized, T: ?Sized + 'a>(_ptr: &'a mut S,
                                                            ptr: &mut T)
                                                            -> &'a mut T {
    transmute(ptr)
}
<commit_msg>Make the lifetime anchor immutable on std::mem::copy_mut_lifetime<commit_after>// Copyright 2012-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.

//! Basic functions for dealing with memory
//!
//! This module contains functions for querying the size and alignment of
//! types, initializing and manipulating memory.

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

use marker::Sized;
use intrinsics;
use ptr;

#[stable(feature = "rust1", since = "1.0.0")]
pub use intrinsics::transmute;

/// Moves a thing into the void.
///
/// The forget function will take ownership of the provided value but neglect
/// to run any required cleanup or memory management operations on it.
///
/// This function is the unsafe version of the `drop` function because it does
/// not run any destructors.
#[stable(feature = "rust1", since = "1.0.0")]
pub use intrinsics::forget;

/// Returns the size of a type in bytes.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// assert_eq!(4, mem::size_of::<i32>());
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn size_of<T>() -> uint {
    unsafe { intrinsics::size_of::<T>() }
}

/// Returns the size of the type that `_val` points to in bytes.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// assert_eq!(4, mem::size_of_val(&5i32));
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn size_of_val<T>(_val: &T) -> uint {
    size_of::<T>()
}

/// Returns the ABI-required minimum alignment of a type
///
/// This is the alignment used for struct fields. It may be smaller than the preferred alignment.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// assert_eq!(4, mem::min_align_of::<i32>());
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn min_align_of<T>() -> uint {
    unsafe { intrinsics::min_align_of::<T>() }
}

/// Returns the ABI-required minimum alignment of the type of the value that `_val` points to
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// assert_eq!(4, mem::min_align_of_val(&5i32));
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn min_align_of_val<T>(_val: &T) -> uint {
    min_align_of::<T>()
}

/// Returns the alignment in memory for a type.
///
/// This function will return the alignment, in bytes, of a type in memory. If the alignment
/// returned is adhered to, then the type is guaranteed to function properly.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// assert_eq!(4, mem::align_of::<i32>());
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn align_of<T>() -> uint {
    // We use the preferred alignment as the default alignment for a type. This
    // appears to be what clang migrated towards as well:
    //
    // http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20110725/044411.html
    unsafe { intrinsics::pref_align_of::<T>() }
}

/// Returns the alignment of the type of the value that `_val` points to.
///
/// This is similar to `align_of`, but function will properly handle types such as trait objects
/// (in the future), returning the alignment for an arbitrary value at runtime.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// assert_eq!(4, mem::align_of_val(&5i32));
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn align_of_val<T>(_val: &T) -> uint {
    align_of::<T>()
}

/// Create a value initialized to zero.
///
/// This function is similar to allocating space for a local variable and zeroing it out (an unsafe
/// operation).
///
/// Care must be taken when using this function, if the type `T` has a destructor and the value
/// falls out of scope (due to unwinding or returning) before being initialized, then the
/// destructor will run on zeroed data, likely leading to crashes.
///
/// This is useful for FFI functions sometimes, but should generally be avoided.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// let x: int = unsafe { mem::zeroed() };
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn zeroed<T>() -> T {
    intrinsics::init()
}

/// Create an uninitialized value.
///
/// Care must be taken when using this function, if the type `T` has a destructor and the value
/// falls out of scope (due to unwinding or returning) before being initialized, then the
/// destructor will run on uninitialized data, likely leading to crashes.
///
/// This is useful for FFI functions sometimes, but should generally be avoided.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// let x: int = unsafe { mem::uninitialized() };
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn uninitialized<T>() -> T {
    intrinsics::uninit()
}

/// Swap the values at two mutable locations of the same type, without deinitialising or copying
/// either one.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// let x = &mut 5;
/// let y = &mut 42;
///
/// mem::swap(x, y);
///
/// assert_eq!(42, *x);
/// assert_eq!(5, *y);
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn swap<T>(x: &mut T, y: &mut T) {
    unsafe {
        // Give ourselves some scratch space to work with
        let mut t: T = uninitialized();

        // Perform the swap, `&mut` pointers never alias
        ptr::copy_nonoverlapping_memory(&mut t, &*x, 1);
        ptr::copy_nonoverlapping_memory(x, &*y, 1);
        ptr::copy_nonoverlapping_memory(y, &t, 1);

        // y and t now point to the same thing, but we need to completely forget `t`
        // because it's no longer relevant.
        forget(t);
    }
}

/// Replace the value at a mutable location with a new one, returning the old value, without
/// deinitialising or copying either one.
///
/// This is primarily used for transferring and swapping ownership of a value in a mutable
/// location.
///
/// # Examples
///
/// A simple example:
///
/// ```
/// use std::mem;
///
/// let mut v: Vec<i32> = Vec::new();
///
/// mem::replace(&mut v, Vec::new());
/// ```
///
/// This function allows consumption of one field of a struct by replacing it with another value.
/// The normal approach doesn't always work:
///
/// ```rust,ignore
/// struct Buffer<T> { buf: Vec<T> }
///
/// impl<T> Buffer<T> {
///     fn get_and_reset(&mut self) -> Vec<T> {
///         // error: cannot move out of dereference of `&mut`-pointer
///         let buf = self.buf;
///         self.buf = Vec::new();
///         buf
///     }
/// }
/// ```
///
/// Note that `T` does not necessarily implement `Clone`, so it can't even clone and reset
/// `self.buf`. But `replace` can be used to disassociate the original value of `self.buf` from
/// `self`, allowing it to be returned:
///
/// ```rust
/// use std::mem;
/// # struct Buffer<T> { buf: Vec<T> }
/// impl<T> Buffer<T> {
///     fn get_and_reset(&mut self) -> Vec<T> {
///         mem::replace(&mut self.buf, Vec::new())
///     }
/// }
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn replace<T>(dest: &mut T, mut src: T) -> T {
    swap(dest, &mut src);
    src
}

/// Disposes of a value.
///
/// This function can be used to destroy any value by allowing `drop` to take ownership of its
/// argument.
///
/// # Examples
///
/// ```
/// use std::cell::RefCell;
///
/// let x = RefCell::new(1);
///
/// let mut mutable_borrow = x.borrow_mut();
/// *mutable_borrow = 1;
///
/// drop(mutable_borrow); // relinquish the mutable borrow on this slot
///
/// let borrow = x.borrow();
/// println!("{}", *borrow);
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn drop<T>(_x: T) { }

/// Interprets `src` as `&U`, and then reads `src` without moving the contained value.
///
/// This function will unsafely assume the pointer `src` is valid for `sizeof(U)` bytes by
/// transmuting `&T` to `&U` and then reading the `&U`. It will also unsafely create a copy of the
/// contained value instead of moving out of `src`.
///
/// It is not a compile-time error if `T` and `U` have different sizes, but it is highly encouraged
/// to only invoke this function where `T` and `U` have the same size. This function triggers
/// undefined behavior if `U` is larger than `T`.
///
/// # Examples
///
/// ```
/// use std::mem;
///
/// let one = unsafe { mem::transmute_copy(&1) };
///
/// assert_eq!(1, one);
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
    ptr::read(src as *const T as *const U)
}

/// Transforms lifetime of the second pointer to match the first.
#[inline]
#[unstable(feature = "core",
           reason = "this function may be removed in the future due to its \
                     questionable utility")]
pub unsafe fn copy_lifetime<'a, S: ?Sized, T: ?Sized + 'a>(_ptr: &'a S,
                                                        ptr: &T) -> &'a T {
    transmute(ptr)
}

/// Transforms lifetime of the second mutable pointer to match the first.
#[inline]
#[unstable(feature = "core",
           reason = "this function may be removed in the future due to its \
                     questionable utility")]
pub unsafe fn copy_mut_lifetime<'a, S: ?Sized, T: ?Sized + 'a>(_ptr: &'a S,
                                                               ptr: &mut T)
                                                              -> &'a mut T
{
    transmute(ptr)
}
<|endoftext|>


<commit_before><commit_msg>fix(POSIX Overrides): fixes bug where required args are overridden<commit_after><|endoftext|>


<commit_before><commit_msg>Remove unused Error::from() call<commit_after><|endoftext|>


<commit_before><commit_msg>add figure 2.17<commit_after>/// Figure 2.17: Determine the number of file descriptors

/// Takeaway: On OSX this outputs 256 which is way too low.
/// `sysctl kern.maxfiles` returns 12288 and `kern.maxfilesperproc` returns 10240.
/// OPEN_MAX is defined in /usr/include/sys/syslimits.h as 10240 but I didn't find a way
/// how to reference that (AFAIK extern blocks can only reference functions, not constants)
/// On Linux it returns 1024 (which matches `ulimit -n`)

extern crate libc;
extern crate errno;
extern crate apue;

use libc::{_SC_OPEN_MAX, sysconf};
use errno::{errno};
use apue::LibcResult;

const OPEN_MAX_GUESS: i64 = 256;

unsafe fn open_max(openmax: &mut i64) -> i64 {
	if *openmax == 0 {
		*openmax = if let Some(val) = sysconf(_SC_OPEN_MAX).to_option() {
			println!("sysconf succeeded..");
			val
		} else {
			println!("sysconf failed..");
	    	match errno().0 {
	    	    0 => OPEN_MAX_GUESS, // indeterminate so just a guess
	    	    _ => panic!("pathconf error for _PC_PATH_MAX")
	    	}
		}
	}
	*openmax
}

fn main() {
	let mut openmax = 0;
	unsafe {
    	println!("{:?}", open_max(&mut openmax));
    }
}<|endoftext|>


<commit_before>mod data_structures;
#[cfg(feature = "postgres")]
mod pg;
#[cfg(feature = "sqlite")]
mod sqlite;

use diesel::{QueryResult, Connection};
use syntax::ast;
use syntax::codemap::Span;
use syntax::ext::base::*;
use syntax::parse::token::{InternedString, str_to_ident};
use syntax::ptr::P;
use syntax::util::small_vector::SmallVector;

use self::data_structures::*;

pub fn expand_load_table<'cx>(
    cx: &'cx mut ExtCtxt,
    sp: Span,
    tts: &[ast::TokenTree]
) -> Box<MacResult+'cx> {
    let mut exprs = match get_exprs_from_tts(cx, sp, tts) {
        Some(ref exprs) if exprs.is_empty() => {
            cx.span_err(sp, "load_table_from_schema! takes 2 arguments");
            return DummyResult::any(sp);
        }
        None => return DummyResult::any(sp),
        Some(exprs) => exprs.into_iter()
    };

    match load_table_body(cx, sp, &mut exprs) {
        Ok(res) => res,
        Err(res) => res,
    }
}

pub fn load_table_body<T: Iterator<Item=P<ast::Expr>>>(
    cx: &mut ExtCtxt,
    sp: Span,
    exprs: &mut T,
) -> Result<Box<MacResult>, Box<MacResult>> {
    let database_url = try!(next_str_lit(cx, sp, exprs));
    let table_name = try!(next_str_lit(cx, sp, exprs));
    let connection = try!(establish_connection(cx, sp, &database_url));
    table_macro_call(cx, sp, &connection, &table_name)
        .map(|item| MacEager::items(SmallVector::one(item)))
}

pub fn expand_infer_schema<'cx>(
    cx: &'cx mut ExtCtxt,
    sp: Span,
    tts: &[ast::TokenTree]
) -> Box<MacResult+'cx> {
    let mut exprs = match get_exprs_from_tts(cx, sp, tts) {
        Some(exprs) => exprs.into_iter(),
        None => return DummyResult::any(sp),
    };

    match infer_schema_body(cx, sp, &mut exprs) {
        Ok(res) => res,
        Err(res) => res,
    }
}

pub fn infer_schema_body<T: Iterator<Item=P<ast::Expr>>>(
    cx: &mut ExtCtxt,
    sp: Span,
    exprs: &mut T,
) -> Result<Box<MacResult>, Box<MacResult>> {
    let database_url = try!(next_str_lit(cx, sp, exprs));
    let connection = try!(establish_connection(cx, sp, &database_url));
    let table_names = load_table_names(cx, sp, &connection).unwrap();
    let impls = table_names.into_iter()
        .map(|n| table_macro_call(cx, sp, &connection, &n))
        .collect();
    Ok(MacEager::items(SmallVector::many(try!(impls))))
}

fn table_macro_call(
    cx: &mut ExtCtxt,
    sp: Span,
    connection: &InferConnection,
    table_name: &str,
) -> Result<P<ast::Item>, Box<MacResult>> {
    match get_table_data(connection, table_name) {
        Err(::diesel::result::Error::NotFound) => {
            cx.span_err(sp, &format!("no table exists named {}", table_name));
            Err(DummyResult::any(sp))
        }
        Err(_) => {
            cx.span_err(sp, "error loading schema");
            Err(DummyResult::any(sp))
        }
        Ok(data) => {
            let tokens = data.iter().map(|a| column_def_tokens(cx, a, &connection))
                .collect::<Vec<_>>();
            let table_name = str_to_ident(table_name);
            let item = quote_item!(cx, table! {
                $table_name {
                    $tokens
                }
            }).unwrap();
            Ok(item)
        }
    }
}

fn next_str_lit<T: Iterator<Item=P<ast::Expr>>>(
    cx: &mut ExtCtxt,
    sp: Span,
    exprs: &mut T,
) -> Result<InternedString, Box<MacResult>> {
    match expr_to_string(cx, exprs.next().unwrap(), "expected string literal") {
        Some((s, _)) => Ok(s),
        None => Err(DummyResult::any(sp)),
    }
}

fn column_def_tokens(cx: &mut ExtCtxt, attr: &ColumnInformation, conn: &InferConnection)
    -> Vec<ast::TokenTree>
{
    let column_name = str_to_ident(&attr.column_name);
    let tpe = determine_column_type(cx, attr, conn);
    quote_tokens!(cx, $column_name -> $tpe,)
}

fn establish_real_connection<Conn>(
    cx: &mut ExtCtxt,
    sp: Span,
    database_url: &str,
) -> Result<Conn, Box<MacResult>> where
    Conn: Connection,
{
    Conn::establish(database_url).map_err(|_| {
        cx.span_err(sp, "failed to establish a database connection");
        DummyResult::any(sp)
    })
}

// FIXME: Remove the duplicates of this function once expression level attributes
// are stable (I believe this is in 1.7)
#[cfg(all(feature = "sqlite", not(feature = "postgres")))]
fn establish_connection(
    cx: &mut ExtCtxt,
    sp: Span,
    database_url: &str,
) -> Result<InferConnection, Box<MacResult>> {
    establish_real_connection(cx, sp, database_url)
}

#[cfg(all(feature = "postgres", not(feature = "sqlite")))]
fn establish_connection(
    cx: &mut ExtCtxt,
    sp: Span,
    database_url: &str,
) -> Result<InferConnection, Box<MacResult>> {
    establish_real_connection(cx, sp, database_url)
}

#[cfg(all(feature = "sqlite", feature = "postgres"))]
fn establish_connection(
    cx: &mut ExtCtxt,
    sp: Span,
    database_url: &str,
) -> Result<InferConnection, Box<MacResult>> {
    if database_url.starts_with("postgres://") || database_url.starts_with("postgresql://") {
        establish_real_connection(cx, sp, database_url).map(|c| InferConnection::Pg(c))
    } else {
        establish_real_connection(cx, sp, database_url).map(|c| InferConnection::Sqlite(c))
    }
}

#[cfg(all(feature = "sqlite", not(feature = "postgres")))]
fn get_table_data(conn: &InferConnection, table_name: &str)
    -> QueryResult<Vec<ColumnInformation>>
{
    sqlite::get_table_data(conn, table_name)
}

#[cfg(all(feature = "postgres", not(feature = "sqlite")))]
fn get_table_data(conn: &InferConnection, table_name: &str)
    -> QueryResult<Vec<ColumnInformation>>
{
    pg::get_table_data(conn, table_name)
}

#[cfg(all(feature = "postgres", feature = "sqlite"))]
fn get_table_data(conn: &InferConnection, table_name: &str)
    -> QueryResult<Vec<ColumnInformation>>
{
    match *conn{
        InferConnection::Sqlite(ref c) => sqlite::get_table_data(c, table_name),
        InferConnection::Pg(ref c) => pg::get_table_data(c, table_name),
    }
}

#[cfg(all(feature = "sqlite", not(feature = "postgres")))]
fn load_table_names(
    cx: &mut ExtCtxt,
    sp: Span,
    connection: &InferConnection,
) -> Result<Vec<String>, ::diesel::result::Error> {
    sqlite::load_table_names(cx, sp, connection)
}

#[cfg(all(feature = "postgres", not(feature = "sqlite")))]
fn load_table_names(
    cx: &mut ExtCtxt,
    sp: Span,
    connection: &InferConnection,
) -> Result<Vec<String>, ::diesel::result::Error> {
    pg::load_table_names(cx, sp, connection)
}

#[cfg(all(feature = "sqlite", feature = "postgres"))]
fn load_table_names(
    cx: &mut ExtCtxt,
    sp: Span,
    connection: &InferConnection,
) -> Result<Vec<String>, ::diesel::result::Error> {
    match *connection {
        InferConnection::Sqlite(ref c) => sqlite::load_table_names(cx, sp, c),
        InferConnection::Pg(ref c) => pg::load_table_names(cx, sp, c),
    }
}

#[cfg(all(feature = "sqlite", not(feature = "postgres")))]
fn determine_column_type(cx: &mut ExtCtxt, attr: &ColumnInformation, _conn: &InferConnection)
    -> P<ast::Ty>
{
    sqlite::determine_column_type(cx, attr)
}

#[cfg(all(feature = "postgres", not(feature = "sqlite")))]
fn determine_column_type(cx: &mut ExtCtxt, attr: &ColumnInformation, _conn: &InferConnection)
    -> P<ast::Ty>
{
    pg::determine_column_type(cx, attr)
}

#[cfg(all(feature = "sqlite", feature = "postgres"))]
fn determine_column_type(cx: &mut ExtCtxt, attr: &ColumnInformation, conn: &InferConnection)
    -> P<ast::Ty>
{
    match *conn {
        InferConnection::Sqlite(_) => sqlite::determine_column_type(cx, attr),
        InferConnection::Pg(_) => pg::determine_column_type(cx, attr),
    }
}
<commit_msg>Provide better error information when `infer_schema!` fails to connect<commit_after>mod data_structures;
#[cfg(feature = "postgres")]
mod pg;
#[cfg(feature = "sqlite")]
mod sqlite;

use diesel::{QueryResult, Connection};
use syntax::ast;
use syntax::codemap::Span;
use syntax::ext::base::*;
use syntax::parse::token::{InternedString, str_to_ident};
use syntax::ptr::P;
use syntax::util::small_vector::SmallVector;

use self::data_structures::*;

pub fn expand_load_table<'cx>(
    cx: &'cx mut ExtCtxt,
    sp: Span,
    tts: &[ast::TokenTree]
) -> Box<MacResult+'cx> {
    let mut exprs = match get_exprs_from_tts(cx, sp, tts) {
        Some(ref exprs) if exprs.is_empty() => {
            cx.span_err(sp, "load_table_from_schema! takes 2 arguments");
            return DummyResult::any(sp);
        }
        None => return DummyResult::any(sp),
        Some(exprs) => exprs.into_iter()
    };

    match load_table_body(cx, sp, &mut exprs) {
        Ok(res) => res,
        Err(res) => res,
    }
}

pub fn load_table_body<T: Iterator<Item=P<ast::Expr>>>(
    cx: &mut ExtCtxt,
    sp: Span,
    exprs: &mut T,
) -> Result<Box<MacResult>, Box<MacResult>> {
    let database_url = try!(next_str_lit(cx, sp, exprs));
    let table_name = try!(next_str_lit(cx, sp, exprs));
    let connection = try!(establish_connection(cx, sp, &database_url));
    table_macro_call(cx, sp, &connection, &table_name)
        .map(|item| MacEager::items(SmallVector::one(item)))
}

pub fn expand_infer_schema<'cx>(
    cx: &'cx mut ExtCtxt,
    sp: Span,
    tts: &[ast::TokenTree]
) -> Box<MacResult+'cx> {
    let mut exprs = match get_exprs_from_tts(cx, sp, tts) {
        Some(exprs) => exprs.into_iter(),
        None => return DummyResult::any(sp),
    };

    match infer_schema_body(cx, sp, &mut exprs) {
        Ok(res) => res,
        Err(res) => res,
    }
}

pub fn infer_schema_body<T: Iterator<Item=P<ast::Expr>>>(
    cx: &mut ExtCtxt,
    sp: Span,
    exprs: &mut T,
) -> Result<Box<MacResult>, Box<MacResult>> {
    let database_url = try!(next_str_lit(cx, sp, exprs));
    let connection = try!(establish_connection(cx, sp, &database_url));
    let table_names = load_table_names(cx, sp, &connection).unwrap();
    let impls = table_names.into_iter()
        .map(|n| table_macro_call(cx, sp, &connection, &n))
        .collect();
    Ok(MacEager::items(SmallVector::many(try!(impls))))
}

fn table_macro_call(
    cx: &mut ExtCtxt,
    sp: Span,
    connection: &InferConnection,
    table_name: &str,
) -> Result<P<ast::Item>, Box<MacResult>> {
    match get_table_data(connection, table_name) {
        Err(::diesel::result::Error::NotFound) => {
            cx.span_err(sp, &format!("no table exists named {}", table_name));
            Err(DummyResult::any(sp))
        }
        Err(_) => {
            cx.span_err(sp, "error loading schema");
            Err(DummyResult::any(sp))
        }
        Ok(data) => {
            let tokens = data.iter().map(|a| column_def_tokens(cx, a, &connection))
                .collect::<Vec<_>>();
            let table_name = str_to_ident(table_name);
            let item = quote_item!(cx, table! {
                $table_name {
                    $tokens
                }
            }).unwrap();
            Ok(item)
        }
    }
}

fn next_str_lit<T: Iterator<Item=P<ast::Expr>>>(
    cx: &mut ExtCtxt,
    sp: Span,
    exprs: &mut T,
) -> Result<InternedString, Box<MacResult>> {
    match expr_to_string(cx, exprs.next().unwrap(), "expected string literal") {
        Some((s, _)) => Ok(s),
        None => Err(DummyResult::any(sp)),
    }
}

fn column_def_tokens(cx: &mut ExtCtxt, attr: &ColumnInformation, conn: &InferConnection)
    -> Vec<ast::TokenTree>
{
    let column_name = str_to_ident(&attr.column_name);
    let tpe = determine_column_type(cx, attr, conn);
    quote_tokens!(cx, $column_name -> $tpe,)
}

fn establish_real_connection<Conn>(
    cx: &mut ExtCtxt,
    sp: Span,
    database_url: &str,
) -> Result<Conn, Box<MacResult>> where
    Conn: Connection,
{
    Conn::establish(database_url).map_err(|error| {
        let error_message = format!(
            "Failed to establish a database connection at {}. Error: {:?}",
            database_url,
            error,
        );
        cx.span_err(sp, &error_message);
        DummyResult::any(sp)
    })
}

// FIXME: Remove the duplicates of this function once expression level attributes
// are stable (I believe this is in 1.7)
#[cfg(all(feature = "sqlite", not(feature = "postgres")))]
fn establish_connection(
    cx: &mut ExtCtxt,
    sp: Span,
    database_url: &str,
) -> Result<InferConnection, Box<MacResult>> {
    establish_real_connection(cx, sp, database_url)
}

#[cfg(all(feature = "postgres", not(feature = "sqlite")))]
fn establish_connection(
    cx: &mut ExtCtxt,
    sp: Span,
    database_url: &str,
) -> Result<InferConnection, Box<MacResult>> {
    establish_real_connection(cx, sp, database_url)
}

#[cfg(all(feature = "sqlite", feature = "postgres"))]
fn establish_connection(
    cx: &mut ExtCtxt,
    sp: Span,
    database_url: &str,
) -> Result<InferConnection, Box<MacResult>> {
    if database_url.starts_with("postgres://") || database_url.starts_with("postgresql://") {
        establish_real_connection(cx, sp, database_url).map(|c| InferConnection::Pg(c))
    } else {
        establish_real_connection(cx, sp, database_url).map(|c| InferConnection::Sqlite(c))
    }
}

#[cfg(all(feature = "sqlite", not(feature = "postgres")))]
fn get_table_data(conn: &InferConnection, table_name: &str)
    -> QueryResult<Vec<ColumnInformation>>
{
    sqlite::get_table_data(conn, table_name)
}

#[cfg(all(feature = "postgres", not(feature = "sqlite")))]
fn get_table_data(conn: &InferConnection, table_name: &str)
    -> QueryResult<Vec<ColumnInformation>>
{
    pg::get_table_data(conn, table_name)
}

#[cfg(all(feature = "postgres", feature = "sqlite"))]
fn get_table_data(conn: &InferConnection, table_name: &str)
    -> QueryResult<Vec<ColumnInformation>>
{
    match *conn{
        InferConnection::Sqlite(ref c) => sqlite::get_table_data(c, table_name),
        InferConnection::Pg(ref c) => pg::get_table_data(c, table_name),
    }
}

#[cfg(all(feature = "sqlite", not(feature = "postgres")))]
fn load_table_names(
    cx: &mut ExtCtxt,
    sp: Span,
    connection: &InferConnection,
) -> Result<Vec<String>, ::diesel::result::Error> {
    sqlite::load_table_names(cx, sp, connection)
}

#[cfg(all(feature = "postgres", not(feature = "sqlite")))]
fn load_table_names(
    cx: &mut ExtCtxt,
    sp: Span,
    connection: &InferConnection,
) -> Result<Vec<String>, ::diesel::result::Error> {
    pg::load_table_names(cx, sp, connection)
}

#[cfg(all(feature = "sqlite", feature = "postgres"))]
fn load_table_names(
    cx: &mut ExtCtxt,
    sp: Span,
    connection: &InferConnection,
) -> Result<Vec<String>, ::diesel::result::Error> {
    match *connection {
        InferConnection::Sqlite(ref c) => sqlite::load_table_names(cx, sp, c),
        InferConnection::Pg(ref c) => pg::load_table_names(cx, sp, c),
    }
}

#[cfg(all(feature = "sqlite", not(feature = "postgres")))]
fn determine_column_type(cx: &mut ExtCtxt, attr: &ColumnInformation, _conn: &InferConnection)
    -> P<ast::Ty>
{
    sqlite::determine_column_type(cx, attr)
}

#[cfg(all(feature = "postgres", not(feature = "sqlite")))]
fn determine_column_type(cx: &mut ExtCtxt, attr: &ColumnInformation, _conn: &InferConnection)
    -> P<ast::Ty>
{
    pg::determine_column_type(cx, attr)
}

#[cfg(all(feature = "sqlite", feature = "postgres"))]
fn determine_column_type(cx: &mut ExtCtxt, attr: &ColumnInformation, conn: &InferConnection)
    -> P<ast::Ty>
{
    match *conn {
        InferConnection::Sqlite(_) => sqlite::determine_column_type(cx, attr),
        InferConnection::Pg(_) => pg::determine_column_type(cx, attr),
    }
}
<|endoftext|>


<commit_before><commit_msg>tut-03 working now, the fpscamera is functional<commit_after><|endoftext|>


<commit_before><commit_msg>Add edge_test<commit_after>#[macro_use]
extern crate yoga;

use yoga::{Direction, FlexDirection, Node, Point, Undefined};
use yoga::FlexStyle::*;

#[test]
fn test_start_overrides() {
	let mut root = Node::new();

	style!(root,
		FlexDirection(FlexDirection::Row),
		Width(100 pt),
		Height(100 pt)
	);

	let mut root_child_0 = Node::new();

	style!(root_child_0,
		FlexGrow(1.0),
		MarginStart(10 pt),
		MarginLeft(20 pt),
		MarginRight(20 pt)
	);

	root.insert_child(&mut root_child_0, 0);
	root.calculate_layout(Undefined, Undefined, Direction::LTR);

	let root_layout = root.get_layout();
	let child_layout = root_child_0.get_layout();

	assert_eq!(0.0, root_layout.left);
	assert_eq!(0.0, root_layout.top);
	assert_eq!(100.0, root_layout.width);
	assert_eq!(100.0, root_layout.height);

	assert_eq!(10.0, child_layout.left);
	assert_eq!(20.0, child_layout.right);
	assert_eq!(0.0, child_layout.top);
	assert_eq!(70.0, child_layout.width);
	assert_eq!(100.0, child_layout.height);

	root.calculate_layout(Undefined, Undefined, Direction::RTL);

	let root_layout = root.get_layout();
	let child_layout = root_child_0.get_layout();

	assert_eq!(0.0, root_layout.left);
	assert_eq!(0.0, root_layout.top);
	assert_eq!(100.0, root_layout.width);
	assert_eq!(100.0, root_layout.height);

	assert_eq!(20.0, child_layout.left);
	assert_eq!(10.0, child_layout.right);
	assert_eq!(0.0, child_layout.top);
	assert_eq!(70.0, child_layout.width);
	assert_eq!(100.0, child_layout.height);
}

#[test]
fn test_end_overrides() {
	let mut root = Node::new();

	style!(root,
		FlexDirection(FlexDirection::Row),
		Width(100 pt),
		Height(100 pt)
	);

	let mut root_child_0 = Node::new();

	style!(root_child_0,
		FlexGrow(1.0),
		MarginEnd(10 pt),
		MarginLeft(20 pt),
		MarginRight(20 pt)
	);

	root.insert_child(&mut root_child_0, 0);
	root.calculate_layout(Undefined, Undefined, Direction::LTR);

	let root_layout = root.get_layout();
	let child_layout = root_child_0.get_layout();

	assert_eq!(0.0, root_layout.left);
	assert_eq!(0.0, root_layout.top);
	assert_eq!(100.0, root_layout.width);
	assert_eq!(100.0, root_layout.height);

	assert_eq!(20.0, child_layout.left);
	assert_eq!(10.0, child_layout.right);
	assert_eq!(0.0, child_layout.top);
	assert_eq!(70.0, child_layout.width);
	assert_eq!(100.0, child_layout.height);

	root.calculate_layout(Undefined, Undefined, Direction::RTL);

	let root_layout = root.get_layout();
	let child_layout = root_child_0.get_layout();

	assert_eq!(0.0, root_layout.left);
	assert_eq!(0.0, root_layout.top);
	assert_eq!(100.0, root_layout.width);
	assert_eq!(100.0, root_layout.height);

	assert_eq!(10.0, child_layout.left);
	assert_eq!(20.0, child_layout.right);
	assert_eq!(0.0, child_layout.top);
	assert_eq!(70.0, child_layout.width);
	assert_eq!(100.0, child_layout.height);
}

#[test]
fn test_horizontal_overridden() {
	let mut root = Node::new();

	style!(root,
		FlexDirection(FlexDirection::Row),
		Width(100 pt),
		Height(100 pt)
	);

	let mut root_child_0 = Node::new();

	style!(root_child_0,
		FlexGrow(1.0),
		MarginHorizontal(10 pt),
		MarginLeft(20 pt)
	);

	root.insert_child(&mut root_child_0, 0);
	root.calculate_layout(Undefined, Undefined, Direction::LTR);

	let root_layout = root.get_layout();
	let child_layout = root_child_0.get_layout();

	assert_eq!(0.0, root_layout.left);
	assert_eq!(0.0, root_layout.top);
	assert_eq!(100.0, root_layout.width);
	assert_eq!(100.0, root_layout.height);

	assert_eq!(20.0, child_layout.left);
	assert_eq!(10.0, child_layout.right);
	assert_eq!(0.0, child_layout.top);
	assert_eq!(70.0, child_layout.width);
	assert_eq!(100.0, child_layout.height);

	root.calculate_layout(Undefined, Undefined, Direction::RTL);

	let root_layout = root.get_layout();
	let child_layout = root_child_0.get_layout();

	assert_eq!(0.0, root_layout.left);
	assert_eq!(0.0, root_layout.top);
	assert_eq!(100.0, root_layout.width);
	assert_eq!(100.0, root_layout.height);

	assert_eq!(20.0, child_layout.left);
	assert_eq!(10.0, child_layout.right);
	assert_eq!(0.0, child_layout.top);
	assert_eq!(70.0, child_layout.width);
	assert_eq!(100.0, child_layout.height);
}

#[test]
fn test_vertical_overridden() {
	let mut root = Node::new();

	style!(root,
		FlexDirection(FlexDirection::Row),
		Width(100 pt),
		Height(100 pt)
	);

	let mut root_child_0 = Node::new();

	style!(root_child_0,
		FlexGrow(1.0),
		MarginVertical(10 pt),
		MarginTop(20 pt)
	);

	root.insert_child(&mut root_child_0, 0);
	root.calculate_layout(Undefined, Undefined, Direction::LTR);

	let root_layout = root.get_layout();
	let child_layout = root_child_0.get_layout();

	assert_eq!(0.0, root_layout.left);
	assert_eq!(0.0, root_layout.top);
	assert_eq!(100.0, root_layout.width);
	assert_eq!(100.0, root_layout.height);

	assert_eq!(0.0, child_layout.left);
	assert_eq!(0.0, child_layout.right);
	assert_eq!(20.0, child_layout.top);
	assert_eq!(10.0, child_layout.bottom);
	assert_eq!(100.0, child_layout.width);
	assert_eq!(70.0, child_layout.height);

	root.calculate_layout(Undefined, Undefined, Direction::RTL);

	let root_layout = root.get_layout();
	let child_layout = root_child_0.get_layout();

	assert_eq!(0.0, root_layout.left);
	assert_eq!(0.0, root_layout.top);
	assert_eq!(100.0, root_layout.width);
	assert_eq!(100.0, root_layout.height);

	assert_eq!(0.0, child_layout.left);
	assert_eq!(0.0, child_layout.right);
	assert_eq!(20.0, child_layout.top);
	assert_eq!(10.0, child_layout.bottom);
	assert_eq!(100.0, child_layout.width);
	assert_eq!(70.0, child_layout.height);
}

#[test]
fn test_horizontal_overrides_all() {
	let mut root = Node::new();

	style!(root,
		FlexDirection(FlexDirection::Row),
		Width(100 pt),
		Height(100 pt)
	);

	let mut root_child_0 = Node::new();

	style!(root_child_0,
		FlexGrow(1.0),
		MarginHorizontal(10 pt),
		Margin(20 pt)
	);

	root.insert_child(&mut root_child_0, 0);
	root.calculate_layout(Undefined, Undefined, Direction::LTR);

	let root_layout = root.get_layout();
	let child_layout = root_child_0.get_layout();

	assert_eq!(0.0, root_layout.left);
	assert_eq!(0.0, root_layout.top);
	assert_eq!(100.0, root_layout.width);
	assert_eq!(100.0, root_layout.height);

	assert_eq!(10.0, child_layout.left);
	assert_eq!(10.0, child_layout.right);
	assert_eq!(20.0, child_layout.top);
	assert_eq!(20.0, child_layout.bottom);
	assert_eq!(80.0, child_layout.width);
	assert_eq!(60.0, child_layout.height);

	root.calculate_layout(Undefined, Undefined, Direction::RTL);

	let root_layout = root.get_layout();
	let child_layout = root_child_0.get_layout();

	assert_eq!(0.0, root_layout.left);
	assert_eq!(0.0, root_layout.top);
	assert_eq!(100.0, root_layout.width);
	assert_eq!(100.0, root_layout.height);

	assert_eq!(10.0, child_layout.left);
	assert_eq!(10.0, child_layout.right);
	assert_eq!(20.0, child_layout.top);
	assert_eq!(20.0, child_layout.bottom);
	assert_eq!(80.0, child_layout.width);
	assert_eq!(60.0, child_layout.height);
}

#[test]
fn test_vertical_overrides_all() {
	let mut root = Node::new();

	style!(root,
		FlexDirection(FlexDirection::Row),
		Width(100 pt),
		Height(100 pt)
	);

	let mut root_child_0 = Node::new();

	style!(root_child_0,
		FlexGrow(1.0),
		MarginVertical(10 pt),
		Margin(20 pt)
	);

	root.insert_child(&mut root_child_0, 0);
	root.calculate_layout(Undefined, Undefined, Direction::LTR);

	let root_layout = root.get_layout();
	let child_layout = root_child_0.get_layout();

	assert_eq!(0.0, root_layout.left);
	assert_eq!(0.0, root_layout.top);
	assert_eq!(100.0, root_layout.width);
	assert_eq!(100.0, root_layout.height);

	assert_eq!(20.0, child_layout.left);
	assert_eq!(20.0, child_layout.right);
	assert_eq!(10.0, child_layout.top);
	assert_eq!(10.0, child_layout.bottom);
	assert_eq!(60.0, child_layout.width);
	assert_eq!(80.0, child_layout.height);

	root.calculate_layout(Undefined, Undefined, Direction::RTL);

	let root_layout = root.get_layout();
	let child_layout = root_child_0.get_layout();

	assert_eq!(0.0, root_layout.left);
	assert_eq!(0.0, root_layout.top);
	assert_eq!(100.0, root_layout.width);
	assert_eq!(100.0, root_layout.height);

	assert_eq!(20.0, child_layout.left);
	assert_eq!(20.0, child_layout.right);
	assert_eq!(10.0, child_layout.top);
	assert_eq!(10.0, child_layout.bottom);
	assert_eq!(60.0, child_layout.width);
	assert_eq!(80.0, child_layout.height);
}

#[test]
fn test_all_overridden() {
	let mut root = Node::new();

	style!(root,
		FlexDirection(FlexDirection::Row),
		Width(100 pt),
		Height(100 pt)
	);

	let mut root_child_0 = Node::new();

	style!(root_child_0,
		FlexGrow(1.0),
		MarginLeft(10 pt),
		MarginTop(10 pt),
		MarginRight(10 pt),
		MarginBottom(10 pt),
		Margin(20 pt)
	);

	root.insert_child(&mut root_child_0, 0);
	root.calculate_layout(Undefined, Undefined, Direction::LTR);

	let root_layout = root.get_layout();
	let child_layout = root_child_0.get_layout();

	assert_eq!(0.0, root_layout.left);
	assert_eq!(0.0, root_layout.top);
	assert_eq!(100.0, root_layout.width);
	assert_eq!(100.0, root_layout.height);

	assert_eq!(10.0, child_layout.left);
	assert_eq!(10.0, child_layout.right);
	assert_eq!(10.0, child_layout.top);
	assert_eq!(10.0, child_layout.bottom);
	assert_eq!(80.0, child_layout.width);
	assert_eq!(80.0, child_layout.height);

	root.calculate_layout(Undefined, Undefined, Direction::RTL);

	let root_layout = root.get_layout();
	let child_layout = root_child_0.get_layout();

	assert_eq!(0.0, root_layout.left);
	assert_eq!(0.0, root_layout.top);
	assert_eq!(100.0, root_layout.width);
	assert_eq!(100.0, root_layout.height);

	assert_eq!(10.0, child_layout.left);
	assert_eq!(10.0, child_layout.right);
	assert_eq!(10.0, child_layout.top);
	assert_eq!(10.0, child_layout.bottom);
	assert_eq!(80.0, child_layout.width);
	assert_eq!(80.0, child_layout.height);
}
<|endoftext|>


<commit_before><commit_msg>Remove debugging<commit_after><|endoftext|>


<commit_before>// This file is part of libfringe, a low-level green threading library.
// Copyright (c) whitequark <whitequark@whitequark.org>
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://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.
extern crate fringe;

use fringe::{Stack, SliceStack, OwnedStack, OsStack};
use fringe::generator::{Generator, Yielder};

fn add_one_fn<S: Stack>(yielder: &mut Yielder<i32, i32, S>, mut input: i32) {
  loop {
    if input == 0 { break }
    input = yielder.suspend(input + 1)
  }
}

fn new_add_one() -> Generator<i32, i32, OsStack> {
  let stack = OsStack::new(0).unwrap();
  Generator::new(stack, add_one_fn)
}

#[test]
fn generator() {
  let mut add_one = new_add_one();
  assert_eq!(add_one.resume(1), Some(2));
  assert_eq!(add_one.resume(2), Some(3));
  assert_eq!(add_one.resume(0), None);
}

#[test]
fn move_after_new() {
  let mut add_one = new_add_one();
  assert_eq!(add_one.resume(1), Some(2));

  #[inline(never)]
  fn run_moved(mut add_one: Generator<i32, i32, OsStack>) {
    assert_eq!(add_one.resume(2), Some(3));
    assert_eq!(add_one.resume(3), Some(4));
    assert_eq!(add_one.resume(0), None);
  }
  run_moved(add_one);
}

#[test]
#[should_panic]
fn panic_safety() {
  struct Wrapper {
    gen: Generator<(), (), OsStack>
  }

  impl Drop for Wrapper {
    fn drop(&mut self) {
      self.gen.resume(());
    }
  }

  let stack = OsStack::new(4 << 20).unwrap();
  let gen = Generator::new(stack, move |_yielder, ()| {
    panic!("foo")
  });

  let mut wrapper = Wrapper { gen: gen };
  wrapper.gen.resume(());
}

#[test]
fn with_slice_stack() {
  let mut memory = [0; 1024];
  let stack = SliceStack(&mut memory);
  let mut add_one = unsafe { Generator::unsafe_new(stack, add_one_fn) };
  assert_eq!(add_one.resume(1), Some(2));
  assert_eq!(add_one.resume(2), Some(3));
}

#[test]
fn with_owned_stack() {
  let stack = OwnedStack::new(1024);
  let mut add_one = unsafe { Generator::unsafe_new(stack, add_one_fn) };
  assert_eq!(add_one.resume(1), Some(2));
  assert_eq!(add_one.resume(2), Some(3));
}
<commit_msg>add regression test for #31<commit_after>// This file is part of libfringe, a low-level green threading library.
// Copyright (c) whitequark <whitequark@whitequark.org>,
//               Nathan Zadoks <nathan@nathan7.eu>
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://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.
extern crate fringe;

use fringe::{Stack, SliceStack, OwnedStack, OsStack};
use fringe::generator::{Generator, Yielder};

fn add_one_fn<S: Stack>(yielder: &mut Yielder<i32, i32, S>, mut input: i32) {
  loop {
    if input == 0 { break }
    input = yielder.suspend(input + 1)
  }
}

fn new_add_one() -> Generator<i32, i32, OsStack> {
  let stack = OsStack::new(0).unwrap();
  Generator::new(stack, add_one_fn)
}

#[test]
fn generator() {
  let mut add_one = new_add_one();
  assert_eq!(add_one.resume(1), Some(2));
  assert_eq!(add_one.resume(2), Some(3));
  assert_eq!(add_one.resume(0), None);
}

#[test]
fn move_after_new() {
  let mut add_one = new_add_one();
  assert_eq!(add_one.resume(1), Some(2));

  #[inline(never)]
  fn run_moved(mut add_one: Generator<i32, i32, OsStack>) {
    assert_eq!(add_one.resume(2), Some(3));
    assert_eq!(add_one.resume(3), Some(4));
    assert_eq!(add_one.resume(0), None);
  }
  run_moved(add_one);
}

#[test]
#[should_panic]
fn panic_safety() {
  struct Wrapper {
    gen: Generator<(), (), OsStack>
  }

  impl Drop for Wrapper {
    fn drop(&mut self) {
      self.gen.resume(());
    }
  }

  let stack = OsStack::new(4 << 20).unwrap();
  let gen = Generator::new(stack, move |_yielder, ()| {
    panic!("foo")
  });

  let mut wrapper = Wrapper { gen: gen };
  wrapper.gen.resume(());
}

#[test]
fn with_slice_stack() {
  let mut memory = [0; 1024];
  let stack = SliceStack(&mut memory);
  let mut add_one = unsafe { Generator::unsafe_new(stack, add_one_fn) };
  assert_eq!(add_one.resume(1), Some(2));
  assert_eq!(add_one.resume(2), Some(3));
}

#[test]
fn with_owned_stack() {
  let stack = OwnedStack::new(1024);
  let mut add_one = unsafe { Generator::unsafe_new(stack, add_one_fn) };
  assert_eq!(add_one.resume(1), Some(2));
  assert_eq!(add_one.resume(2), Some(3));
}

#[test]
fn forget_yielded() {
  struct Dropper(*mut bool);

  unsafe impl Send for Dropper {}

  impl Drop for Dropper {
    fn drop(&mut self) {
      unsafe {
        if *self.0 {
          panic!("double drop!")
        }
        *self.0 = true;
      }
    }
  }

  let stack = fringe::OsStack::new(1<<16).unwrap();
  let mut generator = Generator::new(stack, |yielder, ()| {
    let mut flag = false;
    yielder.suspend(Dropper(&mut flag as *mut bool));
  });
  generator.resume(());
  generator.resume(());
}
<|endoftext|>


<commit_before><commit_msg>add implementations of `Eq` and `Ord`<commit_after><|endoftext|>


<commit_before><commit_msg>Alias subcommand "show" to "list"<commit_after><|endoftext|>


<commit_before><commit_msg>wording: if -> when<commit_after><|endoftext|>


<commit_before><commit_msg>Do not use StoreId::local() here<commit_after><|endoftext|>


<commit_before><commit_msg>Add urdf example<commit_after>extern crate k;

use k::InverseKinematicsSolver;
use k::KinematicChain;

fn main() {
    let robot = k::urdf::create_tree_from_file("urdf/sample.urdf").unwrap();
    let mut arms = k::create_kinematic_chains(&robot);
    // set joint angles
    let angles = vec![0.8, 0.2, 0.0, -1.5, 0.0, -0.3];
    arms[0].set_joint_angles(&angles).unwrap();
    println!("initial angles={:?}", arms[0].get_joint_angles());
    // get the transform of the end of the manipulator (forward kinematics)
    let mut target = arms[0].calc_end_transform();
    println!("initial target pos = {}", target.translation);
    println!("move z: +0.2");
    target.translation.vector[2] += 0.2;
    let solver = k::JacobianIKSolverBuilder::new().finalize();
    // solve and move the manipulator angles
    solver
        .solve(&mut arms[0], &target)
        .unwrap_or_else(|err| {
                            println!("Err: {}", err);
                            0.0f32
                        });
    println!("solved angles={:?}", arms[0].get_joint_angles());
    println!("solved target pos = {}",
             arms[0].calc_end_transform().translation);
}
<|endoftext|>


<commit_before><commit_msg>Don't reexport IntoOutcome trait.<commit_after><|endoftext|>


<commit_before><commit_msg>Test keyword unreservations<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.

// Test that removed keywords are allowed as identifiers.
fn main () {
    let offsetof = ();
    let alignof = ();
    let sizeof = ();
    let pure = ();
}

fn offsetof() {}
fn alignof() {}
fn sizeof() {}
fn pure() {}
<|endoftext|>


<commit_before><commit_msg>Add TODO<commit_after><|endoftext|>


<commit_before><commit_msg>Add a test for r# identifiers<commit_after>pub mod internal {
    pub struct r#mod;

    /// See [name], [other name]
    ///
    /// [name]: mod
    /// [other name]: ../internal/struct.mod.html
    // @has 'raw_ident_eliminate_r_hashtag/internal/struct.B.html' '//a[@href="../raw_ident_eliminate_r_hashtag/internal/struct.mod.html"]' 'name'
    // @has 'raw_ident_eliminate_r_hashtag/internal/struct.B.html' '//a[@href="../raw_ident_eliminate_r_hashtag/internal/struct.mod.html"]' 'other name'
    pub struct B;
}

/// See [name].
///
/// [name]: internal::mod
// @has 'raw_ident_eliminate_r_hashtag/struct.A.html' '//a[@href="../raw_ident_eliminate_r_hashtag/internal/struct.mod.html"]' 'name'
struct A;
<|endoftext|>


<commit_before><commit_msg>Move thread handle in function<commit_after><|endoftext|>


<commit_before><commit_msg>Add test for short-circuiting #[deriving(Eq,Ord,TotalEq,TotalOrd)].<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.

// check that the derived impls for the comparison traits shortcircuit
// where possible, by having a type that fails when compared as the
// second element, so this passes iff the instances shortcircuit.

pub struct FailCmp;
impl Eq for FailCmp {
    fn eq(&self, _: &FailCmp) -> bool { fail!("eq") }
}

impl Ord for FailCmp {
    fn lt(&self, _: &FailCmp) -> bool { fail!("lt") }
}

impl TotalEq for FailCmp {
    fn equals(&self, _: &FailCmp) -> bool { fail!("equals") }
}

impl TotalOrd for FailCmp {
    fn cmp(&self, _: &FailCmp) -> Ordering { fail!("cmp") }
}

#[deriving(Eq,Ord,TotalEq,TotalOrd)]
struct ShortCircuit {
    x: int,
    y: FailCmp
}

fn main() {
    let a = ShortCircuit { x: 1, y: FailCmp };
    let b = ShortCircuit { x: 2, y: FailCmp };

    assert!(a != b);
    assert!(a < b);
    assert!(!a.equals(&b));
    assert_eq!(a.cmp(&b), ::std::cmp::Less);
}
<|endoftext|>


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

#![crate_type = "rlib"]
#![feature(linkage)]

pub fn foo<T>() -> *const() {
    extern {
        #[linkage = "extern_weak"]
        static FOO: *const();
    }
    unsafe { FOO }
}
<commit_msg>Disable regression test for issue #18804 on Emscripten and Asmjs<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.

// ignore-asmjs no weak symbol support
// ignore-emscripten no weak symbol support

#![crate_type = "rlib"]
#![feature(linkage)]

pub fn foo<T>() -> *const() {
    extern {
        #[linkage = "extern_weak"]
        static FOO: *const();
    }
    unsafe { FOO }
}
<|endoftext|>


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

// Check that when a `let`-binding occurs in a loop, its associated
// drop-flag is reinitialized (to indicate "needs-drop" at the end of
// the owning variable's scope).

struct A<'a>(&'a mut i32);

impl<'a> Drop for A<'a> {
    fn drop(&mut self) {
        *self.0 += 1;
    }
}

fn main() {
    let mut cnt = 0;
    for i in 0..2 {
        let a = A(&mut cnt);
        if i == 1 { // Note that
            break;  //  both this break
        }           //   and also
        drop(a);    //    this move of `a`
        // are necessary to expose the bug
    }
    assert_eq!(cnt, 2);
}
<|endoftext|>


<commit_before><commit_msg>adding ord<commit_after>use std::os::args;
use std::from_str::FromStr;

fn main() {
    let p : int = FromStr::from_str(args()[1]).unwrap();
    let n : int = FromStr::from_str(args()[2]).unwrap();

    println(fmt!("ord_%d(%d) = %d", p, n, ord(p,n,0)));
}

fn ord(p : int, n : int, q : int) -> int {
    if n % p != 0 {
        q
    } else {
        ord(p, n / p, q + 1)
    }
}
<|endoftext|>


<commit_before><commit_msg>Don't allocate strings in Debug for DisplayItem<commit_after><|endoftext|>


<commit_before><commit_msg>Binary search in Rust<commit_after><|endoftext|>


<commit_before><commit_msg>Derive 'PartialOrd', 'Ord', and 'Hash' for 'State'.<commit_after><|endoftext|>


<commit_before>struct Point {
    x: f64,
    y: f64,
}

// Implementation block, all `Point` methods go in here
impl Point {
    // This is a static method
    // Static methods don't need to be called by an instance
    // These methods are generally used as constructors
    fn origin() -> Point {
        Point { x: 0.0, y: 0.0 }
    }

    // Another static method, taking two arguments:
    fn new(x: f64, y: f64) -> Point {
        Point { x: x, y: y }
    }
}

struct Rectangle {
    p1: Point,
    p2: Point,
}

impl Rectangle {
    // This is an instance method
    // `&self` is sugar for `self: &Self`, where `Self` is the type of the
    // caller object. In this case `Self` = `Rectangle`
    fn area(&self) -> f64 {
        // `self` gives access to the struct fields via the dot operator
        let Point { x: x1, y: y1 } = self.p1;
        let Point { x: x2, y: y2 } = self.p2;

        // `abs` is a `f64` method that returns the absolute value of the
        // caller
        ((x1 - x2) * (y1 - y2)).abs()
    }

    fn perimeter(&self) -> f64 {
        let Point { x: x1, y: y1 } = self.p1;
        let Point { x: x2, y: y2 } = self.p2;

        2.0 * ((x1 - x2).abs() + (y1 - y2).abs())
    }

    // This method requires the caller object to be mutable
    // `&mut self` desugars to `self: &mut Self`
    fn translate(&mut self, x: f64, y: f64) {
        self.p1.x += x;
        self.p2.x += x;

        self.p1.y += y;
        self.p2.y += y;
    }
}

// `Pair` owns resources: two heap allocated integers
struct Pair(Box<i32>, Box<i32>);

impl Pair {
    // This method "consumes" the resources of the caller object
    // `self` desugars to `self: Self`
    fn destroy(self) {
        // Destructure `self`
        let Pair(first, second) = self;

        println!("Destroying Pair({}, {})", first, second);

        // `first` and `second` go out of scope and get freed
    }
}

fn main() {
    let rectangle = Rectangle {
        // Static methods are called using double colons
        p1: Point::origin(),
        p2: Point::new(3.0, 4.0),
    };

    // Instance methods are called using the dot operator
    // Note that the first argument `&self` is implicitly passed, i.e.
    // `rectangle.perimeter()` === `perimeter(&rectangle)`
    println!("Rectangle perimeter: {}", rectangle.perimeter());
    println!("Rectangle area: {}", rectangle.area());

    let mut square = Rectangle {
        p1: Point::origin(),
        p2: Point::new(1.0, 1.0),
    };

    // Error! `rectangle` is immutable, but this method requires a mutable
    // object
    //rectangle.translate(1.0, 0.0);
    // TODO ^ Try uncommenting this line

    // Okay! Mutable objects can call mutable methods
    square.translate(1.0, 1.0);

    let pair = Pair(Box::new(1), Box::new(2));

    pair.destroy();

    // Error! Previous `destroy` call "consumed" `pair`
    //pair.destroy();
    // TODO ^ Try uncommenting this line
}
<commit_msg>fn/methods: Clarify method comparison to static call with reference.<commit_after>struct Point {
    x: f64,
    y: f64,
}

// Implementation block, all `Point` methods go in here
impl Point {
    // This is a static method
    // Static methods don't need to be called by an instance
    // These methods are generally used as constructors
    fn origin() -> Point {
        Point { x: 0.0, y: 0.0 }
    }

    // Another static method, taking two arguments:
    fn new(x: f64, y: f64) -> Point {
        Point { x: x, y: y }
    }
}

struct Rectangle {
    p1: Point,
    p2: Point,
}

impl Rectangle {
    // This is an instance method
    // `&self` is sugar for `self: &Self`, where `Self` is the type of the
    // caller object. In this case `Self` = `Rectangle`
    fn area(&self) -> f64 {
        // `self` gives access to the struct fields via the dot operator
        let Point { x: x1, y: y1 } = self.p1;
        let Point { x: x2, y: y2 } = self.p2;

        // `abs` is a `f64` method that returns the absolute value of the
        // caller
        ((x1 - x2) * (y1 - y2)).abs()
    }

    fn perimeter(&self) -> f64 {
        let Point { x: x1, y: y1 } = self.p1;
        let Point { x: x2, y: y2 } = self.p2;

        2.0 * ((x1 - x2).abs() + (y1 - y2).abs())
    }

    // This method requires the caller object to be mutable
    // `&mut self` desugars to `self: &mut Self`
    fn translate(&mut self, x: f64, y: f64) {
        self.p1.x += x;
        self.p2.x += x;

        self.p1.y += y;
        self.p2.y += y;
    }
}

// `Pair` owns resources: two heap allocated integers
struct Pair(Box<i32>, Box<i32>);

impl Pair {
    // This method "consumes" the resources of the caller object
    // `self` desugars to `self: Self`
    fn destroy(self) {
        // Destructure `self`
        let Pair(first, second) = self;

        println!("Destroying Pair({}, {})", first, second);

        // `first` and `second` go out of scope and get freed
    }
}

fn main() {
    let rectangle = Rectangle {
        // Static methods are called using double colons
        p1: Point::origin(),
        p2: Point::new(3.0, 4.0),
    };

    // Instance methods are called using the dot operator
    // Note that the first argument `&self` is implicitly passed, i.e.
    // `rectangle.perimeter()` === `Rectangle::perimeter(&rectangle)`
    println!("Rectangle perimeter: {}", rectangle.perimeter());
    println!("Rectangle area: {}", rectangle.area());

    let mut square = Rectangle {
        p1: Point::origin(),
        p2: Point::new(1.0, 1.0),
    };

    // Error! `rectangle` is immutable, but this method requires a mutable
    // object
    //rectangle.translate(1.0, 0.0);
    // TODO ^ Try uncommenting this line

    // Okay! Mutable objects can call mutable methods
    square.translate(1.0, 1.0);

    let pair = Pair(Box::new(1), Box::new(2));

    pair.destroy();

    // Error! Previous `destroy` call "consumed" `pair`
    //pair.destroy();
    // TODO ^ Try uncommenting this line
}
<|endoftext|>


<commit_before><commit_msg>Add a simple CSP example<commit_after><|endoftext|>


<commit_before><commit_msg>account.setInfo method<commit_after><|endoftext|>


<commit_before><commit_msg>contrl<commit_after><|endoftext|>


<commit_before><commit_msg>Add Rust implementation of 99 Bottles<commit_after>// Sings '99 Bottles of Beer'
fn main()
{
    for bottle in (0..100).rev()
    {
        if bottle > 1
        {
            println!("{} bottles of beer on the wall, {} bottles of beer.", bottle, bottle);
            if bottle > 2
            {
                println!("Take one down and pass it around, {} bottles of beer on the wall.", bottle - 1);
            } else
            {
                println!("Take one down and pass it around, 1 bottle of beer on the wall.");
            }
        } else
        {
            println!("1 bottle of beer on the wall, 1 bottle of beer.");
            println!("Take one down and pass it around, no more bottles of beer on the wall.");
        }
        println!("");
    }
    println!("No more bottles of beer on the wall, no more bottles of beer.");
    println!("Go to the store and buy some more, 99 bottles of beer on the wall.\n");
}
<|endoftext|>


<commit_before><commit_msg>Use panics for evaluation errors.<commit_after><|endoftext|>


<commit_before><commit_msg>Fix missing cmd module<commit_after>use xrl::ViewId;

/// Command system for xi-term.
/// A command represents a task the user wants the editor to preform,
/// currently commands can only be input through the CommandPrompt. Vim style.
#[derive(Debug)]
pub enum Command {
    /// Close the CommandPrompt
    Cancel,
    /// Quit editor.
    Quit,
    /// Save the current file buffer
    Save(Option<ViewId>),
    Invalid(String)
}
<|endoftext|>


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


<commit_before><commit_msg>chore(backend): remove backend.rs after it was moved to mod.rs<commit_after><|endoftext|>


<commit_before><commit_msg>Structures for containing raw authentication messages<commit_after><|endoftext|>