<commit_before>//! OpenGL back-end for Rust-Graphics.

// External crates.
use shader_version::{opengl, glsl};
use graphics::{ Context, BackEnd };
use gl;
use gl::types::{
    GLint,
    GLsizei,
    GLuint,
};
use shader_utils::{
    compile_shader,
    DynamicAttribute,
};

// Local crate.
use Texture;

static VS_COLORED_120: &'static str = "
#version 120
uniform vec4 color;

attribute vec4 pos;

void main()
{
    gl_Position = pos;
}
";

static VS_COLORED_150_CORE: &'static str = "
#version 150 core
uniform vec4 color;

in vec4 pos;

void main()
{
    gl_Position = pos;
}
";

static FS_COLORED_120: &'static str = "
#version 120
uniform vec4 color;

void main()
{
    gl_FragColor = color;
}
";

static FS_COLORED_150_CORE: &'static str = "
#version 150 core
uniform vec4 color;

out vec4 out_color;

void main()
{
    out_color = color;
}
";

static VS_TEXTURED_120: &'static str = "
#version 120
uniform vec4 color;

attribute vec4 pos;
attribute vec2 uv;

uniform sampler2D s_texture;

varying vec2 v_uv;

void main()
{
    v_uv = uv;
    gl_Position = pos;
}
";

static VS_TEXTURED_150_CORE: &'static str = "
#version 150 core
uniform vec4 color;

in vec4 pos;
in vec2 uv;

uniform sampler2D s_texture;

out vec2 v_uv;

void main()
{
    v_uv = uv;
    gl_Position = pos;
}
";

static FS_TEXTURED_120: &'static str = "
#version 120
uniform vec4 color;
uniform sampler2D s_texture;

varying vec2 v_uv;

void main()
{
    gl_FragColor = texture2D(s_texture, v_uv) * color;
}
";

static FS_TEXTURED_150_CORE: &'static str = "
#version 150 core
uniform vec4 color;
uniform sampler2D s_texture;

out vec4 out_color;

in vec2 v_uv;

void main()
{
    out_color = texture(s_texture, v_uv) * color;
}
";

fn pick_120_150<T>(glsl: glsl::GLSL, for_120: T, for_150: T) -> T {
    use shader_version::glsl::GLSL;
    match glsl {
        GLSL::_1_10 => panic!("GLSL 1.10 not supported"),
        GLSL::_1_20
      | GLSL::_1_30
      | GLSL::_1_40 => for_120,
        _ => for_150,
    }
}

struct Colored {
    vao: GLuint,
    vertex_shader: GLuint,
    fragment_shader: GLuint,
    program: GLuint,
    pos: DynamicAttribute,
    color: GLint,
}

impl Drop for Colored {
    fn drop(&mut self) {
        unsafe {
            gl::DeleteVertexArrays(1, &self.vao);
            gl::DeleteProgram(self.program);
            gl::DeleteShader(self.vertex_shader);
            gl::DeleteShader(self.fragment_shader);
        }
    }
}

impl Colored {
    fn new(glsl: glsl::GLSL) -> Colored {
        let vertex_shader = match compile_shader(
            gl::VERTEX_SHADER,                  // shader type
            pick_120_150(glsl, VS_COLORED_120, VS_COLORED_150_CORE)
        ) {
            Ok(id) => id,
            Err(s) => panic!("compile_shader: {}", s)
        };
        let fragment_shader = match compile_shader(
            gl::FRAGMENT_SHADER,                // shader type
            pick_120_150(glsl, FS_COLORED_120, FS_COLORED_150_CORE)
        ) {
            Ok(id) => id,
            Err(s) => panic!("compile_shader: {}", s)
        };

        let program;
        unsafe {
            program = gl::CreateProgram();
            gl::AttachShader(program, vertex_shader);
            gl::AttachShader(program, fragment_shader);

            "out_color".with_c_str(
                |ptr| gl::BindFragDataLocation(program, 0, ptr)
            );
        }

        let mut vao = 0;
        unsafe {
            gl::GenVertexArrays(1, &mut vao);
            gl::LinkProgram(program);
        }
        let pos = DynamicAttribute::xy(
                program,
                "pos",
                vao
            ).unwrap();
        let color = unsafe {
                "color".with_c_str(|name| gl::GetUniformLocation(program, name))
            };
        if color == -1 {
            panic!("Could not find uniform `color`");
        }
        Colored {
            vao: vao,
            vertex_shader: vertex_shader,
            fragment_shader: fragment_shader,
            program: program,
            pos: pos,
            color: color,
        }
    }
}

struct Textured {
    vertex_shader: GLuint,
    fragment_shader: GLuint,
    program: GLuint,
    vao: GLuint,
    color: GLint,
    pos: DynamicAttribute,
    uv: DynamicAttribute,
}

impl Drop for Textured {
    fn drop(&mut self) {
        unsafe {
            gl::DeleteVertexArrays(1, &self.vao);
            gl::DeleteProgram(self.program);
            gl::DeleteShader(self.vertex_shader);
            gl::DeleteShader(self.fragment_shader);
        }
    }
}

impl Textured {
    fn new(glsl: glsl::GLSL) -> Textured {
        let vertex_shader = match compile_shader(
            gl::VERTEX_SHADER,                  // shader type
            pick_120_150(glsl, VS_TEXTURED_120, VS_TEXTURED_150_CORE)
        ) {
            Ok(id) => id,
            Err(s) => panic!("compile_shader: {}", s)
        };
        let fragment_shader = match compile_shader(
            gl::FRAGMENT_SHADER,                // shader type
            pick_120_150(glsl, FS_TEXTURED_120, FS_TEXTURED_150_CORE)
        ) {
            Ok(id) => id,
            Err(s) => panic!("compile_shader: {}", s)
        };

        let program;
        unsafe {
            program = gl::CreateProgram();
            gl::AttachShader(program, vertex_shader);
            gl::AttachShader(program, fragment_shader);

            "out_color".with_c_str(
                |ptr| gl::BindFragDataLocation(program, 0, ptr)
            );
        }

        let mut vao = 0;
        unsafe {
            gl::GenVertexArrays(1, &mut vao);
            gl::LinkProgram(program);
        }
        let pos = DynamicAttribute::xy(
                program,
                "pos",
                vao
            ).unwrap();
        let color = unsafe {
                "color".with_c_str(|name| gl::GetUniformLocation(program, name))
            };
        if color == -1 {
            panic!("Could not find uniform `color`");
        }
        let uv = DynamicAttribute::uv(
                program,
                "uv",
                vao
            ).unwrap();
        Textured {
            vao: vao,
            vertex_shader: vertex_shader,
            fragment_shader: fragment_shader,
            program: program,
            pos: pos,
            color: color,
            uv: uv,
        }
    }
}

/// Contains OpenGL data.
pub struct Gl {
    colored: Colored,
    textured: Textured,
    // Keeps track of the current shader program.
    current_program: Option<GLuint>,
    color: [f32, ..4],
}

impl<'a> Gl {
    /// Creates a new OpenGl back-end.
    pub fn new(opengl: opengl::OpenGL) -> Gl {
        let glsl = opengl.to_GLSL();
        // Load the vertices, color and texture coord buffers.
        Gl {
            colored: Colored::new(glsl),
            textured: Textured::new(glsl),
            current_program: None,
            color: [1.0, ..4],
       }
    }

    /// Sets viewport with normalized coordinates and center as origin.
    pub fn viewport(
        &mut self,
        x: i32,
        y: i32,
        w: i32,
        h: i32
    ) {
        unsafe {
            gl::Viewport(x as GLint, y as GLint, w as GLsizei, h as GLsizei);
        }
    }

    /// Sets the current program only if the program is not in use.
    pub fn use_program(&mut self, program: GLuint) {
        match self.current_program {
            None => {},
            Some(current_program) => {
                if program == current_program { return; }
            },
        }

        unsafe {
            gl::UseProgram(program);
        }
        self.current_program = Some(program);
    }

    /// Unset the current program.
    ///
    /// This forces the current program to be set on next drawing call.
    pub fn clear_program(&mut self) {
        self.current_program = None
    }

    /// Draws graphics.
    pub fn draw(&mut self, viewport: [i32, ..4], f: |c: Context, g: &mut Gl|) {
        let [x, y, w, h] = viewport;
        self.viewport(x, y, w, h);
        self.clear_program();
        self.enable_alpha_blend();
        let c = Context::abs(
            w as f64,
            h as f64
        );
        f(c, self);
        self.disable_alpha_blend();
    }

    /// Assume all textures has alpha channel for now.
    pub fn has_texture_alpha(&self, _texture: &Texture) -> bool { true }

    /// Enabled alpha blending.
    pub fn enable_alpha_blend(&mut self) {
        unsafe {
            gl::Enable(gl::BLEND);
            gl::BlendFunc(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);
        }
    }

    /// Disables alpha blending.
    pub fn disable_alpha_blend(&mut self) {
        unsafe {
            gl::Disable(gl::BLEND);
        }
    }
}

impl BackEnd<Texture> for Gl {
    fn clear(&mut self, color: [f32, ..4]) {
        unsafe {
            let [r, g, b, a] = color;
            gl::ClearColor(r, g, b, a);
            gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
        }
    }

    fn enable_texture(&mut self, texture: &Texture) {
        let texture = texture.get_id();
        unsafe {
            gl::BindTexture(gl::TEXTURE_2D, texture);
        }
    }

    fn disable_texture(&mut self) {}

    fn color(&mut self, color: [f32, ..4]) {
        self.color = color;
    }

    fn tri_list(&mut self, vertices: &[f32]) {
        {
            // Set shader program.
            let shader_program = self.colored.program;
            self.use_program(shader_program);
        }
        let ref mut shader = self.colored;

        // xy makes two floats.
        let size_vertices: i32 = 2;
        let items: i32 = vertices.len() as i32 / size_vertices;

        let color = self.color;
        unsafe {
            gl::BindVertexArray(shader.vao);
            shader.pos.set(vertices);
            gl::Uniform4f(shader.color, color[0], color[1], color[2], color[3]);

            // Render triangles whether they are facing
            // clockwise or counter clockwise.
            gl::CullFace(gl::FRONT_AND_BACK);

            gl::DrawArrays(gl::TRIANGLES, 0, items);

            gl::BindVertexArray(0);
        }
    }

    fn tri_list_uv(&mut self, vertices: &[f32], texture_coords: &[f32]) {
        {
            // Set shader program.
            let shader_program = self.textured.program;
            self.use_program(shader_program);
        }
        let ref mut shader = self.textured;

        let size_vertices: i32 = 2;
        let items: i32 = vertices.len() as i32 / size_vertices;

        let color = self.color;
        unsafe {
            gl::BindVertexArray(shader.vao);
            shader.pos.set(vertices);
            gl::Uniform4f(shader.color, color[0], color[1], color[2], color[3]);
            shader.uv.set(texture_coords);
            // Render triangles whether they are facing
            // clockwise or counter clockwise.
            gl::CullFace(gl::FRONT_AND_BACK);

            gl::DrawArrays(gl::TRIANGLES, 0, items);

            gl::BindVertexArray(0);
        }
    }
}

<commit_msg>Assert that OpenGL function pointers are loaded<commit_after>//! OpenGL back-end for Rust-Graphics.

// External crates.
use shader_version::{opengl, glsl};
use graphics::{ Context, BackEnd };
use gl;
use gl::types::{
    GLint,
    GLsizei,
    GLuint,
};
use shader_utils::{
    compile_shader,
    DynamicAttribute,
};

// Local crate.
use Texture;

static VS_COLORED_120: &'static str = "
#version 120
uniform vec4 color;

attribute vec4 pos;

void main()
{
    gl_Position = pos;
}
";

static VS_COLORED_150_CORE: &'static str = "
#version 150 core
uniform vec4 color;

in vec4 pos;

void main()
{
    gl_Position = pos;
}
";

static FS_COLORED_120: &'static str = "
#version 120
uniform vec4 color;

void main()
{
    gl_FragColor = color;
}
";

static FS_COLORED_150_CORE: &'static str = "
#version 150 core
uniform vec4 color;

out vec4 out_color;

void main()
{
    out_color = color;
}
";

static VS_TEXTURED_120: &'static str = "
#version 120
uniform vec4 color;

attribute vec4 pos;
attribute vec2 uv;

uniform sampler2D s_texture;

varying vec2 v_uv;

void main()
{
    v_uv = uv;
    gl_Position = pos;
}
";

static VS_TEXTURED_150_CORE: &'static str = "
#version 150 core
uniform vec4 color;

in vec4 pos;
in vec2 uv;

uniform sampler2D s_texture;

out vec2 v_uv;

void main()
{
    v_uv = uv;
    gl_Position = pos;
}
";

static FS_TEXTURED_120: &'static str = "
#version 120
uniform vec4 color;
uniform sampler2D s_texture;

varying vec2 v_uv;

void main()
{
    gl_FragColor = texture2D(s_texture, v_uv) * color;
}
";

static FS_TEXTURED_150_CORE: &'static str = "
#version 150 core
uniform vec4 color;
uniform sampler2D s_texture;

out vec4 out_color;

in vec2 v_uv;

void main()
{
    out_color = texture(s_texture, v_uv) * color;
}
";

fn pick_120_150<T>(glsl: glsl::GLSL, for_120: T, for_150: T) -> T {
    use shader_version::glsl::GLSL;
    match glsl {
        GLSL::_1_10 => panic!("GLSL 1.10 not supported"),
        GLSL::_1_20
      | GLSL::_1_30
      | GLSL::_1_40 => for_120,
        _ => for_150,
    }
}

struct Colored {
    vao: GLuint,
    vertex_shader: GLuint,
    fragment_shader: GLuint,
    program: GLuint,
    pos: DynamicAttribute,
    color: GLint,
}

impl Drop for Colored {
    fn drop(&mut self) {
        unsafe {
            gl::DeleteVertexArrays(1, &self.vao);
            gl::DeleteProgram(self.program);
            gl::DeleteShader(self.vertex_shader);
            gl::DeleteShader(self.fragment_shader);
        }
    }
}

impl Colored {
    fn new(glsl: glsl::GLSL) -> Colored {
        let vertex_shader = match compile_shader(
            gl::VERTEX_SHADER,                  // shader type
            pick_120_150(glsl, VS_COLORED_120, VS_COLORED_150_CORE)
        ) {
            Ok(id) => id,
            Err(s) => panic!("compile_shader: {}", s)
        };
        let fragment_shader = match compile_shader(
            gl::FRAGMENT_SHADER,                // shader type
            pick_120_150(glsl, FS_COLORED_120, FS_COLORED_150_CORE)
        ) {
            Ok(id) => id,
            Err(s) => panic!("compile_shader: {}", s)
        };

        let program;
        unsafe {
            program = gl::CreateProgram();
            gl::AttachShader(program, vertex_shader);
            gl::AttachShader(program, fragment_shader);

            "out_color".with_c_str(
                |ptr| gl::BindFragDataLocation(program, 0, ptr)
            );
        }

        let mut vao = 0;
        unsafe {
            gl::GenVertexArrays(1, &mut vao);
            gl::LinkProgram(program);
        }
        let pos = DynamicAttribute::xy(
                program,
                "pos",
                vao
            ).unwrap();
        let color = unsafe {
                "color".with_c_str(|name| gl::GetUniformLocation(program, name))
            };
        if color == -1 {
            panic!("Could not find uniform `color`");
        }
        Colored {
            vao: vao,
            vertex_shader: vertex_shader,
            fragment_shader: fragment_shader,
            program: program,
            pos: pos,
            color: color,
        }
    }
}

struct Textured {
    vertex_shader: GLuint,
    fragment_shader: GLuint,
    program: GLuint,
    vao: GLuint,
    color: GLint,
    pos: DynamicAttribute,
    uv: DynamicAttribute,
}

impl Drop for Textured {
    fn drop(&mut self) {
        unsafe {
            gl::DeleteVertexArrays(1, &self.vao);
            gl::DeleteProgram(self.program);
            gl::DeleteShader(self.vertex_shader);
            gl::DeleteShader(self.fragment_shader);
        }
    }
}

impl Textured {
    fn new(glsl: glsl::GLSL) -> Textured {
        let vertex_shader = match compile_shader(
            gl::VERTEX_SHADER,                  // shader type
            pick_120_150(glsl, VS_TEXTURED_120, VS_TEXTURED_150_CORE)
        ) {
            Ok(id) => id,
            Err(s) => panic!("compile_shader: {}", s)
        };
        let fragment_shader = match compile_shader(
            gl::FRAGMENT_SHADER,                // shader type
            pick_120_150(glsl, FS_TEXTURED_120, FS_TEXTURED_150_CORE)
        ) {
            Ok(id) => id,
            Err(s) => panic!("compile_shader: {}", s)
        };

        let program;
        unsafe {
            program = gl::CreateProgram();
            gl::AttachShader(program, vertex_shader);
            gl::AttachShader(program, fragment_shader);

            "out_color".with_c_str(
                |ptr| gl::BindFragDataLocation(program, 0, ptr)
            );
        }

        let mut vao = 0;
        unsafe {
            gl::GenVertexArrays(1, &mut vao);
            gl::LinkProgram(program);
        }
        let pos = DynamicAttribute::xy(
                program,
                "pos",
                vao
            ).unwrap();
        let color = unsafe {
                "color".with_c_str(|name| gl::GetUniformLocation(program, name))
            };
        if color == -1 {
            panic!("Could not find uniform `color`");
        }
        let uv = DynamicAttribute::uv(
                program,
                "uv",
                vao
            ).unwrap();
        Textured {
            vao: vao,
            vertex_shader: vertex_shader,
            fragment_shader: fragment_shader,
            program: program,
            pos: pos,
            color: color,
            uv: uv,
        }
    }
}

// Newlines and indents for cleaner panic message.
const GL_FUNC_NOT_LOADED: &'static str = "
    OpenGL function pointers must be loaded before creating the `Gl` backend!
    For more info, see the following issue on GitHub:
    https://github.com/PistonDevelopers/opengl_graphics/issues/103
";

/// Contains OpenGL data.
pub struct Gl {
    colored: Colored,
    textured: Textured,
    // Keeps track of the current shader program.
    current_program: Option<GLuint>,
    color: [f32, ..4],
}

impl<'a> Gl {
    /// Creates a new OpenGL back-end.
    ///
    /// # Panics
    /// If the OpenGL function pointers have not been loaded yet.
    /// See https://github.com/PistonDevelopers/opengl_graphics/issues/103 for more info.
    pub fn new(opengl: opengl::OpenGL) -> Gl {
        assert!(gl::Enable::is_loaded(), GL_FUNC_NOT_LOADED);

        let glsl = opengl.to_GLSL();
        // Load the vertices, color and texture coord buffers.
        Gl {
            colored: Colored::new(glsl),
            textured: Textured::new(glsl),
            current_program: None,
            color: [1.0, ..4],
       }
    }

    /// Sets viewport with normalized coordinates and center as origin.
    pub fn viewport(
        &mut self,
        x: i32,
        y: i32,
        w: i32,
        h: i32
    ) {
        unsafe {
            gl::Viewport(x as GLint, y as GLint, w as GLsizei, h as GLsizei);
        }
    }

    /// Sets the current program only if the program is not in use.
    pub fn use_program(&mut self, program: GLuint) {
        match self.current_program {
            None => {},
            Some(current_program) => {
                if program == current_program { return; }
            },
        }

        unsafe {
            gl::UseProgram(program);
        }
        self.current_program = Some(program);
    }

    /// Unset the current program.
    ///
    /// This forces the current program to be set on next drawing call.
    pub fn clear_program(&mut self) {
        self.current_program = None
    }

    /// Draws graphics.
    pub fn draw(&mut self, viewport: [i32, ..4], f: |c: Context, g: &mut Gl|) {
        let [x, y, w, h] = viewport;
        self.viewport(x, y, w, h);
        self.clear_program();
        self.enable_alpha_blend();
        let c = Context::abs(
            w as f64,
            h as f64
        );
        f(c, self);
        self.disable_alpha_blend();
    }

    /// Assume all textures has alpha channel for now.
    pub fn has_texture_alpha(&self, _texture: &Texture) -> bool { true }

    /// Enabled alpha blending.
    pub fn enable_alpha_blend(&mut self) {
        unsafe {
            gl::Enable(gl::BLEND);
            gl::BlendFunc(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);
        }
    }

    /// Disables alpha blending.
    pub fn disable_alpha_blend(&mut self) {
        unsafe {
            gl::Disable(gl::BLEND);
        }
    }
}

impl BackEnd<Texture> for Gl {
    fn clear(&mut self, color: [f32, ..4]) {
        unsafe {
            let [r, g, b, a] = color;
            gl::ClearColor(r, g, b, a);
            gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
        }
    }

    fn enable_texture(&mut self, texture: &Texture) {
        let texture = texture.get_id();
        unsafe {
            gl::BindTexture(gl::TEXTURE_2D, texture);
        }
    }

    fn disable_texture(&mut self) {}

    fn color(&mut self, color: [f32, ..4]) {
        self.color = color;
    }

    fn tri_list(&mut self, vertices: &[f32]) {
        {
            // Set shader program.
            let shader_program = self.colored.program;
            self.use_program(shader_program);
        }
        let ref mut shader = self.colored;

        // xy makes two floats.
        let size_vertices: i32 = 2;
        let items: i32 = vertices.len() as i32 / size_vertices;

        let color = self.color;
        unsafe {
            gl::BindVertexArray(shader.vao);
            shader.pos.set(vertices);
            gl::Uniform4f(shader.color, color[0], color[1], color[2], color[3]);

            // Render triangles whether they are facing
            // clockwise or counter clockwise.
            gl::CullFace(gl::FRONT_AND_BACK);

            gl::DrawArrays(gl::TRIANGLES, 0, items);

            gl::BindVertexArray(0);
        }
    }

    fn tri_list_uv(&mut self, vertices: &[f32], texture_coords: &[f32]) {
        {
            // Set shader program.
            let shader_program = self.textured.program;
            self.use_program(shader_program);
        }
        let ref mut shader = self.textured;

        let size_vertices: i32 = 2;
        let items: i32 = vertices.len() as i32 / size_vertices;

        let color = self.color;
        unsafe {
            gl::BindVertexArray(shader.vao);
            shader.pos.set(vertices);
            gl::Uniform4f(shader.color, color[0], color[1], color[2], color[3]);
            shader.uv.set(texture_coords);
            // Render triangles whether they are facing
            // clockwise or counter clockwise.
            gl::CullFace(gl::FRONT_AND_BACK);

            gl::DrawArrays(gl::TRIANGLES, 0, items);

            gl::BindVertexArray(0);
        }
    }
}

// Might not fail if previous tests loaded functions.
#[test]
#[should_fail]
fn test_gl_loaded() {
    Gl::new(opengl::OpenGL::_3_2);
}
<|endoftext|>


<commit_before>
use error::{ConrodResult, FreetypeError};
use freetype;
use freetype::error::MissingFontField;
use label::FontSize;
use opengl_graphics::Texture;
use std::collections::HashMap;
use std::collections::hashmap::{Occupied, Vacant};

/// Struct used to hold rendered character data.
pub struct Character {
    pub glyph: freetype::Glyph,
    pub bitmap_glyph: freetype::BitmapGlyph,
    pub texture: Texture,
}

/// A struct used for caching rendered font.
pub struct GlyphCache {
    pub face: freetype::Face,
    data: HashMap<FontSize, HashMap<char, Character>>,
}

impl GlyphCache {

    /// Constructor for a GlyphCache.
    pub fn new(font: &Path) -> ConrodResult<GlyphCache> {
        let freetype = match freetype::Library::init() {
            Ok(freetype) => freetype,
            Err(why) => return Err(FreetypeError(why)),
        };
        let font_str = match font.as_str() {
            Some(font_str) => font_str,
            None => return Err(FreetypeError(MissingFontField)),
        };
        let face = match freetype.new_face(font_str, 0) {
            Ok(face) => face,
            Err(why) => return Err(FreetypeError(why)),
        };
        Ok(GlyphCache {
            face: face,
            data: HashMap::new(),
        })
    }

    /// Return a reference to a `Character`. If there is not yet a `Character` for
    /// the given `FontSize` and `char`, load the `Character`.
    pub fn get_character(&mut self, size: FontSize, ch: char) -> &Character {
        match {
            match self.data.entry(size) {
                Vacant(entry) => entry.set(HashMap::new()),
                Occupied(entry) => entry.into_mut(),
            }
        }.contains_key(&ch) {
            true => &self.data[size][ch],
            false => { self.load_character(size, ch); &self.data[size][ch] }
        }
    }

    /// Load a `Character` from a given `FontSize` and `char`.
    fn load_character(&mut self, size: FontSize, ch: char) {
        self.face.set_pixel_sizes(0, size).unwrap();
        self.face.load_char(ch as u64, freetype::face::DEFAULT).unwrap();
        let glyph = self.face.glyph().get_glyph().unwrap();
        let bitmap_glyph = glyph.to_bitmap(freetype::render_mode::Normal, None).unwrap();
        let bitmap = bitmap_glyph.bitmap();
        let texture = Texture::from_memory_alpha(bitmap.buffer(),
                                                 bitmap.width() as u32,
                                                 bitmap.rows() as u32).unwrap();
        self.data[size].insert(ch, Character {
            glyph: glyph,
            bitmap_glyph: bitmap_glyph,
            texture: texture,
        });
    }

}

<commit_msg>hashmap in std::collections is now called hash_map<commit_after>
use error::{ConrodResult, FreetypeError};
use freetype;
use freetype::error::MissingFontField;
use label::FontSize;
use opengl_graphics::Texture;
use std::collections::HashMap;
use std::collections::hash_map::{Occupied, Vacant};

/// Struct used to hold rendered character data.
pub struct Character {
    pub glyph: freetype::Glyph,
    pub bitmap_glyph: freetype::BitmapGlyph,
    pub texture: Texture,
}

/// A struct used for caching rendered font.
pub struct GlyphCache {
    pub face: freetype::Face,
    data: HashMap<FontSize, HashMap<char, Character>>,
}

impl GlyphCache {

    /// Constructor for a GlyphCache.
    pub fn new(font: &Path) -> ConrodResult<GlyphCache> {
        let freetype = match freetype::Library::init() {
            Ok(freetype) => freetype,
            Err(why) => return Err(FreetypeError(why)),
        };
        let font_str = match font.as_str() {
            Some(font_str) => font_str,
            None => return Err(FreetypeError(MissingFontField)),
        };
        let face = match freetype.new_face(font_str, 0) {
            Ok(face) => face,
            Err(why) => return Err(FreetypeError(why)),
        };
        Ok(GlyphCache {
            face: face,
            data: HashMap::new(),
        })
    }

    /// Return a reference to a `Character`. If there is not yet a `Character` for
    /// the given `FontSize` and `char`, load the `Character`.
    pub fn get_character(&mut self, size: FontSize, ch: char) -> &Character {
        match {
            match self.data.entry(size) {
                Vacant(entry) => entry.set(HashMap::new()),
                Occupied(entry) => entry.into_mut(),
            }
        }.contains_key(&ch) {
            true => &self.data[size][ch],
            false => { self.load_character(size, ch); &self.data[size][ch] }
        }
    }

    /// Load a `Character` from a given `FontSize` and `char`.
    fn load_character(&mut self, size: FontSize, ch: char) {
        self.face.set_pixel_sizes(0, size).unwrap();
        self.face.load_char(ch as u64, freetype::face::DEFAULT).unwrap();
        let glyph = self.face.glyph().get_glyph().unwrap();
        let bitmap_glyph = glyph.to_bitmap(freetype::render_mode::Normal, None).unwrap();
        let bitmap = bitmap_glyph.bitmap();
        let texture = Texture::from_memory_alpha(bitmap.buffer(),
                                                 bitmap.width() as u32,
                                                 bitmap.rows() as u32).unwrap();
        self.data[size].insert(ch, Character {
            glyph: glyph,
            bitmap_glyph: bitmap_glyph,
            texture: texture,
        });
    }

}

<|endoftext|>


<commit_before>// The elements of an array can be accessed by their indices
// arr[4]
#[test]
fn array_index() {
  let arr: [i32; 5] = [1, 2, 3, 4, 5];
  assert!(arr[__] == 1);
}

// A new fixed size array can be created by declaring the type of its elements
// along with its length
// [i32; 0] = []
#[test]
fn array_empty() {
  let arr: __;
  assert!(arr.len() == 0);
}

// Attempting to access an array at an index that is
// out of its bounds will cause an error. Let's cause
// that error in this example.
#[test]
#[should_panic]
fn out_of_index() {
  let arr: [&'static str; 5] = ["rust", "is", "mostly", "for", "nerds"];
  arr[__];
}

// Elements can be replaced in an array at a certain index.
// hint: Without the 'mut' keyword, you won't be able to change data.
#[test]
fn insert_at_index() {
  let mut arr: [u8; 5] = [0, 1, 2, 3, 4];
  __ = 0;
  assert!(arr == [0, 1, 2, 3, 0]);
}

// Arrays can be iterated over.
#[test]
fn array_iteration() {
  let arr: [u8; 3] = [3, 2, 1];
  let mut iterator = arr.iter();
  assert!(iterator.next().unwrap() == &__);
  assert!(iterator.next().unwrap() == &__);
  assert!(iterator.next().unwrap() == &__);
}

// Arrays can also be mutated during iteration
#[test]
fn array_map() {
  let arr: [u32; 4] = [2, 5, 7, 4];
  let mut iterator = arr.iter().map(__);
  assert!(iterator.next() == Some(4));
  assert!(iterator.next() == Some(10));
  assert!(iterator.next() == Some(14));
  assert!(iterator.next() == Some(8));
}

// You can filter an array for results that match a given condition
#[test]
fn array_filter() {
  let arr: [u16; 5] = [1, 2, 3, 4, 5];
  let mut iterator = arr.iter().filter(__);
  assert!(iterator.next().unwrap() == &2);
  assert!(iterator.next().unwrap() == &4);
  assert!(iterator.next().is_none());
}

// Filter and map can be combined to do both at once
#[test]
fn array_filter_map() {
  let arr: [u8; 5] = [2, 1, 2, 1, 2];
  let mut iterator = arr.iter().filter_map(|&x|
    if x == 1 {Some(__)} else {None}
  );
  assert!(iterator.next() == Some(3));
  assert!(iterator.next() == Some(3));
  assert!(iterator.next().is_none());
}

// This can be used for more complex logic as well
#[test]
fn complex_array_filter_map() {
  let arr: [u64; 4] = [4, 8, 16, 32];
  let mut iterator = arr.iter().filter_map(|&x|
    if (x as f64).sqrt().floor() == (x as f64).sqrt() {Some((x as f64).sqrt() as u64)} else {None}
  );
  assert!(iterator.next().unwrap() == __);
  assert!(iterator.next().unwrap() == __);
  assert!(iterator.next().is_none());
}
<commit_msg>Add for loop koans to array.rs<commit_after>// The elements of an array can be accessed by their indices
// arr[4]
#[test]
fn array_index() {
  let arr: [i32; 5] = [1, 2, 3, 4, 5];
  assert!(arr[__] == 1);
}

// A new fixed size array can be created by declaring the type of its elements
// along with its length
// [i32; 0] = []
#[test]
fn array_empty() {
  let arr: __;
  assert!(arr.len() == 0);
}

// Attempting to access an array at an index that is
// out of its bounds will cause an error. Let's cause
// that error in this example.
#[test]
#[should_panic]
fn out_of_index() {
  let arr: [&'static str; 5] = ["rust", "is", "mostly", "for", "nerds"];
  arr[__];
}

// Elements can be replaced in an array at a certain index.
// hint: Without the 'mut' keyword, you won't be able to change data.
#[test]
fn insert_at_index() {
  let mut arr: [u8; 5] = [0, 1, 2, 3, 4];
  __ = 0;
  assert!(arr == [0, 1, 2, 3, 0]);
}

// Arrays can be iterated over.
#[test]
fn array_iteration() {
  let arr: [u8; 3] = [3, 2, 1];
  let mut iterator = arr.iter();
  assert!(iterator.next().unwrap() == &__);
  assert!(iterator.next().unwrap() == &__);
  assert!(iterator.next().unwrap() == &__);
}

// Arrays can also be mutated during iteration
#[test]
fn array_map() {
  let arr: [u32; 4] = [2, 5, 7, 4];
  let mut iterator = arr.iter().map(__);
  assert!(iterator.next() == Some(4));
  assert!(iterator.next() == Some(10));
  assert!(iterator.next() == Some(14));
  assert!(iterator.next() == Some(8));
}

// You can filter an array for results that match a given condition
#[test]
fn array_filter() {
  let arr: [u16; 5] = [1, 2, 3, 4, 5];
  let mut iterator = arr.iter().filter(__);
  assert!(iterator.next().unwrap() == &2);
  assert!(iterator.next().unwrap() == &4);
  assert!(iterator.next().is_none());
}

// Filter and map can be combined to do both at once
#[test]
fn array_filter_map() {
  let arr: [u8; 5] = [2, 1, 2, 1, 2];
  let mut iterator = arr.iter().filter_map(|&x|
    if x == 1 {Some(__)} else {None}
  );
  assert!(iterator.next() == Some(3));
  assert!(iterator.next() == Some(3));
  assert!(iterator.next().is_none());
}

// This can be used for more complex logic as well
#[test]
fn complex_array_filter_map() {
  let arr: [u64; 4] = [4, 8, 16, 32];
  let mut iterator = arr.iter().filter_map(|&x|
    if (x as f64).sqrt().floor() == (x as f64).sqrt() {Some((x as f64).sqrt() as u64)} else {None}
  );
  assert!(iterator.next().unwrap() == __);
  assert!(iterator.next().unwrap() == __);
  assert!(iterator.next().is_none());
}

// Arrays can also be iterated through using a for loop
#[test]
fn for_loops() {
  let arr: [u64; 3] = [1, 2, 3];
  let mut y: u64 = 1;
  for x in &arr {
    assert!(*x == y);
  }
}

// Let's try iterating over an array of strings to build a sentence
#[test]
fn for_loops_two() {
  let words: [&'static str; 3] = ["I", "love", "Rust"];
  let mut sentence: String = String::new();
  for word in words.iter() {
    __
  }
  println!("{:?}", sentence);
  assert!(sentence == "I love Rust".to_string());
}
<|endoftext|>


<commit_before>/*!
A macro for declaring lazily evaluated statics.

Using this macro, it is possible to have `static`s that require code to be
executed at runtime in order to be initialized.
This includes anything requiring heap allocations, like vectors or hash maps,
as well as anything that requires function calls to be computed.

# Syntax

```ignore
lazy_static! {
    [pub] static ref NAME_1: TYPE_1 = EXPR_1;
    [pub] static ref NAME_2: TYPE_2 = EXPR_2;
    ...
    [pub] static ref NAME_N: TYPE_N = EXPR_N;
}
```

# Semantic

For a given `static ref NAME: TYPE = EXPR;`, the macro generates a
unique type that implements `Deref<TYPE>` and stores it in a static with name `NAME`.

On first deref, `EXPR` gets evaluated and stored internally, such that all further derefs
can return a reference to the same object.

Like regular `static mut`s, this macro only works for types that fulfill the `Sync`
trait.

# Example

Using the macro:

```rust
#![feature(phase)]

#[phase(plugin)]
extern crate lazy_static;

use std::collections::HashMap;

lazy_static! {
    static ref HASHMAP: HashMap<uint, &'static str> = {
        let mut m = HashMap::new();
        m.insert(0u, "foo");
        m.insert(1u, "bar");
        m.insert(2u, "baz");
        m
    };
    static ref COUNT: uint = HASHMAP.len();
    static ref NUMBER: uint = times_two(21);
}

fn times_two(n: uint) -> uint { n * 2 }

fn main() {
    println!("The map has {} entries.", *COUNT);
    println!("The entry for `0` is \"{}\".", HASHMAP.get(&0).unwrap());
    println!("A expensive calculation on a static results in: {}.", *NUMBER);
}
```

# Implementation details

The `Deref` implementation uses a hidden `static mut` that is guarded by a atomic check
using the `sync::Once` abstraction. All lazily evaluated values are currently
put in a heap allocated box, due to the Rust language currently not providing any way to
define uninitialized `static mut` values.

*/

#![crate_type = "dylib"]
#![license = "MIT"]

#![feature(macro_rules)]

#[macro_export]
macro_rules! lazy_static {
    (static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
        lazy_static!(PRIV static ref $N : $T = $e; $($t)*);
    };
    (pub static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
        lazy_static!(PUB static ref $N : $T = $e; $($t)*);
    };
    ($VIS:ident static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
        lazy_static!(MAKE TY $VIS $N);
        impl Deref<$T> for $N {
            fn deref<'a>(&'a self) -> &'a $T {
                use std::sync::{Once, ONCE_INIT};
                use std::mem::transmute;

                #[inline(always)]
                fn require_sync<T: Sync>(_: &T) { }

                unsafe {
                    static mut s: *const $T = 0 as *const $T;
                    static mut ONCE: Once = ONCE_INIT;
                    ONCE.doit(|| {
                        s = transmute::<Box<$T>, *const $T>(box() ($e));
                    });
                    let static_ref = &*s;
                    require_sync(static_ref);
                    static_ref
                }
            }
        }
        lazy_static!($($t)*);
    };
    (MAKE TY PUB $N:ident) => {
        #[allow(non_camel_case_types)]
        #[allow(dead_code)]
        pub struct $N {__private_field: ()}
        pub static $N: $N = $N {__private_field: ()};
    };
    (MAKE TY PRIV $N:ident) => {
        #[allow(non_camel_case_types)]
        #[allow(dead_code)]
        struct $N {__private_field: ()}
        static $N: $N = $N {__private_field: ()};
    };
    () => ()
}
<commit_msg>Remove unused license attribute<commit_after>/*!
A macro for declaring lazily evaluated statics.

Using this macro, it is possible to have `static`s that require code to be
executed at runtime in order to be initialized.
This includes anything requiring heap allocations, like vectors or hash maps,
as well as anything that requires function calls to be computed.

# Syntax

```ignore
lazy_static! {
    [pub] static ref NAME_1: TYPE_1 = EXPR_1;
    [pub] static ref NAME_2: TYPE_2 = EXPR_2;
    ...
    [pub] static ref NAME_N: TYPE_N = EXPR_N;
}
```

# Semantic

For a given `static ref NAME: TYPE = EXPR;`, the macro generates a
unique type that implements `Deref<TYPE>` and stores it in a static with name `NAME`.

On first deref, `EXPR` gets evaluated and stored internally, such that all further derefs
can return a reference to the same object.

Like regular `static mut`s, this macro only works for types that fulfill the `Sync`
trait.

# Example

Using the macro:

```rust
#![feature(phase)]

#[phase(plugin)]
extern crate lazy_static;

use std::collections::HashMap;

lazy_static! {
    static ref HASHMAP: HashMap<uint, &'static str> = {
        let mut m = HashMap::new();
        m.insert(0u, "foo");
        m.insert(1u, "bar");
        m.insert(2u, "baz");
        m
    };
    static ref COUNT: uint = HASHMAP.len();
    static ref NUMBER: uint = times_two(21);
}

fn times_two(n: uint) -> uint { n * 2 }

fn main() {
    println!("The map has {} entries.", *COUNT);
    println!("The entry for `0` is \"{}\".", HASHMAP.get(&0).unwrap());
    println!("A expensive calculation on a static results in: {}.", *NUMBER);
}
```

# Implementation details

The `Deref` implementation uses a hidden `static mut` that is guarded by a atomic check
using the `sync::Once` abstraction. All lazily evaluated values are currently
put in a heap allocated box, due to the Rust language currently not providing any way to
define uninitialized `static mut` values.

*/

#![crate_type = "dylib"]

#![feature(macro_rules)]

#[macro_export]
macro_rules! lazy_static {
    (static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
        lazy_static!(PRIV static ref $N : $T = $e; $($t)*);
    };
    (pub static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
        lazy_static!(PUB static ref $N : $T = $e; $($t)*);
    };
    ($VIS:ident static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
        lazy_static!(MAKE TY $VIS $N);
        impl Deref<$T> for $N {
            fn deref<'a>(&'a self) -> &'a $T {
                use std::sync::{Once, ONCE_INIT};
                use std::mem::transmute;

                #[inline(always)]
                fn require_sync<T: Sync>(_: &T) { }

                unsafe {
                    static mut s: *const $T = 0 as *const $T;
                    static mut ONCE: Once = ONCE_INIT;
                    ONCE.doit(|| {
                        s = transmute::<Box<$T>, *const $T>(box() ($e));
                    });
                    let static_ref = &*s;
                    require_sync(static_ref);
                    static_ref
                }
            }
        }
        lazy_static!($($t)*);
    };
    (MAKE TY PUB $N:ident) => {
        #[allow(non_camel_case_types)]
        #[allow(dead_code)]
        pub struct $N {__private_field: ()}
        pub static $N: $N = $N {__private_field: ()};
    };
    (MAKE TY PRIV $N:ident) => {
        #[allow(non_camel_case_types)]
        #[allow(dead_code)]
        struct $N {__private_field: ()}
        static $N: $N = $N {__private_field: ()};
    };
    () => ()
}
<|endoftext|>


<commit_before>#[derive(PartialEq, Show)]
pub enum Category {
    Whitespace,
    Identifier,
    Brace,
    Parenthesis,
    AssignmentOperator,
    IntegerLiteral,
    StringLiteral,
}

pub struct Token {
    pub lexeme: String,
    pub category: Category,
}
<commit_msg>Fix deprecation by deriving from Debug rather than Show.<commit_after>#[derive(PartialEq, Debug)]
pub enum Category {
    Whitespace,
    Identifier,
    Brace,
    Parenthesis,
    AssignmentOperator,
    IntegerLiteral,
    StringLiteral,
}

pub struct Token {
    pub lexeme: String,
    pub category: Category,
}
<|endoftext|>


<commit_before>/**
 * 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"]
extern 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 send> = arc_destruct<T>;

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

/**
 * Access the underlying data in an atomically reference counted
 * wrapper.
 */
fn get<T: const send>(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;
    }
}

/**
 * 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 send>(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::lock_and_signal(),
                                      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
        };
    }
}
<commit_msg>arc.rs: make exclusive's data mutable<commit_after>/**
 * 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"]
extern 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 send> = arc_destruct<T>;

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

/**
 * Access the underlying data in an atomically reference counted
 * wrapper.
 */
fn get<T: const send>(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;
    }
}

/**
 * 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 send>(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, mut 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::lock_and_signal(),
                                      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: &mut 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, &mut 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.

//! Defines the `PartialOrd` and `PartialEq` comparison traits.
//!
//! This module defines both `PartialOrd` and `PartialEq` traits which are used by the
//! compiler to implement comparison operators. Rust programs may implement
//!`PartialOrd` to overload the `<`, `<=`, `>`, and `>=` operators, and may implement
//! `PartialEq` to overload the `==` and `!=` operators.
//!
//! For example, to define a type with a customized definition for the PartialEq
//! operators, you could do the following:
//!
//! ```rust
//! // Our type.
//! struct SketchyNum {
//!     num : int
//! }
//!
//! // Our implementation of `PartialEq` to support `==` and `!=`.
//! impl PartialEq for SketchyNum {
//!     // Our custom eq allows numbers which are near each other to be equal! :D
//!     fn eq(&self, other: &SketchyNum) -> bool {
//!         (self.num - other.num).abs() < 5
//!     }
//! }
//!
//! // Now these binary operators will work when applied!
//! assert!(SketchyNum {num: 37} == SketchyNum {num: 34});
//! assert!(SketchyNum {num: 25} != SketchyNum {num: 57});
//! ```

use option::{Option, Some};

/// Trait for values that can be compared for equality and inequality.
///
/// This trait allows for partial equality, for types that do not have an
/// equivalence relation. For example, in floating point numbers `NaN != NaN`,
/// so floating point types implement `PartialEq` but not `Eq`.
///
/// PartialEq only requires the `eq` method to be implemented; `ne` is defined
/// in terms of it by default. Any manual implementation of `ne` *must* respect
/// the rule that `eq` is a strict inverse of `ne`; that is, `!(a == b)` if and
/// only if `a != b`.
///
/// Eventually, this will be implemented by default for types that implement
/// `Eq`.
#[lang="eq"]
pub trait PartialEq {
    /// This method tests for `self` and `other` values to be equal, and is used by `==`.
    fn eq(&self, other: &Self) -> bool;

    /// This method tests for `!=`.
    #[inline]
    fn ne(&self, other: &Self) -> bool { !self.eq(other) }
}

/// Trait for equality comparisons which are [equivalence relations](
/// https://en.wikipedia.org/wiki/Equivalence_relation).
///
/// This means, that in addition to `a == b` and `a != b` being strict
/// inverses, the equality must be (for all `a`, `b` and `c`):
///
/// - reflexive: `a == a`;
/// - symmetric: `a == b` implies `b == a`; and
/// - transitive: `a == b` and `b == c` implies `a == c`.
pub trait Eq: PartialEq {
    // FIXME #13101: this method is used solely by #[deriving] to
    // assert that every component of a type implements #[deriving]
    // itself, the current deriving infrastructure means doing this
    // assertion without using a method on this trait is nearly
    // impossible.
    //
    // This should never be implemented by hand.
    #[doc(hidden)]
    #[inline(always)]
    fn assert_receiver_is_total_eq(&self) {}
}

/// An ordering is, e.g, a result of a comparison between two values.
#[deriving(Clone, PartialEq, Show)]
pub enum Ordering {
   /// An ordering where a compared value is less [than another].
   Less = -1i,
   /// An ordering where a compared value is equal [to another].
   Equal = 0i,
   /// An ordering where a compared value is greater [than another].
   Greater = 1i,
}

/// Trait for types that form a [total order](
/// https://en.wikipedia.org/wiki/Total_order).
///
/// An order is a total order if it is (for all `a`, `b` and `c`):
///
/// - total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is
///   true; and
/// - transitive, `a < b` and `b < c` implies `a < c`. The same must hold for
///   both `==` and `>`.
pub trait Ord: Eq + PartialOrd {
    /// This method returns an ordering between `self` and `other` values.
    ///
    /// By convention, `self.cmp(&other)` returns the ordering matching
    /// the expression `self <operator> other` if true.  For example:
    ///
    /// ```
    /// assert_eq!( 5u.cmp(&10), Less);     // because 5 < 10
    /// assert_eq!(10u.cmp(&5),  Greater);  // because 10 > 5
    /// assert_eq!( 5u.cmp(&5),  Equal);    // because 5 == 5
    /// ```
    fn cmp(&self, other: &Self) -> Ordering;
}

impl Eq for Ordering {}

impl Ord for Ordering {
    #[inline]
    fn cmp(&self, other: &Ordering) -> Ordering {
        (*self as int).cmp(&(*other as int))
    }
}

impl PartialOrd for Ordering {
    #[inline]
    fn partial_cmp(&self, other: &Ordering) -> Option<Ordering> {
        (*self as int).partial_cmp(&(*other as int))
    }
}

/// Combine orderings, lexically.
///
/// For example for a type `(int, int)`, two comparisons could be done.
/// If the first ordering is different, the first ordering is all that must be returned.
/// If the first ordering is equal, then second ordering is returned.
#[inline]
pub fn lexical_ordering(o1: Ordering, o2: Ordering) -> Ordering {
    match o1 {
        Equal => o2,
        _ => o1
    }
}

/// Trait for values that can be compared for a sort-order.
///
/// PartialOrd only requires implementation of the `partial_cmp` method,
/// with the others generated from default implementations.
///
/// However it remains possible to implement the others separately for types
/// which do not have a total order. For example, for floating point numbers,
/// `NaN < 0 == false` and `NaN >= 0 == false` (cf. IEEE 754-2008 section
/// 5.11).
#[lang="ord"]
pub trait PartialOrd: PartialEq {
    /// This method returns an ordering between `self` and `other` values
    /// if one exists.
    fn partial_cmp(&self, other: &Self) -> Option<Ordering>;

    /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
    fn lt(&self, other: &Self) -> bool {
        match self.partial_cmp(other) {
            Some(Less) => true,
            _ => false,
        }
    }

    /// This method tests less than or equal to (`<=`).
    #[inline]
    fn le(&self, other: &Self) -> bool {
        match self.partial_cmp(other) {
            Some(Less) | Some(Equal) => true,
            _ => false,
        }
    }

    /// This method tests greater than (`>`).
    #[inline]
    fn gt(&self, other: &Self) -> bool {
        match self.partial_cmp(other) {
            Some(Greater) => true,
            _ => false,
        }
    }

    /// This method tests greater than or equal to (`>=`).
    #[inline]
    fn ge(&self, other: &Self) -> bool {
        match self.partial_cmp(other) {
            Some(Greater) | Some(Equal) => true,
            _ => false,
        }
    }
}

/// The equivalence relation. Two values may be equivalent even if they are
/// of different types. The most common use case for this relation is
/// container types; e.g. it is often desirable to be able to use `&str`
/// values to look up entries in a container with `String` keys.
pub trait Equiv<T> {
    /// Implement this function to decide equivalent values.
    fn equiv(&self, other: &T) -> bool;
}

/// Compare and return the minimum of two values.
#[inline]
pub fn min<T: Ord>(v1: T, v2: T) -> T {
    if v1 < v2 { v1 } else { v2 }
}

/// Compare and return the maximum of two values.
#[inline]
pub fn max<T: Ord>(v1: T, v2: T) -> T {
    if v1 > v2 { v1 } else { v2 }
}

// Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types
mod impls {
    use cmp::{PartialOrd, Ord, PartialEq, Eq, Ordering,
              Less, Greater, Equal};
    use option::{Option, Some, None};

    macro_rules! eq_impl(
        ($($t:ty)*) => ($(
            impl PartialEq for $t {
                #[inline]
                fn eq(&self, other: &$t) -> bool { (*self) == (*other) }
                #[inline]
                fn ne(&self, other: &$t) -> bool { (*self) != (*other) }
            }
        )*)
    )

    impl PartialEq for () {
        #[inline]
        fn eq(&self, _other: &()) -> bool { true }
        #[inline]
        fn ne(&self, _other: &()) -> bool { false }
    }

    eq_impl!(bool char uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64)

    macro_rules! totaleq_impl(
        ($($t:ty)*) => ($(
            impl Eq for $t {}
        )*)
    )

    totaleq_impl!(() bool char uint u8 u16 u32 u64 int i8 i16 i32 i64)

    macro_rules! ord_impl(
        ($($t:ty)*) => ($(
            impl PartialOrd for $t {
                #[inline]
                fn partial_cmp(&self, other: &$t) -> Option<Ordering> {
                    match (self <= other, self >= other) {
                        (false, false) => None,
                        (false, true) => Some(Greater),
                        (true, false) => Some(Less),
                        (true, true) => Some(Equal),
                    }
                }
                #[inline]
                fn lt(&self, other: &$t) -> bool { (*self) < (*other) }
                #[inline]
                fn le(&self, other: &$t) -> bool { (*self) <= (*other) }
                #[inline]
                fn ge(&self, other: &$t) -> bool { (*self) >= (*other) }
                #[inline]
                fn gt(&self, other: &$t) -> bool { (*self) > (*other) }
            }
        )*)
    )

    impl PartialOrd for () {
        #[inline]
        fn partial_cmp(&self, _: &()) -> Option<Ordering> {
            Some(Equal)
        }
    }

    impl PartialOrd for bool {
        #[inline]
        fn partial_cmp(&self, other: &bool) -> Option<Ordering> {
            (*self as u8).partial_cmp(&(*other as u8))
        }
    }

    ord_impl!(char uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64)

    macro_rules! totalord_impl(
        ($($t:ty)*) => ($(
            impl Ord for $t {
                #[inline]
                fn cmp(&self, other: &$t) -> Ordering {
                    if *self < *other { Less }
                    else if *self > *other { Greater }
                    else { Equal }
                }
            }
        )*)
    )

    impl Ord for () {
        #[inline]
        fn cmp(&self, _other: &()) -> Ordering { Equal }
    }

    impl Ord for bool {
        #[inline]
        fn cmp(&self, other: &bool) -> Ordering {
            (*self as u8).cmp(&(*other as u8))
        }
    }

    totalord_impl!(char uint u8 u16 u32 u64 int i8 i16 i32 i64)

    // & pointers
    impl<'a, T: PartialEq> PartialEq for &'a T {
        #[inline]
        fn eq(&self, other: & &'a T) -> bool { *(*self) == *(*other) }
        #[inline]
        fn ne(&self, other: & &'a T) -> bool { *(*self) != *(*other) }
    }
    impl<'a, T: PartialOrd> PartialOrd for &'a T {
        #[inline]
        fn partial_cmp(&self, other: &&'a T) -> Option<Ordering> {
            (**self).partial_cmp(*other)
        }
        #[inline]
        fn lt(&self, other: & &'a T) -> bool { *(*self) < *(*other) }
        #[inline]
        fn le(&self, other: & &'a T) -> bool { *(*self) <= *(*other) }
        #[inline]
        fn ge(&self, other: & &'a T) -> bool { *(*self) >= *(*other) }
        #[inline]
        fn gt(&self, other: & &'a T) -> bool { *(*self) > *(*other) }
    }
    impl<'a, T: Ord> Ord for &'a T {
        #[inline]
        fn cmp(&self, other: & &'a T) -> Ordering { (**self).cmp(*other) }
    }
    impl<'a, T: Eq> Eq for &'a T {}

    // &mut pointers
    impl<'a, T: PartialEq> PartialEq for &'a mut T {
        #[inline]
        fn eq(&self, other: &&'a mut T) -> bool { **self == *(*other) }
        #[inline]
        fn ne(&self, other: &&'a mut T) -> bool { **self != *(*other) }
    }
    impl<'a, T: PartialOrd> PartialOrd for &'a mut T {
        #[inline]
        fn partial_cmp(&self, other: &&'a mut T) -> Option<Ordering> {
            (**self).partial_cmp(*other)
        }
        #[inline]
        fn lt(&self, other: &&'a mut T) -> bool { **self < **other }
        #[inline]
        fn le(&self, other: &&'a mut T) -> bool { **self <= **other }
        #[inline]
        fn ge(&self, other: &&'a mut T) -> bool { **self >= **other }
        #[inline]
        fn gt(&self, other: &&'a mut T) -> bool { **self > **other }
    }
    impl<'a, T: Ord> Ord for &'a mut T {
        #[inline]
        fn cmp(&self, other: &&'a mut T) -> Ordering { (**self).cmp(*other) }
    }
    impl<'a, T: Eq> Eq for &'a mut T {}
}
<commit_msg>core: Stabliize core::cmp<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.

//! Defines the `PartialOrd` and `PartialEq` comparison traits.
//!
//! This module defines both `PartialOrd` and `PartialEq` traits which are used by the
//! compiler to implement comparison operators. Rust programs may implement
//!`PartialOrd` to overload the `<`, `<=`, `>`, and `>=` operators, and may implement
//! `PartialEq` to overload the `==` and `!=` operators.
//!
//! For example, to define a type with a customized definition for the PartialEq
//! operators, you could do the following:
//!
//! ```rust
//! // Our type.
//! struct SketchyNum {
//!     num : int
//! }
//!
//! // Our implementation of `PartialEq` to support `==` and `!=`.
//! impl PartialEq for SketchyNum {
//!     // Our custom eq allows numbers which are near each other to be equal! :D
//!     fn eq(&self, other: &SketchyNum) -> bool {
//!         (self.num - other.num).abs() < 5
//!     }
//! }
//!
//! // Now these binary operators will work when applied!
//! assert!(SketchyNum {num: 37} == SketchyNum {num: 34});
//! assert!(SketchyNum {num: 25} != SketchyNum {num: 57});
//! ```

#![stable]

use option::{Option, Some};

/// Trait for values that can be compared for equality and inequality.
///
/// This trait allows for partial equality, for types that do not have an
/// equivalence relation. For example, in floating point numbers `NaN != NaN`,
/// so floating point types implement `PartialEq` but not `Eq`.
///
/// PartialEq only requires the `eq` method to be implemented; `ne` is defined
/// in terms of it by default. Any manual implementation of `ne` *must* respect
/// the rule that `eq` is a strict inverse of `ne`; that is, `!(a == b)` if and
/// only if `a != b`.
///
/// Eventually, this will be implemented by default for types that implement
/// `Eq`.
#[lang="eq"]
#[unstable = "Definition may change slightly after trait reform"]
pub trait PartialEq {
    /// This method tests for `self` and `other` values to be equal, and is used by `==`.
    fn eq(&self, other: &Self) -> bool;

    /// This method tests for `!=`.
    #[inline]
    fn ne(&self, other: &Self) -> bool { !self.eq(other) }
}

/// Trait for equality comparisons which are [equivalence relations](
/// https://en.wikipedia.org/wiki/Equivalence_relation).
///
/// This means, that in addition to `a == b` and `a != b` being strict
/// inverses, the equality must be (for all `a`, `b` and `c`):
///
/// - reflexive: `a == a`;
/// - symmetric: `a == b` implies `b == a`; and
/// - transitive: `a == b` and `b == c` implies `a == c`.
#[unstable = "Definition may change slightly after trait reform"]
pub trait Eq: PartialEq {
    // FIXME #13101: this method is used solely by #[deriving] to
    // assert that every component of a type implements #[deriving]
    // itself, the current deriving infrastructure means doing this
    // assertion without using a method on this trait is nearly
    // impossible.
    //
    // This should never be implemented by hand.
    #[doc(hidden)]
    #[inline(always)]
    fn assert_receiver_is_total_eq(&self) {}
}

/// An ordering is, e.g, a result of a comparison between two values.
#[deriving(Clone, PartialEq, Show)]
#[stable]
pub enum Ordering {
   /// An ordering where a compared value is less [than another].
   Less = -1i,
   /// An ordering where a compared value is equal [to another].
   Equal = 0i,
   /// An ordering where a compared value is greater [than another].
   Greater = 1i,
}

/// Trait for types that form a [total order](
/// https://en.wikipedia.org/wiki/Total_order).
///
/// An order is a total order if it is (for all `a`, `b` and `c`):
///
/// - total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is
///   true; and
/// - transitive, `a < b` and `b < c` implies `a < c`. The same must hold for
///   both `==` and `>`.
#[unstable = "Definition may change slightly after trait reform"]
pub trait Ord: Eq + PartialOrd {
    /// This method returns an ordering between `self` and `other` values.
    ///
    /// By convention, `self.cmp(&other)` returns the ordering matching
    /// the expression `self <operator> other` if true.  For example:
    ///
    /// ```
    /// assert_eq!( 5u.cmp(&10), Less);     // because 5 < 10
    /// assert_eq!(10u.cmp(&5),  Greater);  // because 10 > 5
    /// assert_eq!( 5u.cmp(&5),  Equal);    // because 5 == 5
    /// ```
    fn cmp(&self, other: &Self) -> Ordering;
}

#[unstable = "Trait is unstable."]
impl Eq for Ordering {}

#[unstable = "Trait is unstable."]
impl Ord for Ordering {
    #[inline]
    fn cmp(&self, other: &Ordering) -> Ordering {
        (*self as int).cmp(&(*other as int))
    }
}

#[unstable = "Trait is unstable."]
impl PartialOrd for Ordering {
    #[inline]
    fn partial_cmp(&self, other: &Ordering) -> Option<Ordering> {
        (*self as int).partial_cmp(&(*other as int))
    }
}

/// Combine orderings, lexically.
///
/// For example for a type `(int, int)`, two comparisons could be done.
/// If the first ordering is different, the first ordering is all that must be returned.
/// If the first ordering is equal, then second ordering is returned.
#[inline]
#[deprecated = "Just call .cmp() on an Ordering"]
pub fn lexical_ordering(o1: Ordering, o2: Ordering) -> Ordering {
    match o1 {
        Equal => o2,
        _ => o1
    }
}

/// Trait for values that can be compared for a sort-order.
///
/// PartialOrd only requires implementation of the `partial_cmp` method,
/// with the others generated from default implementations.
///
/// However it remains possible to implement the others separately for types
/// which do not have a total order. For example, for floating point numbers,
/// `NaN < 0 == false` and `NaN >= 0 == false` (cf. IEEE 754-2008 section
/// 5.11).
#[lang="ord"]
#[unstable = "Definition may change slightly after trait reform"]
pub trait PartialOrd: PartialEq {
    /// This method returns an ordering between `self` and `other` values
    /// if one exists.
    fn partial_cmp(&self, other: &Self) -> Option<Ordering>;

    /// This method tests less than (for `self` and `other`) and is used by the `<` operator.
    fn lt(&self, other: &Self) -> bool {
        match self.partial_cmp(other) {
            Some(Less) => true,
            _ => false,
        }
    }

    /// This method tests less than or equal to (`<=`).
    #[inline]
    fn le(&self, other: &Self) -> bool {
        match self.partial_cmp(other) {
            Some(Less) | Some(Equal) => true,
            _ => false,
        }
    }

    /// This method tests greater than (`>`).
    #[inline]
    fn gt(&self, other: &Self) -> bool {
        match self.partial_cmp(other) {
            Some(Greater) => true,
            _ => false,
        }
    }

    /// This method tests greater than or equal to (`>=`).
    #[inline]
    fn ge(&self, other: &Self) -> bool {
        match self.partial_cmp(other) {
            Some(Greater) | Some(Equal) => true,
            _ => false,
        }
    }
}

/// The equivalence relation. Two values may be equivalent even if they are
/// of different types. The most common use case for this relation is
/// container types; e.g. it is often desirable to be able to use `&str`
/// values to look up entries in a container with `String` keys.
#[experimental = "Better solutions may be discovered."]
pub trait Equiv<T> {
    /// Implement this function to decide equivalent values.
    fn equiv(&self, other: &T) -> bool;
}

/// Compare and return the minimum of two values.
#[inline]
#[stable]
pub fn min<T: Ord>(v1: T, v2: T) -> T {
    if v1 < v2 { v1 } else { v2 }
}

/// Compare and return the maximum of two values.
#[inline]
#[stable]
pub fn max<T: Ord>(v1: T, v2: T) -> T {
    if v1 > v2 { v1 } else { v2 }
}

// Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types
mod impls {
    use cmp::{PartialOrd, Ord, PartialEq, Eq, Ordering,
              Less, Greater, Equal};
    use option::{Option, Some, None};

    macro_rules! eq_impl(
        ($($t:ty)*) => ($(
            #[unstable = "Trait is unstable."]
            impl PartialEq for $t {
                #[inline]
                fn eq(&self, other: &$t) -> bool { (*self) == (*other) }
                #[inline]
                fn ne(&self, other: &$t) -> bool { (*self) != (*other) }
            }
        )*)
    )

    #[unstable = "Trait is unstable."]
    impl PartialEq for () {
        #[inline]
        fn eq(&self, _other: &()) -> bool { true }
        #[inline]
        fn ne(&self, _other: &()) -> bool { false }
    }

    eq_impl!(bool char uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64)

    macro_rules! totaleq_impl(
        ($($t:ty)*) => ($(
            #[unstable = "Trait is unstable."]
            impl Eq for $t {}
        )*)
    )

    totaleq_impl!(() bool char uint u8 u16 u32 u64 int i8 i16 i32 i64)

    macro_rules! ord_impl(
        ($($t:ty)*) => ($(
            #[unstable = "Trait is unstable."]
            impl PartialOrd for $t {
                #[inline]
                fn partial_cmp(&self, other: &$t) -> Option<Ordering> {
                    match (self <= other, self >= other) {
                        (false, false) => None,
                        (false, true) => Some(Greater),
                        (true, false) => Some(Less),
                        (true, true) => Some(Equal),
                    }
                }
                #[inline]
                fn lt(&self, other: &$t) -> bool { (*self) < (*other) }
                #[inline]
                fn le(&self, other: &$t) -> bool { (*self) <= (*other) }
                #[inline]
                fn ge(&self, other: &$t) -> bool { (*self) >= (*other) }
                #[inline]
                fn gt(&self, other: &$t) -> bool { (*self) > (*other) }
            }
        )*)
    )

    #[unstable = "Trait is unstable."]
    impl PartialOrd for () {
        #[inline]
        fn partial_cmp(&self, _: &()) -> Option<Ordering> {
            Some(Equal)
        }
    }

    #[unstable = "Trait is unstable."]
    impl PartialOrd for bool {
        #[inline]
        fn partial_cmp(&self, other: &bool) -> Option<Ordering> {
            (*self as u8).partial_cmp(&(*other as u8))
        }
    }

    ord_impl!(char uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64)

    macro_rules! totalord_impl(
        ($($t:ty)*) => ($(
            #[unstable = "Trait is unstable."]
            impl Ord for $t {
                #[inline]
                fn cmp(&self, other: &$t) -> Ordering {
                    if *self < *other { Less }
                    else if *self > *other { Greater }
                    else { Equal }
                }
            }
        )*)
    )

    #[unstable = "Trait is unstable."]
    impl Ord for () {
        #[inline]
        fn cmp(&self, _other: &()) -> Ordering { Equal }
    }

    #[unstable = "Trait is unstable."]
    impl Ord for bool {
        #[inline]
        fn cmp(&self, other: &bool) -> Ordering {
            (*self as u8).cmp(&(*other as u8))
        }
    }

    totalord_impl!(char uint u8 u16 u32 u64 int i8 i16 i32 i64)

    // & pointers
    #[unstable = "Trait is unstable."]
    impl<'a, T: PartialEq> PartialEq for &'a T {
        #[inline]
        fn eq(&self, other: & &'a T) -> bool { *(*self) == *(*other) }
        #[inline]
        fn ne(&self, other: & &'a T) -> bool { *(*self) != *(*other) }
    }
    #[unstable = "Trait is unstable."]
    impl<'a, T: PartialOrd> PartialOrd for &'a T {
        #[inline]
        fn partial_cmp(&self, other: &&'a T) -> Option<Ordering> {
            (**self).partial_cmp(*other)
        }
        #[inline]
        fn lt(&self, other: & &'a T) -> bool { *(*self) < *(*other) }
        #[inline]
        fn le(&self, other: & &'a T) -> bool { *(*self) <= *(*other) }
        #[inline]
        fn ge(&self, other: & &'a T) -> bool { *(*self) >= *(*other) }
        #[inline]
        fn gt(&self, other: & &'a T) -> bool { *(*self) > *(*other) }
    }
    #[unstable = "Trait is unstable."]
    impl<'a, T: Ord> Ord for &'a T {
        #[inline]
        fn cmp(&self, other: & &'a T) -> Ordering { (**self).cmp(*other) }
    }
    #[unstable = "Trait is unstable."]
    impl<'a, T: Eq> Eq for &'a T {}

    // &mut pointers
    #[unstable = "Trait is unstable."]
    impl<'a, T: PartialEq> PartialEq for &'a mut T {
        #[inline]
        fn eq(&self, other: &&'a mut T) -> bool { **self == *(*other) }
        #[inline]
        fn ne(&self, other: &&'a mut T) -> bool { **self != *(*other) }
    }
    #[unstable = "Trait is unstable."]
    impl<'a, T: PartialOrd> PartialOrd for &'a mut T {
        #[inline]
        fn partial_cmp(&self, other: &&'a mut T) -> Option<Ordering> {
            (**self).partial_cmp(*other)
        }
        #[inline]
        fn lt(&self, other: &&'a mut T) -> bool { **self < **other }
        #[inline]
        fn le(&self, other: &&'a mut T) -> bool { **self <= **other }
        #[inline]
        fn ge(&self, other: &&'a mut T) -> bool { **self >= **other }
        #[inline]
        fn gt(&self, other: &&'a mut T) -> bool { **self > **other }
    }
    #[unstable = "Trait is unstable."]
    impl<'a, T: Ord> Ord for &'a mut T {
        #[inline]
        fn cmp(&self, other: &&'a mut T) -> Ordering { (**self).cmp(*other) }
    }
    #[unstable = "Trait is unstable."]
    impl<'a, T: Eq> Eq for &'a mut T {}
}
<|endoftext|>


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

use std::c_str::ToCStr;
use std::libc::{c_char, c_int};
use std::{local_data, str, rt};
use std::unstable::finally::Finally;

#[cfg(stage0)]
pub mod rustrt {
    use std::libc::{c_char, c_int};

    extern {
        fn linenoise(prompt: *c_char) -> *c_char;
        fn linenoiseHistoryAdd(line: *c_char) -> c_int;
        fn linenoiseHistorySetMaxLen(len: c_int) -> c_int;
        fn linenoiseHistorySave(file: *c_char) -> c_int;
        fn linenoiseHistoryLoad(file: *c_char) -> c_int;
        fn linenoiseSetCompletionCallback(callback: *u8);
        fn linenoiseAddCompletion(completions: *(), line: *c_char);

        fn rust_take_linenoise_lock();
        fn rust_drop_linenoise_lock();
    }
}

#[cfg(not(stage0))]
pub mod rustrt {
    use std::libc::{c_char, c_int};

    externfn!(fn linenoise(prompt: *c_char) -> *c_char)
    externfn!(fn linenoiseHistoryAdd(line: *c_char) -> c_int)
    externfn!(fn linenoiseHistorySetMaxLen(len: c_int) -> c_int)
    externfn!(fn linenoiseHistorySave(file: *c_char) -> c_int)
    externfn!(fn linenoiseHistoryLoad(file: *c_char) -> c_int)
    externfn!(fn linenoiseSetCompletionCallback(callback: extern "C" fn(*i8, *())))
    externfn!(fn linenoiseAddCompletion(completions: *(), line: *c_char))

    externfn!(fn rust_take_linenoise_lock())
    externfn!(fn rust_drop_linenoise_lock())
}

macro_rules! locked {
    ($expr:expr) => {
        unsafe {
            // FIXME #9105: can't use a static mutex in pure Rust yet.
            rustrt::rust_take_linenoise_lock();
            let x = $expr;
            rustrt::rust_drop_linenoise_lock();
            x
        }
    }
}

/// Add a line to history
pub fn add_history(line: &str) -> bool {
    do line.with_c_str |buf| {
        (locked!(rustrt::linenoiseHistoryAdd(buf))) == 1 as c_int
    }
}

/// Set the maximum amount of lines stored
pub fn set_history_max_len(len: int) -> bool {
    (locked!(rustrt::linenoiseHistorySetMaxLen(len as c_int))) == 1 as c_int
}

/// Save line history to a file
pub fn save_history(file: &str) -> bool {
    do file.with_c_str |buf| {
        (locked!(rustrt::linenoiseHistorySave(buf))) == 1 as c_int
    }
}

/// Load line history from a file
pub fn load_history(file: &str) -> bool {
    do file.with_c_str |buf| {
        (locked!(rustrt::linenoiseHistoryLoad(buf))) == 1 as c_int
    }
}

/// Print out a prompt and then wait for input and return it
pub fn read(prompt: &str) -> Option<~str> {
    do prompt.with_c_str |buf| {
        let line = locked!(rustrt::linenoise(buf));

        if line.is_null() { None }
        else { Some(str::raw::from_c_str(line)) }
    }
}

pub type CompletionCb = @fn(~str, @fn(~str));

static complete_key: local_data::Key<@CompletionCb> = &local_data::Key;

/// Bind to the main completion callback.
///
/// The completion callback should not call any `extra::rl` functions
/// other than the closure that it receives as its second
/// argument. Calling such a function will deadlock on the mutex used
/// to ensure that the calls are thread-safe.
pub fn complete(cb: CompletionCb) {
    local_data::set(complete_key, @cb);

    extern fn callback(line: *c_char, completions: *()) {
        do local_data::get(complete_key) |cb| {
            let cb = **cb.unwrap();

            unsafe {
                do cb(str::raw::from_c_str(line)) |suggestion| {
                    do suggestion.with_c_str |buf| {
                        // This isn't locked, because `callback` gets
                        // called inside `rustrt::linenoise`, which
                        // *is* already inside the mutex, so
                        // re-locking would be a deadlock.
                        rustrt::linenoiseAddCompletion(completions, buf);
                    }
                }
            }
        }
    }

    locked!(rustrt::linenoiseSetCompletionCallback(callback));
}
<commit_msg>extra: stop rl from leaking each line that is read.<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::c_str::ToCStr;
use std::libc::{c_char, c_int};
use std::{local_data, str, rt};
use std::unstable::finally::Finally;

#[cfg(stage0)]
pub mod rustrt {
    use std::libc::{c_char, c_int};

    extern {
        fn linenoise(prompt: *c_char) -> *c_char;
        fn linenoiseHistoryAdd(line: *c_char) -> c_int;
        fn linenoiseHistorySetMaxLen(len: c_int) -> c_int;
        fn linenoiseHistorySave(file: *c_char) -> c_int;
        fn linenoiseHistoryLoad(file: *c_char) -> c_int;
        fn linenoiseSetCompletionCallback(callback: *u8);
        fn linenoiseAddCompletion(completions: *(), line: *c_char);

        fn rust_take_linenoise_lock();
        fn rust_drop_linenoise_lock();
    }
}

#[cfg(not(stage0))]
pub mod rustrt {
    use std::libc::{c_char, c_int};

    externfn!(fn linenoise(prompt: *c_char) -> *c_char)
    externfn!(fn linenoiseHistoryAdd(line: *c_char) -> c_int)
    externfn!(fn linenoiseHistorySetMaxLen(len: c_int) -> c_int)
    externfn!(fn linenoiseHistorySave(file: *c_char) -> c_int)
    externfn!(fn linenoiseHistoryLoad(file: *c_char) -> c_int)
    externfn!(fn linenoiseSetCompletionCallback(callback: extern "C" fn(*i8, *())))
    externfn!(fn linenoiseAddCompletion(completions: *(), line: *c_char))

    externfn!(fn rust_take_linenoise_lock())
    externfn!(fn rust_drop_linenoise_lock())
}

macro_rules! locked {
    ($expr:expr) => {
        unsafe {
            // FIXME #9105: can't use a static mutex in pure Rust yet.
            rustrt::rust_take_linenoise_lock();
            let x = $expr;
            rustrt::rust_drop_linenoise_lock();
            x
        }
    }
}

/// Add a line to history
pub fn add_history(line: &str) -> bool {
    do line.with_c_str |buf| {
        (locked!(rustrt::linenoiseHistoryAdd(buf))) == 1 as c_int
    }
}

/// Set the maximum amount of lines stored
pub fn set_history_max_len(len: int) -> bool {
    (locked!(rustrt::linenoiseHistorySetMaxLen(len as c_int))) == 1 as c_int
}

/// Save line history to a file
pub fn save_history(file: &str) -> bool {
    do file.with_c_str |buf| {
        (locked!(rustrt::linenoiseHistorySave(buf))) == 1 as c_int
    }
}

/// Load line history from a file
pub fn load_history(file: &str) -> bool {
    do file.with_c_str |buf| {
        (locked!(rustrt::linenoiseHistoryLoad(buf))) == 1 as c_int
    }
}

/// Print out a prompt and then wait for input and return it
pub fn read(prompt: &str) -> Option<~str> {
    do prompt.with_c_str |buf| {
        let line = locked!(rustrt::linenoise(buf));

        if line.is_null() { None }
        else {
            unsafe {
                do (|| {
                    Some(str::raw::from_c_str(line))
                }).finally {
                    // linenoise's return value is from strdup, so we
                    // better not leak it.
                    rt::global_heap::exchange_free(line);
                }
            }
        }
    }
}

pub type CompletionCb = @fn(~str, @fn(~str));

static complete_key: local_data::Key<@CompletionCb> = &local_data::Key;

/// Bind to the main completion callback.
///
/// The completion callback should not call any `extra::rl` functions
/// other than the closure that it receives as its second
/// argument. Calling such a function will deadlock on the mutex used
/// to ensure that the calls are thread-safe.
pub fn complete(cb: CompletionCb) {
    local_data::set(complete_key, @cb);

    extern fn callback(line: *c_char, completions: *()) {
        do local_data::get(complete_key) |cb| {
            let cb = **cb.unwrap();

            unsafe {
                do cb(str::raw::from_c_str(line)) |suggestion| {
                    do suggestion.with_c_str |buf| {
                        // This isn't locked, because `callback` gets
                        // called inside `rustrt::linenoise`, which
                        // *is* already inside the mutex, so
                        // re-locking would be a deadlock.
                        rustrt::linenoiseAddCompletion(completions, buf);
                    }
                }
            }
        }
    }

    locked!(rustrt::linenoiseSetCompletionCallback(callback));
}
<|endoftext|>


<commit_before>/*
Module: time
*/

#[abi = "cdecl"]
native mod rustrt {
    fn get_time(&sec: u32, &usec: u32);
    fn nano_time(&ns: u64);
}

/*
Type: timeval

A record specifying a time value in seconds and microseconds.
*/
type timeval = {sec: u32, usec: u32};

/*
Function: get_time

Returns the current time as a `timeval` containing the seconds and
microseconds since 1970-01-01T00:00:00Z.
*/
fn get_time() -> timeval {
    let sec = 0u32;
    let usec = 0u32;
    rustrt::get_time(sec, usec);
    ret {sec: sec, usec: usec};
}

/*
Function: precise_time_ns

Returns the current value of a high-resolution performance counter
in nanoseconds since an unspecified epoch.
*/
fn precise_time_ns() -> u64 { let ns = 0u64; rustrt::nano_time(ns); ret ns; }

/*
Function: precise_time_s

Returns the current value of a high-resolution performance counter
in seconds since an unspecified epoch.
*/
fn precise_time_s() -> float {
    ret (precise_time_ns() as float) / 1000000000.;
}
<commit_msg>std: Add tests for time module<commit_after>/*
Module: time
*/

#[abi = "cdecl"]
native mod rustrt {
    fn get_time(&sec: u32, &usec: u32);
    fn nano_time(&ns: u64);
}

/*
Type: timeval

A record specifying a time value in seconds and microseconds.
*/
type timeval = {sec: u32, usec: u32};

/*
Function: get_time

Returns the current time as a `timeval` containing the seconds and
microseconds since 1970-01-01T00:00:00Z.
*/
fn get_time() -> timeval {
    let sec = 0u32;
    let usec = 0u32;
    rustrt::get_time(sec, usec);
    ret {sec: sec, usec: usec};
}

/*
Function: precise_time_ns

Returns the current value of a high-resolution performance counter
in nanoseconds since an unspecified epoch.
*/
fn precise_time_ns() -> u64 { let ns = 0u64; rustrt::nano_time(ns); ret ns; }

/*
Function: precise_time_s

Returns the current value of a high-resolution performance counter
in seconds since an unspecified epoch.
*/
fn precise_time_s() -> float {
    ret (precise_time_ns() as float) / 1000000000.;
}

#[cfg(test)]
mod tests {
    import task;

    #[test]
    fn test_get_time() {
        const some_recent_date: u32 = 1325376000u32; // 2012-01-01T00:00:00Z
        const some_future_date: u32 = 1577836800u32; // 2020-01-01T00:00:00Z

        let tv1 = get_time();
        log(debug, "tv1=" + uint::str(tv1.sec as uint) + " sec + "
                   + uint::str(tv1.usec as uint) + " usec");

        assert tv1.sec > some_recent_date;
        assert tv1.usec < 1000000u32;

        let tv2 = get_time();
        log(debug, "tv2=" + uint::str(tv2.sec as uint) + " sec + "
                   + uint::str(tv2.usec as uint) + " usec");

        assert tv2.sec >= tv1.sec;
        assert tv2.sec < some_future_date;
        assert tv2.usec < 1000000u32;
        if tv2.sec == tv1.sec {
            assert tv2.usec >= tv1.usec;
        }
    }

    #[test]
    fn test_precise_time() {
        let s0 = precise_time_s();
        let ns1 = precise_time_ns();

        log(debug, "s0=" + float::to_str(s0, 9u) + " sec");
        assert s0 > 0.;
        let ns0 = (s0 * 1000000000.) as u64;
        log(debug, "ns0=" + u64::str(ns0) + " ns");

        log(debug, "ns1=" + u64::str(ns1) + " ns");
        assert ns1 >= ns0;

        let ns2 = precise_time_ns();
        log(debug, "ns2=" + u64::str(ns2) + " ns");
        assert ns2 >= ns1;
    }
}
<|endoftext|>