<commit_before>// See LICENSE file for copyright and license details.

// Marauder is grid-less turn-based strategy game.

extern mod glfw;
extern mod gl;
extern mod cgmath;

use gl::types::{
  GLenum,
  GLuint,
  GLint,
  GLchar,
  GLfloat,
  GLsizeiptr,
  GLboolean
};
use cgmath::matrix::{Matrix, Mat4, Mat3, ToMat4};
use cgmath::projection;
use cgmath::angle;
use cgmath::vector::{Vec3, Vec2};

#[link(name = "glfw")]
#[link(name = "m")]
extern {}

/// usage: let s = mvp_matrix; println(type_of(&s));
fn type_of<T>(_: &T) -> &'static str {
  unsafe {
    (*std::unstable::intrinsics::get_tydesc::<T>()).name
  }
}

fn print_mat4(name: &str, mat: Mat4<f32>) {
  println!("{}:", name);
  for i in range(0u, 4) {
    for j in range(0u, 4) {
      print!("{} ", *mat.cr(i, j));
    }
    println("");
  }
  println("");
}

static mut MOUSE_POS: Vec2<f32> = Vec2{x: 0.0f32, y: 0.0};
static mut CAMERA_POS: Vec3<f32> = Vec3{x: 0.0f32, y: 0.0, z: 0.0};

static WIN_SIZE: Vec2<uint> = Vec2{x: 640, y: 480};
static VERTICES_COUNT: i32 = 3 * 2;

static VERTEX_DATA: [GLfloat, ..VERTICES_COUNT * 3] = [
   0.0,  1.0, 0.0,
   2.0, -1.0, 0.0,
  -2.0, -1.0, 0.0,

  0.0,  1.0,  0.0,
  0.0, -1.0,  2.0,
  0.0, -1.0, -2.0
];

static VERTEX_SHADER_SRC: &'static str = "
  #version 130
  in vec3 position;
  uniform mat4 model_view_proj_matrix;
  void main() {
    vec4 v = vec4(position, 1);
    gl_Position = model_view_proj_matrix * v;
  }
";

static FRAGMENT_SHADER_SRC: &'static str = "
  #version 130
  out vec4 out_color;
  void main() {
    out_color = vec4(1.0, 1.0, 1.0, 1.0);
  }
";

#[start]
fn start(argc: int, argv: **u8) -> int {
  std::rt::start_on_main_thread(argc, argv, main)
}

fn compile_shader(src: &str, ty: GLenum) -> GLuint {
  let shader = gl::CreateShader(ty);
  unsafe {
    // Attempt to compile the shader
    gl::ShaderSource(shader, 1, &src.to_c_str().unwrap(), std::ptr::null());
    gl::CompileShader(shader);

    // Get the compile status
    let mut status = gl::FALSE as GLint;
    gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut status);

    // Fail on error
    if status != (gl::TRUE as GLint) {
      let mut len = 0;
      gl::GetShaderiv(shader, gl::INFO_LOG_LENGTH, &mut len);
      // subtract 1 to skip the trailing null character
      let mut buf = std::vec::from_elem(len as uint - 1, 0u8);
      gl::GetShaderInfoLog(shader, len, std::ptr::mut_null(),
        std::vec::raw::to_mut_ptr(buf) as *mut GLchar
      );
      fail!("compile_shader(): " + std::str::raw::from_utf8(buf));
    }
  }
  shader
}

fn link_program(vertex_shader: GLuint, fragment_shader: GLuint) -> GLuint {
  let program = gl::CreateProgram();
  gl::AttachShader(program, vertex_shader);
  gl::AttachShader(program, fragment_shader);
  gl::LinkProgram(program);
  unsafe {
    // Get the link status
    let mut status = gl::FALSE as GLint;
    gl::GetProgramiv(program, gl::LINK_STATUS, &mut status);

    // Fail on error
    if status != (gl::TRUE as GLint) {
      let mut len: GLint = 0;
      gl::GetProgramiv(program, gl::INFO_LOG_LENGTH, &mut len);
      // subtract 1 to skip the trailing null character
      let mut buf = std::vec::from_elem(len as uint - 1, 0u8);
      gl::GetProgramInfoLog(program, len, std::ptr::mut_null(),
        std::vec::raw::to_mut_ptr(buf) as *mut GLchar
      );
      fail!("link_program(): " + std::str::raw::from_utf8(buf));
    }
  }
  program
}

fn tr(m: Mat4<f32>, v: Vec3<f32>) -> Mat4<f32> {
  let mut t = Mat4::<f32>::identity();
  *t.mut_cr(3, 0) = v.x;
  *t.mut_cr(3, 1) = v.y;
  *t.mut_cr(3, 2) = v.z;
  m.mul_m(&t)
}

fn rot_x(m: Mat4<f32>, angle: f32) -> Mat4<f32> {
  let r = Mat3::from_angle_x(angle::rad(angle)).to_mat4();
  m.mul_m(&r)
}

fn rot_y(m: Mat4<f32>, angle: f32) -> Mat4<f32> {
  let r = Mat3::from_angle_y(angle::rad(angle)).to_mat4();
  m.mul_m(&r)
}

// change matrices
fn upd(programId: GLuint) {
  let fov = angle::deg(45.0f32);
  let ratio = 4.0 / 3.0;
  let display_range_min = 0.1;
  let display_range_max = 100.0;
  let projection_matrix = projection::perspective(
    fov, ratio, display_range_min, display_range_max
  );

  let mut mvp_matrix = projection_matrix;
  unsafe {
    mvp_matrix = tr(mvp_matrix, Vec3{x: 0.0f32, y: 0.0, z: -10.0f32});
    mvp_matrix = rot_x(mvp_matrix, MOUSE_POS.y / 100.0);
    mvp_matrix = rot_y(mvp_matrix, MOUSE_POS.x / 100.0);
    mvp_matrix = tr(mvp_matrix, CAMERA_POS);
  }

  unsafe {
    // Get a handle for our "model_view_proj_matrix" uniform.
    // Only at initialisation time.
    let matrixId = gl::GetUniformLocation(
      programId, "model_view_proj_matrix".to_c_str().unwrap());

    // Send our transformation to the currently bound shader,
    // in the "model_view_proj_matrix" uniform.
    // For each model you render, since the model_view_proj_matrix
    // will be different (at least the M part).
    gl::UniformMatrix4fv(matrixId, 1, gl::FALSE, mvp_matrix.cr(0, 0));
  }
}

struct Win {
  vertex_shader: GLuint,
  fragment_shader: GLuint,
  program: GLuint,
  vertex_array_obj: GLuint,
  vertex_buffer_obj: GLuint,
  window: glfw::Window
}

impl Win {
  fn new() -> Win {
    let mut win =  Win{
      vertex_shader: 0,
      fragment_shader: 0,
      program: 0,
      vertex_array_obj: 0,
      vertex_buffer_obj: 0,
      window: glfw::Window::create(
        WIN_SIZE.x,
        WIN_SIZE.y,
        "OpenGL",
        glfw::Windowed
      ).unwrap()
    };
    win
  }

  fn cleanup(&self) {
    // Cleanup
    gl::DeleteProgram(self.program);
    gl::DeleteShader(self.fragment_shader);
    gl::DeleteShader(self.vertex_shader);
    unsafe {
      gl::DeleteBuffers(1, &self.vertex_buffer_obj);
      gl::DeleteVertexArrays(1, &self.vertex_array_obj);
    }
  }
}

fn main() {
  glfw::set_error_callback(~ErrorContext);

  do glfw::start {
    // glfw::window_hint::context_version(3, 2);

    let mut win =  Win::new();

    win.window.make_context_current();
    win.window.set_cursor_pos_callback(~CursorPosContext);
    win.window.set_key_callback(~KeyContext);

    // Load the OpenGL function pointers
    gl::load_with(glfw::get_proc_address);

    // Create GLSL shaders
    win.vertex_shader = compile_shader(
      VERTEX_SHADER_SRC, gl::VERTEX_SHADER);
    win.fragment_shader = compile_shader(
      FRAGMENT_SHADER_SRC, gl::FRAGMENT_SHADER);
    win.program = link_program(win.vertex_shader, win.fragment_shader);

    unsafe {
      // Create Vertex Array Object
      gl::GenVertexArrays(1, &mut win.vertex_array_obj);
      gl::BindVertexArray(win.vertex_array_obj);

      // Create a Vertex Buffer Object and copy the vertex data to it
      gl::GenBuffers(1, &mut win.vertex_buffer_obj);
      gl::BindBuffer(gl::ARRAY_BUFFER, win.vertex_buffer_obj);
      let float_size = std::mem::size_of::<GLfloat>();
      let vertices_ptr = (VERTEX_DATA.len() * float_size) as GLsizeiptr;
      gl::BufferData(
        gl::ARRAY_BUFFER,
        vertices_ptr,
        std::cast::transmute(&VERTEX_DATA[0]),
        gl::STATIC_DRAW
      );

      gl::UseProgram(win.program);
      gl::BindFragDataLocation(win.program, 0, "out_color".to_c_str().unwrap());

      // Specify the layout of the vertex data
      let pos_attr = gl::GetAttribLocation(
        win.program, "position".to_c_str().unwrap()) as GLuint;
      gl::EnableVertexAttribArray(pos_attr);
      let size = 3;
      let normalized = gl::FALSE as GLboolean;
      let stride = 0;
      gl::VertexAttribPointer(
        pos_attr,
        size,
        gl::FLOAT,
        normalized,
        stride,
        std::ptr::null()
      );
    }

    while !win.window.should_close() {
      glfw::poll_events();

      upd(win.program);

      // Clear the screen to black
      gl::ClearColor(0.3, 0.3, 0.3, 1.0);
      gl::Clear(gl::COLOR_BUFFER_BIT);

      // Draw a triangle from the 3 vertices
      gl::DrawArrays(gl::TRIANGLES, 0, VERTICES_COUNT);

      win.window.swap_buffers();
    }

    win.cleanup();
  }
}

struct CursorPosContext;
impl glfw::CursorPosCallback for CursorPosContext {
  fn call(&self, w: &glfw::Window, xpos: f64, ypos: f64) {
    if w.get_mouse_button(glfw::MouseButtonRight) == glfw::Press {
      // println!("Cursor position: ({}, {})", xpos, ypos);
      unsafe {
        MOUSE_POS.x = xpos as f32;
        MOUSE_POS.y = ypos as f32;
      }
    }
  }
}

struct ErrorContext;
impl glfw::ErrorCallback for ErrorContext {
  fn call(&self, _: glfw::Error, description: ~str) {
    println!("GLFW Error: {:s}", description);
  }
}

struct KeyContext;
impl glfw::KeyCallback for KeyContext {
  fn call(
    &self,
    window: &glfw::Window,
    key:    glfw::Key,
    _:      std::libc::c_int,
    action: glfw::Action,
    _:      glfw::Modifiers
  ) {
    match (action, key) {
      (glfw::Press, glfw::KeyEscape) => {
        window.set_should_close(true)
      }
      (glfw::Press, glfw::KeySpace) => {
        println!("space")
      }
      (glfw::Press, glfw::KeyUp) => unsafe { CAMERA_POS.y -= 1.0f32 },
      (glfw::Press, glfw::KeyDown) => unsafe { CAMERA_POS.y += 1.0f32 },
      (glfw::Press, glfw::KeyRight) => unsafe { CAMERA_POS.x -= 1.0f32 },
      (glfw::Press, glfw::KeyLeft) => unsafe { CAMERA_POS.x += 1.0f32 },
      _ => {}
    }
  }
}

// vim: set tabstop=2 shiftwidth=2 softtabstop=2 expandtab:
<commit_msg>Updated Win::new()<commit_after>// See LICENSE file for copyright and license details.

// Marauder is grid-less turn-based strategy game.

extern mod glfw;
extern mod gl;
extern mod cgmath;

use gl::types::{
  GLenum,
  GLuint,
  GLint,
  GLchar,
  GLfloat,
  GLsizeiptr,
  GLboolean
};
use cgmath::matrix::{Matrix, Mat4, Mat3, ToMat4};
use cgmath::projection;
use cgmath::angle;
use cgmath::vector::{Vec3, Vec2};

#[link(name = "glfw")]
#[link(name = "m")]
extern {}

/// usage: let s = mvp_matrix; println(type_of(&s));
fn type_of<T>(_: &T) -> &'static str {
  unsafe {
    (*std::unstable::intrinsics::get_tydesc::<T>()).name
  }
}

fn print_mat4(name: &str, mat: Mat4<f32>) {
  println!("{}:", name);
  for i in range(0u, 4) {
    for j in range(0u, 4) {
      print!("{} ", *mat.cr(i, j));
    }
    println("");
  }
  println("");
}

static mut MOUSE_POS: Vec2<f32> = Vec2{x: 0.0f32, y: 0.0};
static mut CAMERA_POS: Vec3<f32> = Vec3{x: 0.0f32, y: 0.0, z: 0.0};

static WIN_SIZE: Vec2<uint> = Vec2{x: 640, y: 480};
static VERTICES_COUNT: i32 = 3 * 2;

static VERTEX_DATA: [GLfloat, ..VERTICES_COUNT * 3] = [
   0.0,  1.0, 0.0,
   2.0, -1.0, 0.0,
  -2.0, -1.0, 0.0,

  0.0,  1.0,  0.0,
  0.0, -1.0,  2.0,
  0.0, -1.0, -2.0
];

static VERTEX_SHADER_SRC: &'static str = "
  #version 130
  in vec3 position;
  uniform mat4 model_view_proj_matrix;
  void main() {
    vec4 v = vec4(position, 1);
    gl_Position = model_view_proj_matrix * v;
  }
";

static FRAGMENT_SHADER_SRC: &'static str = "
  #version 130
  out vec4 out_color;
  void main() {
    out_color = vec4(1.0, 1.0, 1.0, 1.0);
  }
";

#[start]
fn start(argc: int, argv: **u8) -> int {
  std::rt::start_on_main_thread(argc, argv, main)
}

fn compile_shader(src: &str, ty: GLenum) -> GLuint {
  let shader = gl::CreateShader(ty);
  unsafe {
    // Attempt to compile the shader
    gl::ShaderSource(shader, 1, &src.to_c_str().unwrap(), std::ptr::null());
    gl::CompileShader(shader);

    // Get the compile status
    let mut status = gl::FALSE as GLint;
    gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut status);

    // Fail on error
    if status != (gl::TRUE as GLint) {
      let mut len = 0;
      gl::GetShaderiv(shader, gl::INFO_LOG_LENGTH, &mut len);
      // subtract 1 to skip the trailing null character
      let mut buf = std::vec::from_elem(len as uint - 1, 0u8);
      gl::GetShaderInfoLog(shader, len, std::ptr::mut_null(),
        std::vec::raw::to_mut_ptr(buf) as *mut GLchar
      );
      fail!("compile_shader(): " + std::str::raw::from_utf8(buf));
    }
  }
  shader
}

fn link_program(vertex_shader: GLuint, fragment_shader: GLuint) -> GLuint {
  let program = gl::CreateProgram();
  gl::AttachShader(program, vertex_shader);
  gl::AttachShader(program, fragment_shader);
  gl::LinkProgram(program);
  unsafe {
    // Get the link status
    let mut status = gl::FALSE as GLint;
    gl::GetProgramiv(program, gl::LINK_STATUS, &mut status);

    // Fail on error
    if status != (gl::TRUE as GLint) {
      let mut len: GLint = 0;
      gl::GetProgramiv(program, gl::INFO_LOG_LENGTH, &mut len);
      // subtract 1 to skip the trailing null character
      let mut buf = std::vec::from_elem(len as uint - 1, 0u8);
      gl::GetProgramInfoLog(program, len, std::ptr::mut_null(),
        std::vec::raw::to_mut_ptr(buf) as *mut GLchar
      );
      fail!("link_program(): " + std::str::raw::from_utf8(buf));
    }
  }
  program
}

fn tr(m: Mat4<f32>, v: Vec3<f32>) -> Mat4<f32> {
  let mut t = Mat4::<f32>::identity();
  *t.mut_cr(3, 0) = v.x;
  *t.mut_cr(3, 1) = v.y;
  *t.mut_cr(3, 2) = v.z;
  m.mul_m(&t)
}

fn rot_x(m: Mat4<f32>, angle: f32) -> Mat4<f32> {
  let r = Mat3::from_angle_x(angle::rad(angle)).to_mat4();
  m.mul_m(&r)
}

fn rot_y(m: Mat4<f32>, angle: f32) -> Mat4<f32> {
  let r = Mat3::from_angle_y(angle::rad(angle)).to_mat4();
  m.mul_m(&r)
}

// change matrices
fn upd(programId: GLuint) {
  let fov = angle::deg(45.0f32);
  let ratio = 4.0 / 3.0;
  let display_range_min = 0.1;
  let display_range_max = 100.0;
  let projection_matrix = projection::perspective(
    fov, ratio, display_range_min, display_range_max
  );

  let mut mvp_matrix = projection_matrix;
  unsafe {
    mvp_matrix = tr(mvp_matrix, Vec3{x: 0.0f32, y: 0.0, z: -10.0f32});
    mvp_matrix = rot_x(mvp_matrix, MOUSE_POS.y / 100.0);
    mvp_matrix = rot_y(mvp_matrix, MOUSE_POS.x / 100.0);
    mvp_matrix = tr(mvp_matrix, CAMERA_POS);
  }

  unsafe {
    // Get a handle for our "model_view_proj_matrix" uniform.
    // Only at initialisation time.
    let matrixId = gl::GetUniformLocation(
      programId, "model_view_proj_matrix".to_c_str().unwrap());

    // Send our transformation to the currently bound shader,
    // in the "model_view_proj_matrix" uniform.
    // For each model you render, since the model_view_proj_matrix
    // will be different (at least the M part).
    gl::UniformMatrix4fv(matrixId, 1, gl::FALSE, mvp_matrix.cr(0, 0));
  }
}

struct Win {
  vertex_shader: GLuint,
  fragment_shader: GLuint,
  program: GLuint,
  vertex_array_obj: GLuint,
  vertex_buffer_obj: GLuint,
  window: glfw::Window
}

impl Win {
  fn new() -> Win {
    let mut win =  Win{
      vertex_shader: 0,
      fragment_shader: 0,
      program: 0,
      vertex_array_obj: 0,
      vertex_buffer_obj: 0,
      window: glfw::Window::create(
        WIN_SIZE.x,
        WIN_SIZE.y,
        "OpenGL",
        glfw::Windowed
      ).unwrap()
    };

    win.window.make_context_current();
    win.window.set_cursor_pos_callback(~CursorPosContext);
    win.window.set_key_callback(~KeyContext);

    // Load the OpenGL function pointers
    gl::load_with(glfw::get_proc_address);

    // Create GLSL shaders
    win.vertex_shader = compile_shader(
      VERTEX_SHADER_SRC, gl::VERTEX_SHADER);
    win.fragment_shader = compile_shader(
      FRAGMENT_SHADER_SRC, gl::FRAGMENT_SHADER);
    win.program = link_program(win.vertex_shader, win.fragment_shader);

    unsafe {
      // Create Vertex Array Object
      gl::GenVertexArrays(1, &mut win.vertex_array_obj);
      gl::BindVertexArray(win.vertex_array_obj);

      // Create a Vertex Buffer Object and copy the vertex data to it
      gl::GenBuffers(1, &mut win.vertex_buffer_obj);
      gl::BindBuffer(gl::ARRAY_BUFFER, win.vertex_buffer_obj);
      let float_size = std::mem::size_of::<GLfloat>();
      let vertices_ptr = (VERTEX_DATA.len() * float_size) as GLsizeiptr;
      gl::BufferData(
        gl::ARRAY_BUFFER,
        vertices_ptr,
        std::cast::transmute(&VERTEX_DATA[0]),
        gl::STATIC_DRAW
      );

      gl::UseProgram(win.program);
      gl::BindFragDataLocation(win.program, 0, "out_color".to_c_str().unwrap());

      // Specify the layout of the vertex data
      let pos_attr = gl::GetAttribLocation(
        win.program, "position".to_c_str().unwrap()) as GLuint;
      gl::EnableVertexAttribArray(pos_attr);
      let size = 3;
      let normalized = gl::FALSE as GLboolean;
      let stride = 0;
      gl::VertexAttribPointer(
        pos_attr,
        size,
        gl::FLOAT,
        normalized,
        stride,
        std::ptr::null()
      );
    }

    win
  }

  fn cleanup(&self) {
    // Cleanup
    gl::DeleteProgram(self.program);
    gl::DeleteShader(self.fragment_shader);
    gl::DeleteShader(self.vertex_shader);
    unsafe {
      gl::DeleteBuffers(1, &self.vertex_buffer_obj);
      gl::DeleteVertexArrays(1, &self.vertex_array_obj);
    }
  }
}

fn main() {
  glfw::set_error_callback(~ErrorContext);

  do glfw::start {
    // glfw::window_hint::context_version(3, 2);

    let win =  Win::new();

    while !win.window.should_close() {
      glfw::poll_events();

      upd(win.program);

      // Clear the screen to black
      gl::ClearColor(0.3, 0.3, 0.3, 1.0);
      gl::Clear(gl::COLOR_BUFFER_BIT);

      // Draw a triangle from the 3 vertices
      gl::DrawArrays(gl::TRIANGLES, 0, VERTICES_COUNT);

      win.window.swap_buffers();
    }

    win.cleanup();
  }
}

struct CursorPosContext;
impl glfw::CursorPosCallback for CursorPosContext {
  fn call(&self, w: &glfw::Window, xpos: f64, ypos: f64) {
    if w.get_mouse_button(glfw::MouseButtonRight) == glfw::Press {
      // println!("Cursor position: ({}, {})", xpos, ypos);
      unsafe {
        MOUSE_POS.x = xpos as f32;
        MOUSE_POS.y = ypos as f32;
      }
    }
  }
}

struct ErrorContext;
impl glfw::ErrorCallback for ErrorContext {
  fn call(&self, _: glfw::Error, description: ~str) {
    println!("GLFW Error: {:s}", description);
  }
}

struct KeyContext;
impl glfw::KeyCallback for KeyContext {
  fn call(
    &self,
    window: &glfw::Window,
    key:    glfw::Key,
    _:      std::libc::c_int,
    action: glfw::Action,
    _:      glfw::Modifiers
  ) {
    match (action, key) {
      (glfw::Press, glfw::KeyEscape) => {
        window.set_should_close(true)
      }
      (glfw::Press, glfw::KeySpace) => {
        println!("space")
      }
      (glfw::Press, glfw::KeyUp) => unsafe { CAMERA_POS.y -= 1.0f32 },
      (glfw::Press, glfw::KeyDown) => unsafe { CAMERA_POS.y += 1.0f32 },
      (glfw::Press, glfw::KeyRight) => unsafe { CAMERA_POS.x -= 1.0f32 },
      (glfw::Press, glfw::KeyLeft) => unsafe { CAMERA_POS.x += 1.0f32 },
      _ => {}
    }
  }
}

// vim: set tabstop=2 shiftwidth=2 softtabstop=2 expandtab:
<|endoftext|>


<commit_before>use error::SendSecure;
use utils::requester::{make_request, post_file};
use hyper::{header, method, client};
use url::Url;
use std::path::Path;
use std::io::Read;
use multipart::client::Multipart;
use mime::Mime;

#[derive(Debug)]
pub struct JsonClient {
    pub locale: String,
    pub enterprise_account: String,
    pub endpoint: String,
    pub api_token: String,
    pub sendsecure_url: Option<Url>,
}

pub trait UploadFileWithPath {
    fn upload_file(&mut self,
                   upload_url: Url,
                   file_path: &Path)
                   -> SendSecure::SendSecureResult<String>;
}

pub trait UploadFileWithStream {
    fn upload_file<St: Read>(&mut self,
                             upload_url: Url,
                             stream: &mut St,
                             content_type: Option<Mime>,
                             file_name: String)
                             -> SendSecure::SendSecureResult<String>;
}

impl JsonClient {
    pub fn new(api_token: String,
               enterprise_account: String,
               endpoint: Option<String>,
               locale: Option<String>)
               -> JsonClient {
        JsonClient {
            api_token: api_token,
            enterprise_account: enterprise_account,
            endpoint: match endpoint {
                Some(x) => x,
                None => "https://portal.xmedius.com".to_string(),
            },
            locale: match locale {
                Some(x) => x,
                None => "en".to_string(),
            },
            sendsecure_url: None,
        }
    }

    fn get_sendsecure_endpoint(&mut self) -> SendSecure::SendSecureResult<Option<Url>> {
        let formatted_url = format!("{}/services/{}/sendsecure/server/url",
                                    self.endpoint,
                                    self.enterprise_account);

        if self.sendsecure_url.is_none() {
            let default = make_request(method::Method::Get, formatted_url.as_str(), None, None)?;
            let default_url = Url::parse(default.as_str())?;
            self.sendsecure_url = Some(default_url);
        }
        Ok(self.sendsecure_url.to_owned())
    }

    pub fn new_safebox(&mut self, user_email: &str) -> SendSecure::SendSecureResult<String> {
        let suffix = format!("api/v2/safeboxes/new?user_email={}&locale={}",
                             user_email,
                             self.locale);
        if let Some(sendsecure_endpoint) = self.get_sendsecure_endpoint()? {
            let mut headers = header::Headers::new();
            headers.set_raw("Authorization-Token",
                            vec![self.api_token.clone().into_bytes()]);
            let result = make_request(method::Method::Get,
                                      sendsecure_endpoint.join(suffix.as_str())?.as_str(),
                                      None,
                                      Some(headers))?;
            Ok(result)
        } else {
            Err(SendSecure::SendSecureError::UnexpectedError)
        }
    }

    pub fn security_profiles(&mut self, user_email: &str) -> SendSecure::SendSecureResult<String> {
        let suffix = format!("api/v2/enterprises/{}/security_profiles?user_email={}&locale={}",
                             self.enterprise_account,
                             user_email,
                             self.locale);
        if let Some(sendsecure_endpoint) = self.get_sendsecure_endpoint()? {
            let mut headers = header::Headers::new();
            headers.set_raw("Authorization-Token",
                            vec![self.api_token.clone().into_bytes()]);
            let result = make_request(method::Method::Get,
                                      sendsecure_endpoint.join(suffix.as_str())?.as_str(),
                                      None,
                                      Some(headers))?;
            Ok(result)
        } else {
            Err(SendSecure::SendSecureError::UnexpectedError)
        }
    }

    pub fn enterprise_settings(&mut self) -> SendSecure::SendSecureResult<String> {
        let suffix = format!("api/v2/enterprises/{}/settings?locale={}",
                             self.enterprise_account,
                             self.locale);
        if let Some(sendsecure_endpoint) = self.get_sendsecure_endpoint()? {
            let mut headers = header::Headers::new();
            headers.set_raw("Authorization-Token",
                            vec![self.api_token.clone().into_bytes()]);
            let result = make_request(method::Method::Get,
                                      sendsecure_endpoint.join(suffix.as_str())?.as_str(),
                                      None,
                                      Some(headers))?;
            Ok(result)
        } else {
            Err(SendSecure::SendSecureError::UnexpectedError)
        }
    }
}

impl UploadFileWithPath for JsonClient {
    fn upload_file(&mut self,
                   upload_url: Url,
                   file_path: &Path)
                   -> SendSecure::SendSecureResult<String> {
        post_file(upload_url, |mut multipart| {
            try!(multipart.write_file("file", file_path));
            Ok(())
        })
    }
}

impl UploadFileWithStream for JsonClient {
    fn upload_file<St: Read>(&mut self,
                             upload_url: Url,
                             stream: &mut St,
                             content_type: Option<Mime>,
                             file_name: String)
                             -> SendSecure::SendSecureResult<String> {
        post_file(upload_url, |mut multipart| {
            try!(multipart.write_stream("file",
                                        stream,
                                        Some(file_name.as_str()),
                                        content_type.to_owned()));
            Ok(())
        })
    }
}
<commit_msg>Add method commit safebox<commit_after>use error::SendSecure;
use utils::requester::{make_request, post_file};
use hyper::{header, method, client};
use url::Url;
use std::path::Path;
use std::io::Read;
use multipart::client::Multipart;
use mime::Mime;

#[derive(Debug)]
pub struct JsonClient {
    pub locale: String,
    pub enterprise_account: String,
    pub endpoint: String,
    pub api_token: String,
    pub sendsecure_url: Option<Url>,
}

pub trait UploadFileWithPath {
    fn upload_file(&mut self,
                   upload_url: Url,
                   file_path: &Path)
                   -> SendSecure::SendSecureResult<String>;
}

pub trait UploadFileWithStream {
    fn upload_file<St: Read>(&mut self,
                             upload_url: Url,
                             stream: &mut St,
                             content_type: Option<Mime>,
                             file_name: String)
                             -> SendSecure::SendSecureResult<String>;
}

impl JsonClient {
    pub fn new(api_token: String,
               enterprise_account: String,
               endpoint: Option<String>,
               locale: Option<String>)
               -> JsonClient {
        JsonClient {
            api_token: api_token,
            enterprise_account: enterprise_account,
            endpoint: match endpoint {
                Some(x) => x,
                None => "https://portal.xmedius.com".to_string(),
            },
            locale: match locale {
                Some(x) => x,
                None => "en".to_string(),
            },
            sendsecure_url: None,
        }
    }

    fn get_sendsecure_endpoint(&mut self) -> SendSecure::SendSecureResult<Option<Url>> {
        let formatted_url = format!("{}/services/{}/sendsecure/server/url",
                                    self.endpoint,
                                    self.enterprise_account);

        if self.sendsecure_url.is_none() {
            let default = make_request(method::Method::Get, formatted_url.as_str(), None, None)?;
            let default_url = Url::parse(default.as_str())?;
            self.sendsecure_url = Some(default_url);
        }
        Ok(self.sendsecure_url.to_owned())
    }

    pub fn new_safebox(&mut self, user_email: &str) -> SendSecure::SendSecureResult<String> {
        let suffix = format!("api/v2/safeboxes/new?user_email={}&locale={}",
                             user_email,
                             self.locale);
        if let Some(sendsecure_endpoint) = self.get_sendsecure_endpoint()? {
            let mut headers = header::Headers::new();
            headers.set_raw("Authorization-Token",
                            vec![self.api_token.clone().into_bytes()]);
            let result = make_request(method::Method::Get,
                                      sendsecure_endpoint.join(suffix.as_str())?.as_str(),
                                      None,
                                      Some(headers))?;
            Ok(result)
        } else {
            Err(SendSecure::SendSecureError::UnexpectedError)
        }
    }

    pub fn security_profiles(&mut self, user_email: &str) -> SendSecure::SendSecureResult<String> {
        let suffix = format!("api/v2/enterprises/{}/security_profiles?user_email={}&locale={}",
                             self.enterprise_account,
                             user_email,
                             self.locale);
        if let Some(sendsecure_endpoint) = self.get_sendsecure_endpoint()? {
            let mut headers = header::Headers::new();
            headers.set_raw("Authorization-Token",
                            vec![self.api_token.clone().into_bytes()]);
            let result = make_request(method::Method::Get,
                                      sendsecure_endpoint.join(suffix.as_str())?.as_str(),
                                      None,
                                      Some(headers))?;
            Ok(result)
        } else {
            Err(SendSecure::SendSecureError::UnexpectedError)
        }
    }

    pub fn enterprise_settings(&mut self) -> SendSecure::SendSecureResult<String> {
        let suffix = format!("api/v2/enterprises/{}/settings?locale={}",
                             self.enterprise_account,
                             self.locale);
        if let Some(sendsecure_endpoint) = self.get_sendsecure_endpoint()? {
            let mut headers = header::Headers::new();
            headers.set_raw("Authorization-Token",
                            vec![self.api_token.clone().into_bytes()]);
            let result = make_request(method::Method::Get,
                                      sendsecure_endpoint.join(suffix.as_str())?.as_str(),
                                      None,
                                      Some(headers))?;
            Ok(result)
        } else {
            Err(SendSecure::SendSecureError::UnexpectedError)
        }
    }

    pub fn commit_safebox(&mut self, safebox_json: String) -> SendSecure::SendSecureResult<String> {
        let suffix = format!("api/v2/safeboxes?locale={}", self.locale);
        if let Some(sendsecure_endpoint) = self.get_sendsecure_endpoint()? {
            let mut headers = header::Headers::new();
            headers.set_raw("Authorization-Token",
                            vec![self.api_token.clone().into_bytes()]);
            let result = make_request(method::Method::Post,
                                      sendsecure_endpoint.join(suffix.as_str())?.as_str(),
                                      Some(safebox_json),
                                      Some(headers))?;
            Ok(result)
        } else {
            Err(SendSecure::SendSecureError::UnexpectedError)
        }
    }
}

impl UploadFileWithPath for JsonClient {
    fn upload_file(&mut self,
                   upload_url: Url,
                   file_path: &Path)
                   -> SendSecure::SendSecureResult<String> {
        post_file(upload_url, |mut multipart| {
            try!(multipart.write_file("file", file_path));
            Ok(())
        })
    }
}

impl UploadFileWithStream for JsonClient {
    fn upload_file<St: Read>(&mut self,
                             upload_url: Url,
                             stream: &mut St,
                             content_type: Option<Mime>,
                             file_name: String)
                             -> SendSecure::SendSecureResult<String> {
        post_file(upload_url, |mut multipart| {
            try!(multipart.write_stream("file",
                                        stream,
                                        Some(file_name.as_str()),
                                        content_type.to_owned()));
            Ok(())
        })
    }
}
<|endoftext|>


<commit_before>/* Copyright (c) 2014, Peter Nelson
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#![crate_id = "jit"]
#![comment = "LibJIT Bindings"]
#![crate_type = "dylib"]
#![crate_type = "rlib"]
#![allow(raw_pointer_deriving, dead_code, non_camel_case_types)]
#![deny(unnecessary_parens, unrecognized_lint, unreachable_code, unnecessary_allocation, unnecessary_allocation, uppercase_variables, unused_must_use)]
#![feature(globs, macro_rules)]
#![stable]
//! This crate wraps LibJIT in an idiomatic style.
//! For example, here's a quick example which makes a multiply function using LibJIT:
//!
//! ```rust
//! extern crate jit;
//! use jit::{C_DECL, Context, Function, Type, Types, get_type};
//! fn main() {
//!     let cx = Context::new();
//!     cx.build(|| {
//!         // build the IR
//!         let sig = get_type::<fn(int, int) -> int>();
//!         let func = Function::new(cx, sig);
//!         let x = func.get_param(0);
//!         let y = func.get_param(1);
//!         let result = func.insn_mul(&x, &y);
//!         func.insn_return(&result);
//!         /// compile the IR into machine code
//!         func.compile();
//!         /// get the machine code as a function
//!         func.with_closure2(|mul:fn(int, int) -> int| {
//!             assert_eq!(mul(4, 5), 20);
//!         });
//!     });
//! }
//! ```

extern crate libc;
use bindings::{
    jit_init,
    jit_uses_interpreter,
    jit_supports_threads,
    jit_supports_virtual_memory
};
pub use bindings::{
    jit_nint,
    jit_nuint
};
pub use compile::Compile;
pub use context::{
    Context,
    InContext,
    Functions
};
pub use function::{
    ABI,
    CDECL,
    Function
};
pub use label::Label;
pub use types::*;
pub use get_type = types::get;
pub use util::NativeRef;
pub use value::Value;

/// Initialise the library and prepare for operations
#[inline]
pub fn init() -> () {
    unsafe {
        jit_init()
    }
}
/// Check if the JIT is using a fallback interpreter
#[inline]
pub fn uses_interpreter() -> bool {
    unsafe {
        jit_uses_interpreter() != 0
    }
}
/// Check if the JIT supports theads
#[inline]
pub fn supports_threads() -> bool {
    unsafe {
        jit_supports_threads() != 0
    }
}
/// Check if the JIT supports virtual memory
#[inline]
pub fn supports_virtual_memory() -> bool {
    unsafe {
        jit_supports_virtual_memory() != 0
    }
}
#[macro_escape]
mod macros;
mod bindings;
mod context;
mod compile;
mod elf;
mod function;
mod label;
#[cfg(test)]
mod tests;
mod types;
mod util;
mod value;<commit_msg>Add `unsafe_destructor` feature to crate<commit_after>/* Copyright (c) 2014, Peter Nelson
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#![crate_id = "jit"]
#![comment = "LibJIT Bindings"]
#![crate_type = "dylib"]
#![crate_type = "rlib"]
#![allow(raw_pointer_deriving, dead_code, non_camel_case_types, unknown_features)]
#![deny(unnecessary_parens, unrecognized_lint, unreachable_code, unnecessary_allocation, unnecessary_allocation, uppercase_variables, unused_must_use)]
#![feature(globs, macro_rules, unsafe_destructor)]
#![stable]
//! This crate wraps LibJIT in an idiomatic style.
//! For example, here's a quick example which makes a multiply function using LibJIT:
//!
//! ```rust
//! extern crate jit;
//! use jit::{C_DECL, Context, Function, Type, Types, get_type};
//! fn main() {
//!     let cx = Context::new();
//!     cx.build(|| {
//!         // build the IR
//!         let sig = get_type::<fn(int, int) -> int>();
//!         let func = Function::new(cx, sig);
//!         let x = func.get_param(0);
//!         let y = func.get_param(1);
//!         let result = func.insn_mul(&x, &y);
//!         func.insn_return(&result);
//!         /// compile the IR into machine code
//!         func.compile();
//!         /// get the machine code as a function
//!         func.with_closure2(|mul:fn(int, int) -> int| {
//!             assert_eq!(mul(4, 5), 20);
//!         });
//!     });
//! }
//! ```

extern crate libc;
use bindings::{
    jit_init,
    jit_uses_interpreter,
    jit_supports_threads,
    jit_supports_virtual_memory
};
pub use bindings::{
    jit_nint,
    jit_nuint
};
pub use compile::Compile;
pub use context::{
    Context,
    InContext,
    Functions
};
pub use function::{
    ABI,
    CDECL,
    Function
};
pub use label::Label;
pub use types::*;
pub use get_type = types::get;
pub use util::NativeRef;
pub use value::Value;

/// Initialise the library and prepare for operations
#[inline]
pub fn init() -> () {
    unsafe {
        jit_init()
    }
}
/// Check if the JIT is using a fallback interpreter
#[inline]
pub fn uses_interpreter() -> bool {
    unsafe {
        jit_uses_interpreter() != 0
    }
}
/// Check if the JIT supports theads
#[inline]
pub fn supports_threads() -> bool {
    unsafe {
        jit_supports_threads() != 0
    }
}
/// Check if the JIT supports virtual memory
#[inline]
pub fn supports_virtual_memory() -> bool {
    unsafe {
        jit_supports_virtual_memory() != 0
    }
}
#[macro_escape]
mod macros;
mod bindings;
mod context;
mod compile;
mod elf;
mod function;
mod label;
#[cfg(test)]
mod tests;
mod types;
mod util;
mod value;<|endoftext|>


<commit_before>#[derive(Debug, PartialEq, Eq)]
pub struct LexerElem<'a> {
    pub elem: Elem<'a>,
    pub pos: Position,
}

impl<'a> LexerElem<'a> {
    pub fn new(elem: Elem<'a>, pos: Position) -> Self {
        LexerElem { elem, pos }
    }
}

#[derive(Debug, PartialEq, Eq)]
pub enum Elem<'a> {
    Text(&'a str),
    Command(&'a str),
    Comment(&'a str),
    Number(i32),
    EscapedChar(char),
    SpecialChar(char),
    LineBreak,
    EndOfFile,
    Space,
    BeginGroup,
    EndGroup,
    MathShift,
    AlignementTab,
    SuperScript,
    SubScript,
    Active,
    MacroParam,

    Char(char),
}

#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct Position {
    pub line: usize,
    pub column: usize,
}

impl Position {
    pub fn new(line: usize, column: usize) -> Self {
        Position { line, column }
    }
}
<commit_msg>improve LexerElem access api<commit_after>#[derive(Debug, PartialEq, Eq)]
pub struct LexerElem<'a> {
    elem: Elem<'a>,
    pos: Position,
}

impl<'a> LexerElem<'a> {
    pub fn new(elem: Elem<'a>, pos: Position) -> Self {
        LexerElem { elem, pos }
    }

    pub fn elem(&self) -> &Elem<'a> {
        &self.elem
    }

    pub fn position(&self) -> &Position {
        &self.pos
    }
}

#[derive(Debug, PartialEq, Eq)]
pub enum Elem<'a> {
    Text(&'a str),
    Command(&'a str),
    Comment(&'a str),
    Number(i32),
    EscapedChar(char),
    SpecialChar(char),
    LineBreak,
    EndOfFile,
    Space,
    BeginGroup,
    EndGroup,
    MathShift,
    AlignementTab,
    SuperScript,
    SubScript,
    Active,
    MacroParam,

    Char(char),
}

#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct Position {
    pub line: usize,
    pub column: usize,
}

impl Position {
    pub fn new(line: usize, column: usize) -> Self {
        Position { line, column }
    }
}
<|endoftext|>


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

//! A radix trie for storing integers in sorted order

use prelude::*;

// FIXME: #3469: need to manually update TrieNode when SHIFT changes
// FIXME: #5244: need to manually update the TrieNode constructor
const SHIFT: uint = 4;
const SIZE: uint = 1 << SHIFT;
const MASK: uint = SIZE - 1;

enum Child<T> {
    Internal(~TrieNode<T>),
    External(uint, T),
    Nothing
}

pub struct TrieMap<T> {
    priv root: TrieNode<T>,
    priv length: uint
}

impl<T> BaseIter<(uint, &'self T)> for TrieMap<T> {
    /// Visit all key-value pairs in order
    #[inline(always)]
    pure fn each(&self, f: &fn(&(uint, &self/T)) -> bool) {
        self.root.each(f);
    }
    #[inline(always)]
    pure fn size_hint(&self) -> Option<uint> { Some(self.len()) }
}

impl<T> ReverseIter<(uint, &'self T)> for TrieMap<T> {
    /// Visit all key-value pairs in reverse order
    #[inline(always)]
    pure fn each_reverse(&self, f: &fn(&(uint, &self/T)) -> bool) {
        self.root.each_reverse(f);
    }
}

impl<T> Container for TrieMap<T> {
    /// Return the number of elements in the map
    #[inline(always)]
    pure fn len(&self) -> uint { self.length }

    /// Return true if the map contains no elements
    #[inline(always)]
    pure fn is_empty(&self) -> bool { self.len() == 0 }
}

impl<T> Mutable for TrieMap<T> {
    /// Clear the map, removing all values.
    #[inline(always)]
    fn clear(&mut self) {
        self.root = TrieNode::new();
        self.length = 0;
    }
}

impl<T> Map<uint, T> for TrieMap<T> {
    /// Return true if the map contains a value for the specified key
    #[inline(always)]
    pure fn contains_key(&self, key: &uint) -> bool {
        self.find(key).is_some()
    }

    /// Visit all keys in order
    #[inline(always)]
    pure fn each_key(&self, f: &fn(&uint) -> bool) {
        self.each(|&(k, _)| f(&k))
    }

    /// Visit all values in order
    #[inline(always)]
    pure fn each_value(&self, f: &fn(&T) -> bool) {
        self.each(|&(_, v)| f(v))
    }

    /// Iterate over the map and mutate the contained values
    #[inline(always)]
    fn mutate_values(&mut self, f: &fn(&uint, &mut T) -> bool) {
        self.root.mutate_values(f);
    }

    /// Return the value corresponding to the key in the map
    #[inline(hint)]
    pure fn find(&self, key: &uint) -> Option<&self/T> {
        let mut node: &self/TrieNode<T> = &self.root;
        let mut idx = 0;
        loop {
            match node.children[chunk(*key, idx)] {
              Internal(ref x) => node = &**x,
              External(stored, ref value) => {
                if stored == *key {
                    return Some(value)
                } else {
                    return None
                }
              }
              Nothing => return None
            }
            idx += 1;
        }
    }

    /// Insert a key-value pair into the map. An existing value for a
    /// key is replaced by the new value. Return true if the key did
    /// not already exist in the map.
    #[inline(always)]
    fn insert(&mut self, key: uint, value: T) -> bool {
        let ret = insert(&mut self.root.count,
                         &mut self.root.children[chunk(key, 0)],
                         key, value, 1);
        if ret { self.length += 1 }
        ret
    }

    /// Remove a key-value pair from the map. Return true if the key
    /// was present in the map, otherwise false.
    #[inline(always)]
    fn remove(&mut self, key: &uint) -> bool {
        let ret = remove(&mut self.root.count,
                         &mut self.root.children[chunk(*key, 0)],
                         *key, 1);
        if ret { self.length -= 1 }
        ret
    }
}

impl<T> TrieMap<T> {
    #[inline(always)]
    static pure fn new() -> TrieMap<T> {
        TrieMap{root: TrieNode::new(), length: 0}
    }
}

impl<T> TrieMap<T> {
    /// Visit all keys in reverse order
    #[inline(always)]
    pure fn each_key_reverse(&self, f: &fn(&uint) -> bool) {
        self.each_reverse(|&(k, _)| f(&k))
    }

    /// Visit all values in reverse order
    #[inline(always)]
    pure fn each_value_reverse(&self, f: &fn(&T) -> bool) {
        self.each_reverse(|&(_, v)| f(v))
    }
}

pub struct TrieSet {
    priv map: TrieMap<()>
}

impl BaseIter<uint> for TrieSet {
    /// Visit all values in order
    pure fn each(&self, f: &fn(&uint) -> bool) { self.map.each_key(f) }
    pure fn size_hint(&self) -> Option<uint> { Some(self.len()) }
}

impl ReverseIter<uint> for TrieSet {
    /// Visit all values in reverse order
    pure fn each_reverse(&self, f: &fn(&uint) -> bool) {
        self.map.each_key_reverse(f)
    }
}

impl Container for TrieSet {
    /// Return the number of elements in the set
    #[inline(always)]
    pure fn len(&self) -> uint { self.map.len() }

    /// Return true if the set contains no elements
    #[inline(always)]
    pure fn is_empty(&self) -> bool { self.map.is_empty() }
}

impl Mutable for TrieSet {
    /// Clear the set, removing all values.
    #[inline(always)]
    fn clear(&mut self) { self.map.clear() }
}

impl TrieSet {
    /// Return true if the set contains a value
    #[inline(always)]
    pure fn contains(&self, value: &uint) -> bool {
        self.map.contains_key(value)
    }

    /// Add a value to the set. Return true if the value was not already
    /// present in the set.
    #[inline(always)]
    fn insert(&mut self, value: uint) -> bool { self.map.insert(value, ()) }

    /// Remove a value from the set. Return true if the value was
    /// present in the set.
    #[inline(always)]
    fn remove(&mut self, value: &uint) -> bool { self.map.remove(value) }
}

struct TrieNode<T> {
    count: uint,
    children: [Child<T> * 16] // FIXME: #3469: can't use the SIZE constant yet
}

impl<T> TrieNode<T> {
    #[inline(always)]
    static pure fn new() -> TrieNode<T> {
        // FIXME: #5244: [Nothing, ..SIZE] should be possible without Copy
        TrieNode{count: 0,
                 children: [Nothing, Nothing, Nothing, Nothing,
                            Nothing, Nothing, Nothing, Nothing,
                            Nothing, Nothing, Nothing, Nothing,
                            Nothing, Nothing, Nothing, Nothing]}
    }
}

impl<T> TrieNode<T> {
    pure fn each(&self, f: &fn(&(uint, &self/T)) -> bool) -> bool {
        for uint::range(0, self.children.len()) |idx| {
            match self.children[idx] {
                Internal(ref x) => if !x.each(f) { return false },
                External(k, ref v) => if !f(&(k, v)) { return false },
                Nothing => ()
            }
        }
        true
    }

    pure fn each_reverse(&self, f: &fn(&(uint, &self/T)) -> bool) -> bool {
        for uint::range_rev(self.children.len(), 0) |idx| {
            match self.children[idx - 1] {
                Internal(ref x) => if !x.each_reverse(f) { return false },
                External(k, ref v) => if !f(&(k, v)) { return false },
                Nothing => ()
            }
        }
        true
    }

    fn mutate_values(&mut self, f: &fn(&uint, &mut T) -> bool) -> bool {
        for vec::each_mut(self.children) |child| {
            match *child {
                Internal(ref mut x) => if !x.mutate_values(f) {
                    return false
                },
                External(k, ref mut v) => if !f(&k, v) { return false },
                Nothing => ()
            }
        }
        true
    }
}

// if this was done via a trait, the key could be generic
#[inline(always)]
pure fn chunk(n: uint, idx: uint) -> uint {
    let real_idx = uint::bytes - 1 - idx;
    (n >> (SHIFT * real_idx)) & MASK
}

fn insert<T>(count: &mut uint, child: &mut Child<T>, key: uint, value: T,
             idx: uint) -> bool {
    let mut tmp = Nothing;
    tmp <-> *child;
    let mut added = false;

    *child = match tmp {
      External(stored_key, stored_value) => {
          if stored_key == key {
              External(stored_key, value)
          } else {
              // conflict - split the node
              let mut new = ~TrieNode::new();
              insert(&mut new.count,
                     &mut new.children[chunk(stored_key, idx)],
                     stored_key, stored_value, idx + 1);
              insert(&mut new.count, &mut new.children[chunk(key, idx)], key,
                     value, idx + 1);
              added = true;
              Internal(new)
          }
      }
      Internal(x) => {
        let mut x = x;
        added = insert(&mut x.count, &mut x.children[chunk(key, idx)], key,
                       value, idx + 1);
        Internal(x)

      }
      Nothing => {
        *count += 1;
        added = true;
        External(key, value)
      }
    };
    added
}

fn remove<T>(count: &mut uint, child: &mut Child<T>, key: uint,
             idx: uint) -> bool {
    let (ret, this) = match *child {
      External(stored, _) => {
          if stored == key { (true, true) } else { (false, false) }
      }
      Internal(ref mut x) => {
          let ret = remove(&mut x.count, &mut x.children[chunk(key, idx)],
                           key, idx + 1);
          (ret, x.count == 0)
      }
      Nothing => (false, false)
    };

    if this {
        *child = Nothing;
        *count -= 1;
    }
    ret
}

#[cfg(test)]
pub fn check_integrity<T>(trie: &TrieNode<T>) {
    fail_unless!(trie.count != 0);

    let mut sum = 0;

    for trie.children.each |x| {
        match *x {
          Nothing => (),
          Internal(ref y) => {
              check_integrity(&**y);
              sum += 1
          }
          External(_, _) => { sum += 1 }
        }
    }

    fail_unless!(sum == trie.count);
}

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

    #[test]
    fn test_step() {
        let mut trie = TrieMap::new();
        let n = 300;

        for uint::range_step(1, n, 2) |x| {
            fail_unless!(trie.insert(x, x + 1));
            fail_unless!(trie.contains_key(&x));
            check_integrity(&trie.root);
        }

        for uint::range_step(0, n, 2) |x| {
            fail_unless!(!trie.contains_key(&x));
            fail_unless!(trie.insert(x, x + 1));
            check_integrity(&trie.root);
        }

        for uint::range(0, n) |x| {
            fail_unless!(trie.contains_key(&x));
            fail_unless!(!trie.insert(x, x + 1));
            check_integrity(&trie.root);
        }

        for uint::range_step(1, n, 2) |x| {
            fail_unless!(trie.remove(&x));
            fail_unless!(!trie.contains_key(&x));
            check_integrity(&trie.root);
        }

        for uint::range_step(0, n, 2) |x| {
            fail_unless!(trie.contains_key(&x));
            fail_unless!(!trie.insert(x, x + 1));
            check_integrity(&trie.root);
        }
    }

    #[test]
    fn test_each() {
        let mut m = TrieMap::new();

        fail_unless!(m.insert(3, 6));
        fail_unless!(m.insert(0, 0));
        fail_unless!(m.insert(4, 8));
        fail_unless!(m.insert(2, 4));
        fail_unless!(m.insert(1, 2));

        let mut n = 0;
        for m.each |&(k, v)| {
            fail_unless!(k == n);
            fail_unless!(*v == n * 2);
            n += 1;
        }
    }

    #[test]
    fn test_each_break() {
        let mut m = TrieMap::new();

        for uint::range_rev(uint::max_value, uint::max_value - 10000) |x| {
            m.insert(x, x / 2);
        }

        let mut n = uint::max_value - 9999;
        for m.each |&(k, v)| {
            if n == uint::max_value - 5000 { break }
            fail_unless!(n < uint::max_value - 5000);

            fail_unless!(k == n);
            fail_unless!(*v == n / 2);
            n += 1;
        }
    }

    #[test]
    fn test_each_reverse() {
        let mut m = TrieMap::new();

        fail_unless!(m.insert(3, 6));
        fail_unless!(m.insert(0, 0));
        fail_unless!(m.insert(4, 8));
        fail_unless!(m.insert(2, 4));
        fail_unless!(m.insert(1, 2));

        let mut n = 4;
        for m.each_reverse |&(k, v)| {
            fail_unless!(k == n);
            fail_unless!(*v == n * 2);
            n -= 1;
        }
    }

    #[test]
    fn test_each_reverse_break() {
        let mut m = TrieMap::new();

        for uint::range_rev(uint::max_value, uint::max_value - 10000) |x| {
            m.insert(x, x / 2);
        }

        let mut n = uint::max_value;
        for m.each_reverse |&(k, v)| {
            if n == uint::max_value - 5000 { break }
            fail_unless!(n > uint::max_value - 5000);

            fail_unless!(k == n);
            fail_unless!(*v == n / 2);
            n -= 1;
        }
    }
}
<commit_msg>add constructor to TrieSet (was missing)<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! A radix trie for storing integers in sorted order

use prelude::*;

// FIXME: #3469: need to manually update TrieNode when SHIFT changes
// FIXME: #5244: need to manually update the TrieNode constructor
const SHIFT: uint = 4;
const SIZE: uint = 1 << SHIFT;
const MASK: uint = SIZE - 1;

enum Child<T> {
    Internal(~TrieNode<T>),
    External(uint, T),
    Nothing
}

pub struct TrieMap<T> {
    priv root: TrieNode<T>,
    priv length: uint
}

impl<T> BaseIter<(uint, &'self T)> for TrieMap<T> {
    /// Visit all key-value pairs in order
    #[inline(always)]
    pure fn each(&self, f: &fn(&(uint, &self/T)) -> bool) {
        self.root.each(f);
    }
    #[inline(always)]
    pure fn size_hint(&self) -> Option<uint> { Some(self.len()) }
}

impl<T> ReverseIter<(uint, &'self T)> for TrieMap<T> {
    /// Visit all key-value pairs in reverse order
    #[inline(always)]
    pure fn each_reverse(&self, f: &fn(&(uint, &self/T)) -> bool) {
        self.root.each_reverse(f);
    }
}

impl<T> Container for TrieMap<T> {
    /// Return the number of elements in the map
    #[inline(always)]
    pure fn len(&self) -> uint { self.length }

    /// Return true if the map contains no elements
    #[inline(always)]
    pure fn is_empty(&self) -> bool { self.len() == 0 }
}

impl<T> Mutable for TrieMap<T> {
    /// Clear the map, removing all values.
    #[inline(always)]
    fn clear(&mut self) {
        self.root = TrieNode::new();
        self.length = 0;
    }
}

impl<T> Map<uint, T> for TrieMap<T> {
    /// Return true if the map contains a value for the specified key
    #[inline(always)]
    pure fn contains_key(&self, key: &uint) -> bool {
        self.find(key).is_some()
    }

    /// Visit all keys in order
    #[inline(always)]
    pure fn each_key(&self, f: &fn(&uint) -> bool) {
        self.each(|&(k, _)| f(&k))
    }

    /// Visit all values in order
    #[inline(always)]
    pure fn each_value(&self, f: &fn(&T) -> bool) {
        self.each(|&(_, v)| f(v))
    }

    /// Iterate over the map and mutate the contained values
    #[inline(always)]
    fn mutate_values(&mut self, f: &fn(&uint, &mut T) -> bool) {
        self.root.mutate_values(f);
    }

    /// Return the value corresponding to the key in the map
    #[inline(hint)]
    pure fn find(&self, key: &uint) -> Option<&self/T> {
        let mut node: &self/TrieNode<T> = &self.root;
        let mut idx = 0;
        loop {
            match node.children[chunk(*key, idx)] {
              Internal(ref x) => node = &**x,
              External(stored, ref value) => {
                if stored == *key {
                    return Some(value)
                } else {
                    return None
                }
              }
              Nothing => return None
            }
            idx += 1;
        }
    }

    /// Insert a key-value pair into the map. An existing value for a
    /// key is replaced by the new value. Return true if the key did
    /// not already exist in the map.
    #[inline(always)]
    fn insert(&mut self, key: uint, value: T) -> bool {
        let ret = insert(&mut self.root.count,
                         &mut self.root.children[chunk(key, 0)],
                         key, value, 1);
        if ret { self.length += 1 }
        ret
    }

    /// Remove a key-value pair from the map. Return true if the key
    /// was present in the map, otherwise false.
    #[inline(always)]
    fn remove(&mut self, key: &uint) -> bool {
        let ret = remove(&mut self.root.count,
                         &mut self.root.children[chunk(*key, 0)],
                         *key, 1);
        if ret { self.length -= 1 }
        ret
    }
}

impl<T> TrieMap<T> {
    /// Create an empty TrieMap
    #[inline(always)]
    static pure fn new() -> TrieMap<T> {
        TrieMap{root: TrieNode::new(), length: 0}
    }
}

impl<T> TrieMap<T> {
    /// Visit all keys in reverse order
    #[inline(always)]
    pure fn each_key_reverse(&self, f: &fn(&uint) -> bool) {
        self.each_reverse(|&(k, _)| f(&k))
    }

    /// Visit all values in reverse order
    #[inline(always)]
    pure fn each_value_reverse(&self, f: &fn(&T) -> bool) {
        self.each_reverse(|&(_, v)| f(v))
    }
}

pub struct TrieSet {
    priv map: TrieMap<()>
}

impl BaseIter<uint> for TrieSet {
    /// Visit all values in order
    pure fn each(&self, f: &fn(&uint) -> bool) { self.map.each_key(f) }
    pure fn size_hint(&self) -> Option<uint> { Some(self.len()) }
}

impl ReverseIter<uint> for TrieSet {
    /// Visit all values in reverse order
    pure fn each_reverse(&self, f: &fn(&uint) -> bool) {
        self.map.each_key_reverse(f)
    }
}

impl Container for TrieSet {
    /// Return the number of elements in the set
    #[inline(always)]
    pure fn len(&self) -> uint { self.map.len() }

    /// Return true if the set contains no elements
    #[inline(always)]
    pure fn is_empty(&self) -> bool { self.map.is_empty() }
}

impl Mutable for TrieSet {
    /// Clear the set, removing all values.
    #[inline(always)]
    fn clear(&mut self) { self.map.clear() }
}

impl TrieSet {
    /// Create an empty TrieSet
    #[inline(always)]
    static pure fn new() -> TrieSet {
        TrieSet{map: TrieMap::new()}
    }

    /// Return true if the set contains a value
    #[inline(always)]
    pure fn contains(&self, value: &uint) -> bool {
        self.map.contains_key(value)
    }

    /// Add a value to the set. Return true if the value was not already
    /// present in the set.
    #[inline(always)]
    fn insert(&mut self, value: uint) -> bool { self.map.insert(value, ()) }

    /// Remove a value from the set. Return true if the value was
    /// present in the set.
    #[inline(always)]
    fn remove(&mut self, value: &uint) -> bool { self.map.remove(value) }
}

struct TrieNode<T> {
    count: uint,
    children: [Child<T> * 16] // FIXME: #3469: can't use the SIZE constant yet
}

impl<T> TrieNode<T> {
    #[inline(always)]
    static pure fn new() -> TrieNode<T> {
        // FIXME: #5244: [Nothing, ..SIZE] should be possible without Copy
        TrieNode{count: 0,
                 children: [Nothing, Nothing, Nothing, Nothing,
                            Nothing, Nothing, Nothing, Nothing,
                            Nothing, Nothing, Nothing, Nothing,
                            Nothing, Nothing, Nothing, Nothing]}
    }
}

impl<T> TrieNode<T> {
    pure fn each(&self, f: &fn(&(uint, &self/T)) -> bool) -> bool {
        for uint::range(0, self.children.len()) |idx| {
            match self.children[idx] {
                Internal(ref x) => if !x.each(f) { return false },
                External(k, ref v) => if !f(&(k, v)) { return false },
                Nothing => ()
            }
        }
        true
    }

    pure fn each_reverse(&self, f: &fn(&(uint, &self/T)) -> bool) -> bool {
        for uint::range_rev(self.children.len(), 0) |idx| {
            match self.children[idx - 1] {
                Internal(ref x) => if !x.each_reverse(f) { return false },
                External(k, ref v) => if !f(&(k, v)) { return false },
                Nothing => ()
            }
        }
        true
    }

    fn mutate_values(&mut self, f: &fn(&uint, &mut T) -> bool) -> bool {
        for vec::each_mut(self.children) |child| {
            match *child {
                Internal(ref mut x) => if !x.mutate_values(f) {
                    return false
                },
                External(k, ref mut v) => if !f(&k, v) { return false },
                Nothing => ()
            }
        }
        true
    }
}

// if this was done via a trait, the key could be generic
#[inline(always)]
pure fn chunk(n: uint, idx: uint) -> uint {
    let real_idx = uint::bytes - 1 - idx;
    (n >> (SHIFT * real_idx)) & MASK
}

fn insert<T>(count: &mut uint, child: &mut Child<T>, key: uint, value: T,
             idx: uint) -> bool {
    let mut tmp = Nothing;
    tmp <-> *child;
    let mut added = false;

    *child = match tmp {
      External(stored_key, stored_value) => {
          if stored_key == key {
              External(stored_key, value)
          } else {
              // conflict - split the node
              let mut new = ~TrieNode::new();
              insert(&mut new.count,
                     &mut new.children[chunk(stored_key, idx)],
                     stored_key, stored_value, idx + 1);
              insert(&mut new.count, &mut new.children[chunk(key, idx)], key,
                     value, idx + 1);
              added = true;
              Internal(new)
          }
      }
      Internal(x) => {
        let mut x = x;
        added = insert(&mut x.count, &mut x.children[chunk(key, idx)], key,
                       value, idx + 1);
        Internal(x)

      }
      Nothing => {
        *count += 1;
        added = true;
        External(key, value)
      }
    };
    added
}

fn remove<T>(count: &mut uint, child: &mut Child<T>, key: uint,
             idx: uint) -> bool {
    let (ret, this) = match *child {
      External(stored, _) => {
          if stored == key { (true, true) } else { (false, false) }
      }
      Internal(ref mut x) => {
          let ret = remove(&mut x.count, &mut x.children[chunk(key, idx)],
                           key, idx + 1);
          (ret, x.count == 0)
      }
      Nothing => (false, false)
    };

    if this {
        *child = Nothing;
        *count -= 1;
    }
    ret
}

#[cfg(test)]
pub fn check_integrity<T>(trie: &TrieNode<T>) {
    fail_unless!(trie.count != 0);

    let mut sum = 0;

    for trie.children.each |x| {
        match *x {
          Nothing => (),
          Internal(ref y) => {
              check_integrity(&**y);
              sum += 1
          }
          External(_, _) => { sum += 1 }
        }
    }

    fail_unless!(sum == trie.count);
}

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

    #[test]
    fn test_step() {
        let mut trie = TrieMap::new();
        let n = 300;

        for uint::range_step(1, n, 2) |x| {
            fail_unless!(trie.insert(x, x + 1));
            fail_unless!(trie.contains_key(&x));
            check_integrity(&trie.root);
        }

        for uint::range_step(0, n, 2) |x| {
            fail_unless!(!trie.contains_key(&x));
            fail_unless!(trie.insert(x, x + 1));
            check_integrity(&trie.root);
        }

        for uint::range(0, n) |x| {
            fail_unless!(trie.contains_key(&x));
            fail_unless!(!trie.insert(x, x + 1));
            check_integrity(&trie.root);
        }

        for uint::range_step(1, n, 2) |x| {
            fail_unless!(trie.remove(&x));
            fail_unless!(!trie.contains_key(&x));
            check_integrity(&trie.root);
        }

        for uint::range_step(0, n, 2) |x| {
            fail_unless!(trie.contains_key(&x));
            fail_unless!(!trie.insert(x, x + 1));
            check_integrity(&trie.root);
        }
    }

    #[test]
    fn test_each() {
        let mut m = TrieMap::new();

        fail_unless!(m.insert(3, 6));
        fail_unless!(m.insert(0, 0));
        fail_unless!(m.insert(4, 8));
        fail_unless!(m.insert(2, 4));
        fail_unless!(m.insert(1, 2));

        let mut n = 0;
        for m.each |&(k, v)| {
            fail_unless!(k == n);
            fail_unless!(*v == n * 2);
            n += 1;
        }
    }

    #[test]
    fn test_each_break() {
        let mut m = TrieMap::new();

        for uint::range_rev(uint::max_value, uint::max_value - 10000) |x| {
            m.insert(x, x / 2);
        }

        let mut n = uint::max_value - 9999;
        for m.each |&(k, v)| {
            if n == uint::max_value - 5000 { break }
            fail_unless!(n < uint::max_value - 5000);

            fail_unless!(k == n);
            fail_unless!(*v == n / 2);
            n += 1;
        }
    }

    #[test]
    fn test_each_reverse() {
        let mut m = TrieMap::new();

        fail_unless!(m.insert(3, 6));
        fail_unless!(m.insert(0, 0));
        fail_unless!(m.insert(4, 8));
        fail_unless!(m.insert(2, 4));
        fail_unless!(m.insert(1, 2));

        let mut n = 4;
        for m.each_reverse |&(k, v)| {
            fail_unless!(k == n);
            fail_unless!(*v == n * 2);
            n -= 1;
        }
    }

    #[test]
    fn test_each_reverse_break() {
        let mut m = TrieMap::new();

        for uint::range_rev(uint::max_value, uint::max_value - 10000) |x| {
            m.insert(x, x / 2);
        }

        let mut n = uint::max_value;
        for m.each_reverse |&(k, v)| {
            if n == uint::max_value - 5000 { break }
            fail_unless!(n > uint::max_value - 5000);

            fail_unless!(k == n);
            fail_unless!(*v == n / 2);
            n -= 1;
        }
    }
}
<|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.

/*!
Primitive traits representing basic 'kinds' of types

Rust types can be classified in various useful ways according to
intrinsic properties of the type. These classifications, often called
'kinds', are represented as traits.

They cannot be implemented by user code, but are instead implemented
by the compiler automatically for the types to which they apply.

*/

/// Types able to be transferred across task boundaries.
#[lang="send"]
pub trait Send {
    // empty.
}

/// Types with a constant size known at compile-time.
#[lang="sized"]
pub trait Sized {
    // Empty.
}

/// Types that can be copied by simply copying bits (i.e. `memcpy`).
///
/// The name "POD" stands for "Plain Old Data" and is borrowed from C++.
#[lang="pod"]
pub trait Pod {
    // Empty.
}

/// Types that can be safely shared between threads, hence thread-safe.
#[lang="share"]
pub trait Share {
    // Empty
}

/// Marker types are special types that are used with unsafe code to
/// inform the compiler of special constraints. Marker types should
/// only be needed when you are creating an abstraction that is
/// implemented using unsafe code. In that case, you may want to embed
/// some of the marker types below into your type.
pub mod marker {

    /// A marker type whose type parameter `T` is considered to be
    /// covariant with respect to the type itself. This is (typically)
    /// used to indicate that an instance of the type `T` is being stored
    /// into memory and read from, even though that may not be apparent.
    ///
    /// For more information about variance, refer to this Wikipedia
    /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
    ///
    /// *Note:* It is very unusual to have to add a covariant constraint.
    /// If you are not sure, you probably want to use `InvariantType`.
    ///
    /// # Example
    ///
    /// Given a struct `S` that includes a type parameter `T`
    /// but does not actually *reference* that type parameter:
    ///
    /// ```ignore
    /// use std::cast;
    ///
    /// struct S<T> { x: *() }
    /// fn get<T>(s: &S<T>) -> T {
    ///    unsafe {
    ///        let x: *T = cast::transmute(s.x);
    ///        *x
    ///    }
    /// }
    /// ```
    ///
    /// The type system would currently infer that the value of
    /// the type parameter `T` is irrelevant, and hence a `S<int>` is
    /// a subtype of `S<~[int]>` (or, for that matter, `S<U>` for
    /// any `U`). But this is incorrect because `get()` converts the
    /// `*()` into a `*T` and reads from it. Therefore, we should include the
    /// a marker field `CovariantType<T>` to inform the type checker that
    /// `S<T>` is a subtype of `S<U>` if `T` is a subtype of `U`
    /// (for example, `S<&'static int>` is a subtype of `S<&'a int>`
    /// for some lifetime `'a`, but not the other way around).
    #[lang="covariant_type"]
    #[deriving(Eq,Clone)]
    pub struct CovariantType<T>;

    /// A marker type whose type parameter `T` is considered to be
    /// contravariant with respect to the type itself. This is (typically)
    /// used to indicate that an instance of the type `T` will be consumed
    /// (but not read from), even though that may not be apparent.
    ///
    /// For more information about variance, refer to this Wikipedia
    /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
    ///
    /// *Note:* It is very unusual to have to add a contravariant constraint.
    /// If you are not sure, you probably want to use `InvariantType`.
    ///
    /// # Example
    ///
    /// Given a struct `S` that includes a type parameter `T`
    /// but does not actually *reference* that type parameter:
    ///
    /// ```
    /// use std::cast;
    ///
    /// struct S<T> { x: *() }
    /// fn get<T>(s: &S<T>, v: T) {
    ///    unsafe {
    ///        let x: fn(T) = cast::transmute(s.x);
    ///        x(v)
    ///    }
    /// }
    /// ```
    ///
    /// The type system would currently infer that the value of
    /// the type parameter `T` is irrelevant, and hence a `S<int>` is
    /// a subtype of `S<~[int]>` (or, for that matter, `S<U>` for
    /// any `U`). But this is incorrect because `get()` converts the
    /// `*()` into a `fn(T)` and then passes a value of type `T` to it.
    ///
    /// Supplying a `ContravariantType` marker would correct the
    /// problem, because it would mark `S` so that `S<T>` is only a
    /// subtype of `S<U>` if `U` is a subtype of `T`; given that the
    /// function requires arguments of type `T`, it must also accept
    /// arguments of type `U`, hence such a conversion is safe.
    #[lang="contravariant_type"]
    #[deriving(Eq,Clone)]
    pub struct ContravariantType<T>;

    /// A marker type whose type parameter `T` is considered to be
    /// invariant with respect to the type itself. This is (typically)
    /// used to indicate that instances of the type `T` may be read or
    /// written, even though that may not be apparent.
    ///
    /// For more information about variance, refer to this Wikipedia
    /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
    ///
    /// # Example
    ///
    /// The Cell type is an example which uses unsafe code to achieve
    /// "interior" mutability:
    ///
    /// ```
    /// pub struct Cell<T> { priv value: T }
    /// # fn main() {}
    /// ```
    ///
    /// The type system would infer that `value` is only read here and
    /// never written, but in fact `Cell` uses unsafe code to achieve
    /// interior mutability.
    #[lang="invariant_type"]
    #[deriving(Eq,Clone)]
    pub struct InvariantType<T>;

    /// As `CovariantType`, but for lifetime parameters. Using
    /// `CovariantLifetime<'a>` indicates that it is ok to substitute
    /// a *longer* lifetime for `'a` than the one you originally
    /// started with (e.g., you could convert any lifetime `'foo` to
    /// `'static`). You almost certainly want `ContravariantLifetime`
    /// instead, or possibly `InvariantLifetime`. The only case where
    /// it would be appropriate is that you have a (type-casted, and
    /// hence hidden from the type system) function pointer with a
    /// signature like `fn(&'a T)` (and no other uses of `'a`). In
    /// this case, it is ok to substitute a larger lifetime for `'a`
    /// (e.g., `fn(&'static T)`), because the function is only
    /// becoming more selective in terms of what it accepts as
    /// argument.
    ///
    /// For more information about variance, refer to this Wikipedia
    /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
    #[lang="covariant_lifetime"]
    #[deriving(Eq,Clone)]
    pub struct CovariantLifetime<'a>;

    /// As `ContravariantType`, but for lifetime parameters. Using
    /// `ContravariantLifetime<'a>` indicates that it is ok to
    /// substitute a *shorter* lifetime for `'a` than the one you
    /// originally started with (e.g., you could convert `'static` to
    /// any lifetime `'foo`). This is appropriate for cases where you
    /// have an unsafe pointer that is actually a pointer into some
    /// memory with lifetime `'a`, and thus you want to limit the
    /// lifetime of your data structure to `'a`. An example of where
    /// this is used is the iterator for vectors.
    ///
    /// For more information about variance, refer to this Wikipedia
    /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
    #[lang="contravariant_lifetime"]
    #[deriving(Eq,Clone)]
    pub struct ContravariantLifetime<'a>;

    /// As `InvariantType`, but for lifetime parameters. Using
    /// `InvariantLifetime<'a>` indicates that it is not ok to
    /// substitute any other lifetime for `'a` besides its original
    /// value. This is appropriate for cases where you have an unsafe
    /// pointer that is actually a pointer into memory with lifetime `'a`,
    /// and this pointer is itself stored in an inherently mutable
    /// location (such as a `Cell`).
    #[lang="invariant_lifetime"]
    #[deriving(Eq,Clone)]
    pub struct InvariantLifetime<'a>;

    /// A type which is considered "not sendable", meaning that it cannot
    /// be safely sent between tasks, even if it is owned. This is
    /// typically embedded in other types, such as `Gc`, to ensure that
    /// their instances remain thread-local.
    #[lang="no_send_bound"]
    #[deriving(Eq,Clone)]
    pub struct NoSend;

    /// A type which is considered "not POD", meaning that it is not
    /// implicitly copyable. This is typically embedded in other types to
    /// ensure that they are never copied, even if they lack a destructor.
    #[lang="no_pod_bound"]
    #[deriving(Eq,Clone)]
    pub struct NoPod;

    /// A type which is considered "not sharable", meaning that
    /// its contents are not threadsafe, hence they cannot be
    /// shared between tasks.
    #[lang="no_share_bound"]
    #[deriving(Eq,Clone)]
    pub struct NoShare;

    /// A type which is considered managed by the GC. This is typically
    /// embedded in other types.
    #[lang="managed_bound"]
    #[deriving(Eq,Clone)]
    pub struct Managed;
}
<commit_msg>auto merge of #13070 : huonw/rust/share-doc, r=alexcrichton<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.

/*!
Primitive traits representing basic 'kinds' of types

Rust types can be classified in various useful ways according to
intrinsic properties of the type. These classifications, often called
'kinds', are represented as traits.

They cannot be implemented by user code, but are instead implemented
by the compiler automatically for the types to which they apply.

*/

/// Types able to be transferred across task boundaries.
#[lang="send"]
pub trait Send {
    // empty.
}

/// Types with a constant size known at compile-time.
#[lang="sized"]
pub trait Sized {
    // Empty.
}

/// Types that can be copied by simply copying bits (i.e. `memcpy`).
///
/// The name "POD" stands for "Plain Old Data" and is borrowed from C++.
#[lang="pod"]
pub trait Pod {
    // Empty.
}

/// Types that can be safely shared between tasks when aliased.
///
/// The precise definition is: a type `T` is `Share` if `&T` is
/// thread-safe. In other words, there is no possibility of data races
/// when passing `&T` references between tasks.
///
/// As one would expect, primitive types like `u8` and `f64` are all
/// `Share`, and so are simple aggregate types containing them (like
/// tuples, structs and enums). More instances of basic `Share` types
/// include "immutable" types like `&T` and those with simple
/// inherited mutability, such as `~T`, `Vec<T>` and most other
/// collection types. (Generic parameters need to be `Share` for their
/// container to be `Share`.)
///
/// A somewhat surprising consequence of the definition is `&mut T` is
/// `Share` (if `T` is `Share`) even though it seems that it might
/// provide unsynchronised mutation. The trick is a mutable reference
/// stored in an aliasable reference (that is, `& &mut T`) becomes
/// read-only, as if it were a `& &T`, hence there is no risk of a data
/// race.
///
/// Types that are not `Share` are those that have "interior
/// mutability" in a non-thread-safe way, such as `Cell` and `RefCell`
/// in `std::cell`. These types allow for mutation of their contents
/// even when in an immutable, aliasable slot, e.g. the contents of
/// `&Cell<T>` can be `.set`, and do not ensure data races are
/// impossible, hence they cannot be `Share`. A higher level example
/// of a non-`Share` type is the reference counted pointer
/// `std::rc::Rc`, because any reference `&Rc<T>` can clone a new
/// reference, which modifies the reference counts in a non-atomic
/// way.
///
/// For cases when one does need thread-safe interior mutability,
/// types like the atomics in `std::sync` and `Mutex` & `RWLock` in
/// the `sync` crate do ensure that any mutation cannot cause data
/// races.  Hence these types are `Share`.
///
/// Users writing their own types with interior mutability (or anything
/// else that is not thread-safe) should use the `NoShare` marker type
/// (from `std::kinds::marker`) to ensure that the compiler doesn't
/// consider the user-defined type to be `Share`.  Any types with
/// interior mutability must also use the `std::ty::Unsafe` wrapper
/// around the value(s) which can be mutated when behind a `&`
/// reference; not doing this is undefined behaviour (for example,
/// `transmute`-ing from `&T` to `&mut T` is illegal).
#[lang="share"]
pub trait Share {
    // Empty
}

/// Marker types are special types that are used with unsafe code to
/// inform the compiler of special constraints. Marker types should
/// only be needed when you are creating an abstraction that is
/// implemented using unsafe code. In that case, you may want to embed
/// some of the marker types below into your type.
pub mod marker {

    /// A marker type whose type parameter `T` is considered to be
    /// covariant with respect to the type itself. This is (typically)
    /// used to indicate that an instance of the type `T` is being stored
    /// into memory and read from, even though that may not be apparent.
    ///
    /// For more information about variance, refer to this Wikipedia
    /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
    ///
    /// *Note:* It is very unusual to have to add a covariant constraint.
    /// If you are not sure, you probably want to use `InvariantType`.
    ///
    /// # Example
    ///
    /// Given a struct `S` that includes a type parameter `T`
    /// but does not actually *reference* that type parameter:
    ///
    /// ```ignore
    /// use std::cast;
    ///
    /// struct S<T> { x: *() }
    /// fn get<T>(s: &S<T>) -> T {
    ///    unsafe {
    ///        let x: *T = cast::transmute(s.x);
    ///        *x
    ///    }
    /// }
    /// ```
    ///
    /// The type system would currently infer that the value of
    /// the type parameter `T` is irrelevant, and hence a `S<int>` is
    /// a subtype of `S<~[int]>` (or, for that matter, `S<U>` for
    /// any `U`). But this is incorrect because `get()` converts the
    /// `*()` into a `*T` and reads from it. Therefore, we should include the
    /// a marker field `CovariantType<T>` to inform the type checker that
    /// `S<T>` is a subtype of `S<U>` if `T` is a subtype of `U`
    /// (for example, `S<&'static int>` is a subtype of `S<&'a int>`
    /// for some lifetime `'a`, but not the other way around).
    #[lang="covariant_type"]
    #[deriving(Eq,Clone)]
    pub struct CovariantType<T>;

    /// A marker type whose type parameter `T` is considered to be
    /// contravariant with respect to the type itself. This is (typically)
    /// used to indicate that an instance of the type `T` will be consumed
    /// (but not read from), even though that may not be apparent.
    ///
    /// For more information about variance, refer to this Wikipedia
    /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
    ///
    /// *Note:* It is very unusual to have to add a contravariant constraint.
    /// If you are not sure, you probably want to use `InvariantType`.
    ///
    /// # Example
    ///
    /// Given a struct `S` that includes a type parameter `T`
    /// but does not actually *reference* that type parameter:
    ///
    /// ```
    /// use std::cast;
    ///
    /// struct S<T> { x: *() }
    /// fn get<T>(s: &S<T>, v: T) {
    ///    unsafe {
    ///        let x: fn(T) = cast::transmute(s.x);
    ///        x(v)
    ///    }
    /// }
    /// ```
    ///
    /// The type system would currently infer that the value of
    /// the type parameter `T` is irrelevant, and hence a `S<int>` is
    /// a subtype of `S<~[int]>` (or, for that matter, `S<U>` for
    /// any `U`). But this is incorrect because `get()` converts the
    /// `*()` into a `fn(T)` and then passes a value of type `T` to it.
    ///
    /// Supplying a `ContravariantType` marker would correct the
    /// problem, because it would mark `S` so that `S<T>` is only a
    /// subtype of `S<U>` if `U` is a subtype of `T`; given that the
    /// function requires arguments of type `T`, it must also accept
    /// arguments of type `U`, hence such a conversion is safe.
    #[lang="contravariant_type"]
    #[deriving(Eq,Clone)]
    pub struct ContravariantType<T>;

    /// A marker type whose type parameter `T` is considered to be
    /// invariant with respect to the type itself. This is (typically)
    /// used to indicate that instances of the type `T` may be read or
    /// written, even though that may not be apparent.
    ///
    /// For more information about variance, refer to this Wikipedia
    /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
    ///
    /// # Example
    ///
    /// The Cell type is an example which uses unsafe code to achieve
    /// "interior" mutability:
    ///
    /// ```
    /// pub struct Cell<T> { priv value: T }
    /// # fn main() {}
    /// ```
    ///
    /// The type system would infer that `value` is only read here and
    /// never written, but in fact `Cell` uses unsafe code to achieve
    /// interior mutability.
    #[lang="invariant_type"]
    #[deriving(Eq,Clone)]
    pub struct InvariantType<T>;

    /// As `CovariantType`, but for lifetime parameters. Using
    /// `CovariantLifetime<'a>` indicates that it is ok to substitute
    /// a *longer* lifetime for `'a` than the one you originally
    /// started with (e.g., you could convert any lifetime `'foo` to
    /// `'static`). You almost certainly want `ContravariantLifetime`
    /// instead, or possibly `InvariantLifetime`. The only case where
    /// it would be appropriate is that you have a (type-casted, and
    /// hence hidden from the type system) function pointer with a
    /// signature like `fn(&'a T)` (and no other uses of `'a`). In
    /// this case, it is ok to substitute a larger lifetime for `'a`
    /// (e.g., `fn(&'static T)`), because the function is only
    /// becoming more selective in terms of what it accepts as
    /// argument.
    ///
    /// For more information about variance, refer to this Wikipedia
    /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
    #[lang="covariant_lifetime"]
    #[deriving(Eq,Clone)]
    pub struct CovariantLifetime<'a>;

    /// As `ContravariantType`, but for lifetime parameters. Using
    /// `ContravariantLifetime<'a>` indicates that it is ok to
    /// substitute a *shorter* lifetime for `'a` than the one you
    /// originally started with (e.g., you could convert `'static` to
    /// any lifetime `'foo`). This is appropriate for cases where you
    /// have an unsafe pointer that is actually a pointer into some
    /// memory with lifetime `'a`, and thus you want to limit the
    /// lifetime of your data structure to `'a`. An example of where
    /// this is used is the iterator for vectors.
    ///
    /// For more information about variance, refer to this Wikipedia
    /// article <http://en.wikipedia.org/wiki/Variance_%28computer_science%29>.
    #[lang="contravariant_lifetime"]
    #[deriving(Eq,Clone)]
    pub struct ContravariantLifetime<'a>;

    /// As `InvariantType`, but for lifetime parameters. Using
    /// `InvariantLifetime<'a>` indicates that it is not ok to
    /// substitute any other lifetime for `'a` besides its original
    /// value. This is appropriate for cases where you have an unsafe
    /// pointer that is actually a pointer into memory with lifetime `'a`,
    /// and this pointer is itself stored in an inherently mutable
    /// location (such as a `Cell`).
    #[lang="invariant_lifetime"]
    #[deriving(Eq,Clone)]
    pub struct InvariantLifetime<'a>;

    /// A type which is considered "not sendable", meaning that it cannot
    /// be safely sent between tasks, even if it is owned. This is
    /// typically embedded in other types, such as `Gc`, to ensure that
    /// their instances remain thread-local.
    #[lang="no_send_bound"]
    #[deriving(Eq,Clone)]
    pub struct NoSend;

    /// A type which is considered "not POD", meaning that it is not
    /// implicitly copyable. This is typically embedded in other types to
    /// ensure that they are never copied, even if they lack a destructor.
    #[lang="no_pod_bound"]
    #[deriving(Eq,Clone)]
    pub struct NoPod;

    /// A type which is considered "not sharable", meaning that
    /// its contents are not threadsafe, hence they cannot be
    /// shared between tasks.
    #[lang="no_share_bound"]
    #[deriving(Eq,Clone)]
    pub struct NoShare;

    /// A type which is considered managed by the GC. This is typically
    /// embedded in other types.
    #[lang="managed_bound"]
    #[deriving(Eq,Clone)]
    pub struct Managed;
}
<|endoftext|>