<commit_before><commit_msg>Add compute image load/store example<commit_after>// Based on https://github.com/Erkaman/image-load-store-demo
//
// This example showcases image load/store functionality in compute shaders, which
// allows you to read and write to arbitrary textures in a shader.
//
// Three compute shaders are launched. The first one draws the mandelbrot fractal. The second
// one applies a box filter on the output of the first. Finally, the third one copies data
// the original unsigned integer texture to a signed normalized integer texture.
// Finally, this last texture is blitted to the display framebuffer.

#[macro_use]
extern crate glium;

use std::time::Instant;
mod support;

use glium::{texture::UnsignedTexture2d, uniform, Surface, Texture2d};

fn main() {
    // building the display, ie. the main object
    let event_loop = glutin::event_loop::EventLoop::new();
    let wb = glutin::window::WindowBuilder::new();
    let cb = glutin::ContextBuilder::new()
        .with_vsync(true)
        .with_gl(glutin::GlRequest::Latest);
    let display = glium::Display::new(wb, cb, &event_loop).unwrap();

    let start_time = Instant::now();

    let fract_texture = UnsignedTexture2d::empty_with_format(
        &display,
        glium::texture::UncompressedUintFormat::U8U8U8U8,
        glium::texture::MipmapsOption::NoMipmap,
        1024,
        1024,
    )
    .unwrap();

    let final_texture = Texture2d::empty_with_format(
        &display,
        glium::texture::UncompressedFloatFormat::U8U8U8U8,
        glium::texture::MipmapsOption::NoMipmap,
        1024,
        1024,
    )
    .unwrap();

    let fractal_shader = glium::program::ComputeShader::from_source(&display, r#"\
#version 430
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

uniform uint uWidth;
uniform uint uHeight;
uniform float uTime;
uniform layout(binding=3, rgba8ui) writeonly uimage2D uFractalTexture;

void main() {
  ivec2 i = ivec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y);
  vec2 uv = vec2(i) * vec2(1.0 / float(uWidth), 1.0 / float(uHeight));

  float n = 0.0;
  vec2 c = vec2(-.745, .186) +  (uv - 0.5)*(2.0+ 1.7*cos(1.8*uTime)  ),
    z = vec2(0.0);
  const int M =128;
  for (int i = 0; i<M; i++)
    {
      z = vec2(z.x*z.x - z.y*z.y, 2.*z.x*z.y) + c;
      if (dot(z, z) > 2) break;

      n++;
    }
  vec3 bla = vec3(0,0,0.0);
  vec3 blu = vec3(0,0,0.8);
  vec4 color;
  if( n >= 0 && n <= M/2-1 ) { color = vec4( mix( vec3(0.2, 0.1, 0.4), blu, n / float(M/2-1) ), 1.0) ;  }
  if( n >= M/2 && n <= M ) { color = vec4( mix( blu, bla, float(n - M/2 ) / float(M/2) ), 1.0) ;  }

  imageStore(uFractalTexture, i , uvec4(color * 255.0f));
}
    "#).unwrap();

    let box_blur_shader = glium::program::ComputeShader::from_source(
        &display,
        r#"\
#version 430
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

uniform uint uWidth;
uniform uint uHeight;
uniform layout(binding=3, rgba8ui) uimage2D uFractalTexture;

// sample with clamping from the texture.
vec4 csample(ivec2 i) {
  i = ivec2(clamp(i.x, 0, uWidth-1), clamp(i.y, 0, uHeight-1));
  return imageLoad(uFractalTexture, i);
}

#define R 8
#define W (1.0 / ((1.0+2.0*float(R)) * (1.0+2.0*float(R))))
void main() {
  ivec2 i = ivec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y);

  vec4 sum = vec4(0.0);
  // first compute the blurred color.
       for(int x = -R; x <= +R; x++ )
       for(int y = -R; y <= +R; y++ )
	 sum += W * csample(i + ivec2(x,y));

  // now store the blurred color.
  imageStore(uFractalTexture,  i, uvec4(sum) );
}

    "#,
    )
    .unwrap();

    let copy_shader = glium::program::ComputeShader::from_source(
        &display,
        r#"\
#version 430
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

uniform layout(binding=3, rgba8ui) readonly uimage2D uFractalTexture;
uniform layout(binding=4, rgba8) writeonly image2D destTexture;

void main() {
  ivec2 i = ivec2(gl_GlobalInvocationID.x, gl_GlobalInvocationID.y);
  vec3 c = vec3(imageLoad(uFractalTexture, i).xyz);
  vec3 cnorm = c/255.0;
  imageStore(destTexture, i, vec4(cnorm,1.0));
}
    "#,
    )
    .unwrap();

    support::start_loop(event_loop, move |events| {
        let image_unit = fract_texture
            .image_unit(glium::uniforms::ImageUnitFormat::RGBA8UI)
            .unwrap()
            .set_access(glium::uniforms::ImageUnitAccess::Write);
        fractal_shader.execute(
            uniform! {
                uWidth: fract_texture.width(),
                uHeight: fract_texture.height(),
                uFractalTexture: image_unit,
                uTime: Instant::now().duration_since(start_time.clone()).as_secs_f32(),
            },
            fract_texture.width(),
            fract_texture.height(),
            1,
        );

        let image_unit = fract_texture
            .image_unit(glium::uniforms::ImageUnitFormat::RGBA8UI)
            .unwrap()
            .set_access(glium::uniforms::ImageUnitAccess::ReadWrite);
        box_blur_shader.execute(
            uniform! {
                uWidth: fract_texture.width(),
                uHeight: fract_texture.height(),
                uFractalTexture: image_unit,
            },
            fract_texture.width(),
            fract_texture.height(),
            1,
        );

        let fract_unit = fract_texture
            .image_unit(glium::uniforms::ImageUnitFormat::RGBA8UI)
            .unwrap()
            .set_access(glium::uniforms::ImageUnitAccess::Read);
        let final_unit = final_texture
            .image_unit(glium::uniforms::ImageUnitFormat::RGBA8)
            .unwrap()
            .set_access(glium::uniforms::ImageUnitAccess::Write);

        copy_shader.execute(
            uniform! {
                uFractalTexture: fract_unit,
                destTexture: final_unit,
            },
            fract_texture.width(),
            fract_texture.height(),
            1,
        );

        // drawing a frame
        let target = display.draw();
        final_texture
            .as_surface()
            .fill(&target, glium::uniforms::MagnifySamplerFilter::Nearest);
        target.finish().unwrap();

        // polling and handling the events received by the window
        let mut action = support::Action::Continue;
        for event in events {
            match event {
                glutin::event::Event::WindowEvent { event, .. } => match event {
                    glutin::event::WindowEvent::CloseRequested => action = support::Action::Stop,
                    _ => (),
                },
                _ => (),
            }
        }

        action
    });
}
<|endoftext|>


<commit_before><commit_msg>Add a binary for the example<commit_after>extern crate multirust;
extern crate rust_bisect;
extern crate rust_install;

use std::env;
use std::ffi::OsStr;
use std::path::PathBuf;

///! This example is equivalent to running
///!     rust-bisect --good=nightly-2015-10-27 --bad=nightly-2015-11-30 cargo build
///! in the `examples/rust-issue-30123` directory.
fn main() {
    let manifest_dir = PathBuf::from(&env::var("CARGO_MANIFEST_DIR").unwrap());
    env::set_current_dir(manifest_dir.join("examples/rust-issue-30123")).unwrap();

    let cmd = OsStr::new("cargo");
    let args = vec![OsStr::new("build")];

    let cfg = rust_bisect::Cfg {
        good: "nightly-2015-10-27".parse().unwrap(),
        bad: "nightly-2015-11-30".parse().unwrap(),
        cmd: cmd,
        args: args,
    };

    let mr_cfg = multirust::Cfg::from_env(rust_install::notify::SharedNotifyHandler::none())
                     .expect("multirust config");

    rust_bisect::run(&cfg, &mr_cfg).unwrap();
}
<|endoftext|>


<commit_before><commit_msg>Skeleton for problem 1750<commit_after>// https://leetcode.com/problems/minimum-length-of-string-after-deleting-similar-ends/
pub fn minimum_length(s: String) -> i32 {
    todo!()
}

fn main() {
    println!("{}", minimum_length("ca".to_string())); // 2
    println!("{}", minimum_length("cabaabac".to_string())); // 0
    println!("{}", minimum_length("aabccabba".to_string())); // 3
}
<|endoftext|>


<commit_before><commit_msg>Add a sprites batching example<commit_after>#[macro_use]
extern crate glium;
extern crate rand;

use glium::{DisplayBuild, Surface};
use glium::glutin;

mod support;

fn main() {
    println!("This example demonstrates how to draw a lot of sprites in an efficient manner. \n\n\
              Instead of drawing sprites one by one, it writes the list of sprites in a buffer \
              and draws everything at once. Textures are accessed though a Texture2dArray to \
              avoid the problem of binding textures one by one.\n\n\
              Performances are limited by the synchronization required to write on the color \
              buffer. Enabling depth test would likely increase the framerate.\n");

    const SPRITES_COUNT: usize = 1024;
    println!("Number of sprites: {}", SPRITES_COUNT);

    let display = glutin::WindowBuilder::new().build_glium().unwrap();

    // generating a bunch of unicolor 2D images that will be used for a texture
    // we store all of them in a `Texture2dArray`
    let texture = {
        let images = (0 .. 64).map(|_| {
            let color1: (f32, f32, f32) = (rand::random(), rand::random(), rand::random());
            let color2: (f32, f32, f32) = (rand::random(), rand::random(), rand::random());
            vec![vec![color1], vec![color2]]
        }).collect::<Vec<_>>();

        glium::texture::Texture2dArray::new_if_supported(&display, images).unwrap()
    };

    // building the vertex buffer and index buffers that will be filled with the data of
    // the sprites
    let (mut vertex_buffer, index_buffer) = {
        #[derive(Copy, Clone)]
        struct Vertex {
            i_position: [f32; 2],
            i_tex_id: u32,
        }

        implement_vertex!(Vertex, i_position, i_tex_id);

        let mut vb: glium::VertexBuffer<Vertex> = glium::VertexBuffer::empty_dynamic(&display,
                                                                             SPRITES_COUNT * 4);
        let mut ib_data = Vec::with_capacity(SPRITES_COUNT * 6);

        // initializing with random data
        for (num, sprite) in vb.map().chunks_mut(4).enumerate() {
            let tex_id: u32 = rand::random();
            let tex_id = tex_id % texture.get_array_size().unwrap();
            let position: (f32, f32) = (rand::random(), rand::random());
            let position: (f32, f32) = (position.0 * 2.0 - 1.0, position.1 * 2.0 - 1.0);

            sprite[0].i_position[0] = position.0 - 0.1;
            sprite[0].i_position[1] = position.1 + 0.1;
            sprite[0].i_tex_id = tex_id;
            sprite[1].i_position[0] = position.0 + 0.1;
            sprite[1].i_position[1] = position.1 + 0.1;
            sprite[1].i_tex_id = tex_id;
            sprite[2].i_position[0] = position.0 - 0.1;
            sprite[2].i_position[1] = position.1 - 0.1;
            sprite[2].i_tex_id = tex_id;
            sprite[3].i_position[0] = position.0 + 0.1;
            sprite[3].i_position[1] = position.1 - 0.1;
            sprite[3].i_tex_id = tex_id;

            let num = num as u16;
            ib_data.push(num * 4);
            ib_data.push(num * 4 + 1);
            ib_data.push(num * 4 + 2);
            ib_data.push(num * 4 + 1);
            ib_data.push(num * 4 + 3);
            ib_data.push(num * 4 + 2);
        }

        let ib_data = glium::index::TrianglesList(ib_data);
        (vb, glium::index::IndexBuffer::new(&display, ib_data))
    };

    // we determine the texture coordinates depending on the ID the of vertex
    let program = program!(&display,
        140 => {
            vertex: "
                #version 140

                in vec2 i_position;
                in unsigned int i_tex_id;

                out vec2 v_tex_coords;
                flat out unsigned int v_tex_id;

                void main() {
                    gl_Position = vec4(i_position, 0.0, 1.0);

                    if (gl_VertexID % 4 == 0) {
                        v_tex_coords = vec2(0.0, 1.0);
                    } else if (gl_VertexID % 4 == 1) {
                        v_tex_coords = vec2(1.0, 1.0);
                    } else if (gl_VertexID % 4 == 2) {
                        v_tex_coords = vec2(0.0, 0.0);
                    } else {
                        v_tex_coords = vec2(1.0, 0.0);
                    }

                    v_tex_id = i_tex_id;
                }
            ",

            fragment: "
                #version 140

                uniform sampler2DArray tex;

                in vec2 v_tex_coords;
                flat in unsigned int v_tex_id;

                out vec4 f_color;

                void main() {
                    f_color = texture(tex, vec3(v_tex_coords, float(v_tex_id)));
                }
            "
        },

        110 => {
            vertex: "
                #version 110

                in vec2 i_position;
                in unsigned int i_tex_id;

                varying vec2 v_tex_coords;
                flat varying unsigned int v_tex_id;

                void main() {
                    gl_Position = vec4(i_position, 0.0, 1.0);

                    if (gl_VertexID % 4 == 0) {
                        v_tex_coords = vec2(0.0, 1.0);
                    } else if (gl_VertexID % 4 == 1) {
                        v_tex_coords = vec2(1.0, 1.0);
                    } else if (gl_VertexID % 4 == 2) {
                        v_tex_coords = vec2(0.0, 0.0);
                    } else {
                        v_tex_coords = vec2(1.0, 0.0);
                    }

                    v_tex_id = i_tex_id;
                }
            ",

            fragment: "
                #version 110

                uniform sampler2DArray tex;

                varying vec2 v_tex_coords;
                flat varying unsigned int v_tex_id;

                void main() {
                    gl_FragColor = texture2DArray(tex, vec3(v_tex_coords, float(v_tex_id)));
                }
            "
        },

        100 => {
            vertex: "
                #version 100

                attribute lowp vec2 i_position;
                attribute unsigned int i_tex_id;

                varying lowp vec2 v_tex_coords;
                flat varying unsigned int v_tex_id;

                void main() {
                    gl_Position = vec4(i_position, 0.0, 1.0);

                    if (gl_VertexID % 4 == 0) {
                        v_tex_coords = vec2(0.0, 1.0);
                    } else if (gl_VertexID % 4 == 1) {
                        v_tex_coords = vec2(1.0, 1.0);
                    } else if (gl_VertexID % 4 == 2) {
                        v_tex_coords = vec2(0.0, 0.0);
                    } else {
                        v_tex_coords = vec2(1.0, 0.0);
                    }

                    v_tex_id = i_tex_id;
                }
            ",

            fragment: "
                #version 100

                uniform sampler2DArray tex;

                varying lowp vec2 v_tex_coords;
                flat varying unsigned int v_tex_id;

                void main() {
                    gl_FragColor = texture2DArray(tex, vec3(v_tex_coords, float(v_tex_id)));
                }
            "
        },
    ).unwrap();

    // the main loop
    support::start_loop(|| {
        // moving the sprites in a random direction
        // in a game, you would typically write the exact positions and texture IDs of your sprites
        {
            let mut mapping = vertex_buffer.map();
            for sprite in mapping.chunks_mut(4) {
                let mv: (f32, f32) = (rand::random(), rand::random());
                let mv = (mv.0 * 0.01 - 0.005, mv.1 * 0.01 - 0.005);

                sprite[0].i_position[0] += mv.0;
                sprite[0].i_position[1] += mv.1;
                sprite[1].i_position[0] += mv.0;
                sprite[1].i_position[1] += mv.1;
                sprite[2].i_position[0] += mv.0;
                sprite[2].i_position[1] += mv.1;
                sprite[3].i_position[0] += mv.0;
                sprite[3].i_position[1] += mv.1;
                // sprite[...].i_tex_id = ...;  // if you want to set the texture
            }
        }

        // we must only draw the number of sprites that we have written in the vertex buffer
        // if you only want to draw 20 sprites for example, you should pass `0 .. 20 * 6` instead
        let ib_slice = index_buffer.slice(0 .. SPRITES_COUNT * 6).unwrap();

        // drawing a frame
        let mut target = display.draw();
        target.clear_color(0.0, 0.0, 0.0, 0.0);
        target.draw(&vertex_buffer, &ib_slice,
                    &program, &uniform! { tex: &texture }, &Default::default()).unwrap();
        target.finish();

        for event in display.poll_events() {
            match event {
                glutin::Event::Closed => return support::Action::Stop,
                _ => ()
            }
        }

        support::Action::Continue
    });
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#![allow(missing_copy_implementations)]
#![allow(unstable)]

extern crate azure;
extern crate geom;
extern crate gfx;
extern crate util;

pub mod canvas_paint_task;
<commit_msg>Fix warnings in canvas.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#![feature(core)]

#![allow(missing_copy_implementations)]

extern crate azure;
extern crate geom;
extern crate gfx;
extern crate util;

pub mod canvas_paint_task;
<|endoftext|>


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

enum Foo { Bar }

fn main() {
    Foo::Bar.a;
    //~^ ERROR: attempted access of field `a` on type `Foo`, but no field with that name was found
}
<|endoftext|>


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

// Issue #26656: Verify that trait objects cannot bypass dropck.

// Using this instead of Fn etc. to take HRTB out of the equation.
trait Trigger<B> { fn fire(&self, b: &mut B); }
impl<B: Button> Trigger<B> for () {
    fn fire(&self, b: &mut B) {
        b.push();
    }
}

// Still unsound Zook
trait Button { fn push(&self); }
struct Zook<B> { button: B, trigger: Box<Trigger<B>+'static> }

impl<B> Drop for Zook<B> {
    fn drop(&mut self) {
        self.trigger.fire(&mut self.button);
    }
}

// AND
struct Bomb { usable: bool }
impl Drop for Bomb { fn drop(&mut self) { self.usable = false; } }
impl Bomb { fn activate(&self) { assert!(self.usable) } }

enum B<'a> { HarmlessButton, BigRedButton(&'a Bomb) }
impl<'a> Button for B<'a> {
    fn push(&self) {
        if let B::BigRedButton(borrowed) = *self {
            borrowed.activate();
        }
    }
}

fn main() {
    let (mut zook, ticking);
    zook = Zook { button: B::HarmlessButton,
                  trigger: Box::new(()) };
    ticking = Bomb { usable: true };
    zook.button = B::BigRedButton(&ticking);
    //~^ ERROR `ticking` does not live long enough
}
<|endoftext|>


<commit_before><commit_msg>Fix ImageProcessing example.<commit_after><|endoftext|>


<commit_before>// The Computer Language Benchmarks Game
// http://benchmarksgame.alioth.debian.org/
//
// contributed by the Rust Project Developers

// Copyright (c) 2013-2014 The Rust Project Developers
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// - Redistributions of source code must retain the above copyright
//   notice, this list of conditions and the following disclaimer.
//
// - 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.
//
// - Neither the name of "The Computer Language Benchmarks Game" nor
//   the name of "The Computer Language Shootout Benchmarks" nor the
//   names of its contributors may be used to endorse or promote
//   products derived from this software without specific prior
//   written permission.
//
// 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 OWNER 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.

use std::cmp::min;
use std::env;
use std::io;
use std::io::BufWriter;
use std::io::prelude::*;

const LINE_LEN: usize = 60;
const LOOKUP_SIZE: usize = 4 * 1024;
const LOOKUP_SCALE: f32 = (LOOKUP_SIZE - 1) as f32;

// Random number generator constants
const IM: u32 = 139968;
const IA: u32 = 3877;
const IC: u32 = 29573;

const ALU: &'static str = "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTG\
                            GGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGA\
                            GACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAA\
                            AATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAAT\
                            CCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAAC\
                            CCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTG\
                            CACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA";

const NULL_AMINO_ACID: AminoAcid = AminoAcid { c: ' ' as u8, p: 0.0 };

static IUB: [AminoAcid;15] = [
    AminoAcid { c: 'a' as u8, p: 0.27 },
    AminoAcid { c: 'c' as u8, p: 0.12 },
    AminoAcid { c: 'g' as u8, p: 0.12 },
    AminoAcid { c: 't' as u8, p: 0.27 },
    AminoAcid { c: 'B' as u8, p: 0.02 },
    AminoAcid { c: 'D' as u8, p: 0.02 },
    AminoAcid { c: 'H' as u8, p: 0.02 },
    AminoAcid { c: 'K' as u8, p: 0.02 },
    AminoAcid { c: 'M' as u8, p: 0.02 },
    AminoAcid { c: 'N' as u8, p: 0.02 },
    AminoAcid { c: 'R' as u8, p: 0.02 },
    AminoAcid { c: 'S' as u8, p: 0.02 },
    AminoAcid { c: 'V' as u8, p: 0.02 },
    AminoAcid { c: 'W' as u8, p: 0.02 },
    AminoAcid { c: 'Y' as u8, p: 0.02 },
];

static HOMO_SAPIENS: [AminoAcid;4] = [
    AminoAcid { c: 'a' as u8, p: 0.3029549426680 },
    AminoAcid { c: 'c' as u8, p: 0.1979883004921 },
    AminoAcid { c: 'g' as u8, p: 0.1975473066391 },
    AminoAcid { c: 't' as u8, p: 0.3015094502008 },
];

fn sum_and_scale(a: &'static [AminoAcid]) -> Vec<AminoAcid> {
    let mut p = 0f32;
    let mut result: Vec<AminoAcid> = a.iter().map(|a_i| {
        p += a_i.p;
        AminoAcid { c: a_i.c, p: p * LOOKUP_SCALE }
    }).collect();
    let result_len = result.len();
    result[result_len - 1].p = LOOKUP_SCALE;
    result
}

#[derive(Copy, Clone)]
struct AminoAcid {
    c: u8,
    p: f32,
}

struct RepeatFasta<'a, W:'a> {
    alu: &'static str,
    out: &'a mut W
}

impl<'a, W: Write> RepeatFasta<'a, W> {
    fn new(alu: &'static str, w: &'a mut W) -> RepeatFasta<'a, W> {
        RepeatFasta { alu: alu, out: w }
    }

    fn make(&mut self, n: usize) -> io::Result<()> {
        let alu_len = self.alu.len();
        let mut buf = vec![0; alu_len + LINE_LEN];
        let alu: &[u8] = self.alu.as_bytes();

        for (slot, val) in buf.iter_mut().zip(alu) {
            *slot = *val;
        }
        let buf_len = buf.len();
        for (slot, val) in buf[alu_len..buf_len].iter_mut().zip(&alu[..LINE_LEN]) {
            *slot = *val;
        }

        let mut pos = 0;
        let mut bytes;
        let mut n = n;
        while n > 0 {
            bytes = min(LINE_LEN, n);
            try!(self.out.write_all(&buf[pos..pos + bytes]));
            try!(self.out.write_all(&[b'\n']));
            pos += bytes;
            if pos > alu_len {
                pos -= alu_len;
            }
            n -= bytes;
        }
        Ok(())
    }
}

fn make_lookup(a: &[AminoAcid]) -> [AminoAcid;LOOKUP_SIZE] {
    let mut lookup = [ NULL_AMINO_ACID;LOOKUP_SIZE ];
    let mut j = 0;
    for (i, slot) in lookup.iter_mut().enumerate() {
        while a[j].p < (i as f32) {
            j += 1;
        }
        *slot = a[j];
    }
    lookup
}

struct RandomFasta<'a, W:'a> {
    seed: u32,
    lookup: [AminoAcid;LOOKUP_SIZE],
    out: &'a mut W,
}

impl<'a, W: Write> RandomFasta<'a, W> {
    fn new(w: &'a mut W, a: &[AminoAcid]) -> RandomFasta<'a, W> {
        RandomFasta {
            seed: 42,
            out: w,
            lookup: make_lookup(a),
        }
    }

    fn rng(&mut self, max: f32) -> f32 {
        self.seed = (self.seed * IA + IC) % IM;
        (max * self.seed as f32) / (IM as f32)
    }

    fn nextc(&mut self) -> u8 {
        let r = self.rng(LOOKUP_SCALE);
        for i in (r as usize..LOOKUP_SIZE) {
            if self.lookup[i].p >= r {
                return self.lookup[i].c;
            }
        }
        unreachable!();
    }

    fn make(&mut self, n: usize) -> io::Result<()> {
        let lines = n / LINE_LEN;
        let chars_left = n % LINE_LEN;
        let mut buf = [0;LINE_LEN + 1];

        for _ in 0..lines {
            for i in 0..LINE_LEN {
                buf[i] = self.nextc();
            }
            buf[LINE_LEN] = '\n' as u8;
            try!(self.out.write(&buf));
        }
        for i in 0..chars_left {
            buf[i] = self.nextc();
        }
        self.out.write_all(&buf[..chars_left])
    }
}

fn main() {
    let mut args = env::args();
    let n = if args.len() > 1 {
        args.nth(1).unwrap().parse::<usize>().unwrap()
    } else {
        5
    };

    let stdout = io::stdout();
    let mut out = BufWriter::new(stdout.lock());

    out.write_all(b">ONE Homo sapiens alu\n").unwrap();
    {
        let mut repeat = RepeatFasta::new(ALU, &mut out);
        repeat.make(n * 2).unwrap();
    }

    out.write_all(b">TWO IUB ambiguity codes\n").unwrap();
    let iub = sum_and_scale(&IUB);
    let mut random = RandomFasta::new(&mut out, &iub);
    random.make(n * 3).unwrap();

    random.out.write_all(b">THREE Homo sapiens frequency\n").unwrap();
    let homo_sapiens = sum_and_scale(&HOMO_SAPIENS);
    random.lookup = make_lookup(&homo_sapiens);
    random.make(n * 5).unwrap();

    random.out.write_all(b"\n").unwrap();
}
<commit_msg>the same technique applies to fasta-redux<commit_after>// The Computer Language Benchmarks Game
// http://benchmarksgame.alioth.debian.org/
//
// contributed by the Rust Project Developers

// Copyright (c) 2013-2014 The Rust Project Developers
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// - Redistributions of source code must retain the above copyright
//   notice, this list of conditions and the following disclaimer.
//
// - 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.
//
// - Neither the name of "The Computer Language Benchmarks Game" nor
//   the name of "The Computer Language Shootout Benchmarks" nor the
//   names of its contributors may be used to endorse or promote
//   products derived from this software without specific prior
//   written permission.
//
// 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 OWNER 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.

use std::cmp::min;
use std::io::{self, Write};
use std::sync::{Arc, Mutex};
use std::thread;

const LINE_LEN: usize = 60;

const BLOCK_LINES: usize = 512;
const BLOCK_THOROUGHPUT: usize = LINE_LEN * BLOCK_LINES;
const BLOCK_LEN: usize = BLOCK_THOROUGHPUT + BLOCK_LINES;

const STDIN_BUF: usize = (LINE_LEN + 1) * 1024;
const LOOKUP_SIZE: usize = 4 * 1024;
const LOOKUP_SCALE: f32 = (LOOKUP_SIZE - 1) as f32;

const ALU: &'static [u8] =
    b"GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG\
      GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA\
      CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT\
      ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA\
      GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG\
      AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC\
      AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA";

const IUB: &'static [(u8, f32)] =
    &[(b'a', 0.27), (b'c', 0.12), (b'g', 0.12),
      (b't', 0.27), (b'B', 0.02), (b'D', 0.02),
      (b'H', 0.02), (b'K', 0.02), (b'M', 0.02),
      (b'N', 0.02), (b'R', 0.02), (b'S', 0.02),
      (b'V', 0.02), (b'W', 0.02), (b'Y', 0.02)];

const HOMOSAPIENS: &'static [(u8, f32)] =
    &[(b'a', 0.3029549426680),
      (b'c', 0.1979883004921),
      (b'g', 0.1975473066391),
      (b't', 0.3015094502008)];

// We need a specific Rng,
// so implement this manually

const MODULUS: u32 = 139968;
const MULTIPLIER: u32 = 3877;
const ADDITIVE: u32 = 29573;

// Why doesn't rust already have this?
// Algorithm directly taken from Wikipedia
fn powmod(mut base: u64, mut exponent: u32, modulus: u64) -> u64 {
    let mut ret = 1;
    base %= modulus;

    while exponent > 0 {
        if exponent & 1 == 1 {
           ret *= base;
           ret %= modulus;
        }
        exponent >>= 1;
        base *= base;
        base %= modulus;
    }

    ret
}

// Just a typical LCRNG
pub struct Rng {
    last: u32
}

impl Rng {
    pub fn new() -> Rng {
        Rng { last: 42 }
    }

    pub fn max_value() -> u32 {
        MODULUS - 1
    }

    pub fn normalize(p: f32) -> u32 {
        (p * MODULUS as f32).floor() as u32
    }

    pub fn gen(&mut self) -> u32 {
        self.last = (self.last * MULTIPLIER + ADDITIVE) % MODULUS;
        self.last
    }

    // This allows us to fast-forward the RNG,
    // allowing us to run it in parallel.
    pub fn future(&self, n: u32) -> Rng {
        let a = MULTIPLIER as u64;
        let b = ADDITIVE as u64;
        let m = MODULUS as u64;

        //                          (a^n - 1) mod (a-1) m
        // x_k = ((a^n x_0 mod m) + --------------------- b) mod m
        //                                   a - 1
        //
        // Since (a - 1) divides (a^n - 1) mod (a-1) m,
        // the subtraction does not overflow and thus can be non-modular.
        //
        let new_seed =
            (powmod(a, n, m) * self.last as u64) % m +
            (powmod(a, n, (a-1) * m) - 1) / (a-1) * b;

        Rng { last: (new_seed % m) as u32 }
    }
}

// This will end up keeping track of threads, like
// in the other multithreaded Rust version, in
// order to keep writes in order.
//
// This is stolen from another multithreaded Rust
// implementation, although that implementation
// was not able to parallelize the RNG itself.
struct BlockSubmitter<W: io::Write> {
    writer: W,
    pub waiting_on: usize,
}

impl<W: io::Write> BlockSubmitter<W> {
    fn submit(&mut self, data: &[u8], block_num: usize) -> Option<io::Result<()>> {
        if block_num == self.waiting_on {
            self.waiting_on += 1;
            Some(self.submit_async(data))
        }
        else {
            None
        }
    }

    fn submit_async(&mut self, data: &[u8]) -> io::Result<()> {
        self.writer.write_all(data)
    }
}

// For repeating strings as output
fn fasta_static<W: io::Write>(
    writer: &mut W,
    header: &[u8],
    data: &[u8],
    mut n: usize
) -> io::Result<()>
{
    // The aim here is to print a short(ish) string cyclically
    // with line breaks as appropriate.
    //
    // The secret technique is to repeat the string such that
    // any wanted line is a single offset in the string.
    //
    // This technique is stolen from the Haskell version.

    try!(writer.write_all(header));

    // Maximum offset is data.len(),
    // Maximum read len is LINE_LEN
    let stream = data.iter().cloned().cycle();
    let mut extended: Vec<u8> = stream.take(data.len() + LINE_LEN + 1).collect();

    let mut offset = 0;
    while n > 0 {
        let write_len = min(LINE_LEN, n);
        let end = offset + write_len;
        n -= write_len;

        let tmp = extended[end];
        extended[end] = b'\n';
        try!(writer.write_all(&extended[offset..end + 1]));
        extended[end] = tmp;

        offset = end;
        offset %= data.len();
    }

    Ok(())
}

// For RNG streams as output
fn fasta<W: io::Write + Send + 'static>(
    submitter: &Arc<Mutex<BlockSubmitter<W>>>,
    header: &[u8],
    table: &'static [(u8, f32)],
    rng: &mut Rng,
    n: usize
) -> io::Result<()>
{
    // Here the lookup table is part of the algorithm and needs the
    // original probabilities (scaled with the LOOKUP_SCALE), because
    // Isaac says so :-)
    fn sum_and_scale(a: &'static [(u8, f32)]) -> Vec<(u8, f32)> {
        let mut p = 0f32;
        let mut result: Vec<(u8, f32)> = a.iter().map(|e| {
            p += e.1;
            (e.0, p * LOOKUP_SCALE)
        }).collect();
        let result_len = result.len();
        result[result_len - 1].1 = LOOKUP_SCALE;
        result
    }

    fn make_lookup(a: &[(u8, f32)]) -> [(u8, f32); LOOKUP_SIZE] {
        let mut lookup = [(0, 0f32); LOOKUP_SIZE];
        let mut j = 0;
        for (i, slot) in lookup.iter_mut().enumerate() {
            while a[j].1 < (i as f32) {
                j += 1;
            }
            *slot = a[j];
        }
        lookup
    }

    {
        try!(submitter.lock().unwrap().submit_async(header));
    }

    let lookup_table = Arc::new(make_lookup(&sum_and_scale(table)));

    let thread_count = 4;
    let mut threads = Vec::new();
    for block_num in (0..thread_count) {
        let offset = BLOCK_THOROUGHPUT * block_num;

        let local_submitter = submitter.clone();
        let local_lookup_table = lookup_table.clone();
        let local_rng = rng.future(offset as u32);

        threads.push(thread::spawn(move || {
            gen_block(
                local_submitter,
                local_lookup_table,
                local_rng,
                n.saturating_sub(offset),
                block_num,
                thread_count
            )
        }));
    }

    for thread in threads {
        try!(thread.join().unwrap());
    }

    *rng = rng.future(n as u32);

    Ok(())
}

// A very optimized writer.
// I have a feeling a simpler version wouldn't slow
// things down too much, though, since the RNG
// is the really heavy hitter.
fn gen_block<W: io::Write>(
    submitter: Arc<Mutex<BlockSubmitter<W>>>,
    lookup_table: Arc<[(u8, f32)]>,
    mut rng: Rng,
    mut length: usize,
    mut block_num: usize,
    block_stride: usize,
) -> io::Result<()>
{
    // Include newlines in block
    length += length / LINE_LEN;
    let block: &mut [u8] = &mut [b'\n'; BLOCK_LEN];

    while length > 0 {
        {
            let gen_into = &mut block[..min(length, BLOCK_LEN)];

            // Write random numbers, skipping newlines
            for (i, byte) in gen_into.iter_mut().enumerate() {
                if (i + 1) % (LINE_LEN + 1) != 0 {
                    let p = rng.gen() as f32 * (LOOKUP_SCALE / MODULUS as f32);
                    *byte = lookup_table[p as usize..LOOKUP_SIZE].iter().find(
                        |le| le.1 >= p).unwrap().0;
                }
            }
        }

        let write_out = {
            if length >= BLOCK_LEN               { &mut *block }
            else if length % (LINE_LEN + 1) == 0 { &mut block[..length] }
            else                                 { &mut block[..length + 1] }
        };

        *write_out.last_mut().unwrap() = b'\n';
        loop {
            // Make sure to release lock before calling `yield_now`
            let res = { submitter.lock().unwrap().submit(write_out, block_num) };

            match res {
                Some(result) => { try!(result); break; }
                None => std::thread::yield_now()
            }
        }
        block_num += block_stride;
        rng = rng.future((BLOCK_THOROUGHPUT * (block_stride - 1)) as u32);
        length = length.saturating_sub(BLOCK_LEN * (block_stride - 1));

        length = length.saturating_sub(BLOCK_LEN);
    }

    Ok(())
}

fn run<W: io::Write + Send + 'static>(writer: W) -> io::Result<()> {
    let n = std::env::args_os().nth(1)
        .and_then(|s| s.into_string().ok())
        .and_then(|n| n.parse().ok())
        .unwrap_or(1000);

    let rng = &mut Rng::new();

    // Use automatic buffering for the static version...
    let mut writer = io::BufWriter::with_capacity(STDIN_BUF, writer);
    try!(fasta_static(&mut writer, b">ONE Homo sapiens alu\n", ALU, n * 2));

    // ...but the dynamic version does its own buffering already
    let writer = try!(writer.into_inner());
    let submitter = Arc::new(Mutex::new(BlockSubmitter { writer: writer, waiting_on: 0 }));

    { submitter.lock().unwrap().waiting_on = 0; }
    try!(fasta(&submitter, b">TWO IUB ambiguity codes\n", &IUB, rng, n * 3));
    { submitter.lock().unwrap().waiting_on = 0; }
    try!(fasta(&submitter, b">THREE Homo sapiens frequency\n", &HOMOSAPIENS, rng, n * 5));

    Ok(())
}

fn main() {
    run(io::stdout()).unwrap()
}
<|endoftext|>


<commit_before><commit_msg>Add a test case for calling generic functions taking alias args with box types<commit_after>// xfail-boot
// xfail-stage0

fn id[T](&T t) -> T {
  ret t;
}

fn main() {
  auto expected = @100;
  auto actual = id[@int](expected);
  log *actual;
  check (*expected == *actual);
}<|endoftext|>


<commit_before><commit_msg>Added crazyhouse move gen tests<commit_after>use board::board::Board;
#[allow(unused_imports)]
use uci::UciBoard;
use board::crazyhouse_board::CrazyhouseBoard;

#[test]
fn available_moves_at_start() {
    let mut board = CrazyhouseBoard::start_board().clone();
    let moves = board.all_legal_moves();
    assert_eq!(moves.len(), 20,
               "Found {} legal moves in crazyhouse starting position, expected 20",
               moves.len());
    for mv in moves {
        let old_board = board.clone();
        let undo_move = board.do_move(mv);
        let black_moves = board.all_legal_moves();
        assert_eq!(black_moves.len(), 20,
               "Found {} legal moves for black's first crazyhouse move, expected 20",
                   black_moves.len());
        board.undo_move(undo_move);
        assert_eq!(old_board, board);
    }
}

#[test]
fn starting_position_perf_test() {
    let mut board = CrazyhouseBoard::start_board().clone();
    println!("{:?}", board);
    assert_eq!(legal_moves_after_plies(&mut board, 1), 20);
    assert_eq!(legal_moves_after_plies(&mut board, 2), 400);
    assert_eq!(legal_moves_after_plies(&mut board, 3), 8_902);
    assert_eq!(legal_moves_after_plies(&mut board, 4), 197_281);
}

#[test]
fn block_check_with_crazyhouse_move_test() {
    let board = CrazyhouseBoard::from_fen("k1Q5/pp6/K7/8/8/8/8/8/rqp b - - 0 0").unwrap();
    let moves = board.all_legal_moves();
    assert_eq!(moves.len(), 2);
}

#[test]
fn crazyhouse_moves_test() {
    let board = CrazyhouseBoard::from_fen("k7/8/8/8/8/8/8/7K/QR w - - 0 0").unwrap();
    let moves = board.all_legal_moves();
    assert_eq!(moves.len(), 127);
}

/// Checks that the engine finds the total number of legal moves after n plies.
/// This provides a very strong indication that the move generator is correct
#[allow(dead_code)]
fn legal_moves_after_plies<B: Board>(board : &mut B, n : u8) -> u64 {
    if n == 0 { 1 }
    else {
        let mut total_moves = 0;
        for c_move in board.all_legal_moves() {
            let old_board = board.clone();
            {
                let undo_move = board.do_move(c_move.clone());
                total_moves += legal_moves_after_plies(board, n - 1);
                board.undo_move(undo_move);
            }

            assert_eq!(&old_board, board,
                             "Board was not the same after undoing move {:?}:\nOld:{:?}New:{:?}",
                             c_move, old_board, board);
        }
        total_moves
    }
}
<|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.

/*! Composable external iterators

The `Iterator` trait defines an interface for objects which implement iteration as a state machine.

Algorithms like `zip` are provided as `Iterator` implementations which wrap other objects
implementing the `Iterator` trait.

*/

use prelude::*;

pub trait Iterator<A> {
    /// Advance the iterator and return the next value. Return `None` when the end is reached.
    fn next(&mut self) -> Option<A>;
}

/// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also
/// implementations of the `Iterator` trait.
///
/// In the future these will be default methods instead of a utility trait.
pub trait IteratorUtil<A> {
    fn chain(self, other: Self) -> ChainIterator<Self>;
    fn zip<B, U: Iterator<B>>(self, other: U) -> ZipIterator<Self, U>;
    // FIXME: #5898: should be called map
    fn transform<'r, B>(self, f: &'r fn(A) -> B) -> MapIterator<'r, A, B, Self>;
    fn filter<'r>(self, predicate: &'r fn(&A) -> bool) -> FilterIterator<'r, A, Self>;
    fn enumerate(self) -> EnumerateIterator<Self>;
    fn skip_while<'r>(self, predicate: &'r fn(&A) -> bool) -> SkipWhileIterator<'r, A, Self>;
    fn take_while<'r>(self, predicate: &'r fn(&A) -> bool) -> TakeWhileIterator<'r, A, Self>;
    fn skip(self, n: uint) -> SkipIterator<Self>;
    fn take(self, n: uint) -> TakeIterator<Self>;
    fn advance(&mut self, f: &fn(A) -> bool);
}

/// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also
/// implementations of the `Iterator` trait.
///
/// In the future these will be default methods instead of a utility trait.
impl<A, T: Iterator<A>> IteratorUtil<A> for T {
    #[inline(always)]
    fn chain(self, other: T) -> ChainIterator<T> {
        ChainIterator{a: self, b: other, flag: false}
    }

    #[inline(always)]
    fn zip<B, U: Iterator<B>>(self, other: U) -> ZipIterator<T, U> {
        ZipIterator{a: self, b: other}
    }

    // FIXME: #5898: should be called map
    #[inline(always)]
    fn transform<'r, B>(self, f: &'r fn(A) -> B) -> MapIterator<'r, A, B, T> {
        MapIterator{iter: self, f: f}
    }

    #[inline(always)]
    fn filter<'r>(self, predicate: &'r fn(&A) -> bool) -> FilterIterator<'r, A, T> {
        FilterIterator{iter: self, predicate: predicate}
    }

    #[inline(always)]
    fn enumerate(self) -> EnumerateIterator<T> {
        EnumerateIterator{iter: self, count: 0}
    }

    #[inline(always)]
    fn skip_while<'r>(self, predicate: &'r fn(&A) -> bool) -> SkipWhileIterator<'r, A, T> {
        SkipWhileIterator{iter: self, flag: false, predicate: predicate}
    }

    #[inline(always)]
    fn take_while<'r>(self, predicate: &'r fn(&A) -> bool) -> TakeWhileIterator<'r, A, T> {
        TakeWhileIterator{iter: self, flag: false, predicate: predicate}
    }

    #[inline(always)]
    fn skip(self, n: uint) -> SkipIterator<T> {
        SkipIterator{iter: self, n: n}
    }

    #[inline(always)]
    fn take(self, n: uint) -> TakeIterator<T> {
        TakeIterator{iter: self, n: n}
    }

    /// A shim implementing the `for` loop iteration protocol for iterator objects
    #[inline]
    fn advance(&mut self, f: &fn(A) -> bool) {
        loop {
            match self.next() {
                Some(x) => {
                    if !f(x) { return }
                }
                None => return
            }
        }
    }
}

pub struct ChainIterator<T> {
    priv a: T,
    priv b: T,
    priv flag: bool
}

impl<A, T: Iterator<A>> Iterator<A> for ChainIterator<T> {
    #[inline]
    fn next(&mut self) -> Option<A> {
        if self.flag {
            self.b.next()
        } else {
            match self.a.next() {
                Some(x) => return Some(x),
                _ => ()
            }
            self.flag = true;
            self.b.next()
        }
    }
}

pub struct ZipIterator<T, U> {
    priv a: T,
    priv b: U
}

impl<A, B, T: Iterator<A>, U: Iterator<B>> Iterator<(A, B)> for ZipIterator<T, U> {
    #[inline]
    fn next(&mut self) -> Option<(A, B)> {
        match (self.a.next(), self.b.next()) {
            (Some(x), Some(y)) => Some((x, y)),
            _ => None
        }
    }
}

pub struct MapIterator<'self, A, B, T> {
    priv iter: T,
    priv f: &'self fn(A) -> B
}

impl<'self, A, B, T: Iterator<A>> Iterator<B> for MapIterator<'self, A, B, T> {
    #[inline]
    fn next(&mut self) -> Option<B> {
        match self.iter.next() {
            Some(a) => Some((self.f)(a)),
            _ => None
        }
    }
}

pub struct FilterIterator<'self, A, T> {
    priv iter: T,
    priv predicate: &'self fn(&A) -> bool
}

impl<'self, A, T: Iterator<A>> Iterator<A> for FilterIterator<'self, A, T> {
    #[inline]
    fn next(&mut self) -> Option<A> {
        for self.iter.advance |x| {
            if (self.predicate)(&x) {
                return Some(x);
            } else {
                loop
            }
        }
        None
    }
}

pub struct EnumerateIterator<T> {
    priv iter: T,
    priv count: uint
}

impl<A, T: Iterator<A>> Iterator<(uint, A)> for EnumerateIterator<T> {
    #[inline]
    fn next(&mut self) -> Option<(uint, A)> {
        match self.iter.next() {
            Some(a) => {
                let ret = Some((self.count, a));
                self.count += 1;
                ret
            }
            _ => None
        }
    }
}

pub struct SkipWhileIterator<'self, A, T> {
    priv iter: T,
    priv flag: bool,
    priv predicate: &'self fn(&A) -> bool
}

impl<'self, A, T: Iterator<A>> Iterator<A> for SkipWhileIterator<'self, A, T> {
    #[inline]
    fn next(&mut self) -> Option<A> {
        let mut next = self.iter.next();
        if self.flag {
            next
        } else {
            loop {
                match next {
                    Some(x) => {
                        if (self.predicate)(&x) {
                            next = self.iter.next();
                            loop
                        } else {
                            self.flag = true;
                            return Some(x)
                        }
                    }
                    None => return None
                }
            }
        }
    }
}

pub struct TakeWhileIterator<'self, A, T> {
    priv iter: T,
    priv flag: bool,
    priv predicate: &'self fn(&A) -> bool
}

impl<'self, A, T: Iterator<A>> Iterator<A> for TakeWhileIterator<'self, A, T> {
    #[inline]
    fn next(&mut self) -> Option<A> {
        if self.flag {
            None
        } else {
            match self.iter.next() {
                Some(x) => {
                    if (self.predicate)(&x) {
                        Some(x)
                    } else {
                        self.flag = true;
                        None
                    }
                }
                None => None
            }
        }
    }
}

pub struct SkipIterator<T> {
    priv iter: T,
    priv n: uint
}

impl<A, T: Iterator<A>> Iterator<A> for SkipIterator<T> {
    #[inline]
    fn next(&mut self) -> Option<A> {
        let mut next = self.iter.next();
        if self.n == 0 {
            next
        } else {
            let n = self.n;
            for n.times {
                match next {
                    Some(_) => {
                        next = self.iter.next();
                        loop
                    }
                    None => {
                        self.n = 0;
                        return None
                    }
                }
            }
            self.n = 0;
            next
        }
    }
}

pub struct TakeIterator<T> {
    priv iter: T,
    priv n: uint
}

impl<A, T: Iterator<A>> Iterator<A> for TakeIterator<T> {
    #[inline]
    fn next(&mut self) -> Option<A> {
        let next = self.iter.next();
        if self.n != 0 {
            self.n -= 1;
            next
        } else {
            None
        }
    }
}

pub struct UnfoldrIterator<'self, A, St> {
    priv f: &'self fn(&mut St) -> Option<A>,
    priv state: St
}

pub impl<'self, A, St> UnfoldrIterator<'self, A, St> {
    #[inline]
    fn new(f: &'self fn(&mut St) -> Option<A>, initial_state: St) -> UnfoldrIterator<'self, A, St> {
        UnfoldrIterator {
            f: f,
            state: initial_state
        }
    }
}

impl<'self, A, St> Iterator<A> for UnfoldrIterator<'self, A, St> {
    #[inline]
    fn next(&mut self) -> Option<A> {
        (self.f)(&mut self.state)
    }
}

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

    #[test]
    fn test_iterator_chain() {
        let xs = [0u, 1, 2, 3, 4, 5];
        let ys = [30, 40, 50, 60];
        let expected = [0, 1, 2, 3, 4, 5, 30, 40, 50, 60];
        let mut it = xs.iter().chain(ys.iter());
        let mut i = 0;
        for it.advance |&x: &uint| {
            assert_eq!(x, expected[i]);
            i += 1;
        }
        assert_eq!(i, expected.len());
    }

    #[test]
    fn test_iterator_enumerate() {
        let xs = [0u, 1, 2, 3, 4, 5];
        let mut it = xs.iter().enumerate();
        for it.advance |(i, &x): (uint, &uint)| {
            assert_eq!(i, x);
        }
    }

    #[test]
    fn test_iterator_take_while() {
        let xs = [0u, 1, 2, 3, 5, 13, 15, 16, 17, 19];
        let ys = [0u, 1, 2, 3, 5, 13];
        let mut it = xs.iter().take_while(|&x| *x < 15u);
        let mut i = 0;
        for it.advance |&x: &uint| {
            assert_eq!(x, ys[i]);
            i += 1;
        }
        assert_eq!(i, ys.len());
    }

    #[test]
    fn test_iterator_skip_while() {
        let xs = [0u, 1, 2, 3, 5, 13, 15, 16, 17, 19];
        let ys = [15, 16, 17, 19];
        let mut it = xs.iter().skip_while(|&x| *x < 15u);
        let mut i = 0;
        for it.advance |&x: &uint| {
            assert_eq!(x, ys[i]);
            i += 1;
        }
        assert_eq!(i, ys.len());
    }

    #[test]
    fn test_iterator_skip() {
        let xs = [0u, 1, 2, 3, 5, 13, 15, 16, 17, 19, 20, 30];
        let ys = [13, 15, 16, 17, 19, 20, 30];
        let mut it = xs.iter().skip(5);
        let mut i = 0;
        for it.advance |&x: &uint| {
            assert_eq!(x, ys[i]);
            i += 1;
        }
        assert_eq!(i, ys.len());
    }

    #[test]
    fn test_iterator_take() {
        let xs = [0u, 1, 2, 3, 5, 13, 15, 16, 17, 19];
        let ys = [0u, 1, 2, 3, 5];
        let mut it = xs.iter().take(5);
        let mut i = 0;
        for it.advance |&x: &uint| {
            assert_eq!(x, ys[i]);
            i += 1;
        }
        assert_eq!(i, ys.len());
    }

    #[test]
    fn test_unfoldr() {
        fn count(st: &mut uint) -> Option<uint> {
            if *st < 10 {
                let ret = Some(*st);
                *st += 1;
                ret
            } else {
                None
            }
        }

        let mut it = UnfoldrIterator::new(count, 0);
        let mut i = 0;
        for it.advance |counted| {
            assert_eq!(counted, i);
            i += 1;
        }
        assert_eq!(i, 10);
    }
}
<commit_msg>libcore: add a ScanIterator, a generalisation of MapIterator to have internal state.<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.

/*! Composable external iterators

The `Iterator` trait defines an interface for objects which implement iteration as a state machine.

Algorithms like `zip` are provided as `Iterator` implementations which wrap other objects
implementing the `Iterator` trait.

*/

use prelude::*;

pub trait Iterator<A> {
    /// Advance the iterator and return the next value. Return `None` when the end is reached.
    fn next(&mut self) -> Option<A>;
}

/// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also
/// implementations of the `Iterator` trait.
///
/// In the future these will be default methods instead of a utility trait.
pub trait IteratorUtil<A> {
    fn chain(self, other: Self) -> ChainIterator<Self>;
    fn zip<B, U: Iterator<B>>(self, other: U) -> ZipIterator<Self, U>;
    // FIXME: #5898: should be called map
    fn transform<'r, B>(self, f: &'r fn(A) -> B) -> MapIterator<'r, A, B, Self>;
    fn filter<'r>(self, predicate: &'r fn(&A) -> bool) -> FilterIterator<'r, A, Self>;
    fn enumerate(self) -> EnumerateIterator<Self>;
    fn skip_while<'r>(self, predicate: &'r fn(&A) -> bool) -> SkipWhileIterator<'r, A, Self>;
    fn take_while<'r>(self, predicate: &'r fn(&A) -> bool) -> TakeWhileIterator<'r, A, Self>;
    fn skip(self, n: uint) -> SkipIterator<Self>;
    fn take(self, n: uint) -> TakeIterator<Self>;
    fn scan<'r, St, B>(self, initial_state: St, f: &'r fn(&mut St, A) -> Option<B>)
        -> ScanIterator<'r, A, B, Self, St>;
    fn advance(&mut self, f: &fn(A) -> bool);
}

/// Iterator adaptors provided for every `Iterator` implementation. The adaptor objects are also
/// implementations of the `Iterator` trait.
///
/// In the future these will be default methods instead of a utility trait.
impl<A, T: Iterator<A>> IteratorUtil<A> for T {
    #[inline(always)]
    fn chain(self, other: T) -> ChainIterator<T> {
        ChainIterator{a: self, b: other, flag: false}
    }

    #[inline(always)]
    fn zip<B, U: Iterator<B>>(self, other: U) -> ZipIterator<T, U> {
        ZipIterator{a: self, b: other}
    }

    // FIXME: #5898: should be called map
    #[inline(always)]
    fn transform<'r, B>(self, f: &'r fn(A) -> B) -> MapIterator<'r, A, B, T> {
        MapIterator{iter: self, f: f}
    }

    #[inline(always)]
    fn filter<'r>(self, predicate: &'r fn(&A) -> bool) -> FilterIterator<'r, A, T> {
        FilterIterator{iter: self, predicate: predicate}
    }

    #[inline(always)]
    fn enumerate(self) -> EnumerateIterator<T> {
        EnumerateIterator{iter: self, count: 0}
    }

    #[inline(always)]
    fn skip_while<'r>(self, predicate: &'r fn(&A) -> bool) -> SkipWhileIterator<'r, A, T> {
        SkipWhileIterator{iter: self, flag: false, predicate: predicate}
    }

    #[inline(always)]
    fn take_while<'r>(self, predicate: &'r fn(&A) -> bool) -> TakeWhileIterator<'r, A, T> {
        TakeWhileIterator{iter: self, flag: false, predicate: predicate}
    }

    #[inline(always)]
    fn skip(self, n: uint) -> SkipIterator<T> {
        SkipIterator{iter: self, n: n}
    }

    #[inline(always)]
    fn take(self, n: uint) -> TakeIterator<T> {
        TakeIterator{iter: self, n: n}
    }

    #[inline(always)]
    fn scan<'r, St, B>(self, initial_state: St, f: &'r fn(&mut St, A) -> Option<B>)
        -> ScanIterator<'r, A, B, T, St> {
        ScanIterator{iter: self, f: f, state: initial_state}
    }

    /// A shim implementing the `for` loop iteration protocol for iterator objects
    #[inline]
    fn advance(&mut self, f: &fn(A) -> bool) {
        loop {
            match self.next() {
                Some(x) => {
                    if !f(x) { return }
                }
                None => return
            }
        }
    }
}

pub struct ChainIterator<T> {
    priv a: T,
    priv b: T,
    priv flag: bool
}

impl<A, T: Iterator<A>> Iterator<A> for ChainIterator<T> {
    #[inline]
    fn next(&mut self) -> Option<A> {
        if self.flag {
            self.b.next()
        } else {
            match self.a.next() {
                Some(x) => return Some(x),
                _ => ()
            }
            self.flag = true;
            self.b.next()
        }
    }
}

pub struct ZipIterator<T, U> {
    priv a: T,
    priv b: U
}

impl<A, B, T: Iterator<A>, U: Iterator<B>> Iterator<(A, B)> for ZipIterator<T, U> {
    #[inline]
    fn next(&mut self) -> Option<(A, B)> {
        match (self.a.next(), self.b.next()) {
            (Some(x), Some(y)) => Some((x, y)),
            _ => None
        }
    }
}

pub struct MapIterator<'self, A, B, T> {
    priv iter: T,
    priv f: &'self fn(A) -> B
}

impl<'self, A, B, T: Iterator<A>> Iterator<B> for MapIterator<'self, A, B, T> {
    #[inline]
    fn next(&mut self) -> Option<B> {
        match self.iter.next() {
            Some(a) => Some((self.f)(a)),
            _ => None
        }
    }
}

pub struct FilterIterator<'self, A, T> {
    priv iter: T,
    priv predicate: &'self fn(&A) -> bool
}

impl<'self, A, T: Iterator<A>> Iterator<A> for FilterIterator<'self, A, T> {
    #[inline]
    fn next(&mut self) -> Option<A> {
        for self.iter.advance |x| {
            if (self.predicate)(&x) {
                return Some(x);
            } else {
                loop
            }
        }
        None
    }
}

pub struct EnumerateIterator<T> {
    priv iter: T,
    priv count: uint
}

impl<A, T: Iterator<A>> Iterator<(uint, A)> for EnumerateIterator<T> {
    #[inline]
    fn next(&mut self) -> Option<(uint, A)> {
        match self.iter.next() {
            Some(a) => {
                let ret = Some((self.count, a));
                self.count += 1;
                ret
            }
            _ => None
        }
    }
}

pub struct SkipWhileIterator<'self, A, T> {
    priv iter: T,
    priv flag: bool,
    priv predicate: &'self fn(&A) -> bool
}

impl<'self, A, T: Iterator<A>> Iterator<A> for SkipWhileIterator<'self, A, T> {
    #[inline]
    fn next(&mut self) -> Option<A> {
        let mut next = self.iter.next();
        if self.flag {
            next
        } else {
            loop {
                match next {
                    Some(x) => {
                        if (self.predicate)(&x) {
                            next = self.iter.next();
                            loop
                        } else {
                            self.flag = true;
                            return Some(x)
                        }
                    }
                    None => return None
                }
            }
        }
    }
}

pub struct TakeWhileIterator<'self, A, T> {
    priv iter: T,
    priv flag: bool,
    priv predicate: &'self fn(&A) -> bool
}

impl<'self, A, T: Iterator<A>> Iterator<A> for TakeWhileIterator<'self, A, T> {
    #[inline]
    fn next(&mut self) -> Option<A> {
        if self.flag {
            None
        } else {
            match self.iter.next() {
                Some(x) => {
                    if (self.predicate)(&x) {
                        Some(x)
                    } else {
                        self.flag = true;
                        None
                    }
                }
                None => None
            }
        }
    }
}

pub struct SkipIterator<T> {
    priv iter: T,
    priv n: uint
}

impl<A, T: Iterator<A>> Iterator<A> for SkipIterator<T> {
    #[inline]
    fn next(&mut self) -> Option<A> {
        let mut next = self.iter.next();
        if self.n == 0 {
            next
        } else {
            let n = self.n;
            for n.times {
                match next {
                    Some(_) => {
                        next = self.iter.next();
                        loop
                    }
                    None => {
                        self.n = 0;
                        return None
                    }
                }
            }
            self.n = 0;
            next
        }
    }
}

pub struct TakeIterator<T> {
    priv iter: T,
    priv n: uint
}

impl<A, T: Iterator<A>> Iterator<A> for TakeIterator<T> {
    #[inline]
    fn next(&mut self) -> Option<A> {
        let next = self.iter.next();
        if self.n != 0 {
            self.n -= 1;
            next
        } else {
            None
        }
    }
}

pub struct UnfoldrIterator<'self, A, St> {
    priv f: &'self fn(&mut St) -> Option<A>,
    state: St
}

pub impl<'self, A, St> UnfoldrIterator<'self, A, St> {
    #[inline]
    fn new(f: &'self fn(&mut St) -> Option<A>, initial_state: St)
        -> UnfoldrIterator<'self, A, St> {
        UnfoldrIterator {
            f: f,
            state: initial_state
        }
    }
}

impl<'self, A, St> Iterator<A> for UnfoldrIterator<'self, A, St> {
    #[inline]
    fn next(&mut self) -> Option<A> {
        (self.f)(&mut self.state)
    }
}

pub struct ScanIterator<'self, A, B, T, St> {
    priv iter: T,
    priv f: &'self fn(&mut St, A) -> Option<B>,
    state: St
}

impl<'self, A, B, T: Iterator<A>, St> Iterator<B> for ScanIterator<'self, A, B, T, St> {
    #[inline]
    fn next(&mut self) -> Option<B> {
        self.iter.next().chain(|a| (self.f)(&mut self.state, a))
    }
}

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

    #[test]
    fn test_iterator_chain() {
        let xs = [0u, 1, 2, 3, 4, 5];
        let ys = [30, 40, 50, 60];
        let expected = [0, 1, 2, 3, 4, 5, 30, 40, 50, 60];
        let mut it = xs.iter().chain(ys.iter());
        let mut i = 0;
        for it.advance |&x: &uint| {
            assert_eq!(x, expected[i]);
            i += 1;
        }
        assert_eq!(i, expected.len());
    }

    #[test]
    fn test_iterator_enumerate() {
        let xs = [0u, 1, 2, 3, 4, 5];
        let mut it = xs.iter().enumerate();
        for it.advance |(i, &x): (uint, &uint)| {
            assert_eq!(i, x);
        }
    }

    #[test]
    fn test_iterator_take_while() {
        let xs = [0u, 1, 2, 3, 5, 13, 15, 16, 17, 19];
        let ys = [0u, 1, 2, 3, 5, 13];
        let mut it = xs.iter().take_while(|&x| *x < 15u);
        let mut i = 0;
        for it.advance |&x: &uint| {
            assert_eq!(x, ys[i]);
            i += 1;
        }
        assert_eq!(i, ys.len());
    }

    #[test]
    fn test_iterator_skip_while() {
        let xs = [0u, 1, 2, 3, 5, 13, 15, 16, 17, 19];
        let ys = [15, 16, 17, 19];
        let mut it = xs.iter().skip_while(|&x| *x < 15u);
        let mut i = 0;
        for it.advance |&x: &uint| {
            assert_eq!(x, ys[i]);
            i += 1;
        }
        assert_eq!(i, ys.len());
    }

    #[test]
    fn test_iterator_skip() {
        let xs = [0u, 1, 2, 3, 5, 13, 15, 16, 17, 19, 20, 30];
        let ys = [13, 15, 16, 17, 19, 20, 30];
        let mut it = xs.iter().skip(5);
        let mut i = 0;
        for it.advance |&x: &uint| {
            assert_eq!(x, ys[i]);
            i += 1;
        }
        assert_eq!(i, ys.len());
    }

    #[test]
    fn test_iterator_take() {
        let xs = [0u, 1, 2, 3, 5, 13, 15, 16, 17, 19];
        let ys = [0u, 1, 2, 3, 5];
        let mut it = xs.iter().take(5);
        let mut i = 0;
        for it.advance |&x: &uint| {
            assert_eq!(x, ys[i]);
            i += 1;
        }
        assert_eq!(i, ys.len());
    }

    #[test]
    fn test_iterator_scan() {
        // test the type inference
        fn add(old: &mut int, new: &uint) -> Option<float> {
            *old += *new as int;
            Some(*old as float)
        }
        let xs = [0u, 1, 2, 3, 4];
        let ys = [0f, 1f, 3f, 6f, 10f];

        let mut it = xs.iter().scan(0, add);
        let mut i = 0;
        for it.advance |x| {
            assert_eq!(x, ys[i]);
            i += 1;
        }
        assert_eq!(i, ys.len());
    }

    #[test]
    fn test_unfoldr() {
        fn count(st: &mut uint) -> Option<uint> {
            if *st < 10 {
                let ret = Some(*st);
                *st += 1;
                ret
            } else {
                None
            }
        }

        let mut it = UnfoldrIterator::new(count, 0);
        let mut i = 0;
        for it.advance |counted| {
            assert_eq!(counted, i);
            i += 1;
        }
        assert_eq!(i, 10);
    }
}
<|endoftext|>


<commit_before><commit_msg>ボタンを押すと0が表示されるだけ<commit_after><|endoftext|>


<commit_before><commit_msg>Simplify.<commit_after><|endoftext|>


<commit_before><commit_msg>Rename dom to sem<commit_after><|endoftext|>


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

// compile-flags: -Z saturating-float-casts

#![feature(test, i128, i128_type, stmt_expr_attributes)]
#![deny(overflowing_literals)]
extern crate test;

use std::{f32, f64};
use std::{u8, i8, u16, i16, u32, i32, u64, i64};
#[cfg(not(target_os="emscripten"))]
use std::{u128, i128};
use test::black_box;

macro_rules! test {
    ($val:expr, $src_ty:ident -> $dest_ty:ident, $expected:expr) => (
        // black_box disables constant evaluation to test run-time conversions:
        assert_eq!(black_box::<$src_ty>($val) as $dest_ty, $expected,
                    "run-time {} -> {}", stringify!($src_ty), stringify!($dest_ty));
    );

    ($fval:expr, f* -> $ity:ident, $ival:expr) => (
        test!($fval, f32 -> $ity, $ival);
        test!($fval, f64 -> $ity, $ival);
    )
}

// This macro tests const eval in addition to run-time evaluation.
// If and when saturating casts are adopted, this macro should be merged with test!() to ensure
// that run-time and const eval agree on inputs that currently trigger a const eval error.
macro_rules! test_c {
    ($val:expr, $src_ty:ident -> $dest_ty:ident, $expected:expr) => ({
        test!($val, $src_ty -> $dest_ty, $expected);
        {
            const X: $src_ty = $val;
            const Y: $dest_ty = X as $dest_ty;
            assert_eq!(Y, $expected,
                        "const eval {} -> {}", stringify!($src_ty), stringify!($dest_ty));
        }
    });

    ($fval:expr, f* -> $ity:ident, $ival:expr) => (
        test!($fval, f32 -> $ity, $ival);
        test!($fval, f64 -> $ity, $ival);
    )
}

macro_rules! common_fptoi_tests {
    ($fty:ident -> $($ity:ident)+) => ({ $(
        test!($fty::NAN, $fty -> $ity, 0);
        test!($fty::INFINITY, $fty -> $ity, $ity::MAX);
        test!($fty::NEG_INFINITY, $fty -> $ity, $ity::MIN);
        // These two tests are not solely float->int tests, in particular the latter relies on
        // `u128::MAX as f32` not being UB. But that's okay, since this file tests int->float
        // as well, the test is just slightly misplaced.
        test!($ity::MIN as $fty, $fty -> $ity, $ity::MIN);
        test!($ity::MAX as $fty, $fty -> $ity, $ity::MAX);
        test_c!(0., $fty -> $ity, 0);
        test_c!($fty::MIN_POSITIVE, $fty -> $ity, 0);
        test!(-0.9, $fty -> $ity, 0);
        test_c!(1., $fty -> $ity, 1);
        test_c!(42., $fty -> $ity, 42);
    )+ });

    (f* -> $($ity:ident)+) => ({
        common_fptoi_tests!(f32 -> $($ity)+);
        common_fptoi_tests!(f64 -> $($ity)+);
    })
}

macro_rules! fptoui_tests {
    ($fty: ident -> $($ity: ident)+) => ({ $(
        test!(-0., $fty -> $ity, 0);
        test!(-$fty::MIN_POSITIVE, $fty -> $ity, 0);
        test!(-0.99999994, $fty -> $ity, 0);
        test!(-1., $fty -> $ity, 0);
        test!(-100., $fty -> $ity, 0);
        test!(#[allow(overflowing_literals)] -1e50, $fty -> $ity, 0);
        test!(#[allow(overflowing_literals)] -1e130, $fty -> $ity, 0);
    )+ });

    (f* -> $($ity:ident)+) => ({
        fptoui_tests!(f32 -> $($ity)+);
        fptoui_tests!(f64 -> $($ity)+);
    })
}

pub fn main() {
    common_fptoi_tests!(f* -> i8 i16 i32 i64 u8 u16 u32 u64);
    fptoui_tests!(f* -> u8 u16 u32 u64);
    // FIXME emscripten does not support i128
    #[cfg(not(target_os="emscripten"))] {
        common_fptoi_tests!(f* -> i128 u128);
        fptoui_tests!(f* -> u128);
    }

    // The following tests cover edge cases for some integer types.

    // # u8
    test_c!(254., f* -> u8, 254);
    test!(256., f* -> u8, 255);

    // # i8
    test_c!(-127., f* -> i8, -127);
    test!(-129., f* -> i8, -128);
    test_c!(126., f* -> i8, 126);
    test!(128., f* -> i8, 127);

    // # i32
    // -2147483648. is i32::MIN (exactly)
    test_c!(-2147483648., f* -> i32, i32::MIN);
    // 2147483648. is i32::MAX rounded up
    test!(2147483648., f32 -> i32, 2147483647);
    // With 24 significand bits, floats with magnitude in [2^30 + 1, 2^31] are rounded to
    // multiples of 2^7. Therefore, nextDown(round(i32::MAX)) is 2^31 - 128:
    test_c!(2147483520., f32 -> i32, 2147483520);
    // Similarly, nextUp(i32::MIN) is i32::MIN + 2^8 and nextDown(i32::MIN) is i32::MIN - 2^7
    test!(-2147483904., f* -> i32, i32::MIN);
    test_c!(-2147483520., f* -> i32, -2147483520);

    // # u32
    // round(MAX) and nextUp(round(MAX))
    test_c!(4294967040., f* -> u32, 4294967040);
    test!(4294967296., f* -> u32, 4294967295);

    // # u128
    #[cfg(not(target_os="emscripten"))]
    {
        // float->int:
        test_c!(f32::MAX, f32 -> u128, 0xffffff00000000000000000000000000);
        // nextDown(f32::MAX) = 2^128 - 2 * 2^104
        const SECOND_LARGEST_F32: f32 = 340282326356119256160033759537265639424.;
        test_c!(SECOND_LARGEST_F32, f32 -> u128, 0xfffffe00000000000000000000000000);

        // int->float:
        // f32::MAX - 0.5 ULP and smaller should be rounded down
        test_c!(0xfffffe00000000000000000000000000, u128 -> f32, SECOND_LARGEST_F32);
        test_c!(0xfffffe7fffffffffffffffffffffffff, u128 -> f32, SECOND_LARGEST_F32);
        test_c!(0xfffffe80000000000000000000000000, u128 -> f32, SECOND_LARGEST_F32);
        // numbers within < 0.5 ULP of f32::MAX it should be rounded to f32::MAX
        test_c!(0xfffffe80000000000000000000000001, u128 -> f32, f32::MAX);
        test_c!(0xfffffeffffffffffffffffffffffffff, u128 -> f32, f32::MAX);
        test_c!(0xffffff00000000000000000000000000, u128 -> f32, f32::MAX);
        test_c!(0xffffff00000000000000000000000001, u128 -> f32, f32::MAX);
        test_c!(0xffffff7fffffffffffffffffffffffff, u128 -> f32, f32::MAX);
        // f32::MAX + 0.5 ULP and greater should be rounded to infinity
        test_c!(0xffffff80000000000000000000000000, u128 -> f32, f32::INFINITY);
        test_c!(0xffffff80000000f00000000000000000, u128 -> f32, f32::INFINITY);
        test_c!(0xffffff87ffffffffffffffff00000001, u128 -> f32, f32::INFINITY);

        // u128->f64 should not be affected by the u128->f32 checks
        test_c!(0xffffff80000000000000000000000000, u128 -> f64,
              340282356779733661637539395458142568448.0);
        test_c!(u128::MAX, u128 -> f64, 340282366920938463463374607431768211455.0);
    }
}
<commit_msg>Fix typo in -Zsaturating-float-casts test<commit_after>// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -Z saturating-float-casts

#![feature(test, i128, i128_type, stmt_expr_attributes)]
#![deny(overflowing_literals)]
extern crate test;

use std::{f32, f64};
use std::{u8, i8, u16, i16, u32, i32, u64, i64};
#[cfg(not(target_os="emscripten"))]
use std::{u128, i128};
use test::black_box;

macro_rules! test {
    ($val:expr, $src_ty:ident -> $dest_ty:ident, $expected:expr) => (
        // black_box disables constant evaluation to test run-time conversions:
        assert_eq!(black_box::<$src_ty>($val) as $dest_ty, $expected,
                    "run-time {} -> {}", stringify!($src_ty), stringify!($dest_ty));
    );

    ($fval:expr, f* -> $ity:ident, $ival:expr) => (
        test!($fval, f32 -> $ity, $ival);
        test!($fval, f64 -> $ity, $ival);
    )
}

// This macro tests const eval in addition to run-time evaluation.
// If and when saturating casts are adopted, this macro should be merged with test!() to ensure
// that run-time and const eval agree on inputs that currently trigger a const eval error.
macro_rules! test_c {
    ($val:expr, $src_ty:ident -> $dest_ty:ident, $expected:expr) => ({
        test!($val, $src_ty -> $dest_ty, $expected);
        {
            const X: $src_ty = $val;
            const Y: $dest_ty = X as $dest_ty;
            assert_eq!(Y, $expected,
                        "const eval {} -> {}", stringify!($src_ty), stringify!($dest_ty));
        }
    });

    ($fval:expr, f* -> $ity:ident, $ival:expr) => (
        test_c!($fval, f32 -> $ity, $ival);
        test_c!($fval, f64 -> $ity, $ival);
    )
}

macro_rules! common_fptoi_tests {
    ($fty:ident -> $($ity:ident)+) => ({ $(
        test!($fty::NAN, $fty -> $ity, 0);
        test!($fty::INFINITY, $fty -> $ity, $ity::MAX);
        test!($fty::NEG_INFINITY, $fty -> $ity, $ity::MIN);
        // These two tests are not solely float->int tests, in particular the latter relies on
        // `u128::MAX as f32` not being UB. But that's okay, since this file tests int->float
        // as well, the test is just slightly misplaced.
        test!($ity::MIN as $fty, $fty -> $ity, $ity::MIN);
        test!($ity::MAX as $fty, $fty -> $ity, $ity::MAX);
        test_c!(0., $fty -> $ity, 0);
        test_c!($fty::MIN_POSITIVE, $fty -> $ity, 0);
        test!(-0.9, $fty -> $ity, 0);
        test_c!(1., $fty -> $ity, 1);
        test_c!(42., $fty -> $ity, 42);
    )+ });

    (f* -> $($ity:ident)+) => ({
        common_fptoi_tests!(f32 -> $($ity)+);
        common_fptoi_tests!(f64 -> $($ity)+);
    })
}

macro_rules! fptoui_tests {
    ($fty: ident -> $($ity: ident)+) => ({ $(
        test!(-0., $fty -> $ity, 0);
        test!(-$fty::MIN_POSITIVE, $fty -> $ity, 0);
        test!(-0.99999994, $fty -> $ity, 0);
        test!(-1., $fty -> $ity, 0);
        test!(-100., $fty -> $ity, 0);
        test!(#[allow(overflowing_literals)] -1e50, $fty -> $ity, 0);
        test!(#[allow(overflowing_literals)] -1e130, $fty -> $ity, 0);
    )+ });

    (f* -> $($ity:ident)+) => ({
        fptoui_tests!(f32 -> $($ity)+);
        fptoui_tests!(f64 -> $($ity)+);
    })
}

pub fn main() {
    common_fptoi_tests!(f* -> i8 i16 i32 i64 u8 u16 u32 u64);
    fptoui_tests!(f* -> u8 u16 u32 u64);
    // FIXME emscripten does not support i128
    #[cfg(not(target_os="emscripten"))] {
        common_fptoi_tests!(f* -> i128 u128);
        fptoui_tests!(f* -> u128);
    }

    // The following tests cover edge cases for some integer types.

    // # u8
    test_c!(254., f* -> u8, 254);
    test!(256., f* -> u8, 255);

    // # i8
    test_c!(-127., f* -> i8, -127);
    test!(-129., f* -> i8, -128);
    test_c!(126., f* -> i8, 126);
    test!(128., f* -> i8, 127);

    // # i32
    // -2147483648. is i32::MIN (exactly)
    test_c!(-2147483648., f* -> i32, i32::MIN);
    // 2147483648. is i32::MAX rounded up
    test!(2147483648., f32 -> i32, 2147483647);
    // With 24 significand bits, floats with magnitude in [2^30 + 1, 2^31] are rounded to
    // multiples of 2^7. Therefore, nextDown(round(i32::MAX)) is 2^31 - 128:
    test_c!(2147483520., f32 -> i32, 2147483520);
    // Similarly, nextUp(i32::MIN) is i32::MIN + 2^8 and nextDown(i32::MIN) is i32::MIN - 2^7
    test!(-2147483904., f* -> i32, i32::MIN);
    test_c!(-2147483520., f* -> i32, -2147483520);

    // # u32
    // round(MAX) and nextUp(round(MAX))
    test_c!(4294967040., f* -> u32, 4294967040);
    test!(4294967296., f* -> u32, 4294967295);

    // # u128
    #[cfg(not(target_os="emscripten"))]
    {
        // float->int:
        test_c!(f32::MAX, f32 -> u128, 0xffffff00000000000000000000000000);
        // nextDown(f32::MAX) = 2^128 - 2 * 2^104
        const SECOND_LARGEST_F32: f32 = 340282326356119256160033759537265639424.;
        test_c!(SECOND_LARGEST_F32, f32 -> u128, 0xfffffe00000000000000000000000000);

        // int->float:
        // f32::MAX - 0.5 ULP and smaller should be rounded down
        test_c!(0xfffffe00000000000000000000000000, u128 -> f32, SECOND_LARGEST_F32);
        test_c!(0xfffffe7fffffffffffffffffffffffff, u128 -> f32, SECOND_LARGEST_F32);
        test_c!(0xfffffe80000000000000000000000000, u128 -> f32, SECOND_LARGEST_F32);
        // numbers within < 0.5 ULP of f32::MAX it should be rounded to f32::MAX
        test_c!(0xfffffe80000000000000000000000001, u128 -> f32, f32::MAX);
        test_c!(0xfffffeffffffffffffffffffffffffff, u128 -> f32, f32::MAX);
        test_c!(0xffffff00000000000000000000000000, u128 -> f32, f32::MAX);
        test_c!(0xffffff00000000000000000000000001, u128 -> f32, f32::MAX);
        test_c!(0xffffff7fffffffffffffffffffffffff, u128 -> f32, f32::MAX);
        // f32::MAX + 0.5 ULP and greater should be rounded to infinity
        test_c!(0xffffff80000000000000000000000000, u128 -> f32, f32::INFINITY);
        test_c!(0xffffff80000000f00000000000000000, u128 -> f32, f32::INFINITY);
        test_c!(0xffffff87ffffffffffffffff00000001, u128 -> f32, f32::INFINITY);

        // u128->f64 should not be affected by the u128->f32 checks
        test_c!(0xffffff80000000000000000000000000, u128 -> f64,
              340282356779733661637539395458142568448.0);
        test_c!(u128::MAX, u128 -> f64, 340282366920938463463374607431768211455.0);
    }
}
<|endoftext|>


<commit_before><commit_msg>Add StoreId::local_display_string() function<commit_after><|endoftext|>


<commit_before><commit_msg>added pair generators<commit_after><|endoftext|>


<commit_before><commit_msg>Use `Range` in the output of `Lexer::next()`.<commit_after><|endoftext|>


<commit_before><commit_msg>Add trailing comma<commit_after><|endoftext|>


<commit_before><commit_msg>Skeleton for problem 2410<commit_after>// https://leetcode.com/problems/maximum-matching-of-players-with-trainers/
pub fn match_players_and_trainers(players: Vec<i32>, trainers: Vec<i32>) -> i32 {
    todo!()
}

fn main() {
    println!(
        "{}",
        match_players_and_trainers(vec![4, 7, 9], vec![8, 2, 5, 8])
    ); // 2
    println!("{}", match_players_and_trainers(vec![1, 1, 1], vec![10])); // 1
}
<|endoftext|>


<commit_before><commit_msg>examples: add a simple interactive example<commit_after>extern crate amqp;
extern crate env_logger;

use amqp::session::Session;
use amqp::protocol;
use amqp::table;
use amqp::basic::Basic;
use std::default::Default;
use std::io;

fn main() {
    env_logger::init().unwrap();
    let mut amqp_url = String::new();
    println!("Please input the AMQP endpoint to use: ");
    io::stdin().read_line(&mut amqp_url).ok().expect("Unable to read URL!");
    let mut session = match Session::open_url(&amqp_url[..]) {
        Ok(session) => session,
        Err(error) => panic!("Can't create session: {:?}", error)
    };
    let mut channel = session.open_channel(1).ok().expect("Can't open channel!");

    let queue_name = "test_queue";
    channel.queue_declare(queue_name, false, true, false, false, false, table::new()).ok().expect("Unable to declare queue!");

    println!("Type some text here below, it will be sent into the '{}' queue. Hit Enter when done.", queue_name);
    let mut input_data = String::new();
    io::stdin().read_line(&mut input_data).ok().expect("Unable to read input data!");

    println!("Sending data...\n");
    channel.basic_publish("", queue_name, true, false,
        protocol::basic::BasicProperties{ content_type: Some("text".to_string()), ..Default::default()},
        input_data.trim_right().to_string().into_bytes());

     for get_result in channel.basic_get(queue_name, false) {
        println!("Received: {:?}", String::from_utf8_lossy(&get_result.body));
        get_result.ack();
    }

    println!("Queue is now empty, quitting...");
    channel.close(200, "Bye".to_string());
    session.close(200, "Good Bye".to_string());
}
<|endoftext|>


<commit_before><commit_msg>some very basic num/ops impl for vectors<commit_after><|endoftext|>


<commit_before><commit_msg>Copy addresses from memory.py<commit_after>// In Hex's Cellar, the player's spells manipulate an u8[40] of bytes that
// affect the world around her. This enum gives a "RAM map" for that array.

enum Addr {
    // Color (3 bits = 8 bright colors) and character (5 bits, offset added to '!')
    PlayerAppearance = 0x00,

    // Begins a char[15].
    PlayerName = 0x01,

    // Monster data is a (struct {u8, u8, u8})[5].
    // So add (n * 3) to these, where 0 <= n <= 4, to get the address for the n-th monster.
    MonsterFlags = 0x10,
    MonsterPosition = 0x11,
    MonsterHP = 0x12,

    // An 8-bit bitmask (there are eight spells).
    SpellMemory = 0x1f,

    // A 32-bit bitmask (there are thirty-two items).
    Identification = 0x20,

    // Begins a u8[4]: one byte for each timer.
    Timers = 0x24,

    // Here are their individual addresses, anyway:
    PoisonTimer = 0x24,
    HasteTimer = 0x25,
    ChargeTimer = 0x26,
    ProtectTimer = 0x27,

    // Begins a u8[8].
    Inventory = 0x28,

    // Same as player appearance.
    DoorAppearance = 0x30,
    WallAppearance = 0x31,
    FloorColor = 0x32,

    // u8 to add/subtract from depth when stairs are used; normally 1.
    StaircaseDelta = 0x33,

    // u8 to add to timers each turn if non-zero; normally 0xff.
    TimerDelta = 0x34,

    // s8 to add to each damage roll; normally 0x00.
    DamageOffset = 0x35,

    // ??? = 0x36,
    // ??? = 0x37,

    // The higher this is, the more text gets screwed up.
    TextSync = 0x38,

    // Player stats.
    PlayerHP = 0x39,
    PlayerTP = 0x3a,
    PlayerXLDef = 0x3b, // hi-bits XL, lo-bits Def
    PlayerPosition = 0x3c,
    PlayerDepth = 0x3d,
    MetalAcidResistance = 0x3e, // hi-bits Metal, lo-bits Acid
    FireElecResistance = 0x3f, // hi-bits Fire, lo-bits Elect
}
<|endoftext|>


<commit_before><commit_msg>regression test for #39974<commit_after>// Copyright 2017 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.

const LENGTH: f64 = 2;

struct Thing {
    f: [[f64; 2]; LENGTH],
    //~^ ERROR mismatched types
    //~| expected usize, found f64
}

fn main() {
    let _t = Thing { f: [[0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0]] };
}
<|endoftext|>


<commit_before><commit_msg>Old main included.<commit_after>extern crate mles_utils;

use std::thread;
use std::sync::mpsc::{Sender, Receiver};
use std::sync::mpsc::channel;
use std::net::TcpStream;
use std::net::TcpListener;
use std::collections::HashMap;
use std::io::Write;
use std::time::Duration;
use std::option::Option;
use std::str;
use mles_utils::*;

fn process_channel(tx: Sender<Sender<TcpStream>>, removedtx: Sender<String>, this_channel: String ) {
    let mut cnt = 0;
    let (thr_tx, thr_rx): (Sender<TcpStream>, Receiver<TcpStream>) = channel();
    println!("Spawned: New channel created!");
    let mut users = HashMap::new();
    let mut messages: Vec<Vec<u8>> = Vec::new();
    tx.send(thr_tx.clone()).unwrap();
    loop {
        let mut removals = Vec::new();
        let mut newuser = true;
        while newuser {
            match thr_rx.try_recv() {
                Ok(val) => {
                    let mut thr: TcpStream = val;
                    cnt += 1;
                    println!("Adding user {}", cnt);
                    users.insert(cnt, thr.try_clone().unwrap());

                    /* If a new user, all push messages to her */
                    for buf in &messages {
                        thr.write(buf.as_slice()).unwrap();
                    }
                    newuser = true;
                },
                    Err(_) => { newuser = false; }
            }
        }
        for (user, thr_socket) in &users {
            let stream = thr_socket.try_clone().unwrap();
            let tuple = read_n(&stream, 4);
            let status = tuple.0;
            match status {
                Ok(0) => {
                    removals.push(user.clone());
                },
                    _ => {}
            }
            let mut buf = tuple.1;
            if 0 == buf.len() {
                continue;
            }
            if read_hdr_type(buf.as_slice()) != 'M' as u32 {
                continue;
            }
            let hdr_len = read_hdr_len(buf.as_slice()) as u64;
            if 0 == hdr_len {
                continue;
            }
            let tuple = read_n(&stream, hdr_len);
            let status = tuple.0;
            match status {
                Ok(0) => {
                    removals.push(user.clone());
                },
                    _ => {}
            }
            let payload = tuple.1;
            if payload.len() != (hdr_len as usize) {
                continue;
            }
            buf.extend(payload);
            for (another_user, mut thr_sock) in &users {
                if user != another_user {
                    thr_sock.write(buf.as_slice()).unwrap();
                }
            }
            /* Add to local db */
            messages.push(buf);
        }
        for removal in &removals {
            println!("Removing user {}", removal);
            users.remove(removal);
        }
        if cnt > 0 && users.is_empty() {
            removedtx.send(this_channel).unwrap();
            break;
        }
    }
}

fn main() {
    let address = "0.0.0.0:8081";
    let listener = TcpListener::bind(&address).unwrap();
    let mut spawned = HashMap::new();
    let option: Option<Duration> = Some(Duration::from_millis(50));

    let addr = listener.local_addr().unwrap();
    println!("Listening for connections on {}", addr);
    let (tx, rx) = channel();
    let (removedtx, removedrx) = channel();

    for socket in listener.incoming() {
        /* Check first has anybody removed channels */
        let mut remrx = true;
        while remrx {
            match removedrx.try_recv() {
                Ok(val) => {
                    let removed_channel: String = val;
                    println!("Removing unused channel {}", removed_channel.as_str());
                    spawned.remove(&removed_channel);
                    remrx = true;
                },
                Err(_) => { remrx = false; }
            }
        }
        /* 1. Read incoming msg channel
         * 2. If it does not exist, spawn new thread
         * 3. Send socket to thread
         */
        let socket = socket.unwrap();
        let stream = socket.try_clone().unwrap();
        let tuple = read_n(&stream, 4);
        let status = tuple.0;
        match status {
            Ok(0) => {
               continue;
            },
            Ok(_) => {},
            _ => {
               continue;
            },
        }
        let buf = tuple.1;
        if 0 == buf.len() {
            continue;
        }
        if read_hdr_type(buf.as_slice()) != 'M' as u32 {
            println!("Incorrect payload type");
            continue;
        }
        let tuple = read_n(&stream, read_hdr_len(buf.as_slice()) as u64);
        let status = tuple.0;
        match status {
            Ok(0) => {
               continue;
            },
            Ok(_) => {},
            _ => {
               continue;
            },
        }
        let buf = tuple.1;
        let decoded_msg = message_decode(buf.as_slice());
        if 0 == decoded_msg.channel.len() {
            continue;
        }
        socket.set_nodelay(true);
        socket.set_read_timeout(option);
        if !spawned.contains_key(decoded_msg.channel.as_str()) {
            let tx = tx.clone();
            let removedtx = removedtx.clone();
            let this_channel = decoded_msg.channel.clone();
            thread::spawn(move|| process_channel(tx, removedtx, this_channel));

            let thr_feed = rx.recv().unwrap();
            println!("Channel {}", decoded_msg.channel.as_str());
            spawned.insert(decoded_msg.channel.clone(), thr_feed);
        }
        let thr_socket = spawned.get_mut(&decoded_msg.channel).unwrap();
        thr_socket.send(socket).unwrap();
    }
}
<|endoftext|>


<commit_before><commit_msg>Rename JSON::unwrap() to JSON::into_inner().<commit_after><|endoftext|>


<commit_before>//! A "mutex" which only supports try_lock
//!
//! As a futures library the eventual call to `epoll` should be the only thing
//! that ever blocks, so this is assisted with a fast user-space implementation
//! of a lock that can only have a `try_lock` operation.

use std::cell::UnsafeCell;
use std::ops::{Deref, DerefMut};
use std::sync::atomic::Ordering::{Acquire, Release};
use std::sync::atomic::AtomicBool;

/// A "mutex" around a value, similar to `std::sync::Mutex<T>`.
///
/// This lock only supports the `try_lock` operation, however, and does not
/// implement poisoning.
pub struct Lock<T> {
    locked: AtomicBool,
    data: UnsafeCell<T>,
}

/// Sentinel representing an acquired lock through which the data can be
/// accessed.
pub struct TryLock<'a, T: 'a> {
    __ptr: &'a Lock<T>,
}

unsafe impl<T: Send> Send for Lock<T> {}
unsafe impl<T: Send> Sync for Lock<T> {}

impl<T> Lock<T> {
    /// Creates a new lock around the given value.
    pub fn new(t: T) -> Lock<T> {
        Lock {
            locked: AtomicBool::new(false),
            data: UnsafeCell::new(t),
        }
    }

    /// Attempts to acquire this lock, returning whether the lock was acquired or
    /// not.
    ///
    /// If `Some` is returned then the data this lock protects can be accessed
    /// through the sentinel. This sentinel allows both mutable and immutable
    /// access.
    ///
    /// If `None` is returned then the lock is already locked, either elsewhere
    /// on this thread or on another thread.
    pub fn try_lock(&self) -> Option<TryLock<T>> {
        if !self.locked.swap(true, Acquire) {
            Some(TryLock { __ptr: self })
        } else {
            None
        }
    }
}

impl<'a, T> Deref for TryLock<'a, T> {
    type Target = T;
    fn deref(&self) -> &T {
        unsafe { &*self.__ptr.data.get() }
    }
}

impl<'a, T> DerefMut for TryLock<'a, T> {
    fn deref_mut(&mut self) -> &mut T {
        unsafe { &mut *self.__ptr.data.get() }
    }
}

impl<'a, T> Drop for TryLock<'a, T> {
    fn drop(&mut self) {
        self.__ptr.locked.store(false, Release);
    }
}

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

    #[test]
    fn smoke() {
        let a = Lock::new(1);
        let mut a1 = a.try_lock().unwrap();
        assert!(a.try_lock().is_none());
        assert_eq!(*a1, 1);
        *a1 = 2;
        drop(a1);
        assert_eq!(*a.try_lock().unwrap(), 2);
        assert_eq!(*a.try_lock().unwrap(), 2);
    }
}
<commit_msg>Document some unsafety in lock.rs<commit_after>//! A "mutex" which only supports try_lock
//!
//! As a futures library the eventual call to `epoll` should be the only thing
//! that ever blocks, so this is assisted with a fast user-space implementation
//! of a lock that can only have a `try_lock` operation.

use std::cell::UnsafeCell;
use std::ops::{Deref, DerefMut};
use std::sync::atomic::Ordering::{Acquire, Release};
use std::sync::atomic::AtomicBool;

/// A "mutex" around a value, similar to `std::sync::Mutex<T>`.
///
/// This lock only supports the `try_lock` operation, however, and does not
/// implement poisoning.
pub struct Lock<T> {
    locked: AtomicBool,
    data: UnsafeCell<T>,
}

/// Sentinel representing an acquired lock through which the data can be
/// accessed.
pub struct TryLock<'a, T: 'a> {
    __ptr: &'a Lock<T>,
}

// The `Lock` structure is basically just a `Mutex<T>`, and these two impls are
// intended to mirror the standard library's corresponding impls for `Mutex<T>`.
//
// If a `T` is sendable across threads, so is the lock, and `T` must be sendable
// across threads to be `Sync` because it allows mutable access from multiple
// threads.
unsafe impl<T: Send> Send for Lock<T> {}
unsafe impl<T: Send> Sync for Lock<T> {}

impl<T> Lock<T> {
    /// Creates a new lock around the given value.
    pub fn new(t: T) -> Lock<T> {
        Lock {
            locked: AtomicBool::new(false),
            data: UnsafeCell::new(t),
        }
    }

    /// Attempts to acquire this lock, returning whether the lock was acquired or
    /// not.
    ///
    /// If `Some` is returned then the data this lock protects can be accessed
    /// through the sentinel. This sentinel allows both mutable and immutable
    /// access.
    ///
    /// If `None` is returned then the lock is already locked, either elsewhere
    /// on this thread or on another thread.
    pub fn try_lock(&self) -> Option<TryLock<T>> {
        if !self.locked.swap(true, Acquire) {
            Some(TryLock { __ptr: self })
        } else {
            None
        }
    }
}

impl<'a, T> Deref for TryLock<'a, T> {
    type Target = T;
    fn deref(&self) -> &T {
        // The existence of `TryLock` represents that we own the lock, so we
        // can safely access the data here.
        unsafe { &*self.__ptr.data.get() }
    }
}

impl<'a, T> DerefMut for TryLock<'a, T> {
    fn deref_mut(&mut self) -> &mut T {
        // The existence of `TryLock` represents that we own the lock, so we
        // can safely access the data here.
        //
        // Additionally, we're the *only* `TryLock` in existence so mutable
        // access should be ok.
        unsafe { &mut *self.__ptr.data.get() }
    }
}

impl<'a, T> Drop for TryLock<'a, T> {
    fn drop(&mut self) {
        self.__ptr.locked.store(false, Release);
    }
}

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

    #[test]
    fn smoke() {
        let a = Lock::new(1);
        let mut a1 = a.try_lock().unwrap();
        assert!(a.try_lock().is_none());
        assert_eq!(*a1, 1);
        *a1 = 2;
        drop(a1);
        assert_eq!(*a.try_lock().unwrap(), 2);
        assert_eq!(*a.try_lock().unwrap(), 2);
    }
}
<|endoftext|>


<commit_before><commit_msg>more unit vectors<commit_after><|endoftext|>


<commit_before><commit_msg>:art: Rename command name<commit_after><|endoftext|>


<commit_before><commit_msg>Updated examples<commit_after><|endoftext|>