<commit_before>/*!

A render buffer is similar to a texture, but is optimized for usage as a draw target.

Contrary to a texture, you can't sample nor modify the content of a render buffer.
You should prefer render buffers over textures when you know that you don't need to read or modify
the data of the render buffer.

*/
use std::rc::Rc;
use std::ops::{Deref, DerefMut};
use std::mem;

use framebuffer::{ColorAttachment, ToColorAttachment};
use framebuffer::{DepthAttachment, ToDepthAttachment};
use framebuffer::{StencilAttachment, ToStencilAttachment};
use framebuffer::{DepthStencilAttachment, ToDepthStencilAttachment};
use texture::{UncompressedFloatFormat, DepthFormat, StencilFormat, DepthStencilFormat};

use image_format;

use gl;
use GlObject;
use fbo::FramebuffersContainer;
use backend::Facade;
use context::Context;
use ContextExt;
use version::Version;
use version::Api;

/// A render buffer is similar to a texture, but is optimized for usage as a draw target.
///
/// Contrary to a texture, you can't sample or modify the content of the `RenderBuffer`.
pub struct RenderBuffer {
    buffer: RenderBufferAny,
}

impl RenderBuffer {
    /// Builds a new render buffer.
    pub fn new<F>(facade: &F, format: UncompressedFloatFormat, width: u32, height: u32)
                  -> RenderBuffer where F: Facade
    {
        let format = image_format::TextureFormatRequest::Specific(image_format::TextureFormat::UncompressedFloat(format));
        let (_, format) = image_format::format_request_to_glenum(&facade.get_context(), None, format).unwrap();
        let format = format.expect("Format not supported");

        RenderBuffer {
            buffer: RenderBufferAny::new(facade, format, width, height)
        }
    }
}

impl ToColorAttachment for RenderBuffer {
    fn to_color_attachment(&self) -> ColorAttachment {
        ColorAttachment::RenderBuffer(self)
    }
}

impl Deref for RenderBuffer {
    type Target = RenderBufferAny;

    fn deref(&self) -> &RenderBufferAny {
        &self.buffer
    }
}

impl DerefMut for RenderBuffer {
    fn deref_mut(&mut self) -> &mut RenderBufferAny {
        &mut self.buffer
    }
}

impl GlObject for RenderBuffer {
    type Id = gl::types::GLuint;
    fn get_id(&self) -> gl::types::GLuint {
        self.buffer.get_id()
    }
}

/// A render buffer is similar to a texture, but is optimized for usage as a draw target.
///
/// Contrary to a texture, you can't sample or modify the content of the `DepthRenderBuffer` directly.
pub struct DepthRenderBuffer {
    buffer: RenderBufferAny,
}

impl DepthRenderBuffer {
    /// Builds a new render buffer.
    pub fn new<F>(facade: &F, format: DepthFormat, width: u32, height: u32)
                  -> DepthRenderBuffer where F: Facade
    {
        let format = image_format::TextureFormatRequest::Specific(image_format::TextureFormat::DepthFormat(format));
        let (_, format) = image_format::format_request_to_glenum(&facade.get_context(), None, format).unwrap();
        let format = format.expect("Format not supported");

        DepthRenderBuffer {
            buffer: RenderBufferAny::new(facade, format, width, height)
        }
    }
}

impl ToDepthAttachment for DepthRenderBuffer {
    fn to_depth_attachment(&self) -> DepthAttachment {
        DepthAttachment::RenderBuffer(self)
    }
}

impl Deref for DepthRenderBuffer {
    type Target = RenderBufferAny;

    fn deref(&self) -> &RenderBufferAny {
        &self.buffer
    }
}

impl DerefMut for DepthRenderBuffer {
    fn deref_mut(&mut self) -> &mut RenderBufferAny {
        &mut self.buffer
    }
}

impl GlObject for DepthRenderBuffer {
    type Id = gl::types::GLuint;
    fn get_id(&self) -> gl::types::GLuint {
        self.buffer.get_id()
    }
}

/// A render buffer is similar to a texture, but is optimized for usage as a draw target.
///
/// Contrary to a texture, you can't sample or modify the content of the `StencilRenderBuffer` directly.
pub struct StencilRenderBuffer {
    buffer: RenderBufferAny,
}

impl StencilRenderBuffer {
    /// Builds a new render buffer.
    pub fn new<F>(facade: &F, format: StencilFormat, width: u32, height: u32)
                  -> StencilRenderBuffer where F: Facade
    {
        let format = image_format::TextureFormatRequest::Specific(image_format::TextureFormat::StencilFormat(format));
        let (_, format) = image_format::format_request_to_glenum(&facade.get_context(), None, format).unwrap();
        let format = format.expect("Format not supported");

        StencilRenderBuffer {
            buffer: RenderBufferAny::new(facade, format, width, height)
        }
    }
}

impl ToStencilAttachment for StencilRenderBuffer {
    fn to_stencil_attachment(&self) -> StencilAttachment {
        StencilAttachment::RenderBuffer(self)
    }
}

impl Deref for StencilRenderBuffer {
    type Target = RenderBufferAny;

    fn deref(&self) -> &RenderBufferAny {
        &self.buffer
    }
}

impl DerefMut for StencilRenderBuffer {
    fn deref_mut(&mut self) -> &mut RenderBufferAny {
        &mut self.buffer
    }
}

impl GlObject for StencilRenderBuffer {
    type Id = gl::types::GLuint;
    fn get_id(&self) -> gl::types::GLuint {
        self.buffer.get_id()
    }
}

/// A render buffer is similar to a texture, but is optimized for usage as a draw target.
///
/// Contrary to a texture, you can't sample or modify the content of the `DepthStencilRenderBuffer` directly.
pub struct DepthStencilRenderBuffer {
    buffer: RenderBufferAny,
}

impl DepthStencilRenderBuffer {
    /// Builds a new render buffer.
    pub fn new<F>(facade: &F, format: DepthStencilFormat, width: u32, height: u32)
                  -> DepthStencilRenderBuffer where F: Facade
    {
        let format = image_format::TextureFormatRequest::Specific(image_format::TextureFormat::DepthStencilFormat(format));
        let (_, format) = image_format::format_request_to_glenum(&facade.get_context(), None, format).unwrap();
        let format = format.expect("Format not supported");

        DepthStencilRenderBuffer {
            buffer: RenderBufferAny::new(facade, format, width, height)
        }
    }
}

impl ToDepthStencilAttachment for DepthStencilRenderBuffer {
    fn to_depth_stencil_attachment(&self) -> DepthStencilAttachment {
        DepthStencilAttachment::RenderBuffer(self)
    }
}

impl Deref for DepthStencilRenderBuffer {
    type Target = RenderBufferAny;

    fn deref(&self) -> &RenderBufferAny {
        &self.buffer
    }
}

impl DerefMut for DepthStencilRenderBuffer {
    fn deref_mut(&mut self) -> &mut RenderBufferAny {
        &mut self.buffer
    }
}

impl GlObject for DepthStencilRenderBuffer {
    type Id = gl::types::GLuint;
    fn get_id(&self) -> gl::types::GLuint {
        self.buffer.get_id()
    }
}

/// A RenderBuffer of indeterminate type.
pub struct RenderBufferAny {
    context: Rc<Context>,
    id: gl::types::GLuint,
    width: u32,
    height: u32,
}

impl RenderBufferAny {
    /// Builds a new render buffer.
    fn new<F>(facade: &F, format: gl::types::GLenum, width: u32, height: u32)
              -> RenderBufferAny where F: Facade
    {
        // TODO: check that dimensions don't exceed GL_MAX_RENDERBUFFER_SIZE
        let mut ctxt = facade.get_context().make_current();

        let id = unsafe {
            let mut id = mem::uninitialized();

            if ctxt.version >= &Version(Api::Gl, 4, 5) ||
                ctxt.extensions.gl_arb_direct_state_access
            {
                ctxt.gl.CreateRenderbuffers(1, &mut id);
                ctxt.gl.NamedRenderbufferStorage(id, format, width as gl::types::GLsizei,
                                                 height as gl::types::GLsizei);

            } else if ctxt.version >= &Version(Api::Gl, 3, 0) ||
                      ctxt.version >= &Version(Api::GlEs, 2, 0)
            {
                ctxt.gl.GenRenderbuffers(1, &mut id);
                ctxt.gl.BindRenderbuffer(gl::RENDERBUFFER, id);
                ctxt.state.renderbuffer = id;
                // FIXME: gles2 only supports very few formats
                ctxt.gl.RenderbufferStorage(gl::RENDERBUFFER, format,
                                            width as gl::types::GLsizei,
                                            height as gl::types::GLsizei);

            } else if ctxt.extensions.gl_ext_framebuffer_object {
                ctxt.gl.GenRenderbuffersEXT(1, &mut id);
                ctxt.gl.BindRenderbufferEXT(gl::RENDERBUFFER_EXT, id);
                ctxt.state.renderbuffer = id;
                ctxt.gl.RenderbufferStorageEXT(gl::RENDERBUFFER_EXT, format,
                                               width as gl::types::GLsizei,
                                               height as gl::types::GLsizei);

            } else {
                unreachable!();
            }

            id
        };

        RenderBufferAny {
            context: facade.get_context().clone(),
            id: id,
            width: width,
            height: height,
        }
    }

    /// Returns the dimensions of the render buffer.
    pub fn get_dimensions(&self) -> (u32, u32) {
        (self.width, self.height)
    }
}

impl Drop for RenderBufferAny {
    fn drop(&mut self) {
        unsafe {
            let mut ctxt = self.context.make_current();

            // removing FBOs which contain this buffer
            FramebuffersContainer::purge_renderbuffer(&mut ctxt, self.id);

            if ctxt.version >= &Version(Api::Gl, 3, 0) ||
               ctxt.version >= &Version(Api::GlEs, 2, 0)
            {
                if ctxt.state.renderbuffer == self.id {
                    ctxt.gl.BindRenderbuffer(gl::RENDERBUFFER, 0);
                    ctxt.state.renderbuffer = 0;
                }
                ctxt.gl.DeleteRenderbuffers(1, [ self.id ].as_ptr());

            } else if ctxt.extensions.gl_ext_framebuffer_object {
                if ctxt.state.renderbuffer == self.id {
                    ctxt.gl.BindRenderbufferEXT(gl::RENDERBUFFER_EXT, 0);
                    ctxt.state.renderbuffer = 0;
                }
                ctxt.gl.DeleteRenderbuffersEXT(1, [ self.id ].as_ptr());

            } else {
                unreachable!();
            }
        }
    }
}

impl GlObject for RenderBufferAny {
    type Id = gl::types::GLuint;
    fn get_id(&self) -> gl::types::GLuint {
        self.id
    }
}
<commit_msg>Don't unbind the renderbuffer being destroyed<commit_after>/*!

A render buffer is similar to a texture, but is optimized for usage as a draw target.

Contrary to a texture, you can't sample nor modify the content of a render buffer.
You should prefer render buffers over textures when you know that you don't need to read or modify
the data of the render buffer.

*/
use std::rc::Rc;
use std::ops::{Deref, DerefMut};
use std::mem;

use framebuffer::{ColorAttachment, ToColorAttachment};
use framebuffer::{DepthAttachment, ToDepthAttachment};
use framebuffer::{StencilAttachment, ToStencilAttachment};
use framebuffer::{DepthStencilAttachment, ToDepthStencilAttachment};
use texture::{UncompressedFloatFormat, DepthFormat, StencilFormat, DepthStencilFormat};

use image_format;

use gl;
use GlObject;
use fbo::FramebuffersContainer;
use backend::Facade;
use context::Context;
use ContextExt;
use version::Version;
use version::Api;

/// A render buffer is similar to a texture, but is optimized for usage as a draw target.
///
/// Contrary to a texture, you can't sample or modify the content of the `RenderBuffer`.
pub struct RenderBuffer {
    buffer: RenderBufferAny,
}

impl RenderBuffer {
    /// Builds a new render buffer.
    pub fn new<F>(facade: &F, format: UncompressedFloatFormat, width: u32, height: u32)
                  -> RenderBuffer where F: Facade
    {
        let format = image_format::TextureFormatRequest::Specific(image_format::TextureFormat::UncompressedFloat(format));
        let (_, format) = image_format::format_request_to_glenum(&facade.get_context(), None, format).unwrap();
        let format = format.expect("Format not supported");

        RenderBuffer {
            buffer: RenderBufferAny::new(facade, format, width, height)
        }
    }
}

impl ToColorAttachment for RenderBuffer {
    fn to_color_attachment(&self) -> ColorAttachment {
        ColorAttachment::RenderBuffer(self)
    }
}

impl Deref for RenderBuffer {
    type Target = RenderBufferAny;

    fn deref(&self) -> &RenderBufferAny {
        &self.buffer
    }
}

impl DerefMut for RenderBuffer {
    fn deref_mut(&mut self) -> &mut RenderBufferAny {
        &mut self.buffer
    }
}

impl GlObject for RenderBuffer {
    type Id = gl::types::GLuint;
    fn get_id(&self) -> gl::types::GLuint {
        self.buffer.get_id()
    }
}

/// A render buffer is similar to a texture, but is optimized for usage as a draw target.
///
/// Contrary to a texture, you can't sample or modify the content of the `DepthRenderBuffer` directly.
pub struct DepthRenderBuffer {
    buffer: RenderBufferAny,
}

impl DepthRenderBuffer {
    /// Builds a new render buffer.
    pub fn new<F>(facade: &F, format: DepthFormat, width: u32, height: u32)
                  -> DepthRenderBuffer where F: Facade
    {
        let format = image_format::TextureFormatRequest::Specific(image_format::TextureFormat::DepthFormat(format));
        let (_, format) = image_format::format_request_to_glenum(&facade.get_context(), None, format).unwrap();
        let format = format.expect("Format not supported");

        DepthRenderBuffer {
            buffer: RenderBufferAny::new(facade, format, width, height)
        }
    }
}

impl ToDepthAttachment for DepthRenderBuffer {
    fn to_depth_attachment(&self) -> DepthAttachment {
        DepthAttachment::RenderBuffer(self)
    }
}

impl Deref for DepthRenderBuffer {
    type Target = RenderBufferAny;

    fn deref(&self) -> &RenderBufferAny {
        &self.buffer
    }
}

impl DerefMut for DepthRenderBuffer {
    fn deref_mut(&mut self) -> &mut RenderBufferAny {
        &mut self.buffer
    }
}

impl GlObject for DepthRenderBuffer {
    type Id = gl::types::GLuint;
    fn get_id(&self) -> gl::types::GLuint {
        self.buffer.get_id()
    }
}

/// A render buffer is similar to a texture, but is optimized for usage as a draw target.
///
/// Contrary to a texture, you can't sample or modify the content of the `StencilRenderBuffer` directly.
pub struct StencilRenderBuffer {
    buffer: RenderBufferAny,
}

impl StencilRenderBuffer {
    /// Builds a new render buffer.
    pub fn new<F>(facade: &F, format: StencilFormat, width: u32, height: u32)
                  -> StencilRenderBuffer where F: Facade
    {
        let format = image_format::TextureFormatRequest::Specific(image_format::TextureFormat::StencilFormat(format));
        let (_, format) = image_format::format_request_to_glenum(&facade.get_context(), None, format).unwrap();
        let format = format.expect("Format not supported");

        StencilRenderBuffer {
            buffer: RenderBufferAny::new(facade, format, width, height)
        }
    }
}

impl ToStencilAttachment for StencilRenderBuffer {
    fn to_stencil_attachment(&self) -> StencilAttachment {
        StencilAttachment::RenderBuffer(self)
    }
}

impl Deref for StencilRenderBuffer {
    type Target = RenderBufferAny;

    fn deref(&self) -> &RenderBufferAny {
        &self.buffer
    }
}

impl DerefMut for StencilRenderBuffer {
    fn deref_mut(&mut self) -> &mut RenderBufferAny {
        &mut self.buffer
    }
}

impl GlObject for StencilRenderBuffer {
    type Id = gl::types::GLuint;
    fn get_id(&self) -> gl::types::GLuint {
        self.buffer.get_id()
    }
}

/// A render buffer is similar to a texture, but is optimized for usage as a draw target.
///
/// Contrary to a texture, you can't sample or modify the content of the `DepthStencilRenderBuffer` directly.
pub struct DepthStencilRenderBuffer {
    buffer: RenderBufferAny,
}

impl DepthStencilRenderBuffer {
    /// Builds a new render buffer.
    pub fn new<F>(facade: &F, format: DepthStencilFormat, width: u32, height: u32)
                  -> DepthStencilRenderBuffer where F: Facade
    {
        let format = image_format::TextureFormatRequest::Specific(image_format::TextureFormat::DepthStencilFormat(format));
        let (_, format) = image_format::format_request_to_glenum(&facade.get_context(), None, format).unwrap();
        let format = format.expect("Format not supported");

        DepthStencilRenderBuffer {
            buffer: RenderBufferAny::new(facade, format, width, height)
        }
    }
}

impl ToDepthStencilAttachment for DepthStencilRenderBuffer {
    fn to_depth_stencil_attachment(&self) -> DepthStencilAttachment {
        DepthStencilAttachment::RenderBuffer(self)
    }
}

impl Deref for DepthStencilRenderBuffer {
    type Target = RenderBufferAny;

    fn deref(&self) -> &RenderBufferAny {
        &self.buffer
    }
}

impl DerefMut for DepthStencilRenderBuffer {
    fn deref_mut(&mut self) -> &mut RenderBufferAny {
        &mut self.buffer
    }
}

impl GlObject for DepthStencilRenderBuffer {
    type Id = gl::types::GLuint;
    fn get_id(&self) -> gl::types::GLuint {
        self.buffer.get_id()
    }
}

/// A RenderBuffer of indeterminate type.
pub struct RenderBufferAny {
    context: Rc<Context>,
    id: gl::types::GLuint,
    width: u32,
    height: u32,
}

impl RenderBufferAny {
    /// Builds a new render buffer.
    fn new<F>(facade: &F, format: gl::types::GLenum, width: u32, height: u32)
              -> RenderBufferAny where F: Facade
    {
        // TODO: check that dimensions don't exceed GL_MAX_RENDERBUFFER_SIZE
        let mut ctxt = facade.get_context().make_current();

        let id = unsafe {
            let mut id = mem::uninitialized();

            if ctxt.version >= &Version(Api::Gl, 4, 5) ||
                ctxt.extensions.gl_arb_direct_state_access
            {
                ctxt.gl.CreateRenderbuffers(1, &mut id);
                ctxt.gl.NamedRenderbufferStorage(id, format, width as gl::types::GLsizei,
                                                 height as gl::types::GLsizei);

            } else if ctxt.version >= &Version(Api::Gl, 3, 0) ||
                      ctxt.version >= &Version(Api::GlEs, 2, 0)
            {
                ctxt.gl.GenRenderbuffers(1, &mut id);
                ctxt.gl.BindRenderbuffer(gl::RENDERBUFFER, id);
                ctxt.state.renderbuffer = id;
                // FIXME: gles2 only supports very few formats
                ctxt.gl.RenderbufferStorage(gl::RENDERBUFFER, format,
                                            width as gl::types::GLsizei,
                                            height as gl::types::GLsizei);

            } else if ctxt.extensions.gl_ext_framebuffer_object {
                ctxt.gl.GenRenderbuffersEXT(1, &mut id);
                ctxt.gl.BindRenderbufferEXT(gl::RENDERBUFFER_EXT, id);
                ctxt.state.renderbuffer = id;
                ctxt.gl.RenderbufferStorageEXT(gl::RENDERBUFFER_EXT, format,
                                               width as gl::types::GLsizei,
                                               height as gl::types::GLsizei);

            } else {
                unreachable!();
            }

            id
        };

        RenderBufferAny {
            context: facade.get_context().clone(),
            id: id,
            width: width,
            height: height,
        }
    }

    /// Returns the dimensions of the render buffer.
    pub fn get_dimensions(&self) -> (u32, u32) {
        (self.width, self.height)
    }
}

impl Drop for RenderBufferAny {
    fn drop(&mut self) {
        unsafe {
            let mut ctxt = self.context.make_current();

            // removing FBOs which contain this buffer
            FramebuffersContainer::purge_renderbuffer(&mut ctxt, self.id);

            if ctxt.version >= &Version(Api::Gl, 3, 0) ||
               ctxt.version >= &Version(Api::GlEs, 2, 0)
            {
                if ctxt.state.renderbuffer == self.id {
                    ctxt.state.renderbuffer = 0;
                }

                ctxt.gl.DeleteRenderbuffers(1, [ self.id ].as_ptr());

            } else if ctxt.extensions.gl_ext_framebuffer_object {
                if ctxt.state.renderbuffer == self.id {
                    ctxt.state.renderbuffer = 0;
                }

                ctxt.gl.DeleteRenderbuffersEXT(1, [ self.id ].as_ptr());

            } else {
                unreachable!();
            }
        }
    }
}

impl GlObject for RenderBufferAny {
    type Id = gl::types::GLuint;
    fn get_id(&self) -> gl::types::GLuint {
        self.id
    }
}
<|endoftext|>


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

use ast;
use codemap::{Pos, Span};
use codemap;
use ext::base::*;
use ext::base;
use ext::build::AstBuilder;
use parse::token;
use parse;
use print::pprust;
use ptr::P;
use util::small_vector::SmallVector;

use std::fs::File;
use std::io::prelude::*;
use std::path::{Path, PathBuf};
use std::rc::Rc;

// These macros all relate to the file system; they either return
// the column/row/filename of the expression, or they include
// a given file into the current one.

/// line!(): expands to the current line number
pub fn expand_line(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                   -> Box<base::MacResult+'static> {
    base::check_zero_tts(cx, sp, tts, "line!");

    let topmost = cx.original_span_in_file();
    let loc = cx.codemap().lookup_char_pos(topmost.lo);

    base::MacEager::expr(cx.expr_u32(topmost, loc.line as u32))
}

/* column!(): expands to the current column number */
pub fn expand_column(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                  -> Box<base::MacResult+'static> {
    base::check_zero_tts(cx, sp, tts, "column!");

    let topmost = cx.original_span_in_file();
    let loc = cx.codemap().lookup_char_pos(topmost.lo);

    base::MacEager::expr(cx.expr_u32(topmost, loc.col.to_usize() as u32))
}

/// file!(): expands to the current filename */
/// The filemap (`loc.file`) contains a bunch more information we could spit
/// out if we wanted.
pub fn expand_file(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                   -> Box<base::MacResult+'static> {
    base::check_zero_tts(cx, sp, tts, "file!");

    let topmost = cx.original_span_in_file();
    let loc = cx.codemap().lookup_char_pos(topmost.lo);
    let filename = token::intern_and_get_ident(&loc.file.name);
    base::MacEager::expr(cx.expr_str(topmost, filename))
}

pub fn expand_stringify(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                        -> Box<base::MacResult+'static> {
    let s = pprust::tts_to_string(tts);
    base::MacEager::expr(cx.expr_str(sp,
                                   token::intern_and_get_ident(&s[..])))
}

pub fn expand_mod(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                  -> Box<base::MacResult+'static> {
    base::check_zero_tts(cx, sp, tts, "module_path!");
    let string = cx.mod_path()
                   .iter()
                   .map(|x| token::get_ident(*x).to_string())
                   .collect::<Vec<String>>()
                   .connect("::");
    base::MacEager::expr(cx.expr_str(
            sp,
            token::intern_and_get_ident(&string[..])))
}

/// include! : parse the given file as an expr
/// This is generally a bad idea because it's going to behave
/// unhygienically.
pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                           -> Box<base::MacResult+'cx> {
    let file = match get_single_str_from_tts(cx, sp, tts, "include!") {
        Some(f) => f,
        None => return DummyResult::expr(sp),
    };
    // The file will be added to the code map by the parser
    let p =
        parse::new_sub_parser_from_file(cx.parse_sess(),
                                        cx.cfg(),
                                        &res_rel_file(cx,
                                                      sp,
                                                      Path::new(&file)),
                                        true,
                                        None,
                                        sp);

    struct ExpandResult<'a> {
        p: parse::parser::Parser<'a>,
    }
    impl<'a> base::MacResult for ExpandResult<'a> {
        fn make_expr(mut self: Box<ExpandResult<'a>>) -> Option<P<ast::Expr>> {
            Some(self.p.parse_expr())
        }
        fn make_items(mut self: Box<ExpandResult<'a>>)
                      -> Option<SmallVector<P<ast::Item>>> {
            let mut ret = SmallVector::zero();
            while self.p.token != token::Eof {
                match self.p.parse_item() {
                    Some(item) => ret.push(item),
                    None => panic!(self.p.span_fatal(
                        self.p.span,
                        &format!("expected item, found `{}`",
                                 self.p.this_token_to_string())
                    ))
                }
            }
            Some(ret)
        }
    }

    box ExpandResult { p: p }
}

// include_str! : read the given file, insert it as a literal string expr
pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                          -> Box<base::MacResult+'static> {
    let file = match get_single_str_from_tts(cx, sp, tts, "include_str!") {
        Some(f) => f,
        None => return DummyResult::expr(sp)
    };
    let file = res_rel_file(cx, sp, Path::new(&file));
    let mut bytes = Vec::new();
    match File::open(&file).and_then(|mut f| f.read_to_end(&mut bytes)) {
        Ok(..) => {}
        Err(e) => {
            cx.span_err(sp,
                        &format!("couldn't read {}: {}",
                                file.display(),
                                e));
            return DummyResult::expr(sp);
        }
    };
    match String::from_utf8(bytes) {
        Ok(src) => {
            // Add this input file to the code map to make it available as
            // dependency information
            let filename = format!("{}", file.display());
            let interned = token::intern_and_get_ident(&src[..]);
            cx.codemap().new_filemap(filename, src);

            base::MacEager::expr(cx.expr_str(sp, interned))
        }
        Err(_) => {
            cx.span_err(sp,
                        &format!("{} wasn't a utf-8 file",
                                file.display()));
            return DummyResult::expr(sp);
        }
    }
}

pub fn expand_include_bytes(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                            -> Box<base::MacResult+'static> {
    let file = match get_single_str_from_tts(cx, sp, tts, "include_bytes!") {
        Some(f) => f,
        None => return DummyResult::expr(sp)
    };
    let file = res_rel_file(cx, sp, Path::new(&file));
    let mut bytes = Vec::new();
    match File::open(&file).and_then(|mut f| f.read_to_end(&mut bytes)) {
        Err(e) => {
            cx.span_err(sp,
                        &format!("couldn't read {}: {}", file.display(), e));
            return DummyResult::expr(sp);
        }
        Ok(..) => {
            base::MacEager::expr(cx.expr_lit(sp, ast::LitBinary(Rc::new(bytes))))
        }
    }
}

// resolve a file-system path to an absolute file-system path (if it
// isn't already)
fn res_rel_file(cx: &mut ExtCtxt, sp: codemap::Span, arg: &Path) -> PathBuf {
    // NB: relative paths are resolved relative to the compilation unit
    if !arg.is_absolute() {
        let mut cu = PathBuf::from(&cx.codemap().span_to_filename(sp));
        cu.pop();
        cu.push(arg);
        cu
    } else {
        arg.to_path_buf()
    }
}
<commit_msg>include_bytes! now registers the file included<commit_after>// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use ast;
use codemap::{Pos, Span};
use codemap;
use ext::base::*;
use ext::base;
use ext::build::AstBuilder;
use parse::token;
use parse;
use print::pprust;
use ptr::P;
use util::small_vector::SmallVector;

use std::fs::File;
use std::io::prelude::*;
use std::path::{Path, PathBuf};
use std::rc::Rc;

// These macros all relate to the file system; they either return
// the column/row/filename of the expression, or they include
// a given file into the current one.

/// line!(): expands to the current line number
pub fn expand_line(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                   -> Box<base::MacResult+'static> {
    base::check_zero_tts(cx, sp, tts, "line!");

    let topmost = cx.original_span_in_file();
    let loc = cx.codemap().lookup_char_pos(topmost.lo);

    base::MacEager::expr(cx.expr_u32(topmost, loc.line as u32))
}

/* column!(): expands to the current column number */
pub fn expand_column(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                  -> Box<base::MacResult+'static> {
    base::check_zero_tts(cx, sp, tts, "column!");

    let topmost = cx.original_span_in_file();
    let loc = cx.codemap().lookup_char_pos(topmost.lo);

    base::MacEager::expr(cx.expr_u32(topmost, loc.col.to_usize() as u32))
}

/// file!(): expands to the current filename */
/// The filemap (`loc.file`) contains a bunch more information we could spit
/// out if we wanted.
pub fn expand_file(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                   -> Box<base::MacResult+'static> {
    base::check_zero_tts(cx, sp, tts, "file!");

    let topmost = cx.original_span_in_file();
    let loc = cx.codemap().lookup_char_pos(topmost.lo);
    let filename = token::intern_and_get_ident(&loc.file.name);
    base::MacEager::expr(cx.expr_str(topmost, filename))
}

pub fn expand_stringify(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                        -> Box<base::MacResult+'static> {
    let s = pprust::tts_to_string(tts);
    base::MacEager::expr(cx.expr_str(sp,
                                   token::intern_and_get_ident(&s[..])))
}

pub fn expand_mod(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                  -> Box<base::MacResult+'static> {
    base::check_zero_tts(cx, sp, tts, "module_path!");
    let string = cx.mod_path()
                   .iter()
                   .map(|x| token::get_ident(*x).to_string())
                   .collect::<Vec<String>>()
                   .connect("::");
    base::MacEager::expr(cx.expr_str(
            sp,
            token::intern_and_get_ident(&string[..])))
}

/// include! : parse the given file as an expr
/// This is generally a bad idea because it's going to behave
/// unhygienically.
pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                           -> Box<base::MacResult+'cx> {
    let file = match get_single_str_from_tts(cx, sp, tts, "include!") {
        Some(f) => f,
        None => return DummyResult::expr(sp),
    };
    // The file will be added to the code map by the parser
    let p =
        parse::new_sub_parser_from_file(cx.parse_sess(),
                                        cx.cfg(),
                                        &res_rel_file(cx,
                                                      sp,
                                                      Path::new(&file)),
                                        true,
                                        None,
                                        sp);

    struct ExpandResult<'a> {
        p: parse::parser::Parser<'a>,
    }
    impl<'a> base::MacResult for ExpandResult<'a> {
        fn make_expr(mut self: Box<ExpandResult<'a>>) -> Option<P<ast::Expr>> {
            Some(self.p.parse_expr())
        }
        fn make_items(mut self: Box<ExpandResult<'a>>)
                      -> Option<SmallVector<P<ast::Item>>> {
            let mut ret = SmallVector::zero();
            while self.p.token != token::Eof {
                match self.p.parse_item() {
                    Some(item) => ret.push(item),
                    None => panic!(self.p.span_fatal(
                        self.p.span,
                        &format!("expected item, found `{}`",
                                 self.p.this_token_to_string())
                    ))
                }
            }
            Some(ret)
        }
    }

    box ExpandResult { p: p }
}

// include_str! : read the given file, insert it as a literal string expr
pub fn expand_include_str(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                          -> Box<base::MacResult+'static> {
    let file = match get_single_str_from_tts(cx, sp, tts, "include_str!") {
        Some(f) => f,
        None => return DummyResult::expr(sp)
    };
    let file = res_rel_file(cx, sp, Path::new(&file));
    let mut bytes = Vec::new();
    match File::open(&file).and_then(|mut f| f.read_to_end(&mut bytes)) {
        Ok(..) => {}
        Err(e) => {
            cx.span_err(sp,
                        &format!("couldn't read {}: {}",
                                file.display(),
                                e));
            return DummyResult::expr(sp);
        }
    };
    match String::from_utf8(bytes) {
        Ok(src) => {
            // Add this input file to the code map to make it available as
            // dependency information
            let filename = format!("{}", file.display());
            let interned = token::intern_and_get_ident(&src[..]);
            cx.codemap().new_filemap(filename, src);

            base::MacEager::expr(cx.expr_str(sp, interned))
        }
        Err(_) => {
            cx.span_err(sp,
                        &format!("{} wasn't a utf-8 file",
                                file.display()));
            return DummyResult::expr(sp);
        }
    }
}

pub fn expand_include_bytes(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                            -> Box<base::MacResult+'static> {
    let file = match get_single_str_from_tts(cx, sp, tts, "include_bytes!") {
        Some(f) => f,
        None => return DummyResult::expr(sp)
    };
    let file = res_rel_file(cx, sp, Path::new(&file));
    let mut bytes = Vec::new();
    match File::open(&file).and_then(|mut f| f.read_to_end(&mut bytes)) {
        Err(e) => {
            cx.span_err(sp,
                        &format!("couldn't read {}: {}", file.display(), e));
            return DummyResult::expr(sp);
        }
        Ok(..) => {
            // Add this input file to the code map to make it available as
            // dependency information, but don't enter it's contents
            let filename = format!("{}", file.display());
            cx.codemap().new_filemap(filename, "".to_string());

            base::MacEager::expr(cx.expr_lit(sp, ast::LitBinary(Rc::new(bytes))))
        }
    }
}

// resolve a file-system path to an absolute file-system path (if it
// isn't already)
fn res_rel_file(cx: &mut ExtCtxt, sp: codemap::Span, arg: &Path) -> PathBuf {
    // NB: relative paths are resolved relative to the compilation unit
    if !arg.is_absolute() {
        let mut cu = PathBuf::from(&cx.codemap().span_to_filename(sp));
        cu.pop();
        cu.push(arg);
        cu
    } else {
        arg.to_path_buf()
    }
}
<|endoftext|>


<commit_before><commit_msg>Add Depth-First Search using The Rust Programming Language<commit_after>use std::io::stdin;

// DFS receives a graph and the start point
fn dfs(graph: &mut Vec<Vec<usize>>, start: usize) {
    let mut visited: Box<Vec<bool>> = Box::new(Vec::new());
    visited.resize(graph.len(), false);

    dfs_util(&graph, start, &mut visited);
}

fn dfs_util(graph: &[Vec<usize>], value: usize, visited: &mut Box<Vec<bool>>) {
    visited[value] = true;
    println!("{}", value);

    for node in &graph[value] {
        if !visited[*node] {
            dfs_util(graph, *node, visited);
        }
    }
}

fn add_edge(graph: &mut Vec<Vec<usize>>, u: usize, v: usize) {
    graph[u].push(v);
}

fn main() {
    let mut edges: usize;
    let mut graph: Vec<Vec<usize>> = Vec::new();
    graph.resize(100, vec![]);

    // Read number of edges from user
    let mut input: String = String::new();
    stdin().read_line(&mut input).unwrap();
    edges = input.trim().parse::<u32>().unwrap() as usize;

    while edges > 0 {
        let u: usize;
        let v: usize;

        // Read u and v by splitting input into words and reading the first words found
        let mut input: String = String::new();
        stdin().read_line(&mut input).unwrap();
        let mut words = input.split_whitespace();
        u = words.next().unwrap().parse::<u32>().unwrap() as usize;
        v = words.next().unwrap().parse::<u32>().unwrap() as usize;

        add_edge(&mut graph, u, v);

        edges = edges - 1;
    }

    let start: usize;
    let mut input: String = String::new();
    stdin().read_line(&mut input).unwrap();
    start = input.trim().parse::<u32>().unwrap() as usize;

    dfs(&mut graph, start);
}

#[test]
fn test_dfs_with_graph() {
    let mut graph: Vec<Vec<usize>> = Vec::new();
    graph.resize(4, vec![]);

    add_edge(&mut graph, 0, 1);
    add_edge(&mut graph, 0, 2);
    add_edge(&mut graph, 1, 2);
    add_edge(&mut graph, 2, 0);
    add_edge(&mut graph, 2, 3);
    add_edge(&mut graph, 3, 3);

    println!("DFS Starting from vertex 2");

    dfs(&mut graph, 2);
}
<|endoftext|>


<commit_before><commit_msg>Add a partition_slice function.<commit_after>//! Rearrange the elements in a slice according to a predicate.

/// Rearrange the elements of the mutable slice `s` such that elements where `p(t)` is true precede
/// the elements where `p(t)` is false.
///
/// The order of elements is not preserved, unless the slice is already partitioned.
///
/// Returns the number of elements where `p(t)` is true.
pub fn partition_slice<'a, T: 'a, F>(s: &'a mut [T], mut p: F) -> usize
    where F: FnMut(&T) -> bool
{
    // Count the length of the prefix where `p` returns true.
    let mut count = match s.iter().position(|t| !p(t)) {
        Some(t) => t,
        None => return s.len(),
    };

    // Swap remaining `true` elements into place.
    //
    // This actually preserves the order of the `true` elements, but the `false` elements get
    // shuffled.
    for i in count + 1..s.len() {
        if p(&s[i]) {
            s.swap(count, i);
            count += 1;
        }
    }

    count
}

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

    fn check(x: &[u32], want: &[u32]) {
        assert_eq!(x.len(), want.len());
        let want_count = want.iter().cloned().filter(|&x| x % 10 == 0).count();
        let mut v = Vec::new();
        v.extend(x.iter().cloned());
        let count = partition_slice(&mut v[..], |&x| x % 10 == 0);
        assert_eq!(v, want);
        assert_eq!(count, want_count);
    }

    #[test]
    fn empty() {
        check(&[], &[]);
    }

    #[test]
    fn singles() {
        check(&[0], &[0]);
        check(&[1], &[1]);
        check(&[10], &[10]);
    }

    #[test]
    fn doubles() {
        check(&[0, 0], &[0, 0]);
        check(&[0, 5], &[0, 5]);
        check(&[5, 0], &[0, 5]);
        check(&[5, 4], &[5, 4]);
    }

    #[test]
    fn longer() {
        check(&[1, 2, 3], &[1, 2, 3]);
        check(&[1, 2, 10], &[10, 2, 1]); // Note: 2, 1 order not required.
        check(&[1, 10, 2], &[10, 1, 2]); // Note: 1, 2 order not required.
        check(&[1, 20, 10], &[20, 10, 1]);
        check(&[1, 20, 3, 10], &[20, 10, 3, 1]);
        check(&[20, 3, 10, 1], &[20, 10, 3, 1]);
    }
}
<|endoftext|>


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

// Test that generating drop glue for Box<str> doesn't ICE

fn f(s: Box<str>) -> Box<str> {
    s
}

fn main() {
    // There is currently no safe way to construct a `Box<str>`, so improvise
    let box_arr: Box<[u8]> = box ['h' as u8, 'e' as u8, 'l' as u8, 'l' as u8, 'o' as u8];
    let box_str: Box<str> = unsafe { std::mem::transmute(box_arr) };
    assert_eq!(box_str.as_slice(), "hello");
    f(box_str);
}
<|endoftext|>


<commit_before><commit_msg>Add a regression test for issue #18809.<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.

trait Tup {
    type T0;
    type T1;
}

impl Tup for isize {
    type T0 = f32;
    type T1 = ();
}

fn main() {}
<|endoftext|>


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

#![feature(fn_traits)]

use std::ops::Fn;

fn say(x: u32, y: u32) {
    println!("{} {}", x, y);
}

fn main() {
    Fn::call(&say, (1, 2));
}
<|endoftext|>


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

// compile-flags:--test
#![deny(private_in_public)]

#[test] fn foo() {}
mod foo {}

#[test] fn core() {}
extern crate core;
<|endoftext|>


<commit_before><commit_msg>Add test for #40003.<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.

fn main() {
    if false { test(); }
}

fn test() {
    let rx = Err::<Vec<usize>, u32>(1).into_future();

    rx.map(|l: Vec<usize>| stream::iter(l.into_iter().map(|i| Ok(i))))
      .flatten_stream()
      .chunks(50)
      .buffer_unordered(5);
}

use future::{Future, IntoFuture};
mod future {
    use std::result;

    use {stream, Stream};

    pub trait Future {
        type Item;
        type Error;

        fn map<F, U>(self, _: F) -> Map<Self, F>
            where F: FnOnce(Self::Item) -> U,
                  Self: Sized,
        {
            panic!()
        }

        fn flatten_stream(self) -> FlattenStream<Self>
            where <Self as Future>::Item: stream::Stream<Error=Self::Error>,
                  Self: Sized
        {
            panic!()
        }
    }

    pub trait IntoFuture {
        type Future: Future<Item=Self::Item, Error=Self::Error>;
        type Item;
        type Error;
        fn into_future(self) -> Self::Future;
    }

    impl<F: Future> IntoFuture for F {
        type Future = F;
        type Item = F::Item;
        type Error = F::Error;

        fn into_future(self) -> F {
            panic!()
        }
    }

    impl<T, E> IntoFuture for result::Result<T, E> {
        type Future = FutureResult<T, E>;
        type Item = T;
        type Error = E;

        fn into_future(self) -> FutureResult<T, E> {
            panic!()
        }
    }

    pub struct Map<A, F> {
        _a: (A, F),
    }

    impl<U, A, F> Future for Map<A, F>
        where A: Future,
              F: FnOnce(A::Item) -> U,
    {
        type Item = U;
        type Error = A::Error;
    }

    pub struct FlattenStream<F> {
        _f: F,
    }

    impl<F> Stream for FlattenStream<F>
        where F: Future,
              <F as Future>::Item: Stream<Error=F::Error>,
    {
        type Item = <F::Item as Stream>::Item;
        type Error = <F::Item as Stream>::Error;
    }

    pub struct FutureResult<T, E> {
        _inner: (T, E),
    }

    impl<T, E> Future for FutureResult<T, E> {
        type Item = T;
        type Error = E;
    }
}

mod stream {
    use IntoFuture;

    pub trait Stream {
        type Item;
        type Error;

        fn buffer_unordered(self, amt: usize) -> BufferUnordered<Self>
            where Self::Item: IntoFuture<Error = <Self as Stream>::Error>,
                  Self: Sized
        {
            new(self, amt)
        }

        fn chunks(self, _capacity: usize) -> Chunks<Self>
            where Self: Sized
        {
            panic!()
        }
    }

    pub struct IterStream<I> {
        _iter: I,
    }

    pub fn iter<J, T, E>(_: J) -> IterStream<J::IntoIter>
        where J: IntoIterator<Item=Result<T, E>>,
    {
        panic!()
    }

    impl<I, T, E> Stream for IterStream<I>
        where I: Iterator<Item=Result<T, E>>,
    {
        type Item = T;
        type Error = E;
    }

    pub struct Chunks<S> {
        _stream: S
    }

    impl<S> Stream for Chunks<S>
        where S: Stream
    {
        type Item = Result<Vec<<S as Stream>::Item>, u32>;
        type Error = <S as Stream>::Error;
    }

    pub struct BufferUnordered<S> {
        _stream: S,
    }

    enum Slot<T> {
        Next(usize),
        _Data { _a: T },
    }

    fn new<S>(_s: S, _amt: usize) -> BufferUnordered<S>
        where S: Stream,
              S::Item: IntoFuture<Error=<S as Stream>::Error>,
    {
        (0..0).map(|_| {
            Slot::Next::<<S::Item as IntoFuture>::Future>(1)
        }).collect::<Vec<_>>();
        panic!()
    }

    impl<S> Stream for BufferUnordered<S>
        where S: Stream,
              S::Item: IntoFuture<Error=<S as Stream>::Error>,
    {
        type Item = <S::Item as IntoFuture>::Item;
        type Error = <S as Stream>::Error;
    }
}
use stream::Stream;
<|endoftext|>


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

// compile-flags: -Z borrowck=compare

use std::cell::Cell;
use std::mem::swap;

// Just a grab bag of stuff that you wouldn't want to actually write.

fn strange() -> bool { let _x: bool = return true; }

fn funny() {
    fn f(_x: ()) { }
    f(return);
}

fn what() {
    fn the(x: &Cell<bool>) {
        return while !x.get() { x.set(true); };
    }
    let i = &Cell::new(false);
    let dont = {||the(i)};
    dont();
    assert!((i.get()));
}

fn zombiejesus() {
    loop {
        while (return) {
            if (return) {
                match (return) {
                    1 => {
                        if (return) {
                            return
                        } else {
                            return
                        }
                    }
                    _ => { return }
                };
            } else if (return) {
                return;
            }
        }
        if (return) { break; }
    }
}

fn notsure() {
    let mut _x: isize;
    let mut _y = (_x = 0) == (_x = 0);
    let mut _z = (_x = 0) < (_x = 0);
    let _a = (_x += 0) == (_x = 0);
    let _b = swap(&mut _y, &mut _z) == swap(&mut _y, &mut _z);
}

fn canttouchthis() -> usize {
    fn p() -> bool { true }
    let _a = (assert!((true)) == (assert!(p())));
    let _c = (assert!((p())) == ());
    let _b: bool = (println!("{}", 0) == (return 0));
}

fn angrydome() {
    loop { if break { } }
    let mut i = 0;
    loop { i += 1; if i == 1 { match (continue) { 1 => { }, _ => panic!("wat") } }
      break; }
}

fn evil_lincoln() { let _evil = println!("lincoln"); }

fn dots() {
    assert_eq!(String::from(".................................................."),
               format!("{:?}", .. .. .. .. .. .. .. .. .. .. .. .. ..
                               .. .. .. .. .. .. .. .. .. .. .. ..));
}

fn you_eight() {
    assert_eq!(8, {
        macro_rules! u8 {
            (u8) => {
                mod u8 {
                    pub fn u8<'u8>(u8: &'u8 u8) -> &'u8 u8 {
                        "u8";
                        u8
                    }
                }
            };
        }

        u8!(u8);
        let &u8: &u8 = u8::u8(&8u8);
        u8
    });
}

fn fishy() {
    assert_eq!(String::from("><>"),
               String::<>::from::<>("><>").chars::<>().rev::<>().collect::<String>());
}

fn union() {
    union union<'union> { union: &'union union<'union>, }
}

pub fn main() {
    strange();
    funny();
    what();
    zombiejesus();
    notsure();
    canttouchthis();
    angrydome();
    evil_lincoln();
    dots();
    you_eight();
    fishy();
    union();
}
<commit_msg>What does an expression look like, that consists only of special characters?<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -Z borrowck=compare

use std::cell::Cell;
use std::mem::swap;

// Just a grab bag of stuff that you wouldn't want to actually write.

fn strange() -> bool { let _x: bool = return true; }

fn funny() {
    fn f(_x: ()) { }
    f(return);
}

fn what() {
    fn the(x: &Cell<bool>) {
        return while !x.get() { x.set(true); };
    }
    let i = &Cell::new(false);
    let dont = {||the(i)};
    dont();
    assert!((i.get()));
}

fn zombiejesus() {
    loop {
        while (return) {
            if (return) {
                match (return) {
                    1 => {
                        if (return) {
                            return
                        } else {
                            return
                        }
                    }
                    _ => { return }
                };
            } else if (return) {
                return;
            }
        }
        if (return) { break; }
    }
}

fn notsure() {
    let mut _x: isize;
    let mut _y = (_x = 0) == (_x = 0);
    let mut _z = (_x = 0) < (_x = 0);
    let _a = (_x += 0) == (_x = 0);
    let _b = swap(&mut _y, &mut _z) == swap(&mut _y, &mut _z);
}

fn canttouchthis() -> usize {
    fn p() -> bool { true }
    let _a = (assert!((true)) == (assert!(p())));
    let _c = (assert!((p())) == ());
    let _b: bool = (println!("{}", 0) == (return 0));
}

fn angrydome() {
    loop { if break { } }
    let mut i = 0;
    loop { i += 1; if i == 1 { match (continue) { 1 => { }, _ => panic!("wat") } }
      break; }
}

fn evil_lincoln() { let _evil = println!("lincoln"); }

fn dots() {
    assert_eq!(String::from(".................................................."),
               format!("{:?}", .. .. .. .. .. .. .. .. .. .. .. .. ..
                               .. .. .. .. .. .. .. .. .. .. .. ..));
}

fn you_eight() {
    assert_eq!(8, {
        macro_rules! u8 {
            (u8) => {
                mod u8 {
                    pub fn u8<'u8>(u8: &'u8 u8) -> &'u8 u8 {
                        "u8";
                        u8
                    }
                }
            };
        }

        u8!(u8);
        let &u8: &u8 = u8::u8(&8u8);
        u8
    });
}

fn fishy() {
    assert_eq!(String::from("><>"),
               String::<>::from::<>("><>").chars::<>().rev::<>().collect::<String>());
}

fn union() {
    union union<'union> { union: &'union union<'union>, }
}

fn special_characters() {
    let val = !((|(..):(_,_),__@_|__)((&*"\\",'@')/**/,{})=={&[..=..][..];})//
    ;
    assert!(!val);
}

pub fn main() {
    strange();
    funny();
    what();
    zombiejesus();
    notsure();
    canttouchthis();
    angrydome();
    evil_lincoln();
    dots();
    you_eight();
    fishy();
    union();
}
<|endoftext|>


<commit_before><commit_msg>idna: use standard binary_search_by<commit_after><|endoftext|>


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

#![allow(non_snake_case)]

register_long_diagnostics! {

E0381: r##"
It is not allowed to use or capture an uninitialized variable. For example:

```
fn main() {
    let x: i32;
    let y = x; // error, use of possibly uninitialized variable
```

To fix this, ensure that any declared variables are initialized before being
used.
"##

}

register_diagnostics! {
    E0373, // closure may outlive current fn, but it borrows {}, which is owned by current fn
    E0382, // use of partially/collaterally moved value
    E0383, // partial reinitialization of uninitialized structure
    E0384, // reassignment of immutable variable
    E0385, // {} in an aliasable location
    E0386, // {} in an immutable container
    E0387, // {} in a captured outer variable in an `Fn` closure
    E0388, // {} in a static location
    E0389  // {} in a `&` reference
}
<commit_msg>Rollup merge of #27229 - AlisdairO:diagnostics371, r=Manishearth<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.

#![allow(non_snake_case)]

register_long_diagnostics! {

E0373: r##"
This error occurs when an attempt is made to use data captured by a closure,
when that data may no longer exist. It's most commonly seen when attempting to
return a closure:

```
fn foo() -> Box<Fn(u32) -> u32> {
    let x = 0u32;
    Box::new(|y| x + y)
}
```

Notice that `x` is stack-allocated by `foo()`. By default, Rust captures
closed-over data by reference. This means that once `foo()` returns, `x` no
longer exists. An attempt to access `x` within the closure would thus be unsafe.

Another situation where this might be encountered is when spawning threads:

```
fn foo() {
    let x = 0u32;
    let y = 1u32;

    let thr = std::thread::spawn(|| {
        x + y
    });
}
```

Since our new thread runs in parallel, the stack frame containing `x` and `y`
may well have disappeared by the time we try to use them. Even if we call
`thr.join()` within foo (which blocks until `thr` has completed, ensuring the
stack frame won't disappear), we will not succeed: the compiler cannot prove
that this behaviour is safe, and so won't let us do it.

The solution to this problem is usually to switch to using a `move` closure.
This approach moves (or copies, where possible) data into the closure, rather
than taking references to it. For example:

```
fn foo() -> Box<Fn(u32) -> u32> {
    let x = 0u32;
    Box::new(move |y| x + y)
}
```

Now that the closure has its own copy of the data, there's no need to worry
about safety.
"##,

E0381: r##"
It is not allowed to use or capture an uninitialized variable. For example:

```
fn main() {
    let x: i32;
    let y = x; // error, use of possibly uninitialized variable
```

To fix this, ensure that any declared variables are initialized before being
used.
"##

}

register_diagnostics! {
    E0382, // use of partially/collaterally moved value
    E0383, // partial reinitialization of uninitialized structure
    E0384, // reassignment of immutable variable
    E0385, // {} in an aliasable location
    E0386, // {} in an immutable container
    E0387, // {} in a captured outer variable in an `Fn` closure
    E0388, // {} in a static location
    E0389  // {} in a `&` reference
}
<|endoftext|>


<commit_before><commit_msg>Add xfailed test case for #2354<commit_after>// xfail-test
/*
  Ideally, the error about the missing close brace in foo would be reported
  near the corresponding open brace. But currently it's reported at the end.
  xfailed for now (see Issue #2354)
 */
fn foo() { //! ERROR this open brace is not closed
  alt some(x) {
      some(y) { fail; }
      none    { fail; }
}

fn bar() {
    let mut i = 0;
    while (i < 1000) {}
}

fn main() {}
<|endoftext|>


<commit_before><commit_msg>Add test for #7044.<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.

static X: int = 0;
struct X; //~ ERROR error: duplicate definition of value `X`

fn main() {}
<|endoftext|>


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

use convert::TryFrom;
use mem;
use ops::{self, Add, Sub};
use usize;

use super::{FusedIterator, TrustedLen};

/// Objects that can be stepped over in both directions.
///
/// The `steps_between` function provides a way to efficiently compare
/// two `Step` objects.
#[unstable(feature = "step_trait",
           reason = "likely to be replaced by finer-grained traits",
           issue = "42168")]
pub trait Step: Clone + PartialOrd + Sized {
    /// Returns the number of steps between two step objects. The count is
    /// inclusive of `start` and exclusive of `end`.
    ///
    /// Returns `None` if it is not possible to calculate `steps_between`
    /// without overflow.
    fn steps_between(start: &Self, end: &Self) -> Option<usize>;

    /// Replaces this step with `1`, returning itself
    fn replace_one(&mut self) -> Self;

    /// Replaces this step with `0`, returning itself
    fn replace_zero(&mut self) -> Self;

    /// Adds one to this step, returning the result
    fn add_one(&self) -> Self;

    /// Subtracts one to this step, returning the result
    fn sub_one(&self) -> Self;

    /// Add an usize, returning None on overflow
    fn add_usize(&self, n: usize) -> Option<Self>;
}

// These are still macro-generated because the integer literals resolve to different types.
macro_rules! step_identical_methods {
    () => {
        #[inline]
        fn replace_one(&mut self) -> Self {
            mem::replace(self, 1)
        }

        #[inline]
        fn replace_zero(&mut self) -> Self {
            mem::replace(self, 0)
        }

        #[inline]
        fn add_one(&self) -> Self {
            Add::add(*self, 1)
        }

        #[inline]
        fn sub_one(&self) -> Self {
            Sub::sub(*self, 1)
        }
    }
}

macro_rules! step_impl_unsigned {
    ($($t:ty)*) => ($(
        #[unstable(feature = "step_trait",
                   reason = "likely to be replaced by finer-grained traits",
                   issue = "42168")]
        impl Step for $t {
            #[inline]
            #[allow(trivial_numeric_casts)]
            fn steps_between(start: &$t, end: &$t) -> Option<usize> {
                if *start < *end {
                    // Note: We assume $t <= usize here
                    Some((*end - *start) as usize)
                } else {
                    Some(0)
                }
            }

            #[inline]
            #[allow(unreachable_patterns)]
            fn add_usize(&self, n: usize) -> Option<Self> {
                match <$t>::try_from(n) {
                    Ok(n_as_t) => self.checked_add(n_as_t),
                    Err(_) => None,
                }
            }

            step_identical_methods!();
        }
    )*)
}
macro_rules! step_impl_signed {
    ($( [$t:ty : $unsigned:ty] )*) => ($(
        #[unstable(feature = "step_trait",
                   reason = "likely to be replaced by finer-grained traits",
                   issue = "42168")]
        impl Step for $t {
            #[inline]
            #[allow(trivial_numeric_casts)]
            fn steps_between(start: &$t, end: &$t) -> Option<usize> {
                if *start < *end {
                    // Note: We assume $t <= isize here
                    // Use .wrapping_sub and cast to usize to compute the
                    // difference that may not fit inside the range of isize.
                    Some((*end as isize).wrapping_sub(*start as isize) as usize)
                } else {
                    Some(0)
                }
            }

            #[inline]
            #[allow(unreachable_patterns)]
            fn add_usize(&self, n: usize) -> Option<Self> {
                match <$unsigned>::try_from(n) {
                    Ok(n_as_unsigned) => {
                        // Wrapping in unsigned space handles cases like
                        // `-120_i8.add_usize(200) == Some(80_i8)`,
                        // even though 200_usize is out of range for i8.
                        let wrapped = (*self as $unsigned).wrapping_add(n_as_unsigned) as $t;
                        if wrapped >= *self {
                            Some(wrapped)
                        } else {
                            None  // Addition overflowed
                        }
                    }
                    Err(_) => None,
                }
            }

            step_identical_methods!();
        }
    )*)
}

macro_rules! step_impl_no_between {
    ($($t:ty)*) => ($(
        #[unstable(feature = "step_trait",
                   reason = "likely to be replaced by finer-grained traits",
                   issue = "42168")]
        impl Step for $t {
            #[inline]
            fn steps_between(_start: &Self, _end: &Self) -> Option<usize> {
                None
            }

            #[inline]
            fn add_usize(&self, n: usize) -> Option<Self> {
                self.checked_add(n as $t)
            }

            step_identical_methods!();
        }
    )*)
}

step_impl_unsigned!(usize u8 u16 u32);
step_impl_signed!([isize: usize] [i8: u8] [i16: u16] [i32: u32]);
#[cfg(target_pointer_width = "64")]
step_impl_unsigned!(u64);
#[cfg(target_pointer_width = "64")]
step_impl_signed!([i64: u64]);
// If the target pointer width is not 64-bits, we
// assume here that it is less than 64-bits.
#[cfg(not(target_pointer_width = "64"))]
step_impl_no_between!(u64 i64);
step_impl_no_between!(u128 i128);

macro_rules! range_exact_iter_impl {
    ($($t:ty)*) => ($(
        #[stable(feature = "rust1", since = "1.0.0")]
        impl ExactSizeIterator for ops::Range<$t> { }
    )*)
}

macro_rules! range_incl_exact_iter_impl {
    ($($t:ty)*) => ($(
        #[unstable(feature = "inclusive_range",
                   reason = "recently added, follows RFC",
                   issue = "28237")]
        impl ExactSizeIterator for ops::RangeInclusive<$t> { }
    )*)
}

macro_rules! range_trusted_len_impl {
    ($($t:ty)*) => ($(
        #[unstable(feature = "trusted_len", issue = "37572")]
        unsafe impl TrustedLen for ops::Range<$t> { }
    )*)
}

macro_rules! range_incl_trusted_len_impl {
    ($($t:ty)*) => ($(
        #[unstable(feature = "inclusive_range",
                   reason = "recently added, follows RFC",
                   issue = "28237")]
        unsafe impl TrustedLen for ops::RangeInclusive<$t> { }
    )*)
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Step> Iterator for ops::Range<A> {
    type Item = A;

    #[inline]
    fn next(&mut self) -> Option<A> {
        if self.start < self.end {
            // We check for overflow here, even though it can't actually
            // happen. Adding this check does however help llvm vectorize loops
            // for some ranges that don't get vectorized otherwise,
            // and this won't actually result in an extra check in an optimized build.
            if let Some(mut n) = self.start.add_usize(1) {
                mem::swap(&mut n, &mut self.start);
                Some(n)
            } else {
                None
            }
        } else {
            None
        }
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        match Step::steps_between(&self.start, &self.end) {
            Some(hint) => (hint, Some(hint)),
            None => (0, None)
        }
    }

    #[inline]
    fn nth(&mut self, n: usize) -> Option<A> {
        if let Some(plus_n) = self.start.add_usize(n) {
            if plus_n < self.end {
                self.start = plus_n.add_one();
                return Some(plus_n)
            }
        }

        self.start = self.end.clone();
        None
    }

    #[inline]
    fn max(self) -> Option<A> {
        if self.start != self.end {
            Some(self.end.sub_one())
        } else { None }
    }
}

// These macros generate `ExactSizeIterator` impls for various range types.
// Range<{u,i}64> and RangeInclusive<{u,i}{32,64,size}> are excluded
// because they cannot guarantee having a length <= usize::MAX, which is
// required by ExactSizeIterator.
range_exact_iter_impl!(usize u8 u16 u32 isize i8 i16 i32);
range_incl_exact_iter_impl!(u8 u16 i8 i16);

// These macros generate `TrustedLen` impls.
//
// They need to guarantee that .size_hint() is either exact, or that
// the upper bound is None when it does not fit the type limits.
range_trusted_len_impl!(usize isize u8 i8 u16 i16 u32 i32 i64 u64);
range_incl_trusted_len_impl!(usize isize u8 i8 u16 i16 u32 i32 i64 u64);

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Step> DoubleEndedIterator for ops::Range<A> {
    #[inline]
    fn next_back(&mut self) -> Option<A> {
        if self.start < self.end {
            self.end = self.end.sub_one();
            Some(self.end.clone())
        } else {
            None
        }
    }
}

#[unstable(feature = "fused", issue = "35602")]
impl<A: Step> FusedIterator for ops::Range<A> {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Step> Iterator for ops::RangeFrom<A> {
    type Item = A;

    #[inline]
    fn next(&mut self) -> Option<A> {
        let mut n = self.start.add_one();
        mem::swap(&mut n, &mut self.start);
        Some(n)
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        (usize::MAX, None)
    }

    #[inline]
    fn nth(&mut self, n: usize) -> Option<A> {
        let plus_n = self.start.add_usize(n).expect("overflow in RangeFrom::nth");
        self.start = plus_n.add_one();
        Some(plus_n)
    }
}

#[unstable(feature = "fused", issue = "35602")]
impl<A: Step> FusedIterator for ops::RangeFrom<A> {}

#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
impl<A: Step> Iterator for ops::RangeInclusive<A> {
    type Item = A;

    #[inline]
    fn next(&mut self) -> Option<A> {
        use cmp::Ordering::*;

        match self.start.partial_cmp(&self.end) {
            Some(Less) => {
                let n = self.start.add_one();
                Some(mem::replace(&mut self.start, n))
            },
            Some(Equal) => {
                let last = self.start.replace_one();
                self.end.replace_zero();
                Some(last)
            },
            _ => None,
        }
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        if !(self.start <= self.end) {
            return (0, Some(0));
        }

        match Step::steps_between(&self.start, &self.end) {
            Some(hint) => (hint.saturating_add(1), hint.checked_add(1)),
            None => (0, None),
        }
    }

    #[inline]
    fn nth(&mut self, n: usize) -> Option<A> {
        if let Some(plus_n) = self.start.add_usize(n) {
            use cmp::Ordering::*;

            match plus_n.partial_cmp(&self.end) {
                Some(Less) => {
                    self.start = plus_n.add_one();
                    return Some(plus_n)
                }
                Some(Equal) => {
                    self.start.replace_one();
                    self.end.replace_zero();
                    return Some(plus_n)
                }
                _ => {}
            }
        }

        self.start.replace_one();
        self.end.replace_zero();
        None
    }

    #[inline]
    fn last(self) -> Option<A> {
        if self.start <= self.end {
            Some(self.end)
        } else { None }
    }

    #[inline]
    fn min(self) -> Option<A> {
        if self.start <= self.end {
            Some(self.start)
        } else { None }
    }

    #[inline]
    fn max(self) -> Option<A> {
        if self.start <= self.end {
            Some(self.end)
        } else { None }
    }
}

#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> {
    #[inline]
    fn next_back(&mut self) -> Option<A> {
        use cmp::Ordering::*;

        match self.start.partial_cmp(&self.end) {
            Some(Less) => {
                let n = self.end.sub_one();
                Some(mem::replace(&mut self.end, n))
            },
            Some(Equal) => {
                let last = self.end.replace_zero();
                self.start.replace_one();
                Some(last)
            },
            _ => None,
        }
    }
}

#[unstable(feature = "fused", issue = "35602")]
impl<A: Step> FusedIterator for ops::RangeInclusive<A> {}
<commit_msg>Use `next` and `next_back`<commit_after>// Copyright 2013-2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use convert::TryFrom;
use mem;
use ops::{self, Add, Sub};
use usize;

use super::{FusedIterator, TrustedLen};

/// Objects that can be stepped over in both directions.
///
/// The `steps_between` function provides a way to efficiently compare
/// two `Step` objects.
#[unstable(feature = "step_trait",
           reason = "likely to be replaced by finer-grained traits",
           issue = "42168")]
pub trait Step: Clone + PartialOrd + Sized {
    /// Returns the number of steps between two step objects. The count is
    /// inclusive of `start` and exclusive of `end`.
    ///
    /// Returns `None` if it is not possible to calculate `steps_between`
    /// without overflow.
    fn steps_between(start: &Self, end: &Self) -> Option<usize>;

    /// Replaces this step with `1`, returning itself
    fn replace_one(&mut self) -> Self;

    /// Replaces this step with `0`, returning itself
    fn replace_zero(&mut self) -> Self;

    /// Adds one to this step, returning the result
    fn add_one(&self) -> Self;

    /// Subtracts one to this step, returning the result
    fn sub_one(&self) -> Self;

    /// Add an usize, returning None on overflow
    fn add_usize(&self, n: usize) -> Option<Self>;
}

// These are still macro-generated because the integer literals resolve to different types.
macro_rules! step_identical_methods {
    () => {
        #[inline]
        fn replace_one(&mut self) -> Self {
            mem::replace(self, 1)
        }

        #[inline]
        fn replace_zero(&mut self) -> Self {
            mem::replace(self, 0)
        }

        #[inline]
        fn add_one(&self) -> Self {
            Add::add(*self, 1)
        }

        #[inline]
        fn sub_one(&self) -> Self {
            Sub::sub(*self, 1)
        }
    }
}

macro_rules! step_impl_unsigned {
    ($($t:ty)*) => ($(
        #[unstable(feature = "step_trait",
                   reason = "likely to be replaced by finer-grained traits",
                   issue = "42168")]
        impl Step for $t {
            #[inline]
            #[allow(trivial_numeric_casts)]
            fn steps_between(start: &$t, end: &$t) -> Option<usize> {
                if *start < *end {
                    // Note: We assume $t <= usize here
                    Some((*end - *start) as usize)
                } else {
                    Some(0)
                }
            }

            #[inline]
            #[allow(unreachable_patterns)]
            fn add_usize(&self, n: usize) -> Option<Self> {
                match <$t>::try_from(n) {
                    Ok(n_as_t) => self.checked_add(n_as_t),
                    Err(_) => None,
                }
            }

            step_identical_methods!();
        }
    )*)
}
macro_rules! step_impl_signed {
    ($( [$t:ty : $unsigned:ty] )*) => ($(
        #[unstable(feature = "step_trait",
                   reason = "likely to be replaced by finer-grained traits",
                   issue = "42168")]
        impl Step for $t {
            #[inline]
            #[allow(trivial_numeric_casts)]
            fn steps_between(start: &$t, end: &$t) -> Option<usize> {
                if *start < *end {
                    // Note: We assume $t <= isize here
                    // Use .wrapping_sub and cast to usize to compute the
                    // difference that may not fit inside the range of isize.
                    Some((*end as isize).wrapping_sub(*start as isize) as usize)
                } else {
                    Some(0)
                }
            }

            #[inline]
            #[allow(unreachable_patterns)]
            fn add_usize(&self, n: usize) -> Option<Self> {
                match <$unsigned>::try_from(n) {
                    Ok(n_as_unsigned) => {
                        // Wrapping in unsigned space handles cases like
                        // `-120_i8.add_usize(200) == Some(80_i8)`,
                        // even though 200_usize is out of range for i8.
                        let wrapped = (*self as $unsigned).wrapping_add(n_as_unsigned) as $t;
                        if wrapped >= *self {
                            Some(wrapped)
                        } else {
                            None  // Addition overflowed
                        }
                    }
                    Err(_) => None,
                }
            }

            step_identical_methods!();
        }
    )*)
}

macro_rules! step_impl_no_between {
    ($($t:ty)*) => ($(
        #[unstable(feature = "step_trait",
                   reason = "likely to be replaced by finer-grained traits",
                   issue = "42168")]
        impl Step for $t {
            #[inline]
            fn steps_between(_start: &Self, _end: &Self) -> Option<usize> {
                None
            }

            #[inline]
            fn add_usize(&self, n: usize) -> Option<Self> {
                self.checked_add(n as $t)
            }

            step_identical_methods!();
        }
    )*)
}

step_impl_unsigned!(usize u8 u16 u32);
step_impl_signed!([isize: usize] [i8: u8] [i16: u16] [i32: u32]);
#[cfg(target_pointer_width = "64")]
step_impl_unsigned!(u64);
#[cfg(target_pointer_width = "64")]
step_impl_signed!([i64: u64]);
// If the target pointer width is not 64-bits, we
// assume here that it is less than 64-bits.
#[cfg(not(target_pointer_width = "64"))]
step_impl_no_between!(u64 i64);
step_impl_no_between!(u128 i128);

macro_rules! range_exact_iter_impl {
    ($($t:ty)*) => ($(
        #[stable(feature = "rust1", since = "1.0.0")]
        impl ExactSizeIterator for ops::Range<$t> { }
    )*)
}

macro_rules! range_incl_exact_iter_impl {
    ($($t:ty)*) => ($(
        #[unstable(feature = "inclusive_range",
                   reason = "recently added, follows RFC",
                   issue = "28237")]
        impl ExactSizeIterator for ops::RangeInclusive<$t> { }
    )*)
}

macro_rules! range_trusted_len_impl {
    ($($t:ty)*) => ($(
        #[unstable(feature = "trusted_len", issue = "37572")]
        unsafe impl TrustedLen for ops::Range<$t> { }
    )*)
}

macro_rules! range_incl_trusted_len_impl {
    ($($t:ty)*) => ($(
        #[unstable(feature = "inclusive_range",
                   reason = "recently added, follows RFC",
                   issue = "28237")]
        unsafe impl TrustedLen for ops::RangeInclusive<$t> { }
    )*)
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Step> Iterator for ops::Range<A> {
    type Item = A;

    #[inline]
    fn next(&mut self) -> Option<A> {
        if self.start < self.end {
            // We check for overflow here, even though it can't actually
            // happen. Adding this check does however help llvm vectorize loops
            // for some ranges that don't get vectorized otherwise,
            // and this won't actually result in an extra check in an optimized build.
            if let Some(mut n) = self.start.add_usize(1) {
                mem::swap(&mut n, &mut self.start);
                Some(n)
            } else {
                None
            }
        } else {
            None
        }
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        match Step::steps_between(&self.start, &self.end) {
            Some(hint) => (hint, Some(hint)),
            None => (0, None)
        }
    }

    #[inline]
    fn nth(&mut self, n: usize) -> Option<A> {
        if let Some(plus_n) = self.start.add_usize(n) {
            if plus_n < self.end {
                self.start = plus_n.add_one();
                return Some(plus_n)
            }
        }

        self.start = self.end.clone();
        None
    }

    #[inline]
    fn max(mut self) -> Option<A> {
        self.next_back()
    }
}

// These macros generate `ExactSizeIterator` impls for various range types.
// Range<{u,i}64> and RangeInclusive<{u,i}{32,64,size}> are excluded
// because they cannot guarantee having a length <= usize::MAX, which is
// required by ExactSizeIterator.
range_exact_iter_impl!(usize u8 u16 u32 isize i8 i16 i32);
range_incl_exact_iter_impl!(u8 u16 i8 i16);

// These macros generate `TrustedLen` impls.
//
// They need to guarantee that .size_hint() is either exact, or that
// the upper bound is None when it does not fit the type limits.
range_trusted_len_impl!(usize isize u8 i8 u16 i16 u32 i32 i64 u64);
range_incl_trusted_len_impl!(usize isize u8 i8 u16 i16 u32 i32 i64 u64);

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Step> DoubleEndedIterator for ops::Range<A> {
    #[inline]
    fn next_back(&mut self) -> Option<A> {
        if self.start < self.end {
            self.end = self.end.sub_one();
            Some(self.end.clone())
        } else {
            None
        }
    }
}

#[unstable(feature = "fused", issue = "35602")]
impl<A: Step> FusedIterator for ops::Range<A> {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Step> Iterator for ops::RangeFrom<A> {
    type Item = A;

    #[inline]
    fn next(&mut self) -> Option<A> {
        let mut n = self.start.add_one();
        mem::swap(&mut n, &mut self.start);
        Some(n)
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        (usize::MAX, None)
    }

    #[inline]
    fn nth(&mut self, n: usize) -> Option<A> {
        let plus_n = self.start.add_usize(n).expect("overflow in RangeFrom::nth");
        self.start = plus_n.add_one();
        Some(plus_n)
    }
}

#[unstable(feature = "fused", issue = "35602")]
impl<A: Step> FusedIterator for ops::RangeFrom<A> {}

#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
impl<A: Step> Iterator for ops::RangeInclusive<A> {
    type Item = A;

    #[inline]
    fn next(&mut self) -> Option<A> {
        use cmp::Ordering::*;

        match self.start.partial_cmp(&self.end) {
            Some(Less) => {
                let n = self.start.add_one();
                Some(mem::replace(&mut self.start, n))
            },
            Some(Equal) => {
                let last = self.start.replace_one();
                self.end.replace_zero();
                Some(last)
            },
            _ => None,
        }
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        if !(self.start <= self.end) {
            return (0, Some(0));
        }

        match Step::steps_between(&self.start, &self.end) {
            Some(hint) => (hint.saturating_add(1), hint.checked_add(1)),
            None => (0, None),
        }
    }

    #[inline]
    fn nth(&mut self, n: usize) -> Option<A> {
        if let Some(plus_n) = self.start.add_usize(n) {
            use cmp::Ordering::*;

            match plus_n.partial_cmp(&self.end) {
                Some(Less) => {
                    self.start = plus_n.add_one();
                    return Some(plus_n)
                }
                Some(Equal) => {
                    self.start.replace_one();
                    self.end.replace_zero();
                    return Some(plus_n)
                }
                _ => {}
            }
        }

        self.start.replace_one();
        self.end.replace_zero();
        None
    }

    #[inline]
    fn last(mut self) -> Option<A> {
        self.next_back()
    }

    #[inline]
    fn min(mut self) -> Option<A> {
        self.next()
    }

    #[inline]
    fn max(mut self) -> Option<A> {
        self.next_back()
    }
}

#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> {
    #[inline]
    fn next_back(&mut self) -> Option<A> {
        use cmp::Ordering::*;

        match self.start.partial_cmp(&self.end) {
            Some(Less) => {
                let n = self.end.sub_one();
                Some(mem::replace(&mut self.end, n))
            },
            Some(Equal) => {
                let last = self.end.replace_zero();
                self.start.replace_one();
                Some(last)
            },
            _ => None,
        }
    }
}

#[unstable(feature = "fused", issue = "35602")]
impl<A: Step> FusedIterator for ops::RangeInclusive<A> {}
<|endoftext|>


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

//! A wrapper around any Reader to treat it as an RNG.

use option::{Some, None};
use rt::io::Reader;
use rt::io::ReaderByteConversions;

use rand::Rng;

/// An RNG that reads random bytes straight from a `Reader`. This will
/// work best with an infinite reader, but this is not required.
///
/// It will fail if it there is insufficient data to fulfill a request.
///
/// # Example
///
/// ```rust
/// use std::rand::{reader, Rng};
/// use std::rt::io::mem;
///
/// fn main() {
///     let mut rng = reader::ReaderRng::new(mem::MemReader::new(~[1,2,3,4,5,6,7,8]));
///     println!("{:x}", rng.gen::<uint>());
/// }
/// ```
pub struct ReaderRng<R> {
    priv reader: R
}

impl<R: Reader> ReaderRng<R> {
    /// Create a new `ReaderRng` from a `Reader`.
    pub fn new(r: R) -> ReaderRng<R> {
        ReaderRng {
            reader: r
        }
    }
}

impl<R: Reader> Rng for ReaderRng<R> {
    fn next_u32(&mut self) -> u32 {
        if cfg!(target_endian="little") {
            self.reader.read_le_u32_()
        } else {
            self.reader.read_be_u32_()
        }
    }
    fn next_u64(&mut self) -> u64 {
        if cfg!(target_endian="little") {
            self.reader.read_le_u64_()
        } else {
            self.reader.read_be_u64_()
        }
    }
    fn fill_bytes(&mut self, v: &mut [u8]) {
        if v.len() == 0 { return }
        match self.reader.read(v) {
            Some(n) if n == v.len() => return,
            Some(n) => fail2!("ReaderRng.fill_bytes could not fill buffer: \
                              read {} out of {} bytes.", n, v.len()),
            None => fail2!("ReaderRng.fill_bytes reached eof.")
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use rt::io::mem::MemReader;
    use cast;

    #[test]
    fn test_reader_rng_u64() {
        // transmute from the target to avoid endianness concerns.
        let v = ~[1u64, 2u64, 3u64];
        let bytes: ~[u8] = unsafe {cast::transmute(v)};
        let mut rng = ReaderRng::new(MemReader::new(bytes));

        assert_eq!(rng.next_u64(), 1);
        assert_eq!(rng.next_u64(), 2);
        assert_eq!(rng.next_u64(), 3);
    }
    #[test]
    fn test_reader_rng_u32() {
        // transmute from the target to avoid endianness concerns.
        let v = ~[1u32, 2u32, 3u32];
        let bytes: ~[u8] = unsafe {cast::transmute(v)};
        let mut rng = ReaderRng::new(MemReader::new(bytes));

        assert_eq!(rng.next_u32(), 1);
        assert_eq!(rng.next_u32(), 2);
        assert_eq!(rng.next_u32(), 3);
    }
    #[test]
    fn test_reader_rng_fill_bytes() {
        let v = [1u8, 2, 3, 4, 5, 6, 7, 8];
        let mut w = [0u8, .. 8];

        let mut rng = ReaderRng::new(MemReader::new(v.to_owned()));
        rng.fill_bytes(w);

        assert_eq!(v, w);
    }

    #[test]
    #[should_fail]
    fn test_reader_rng_insufficient_bytes() {
        let mut rng = ReaderRng::new(MemReader::new(~[]));
        let mut v = [0u8, .. 3];
        rng.fill_bytes(v);
    }
}
<commit_msg>std::rand::reader: describe cfg!(endianness).<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! A wrapper around any Reader to treat it as an RNG.

use option::{Some, None};
use rt::io::Reader;
use rt::io::ReaderByteConversions;

use rand::Rng;

/// An RNG that reads random bytes straight from a `Reader`. This will
/// work best with an infinite reader, but this is not required.
///
/// It will fail if it there is insufficient data to fulfill a request.
///
/// # Example
///
/// ```rust
/// use std::rand::{reader, Rng};
/// use std::rt::io::mem;
///
/// fn main() {
///     let mut rng = reader::ReaderRng::new(mem::MemReader::new(~[1,2,3,4,5,6,7,8]));
///     println!("{:x}", rng.gen::<uint>());
/// }
/// ```
pub struct ReaderRng<R> {
    priv reader: R
}

impl<R: Reader> ReaderRng<R> {
    /// Create a new `ReaderRng` from a `Reader`.
    pub fn new(r: R) -> ReaderRng<R> {
        ReaderRng {
            reader: r
        }
    }
}

impl<R: Reader> Rng for ReaderRng<R> {
    fn next_u32(&mut self) -> u32 {
        // This is designed for speed: reading a LE integer on a LE
        // platform just involves blitting the bytes into the memory
        // of the u32, similarly for BE on BE; avoiding byteswapping.
        if cfg!(target_endian="little") {
            self.reader.read_le_u32_()
        } else {
            self.reader.read_be_u32_()
        }
    }
    fn next_u64(&mut self) -> u64 {
        // see above for explanation.
        if cfg!(target_endian="little") {
            self.reader.read_le_u64_()
        } else {
            self.reader.read_be_u64_()
        }
    }
    fn fill_bytes(&mut self, v: &mut [u8]) {
        if v.len() == 0 { return }
        match self.reader.read(v) {
            Some(n) if n == v.len() => return,
            Some(n) => fail2!("ReaderRng.fill_bytes could not fill buffer: \
                              read {} out of {} bytes.", n, v.len()),
            None => fail2!("ReaderRng.fill_bytes reached eof.")
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use rt::io::mem::MemReader;
    use cast;

    #[test]
    fn test_reader_rng_u64() {
        // transmute from the target to avoid endianness concerns.
        let v = ~[1u64, 2u64, 3u64];
        let bytes: ~[u8] = unsafe {cast::transmute(v)};
        let mut rng = ReaderRng::new(MemReader::new(bytes));

        assert_eq!(rng.next_u64(), 1);
        assert_eq!(rng.next_u64(), 2);
        assert_eq!(rng.next_u64(), 3);
    }
    #[test]
    fn test_reader_rng_u32() {
        // transmute from the target to avoid endianness concerns.
        let v = ~[1u32, 2u32, 3u32];
        let bytes: ~[u8] = unsafe {cast::transmute(v)};
        let mut rng = ReaderRng::new(MemReader::new(bytes));

        assert_eq!(rng.next_u32(), 1);
        assert_eq!(rng.next_u32(), 2);
        assert_eq!(rng.next_u32(), 3);
    }
    #[test]
    fn test_reader_rng_fill_bytes() {
        let v = [1u8, 2, 3, 4, 5, 6, 7, 8];
        let mut w = [0u8, .. 8];

        let mut rng = ReaderRng::new(MemReader::new(v.to_owned()));
        rng.fill_bytes(w);

        assert_eq!(v, w);
    }

    #[test]
    #[should_fail]
    fn test_reader_rng_insufficient_bytes() {
        let mut rng = ReaderRng::new(MemReader::new(~[]));
        let mut v = [0u8, .. 3];
        rng.fill_bytes(v);
    }
}
<|endoftext|>


<commit_before><commit_msg>Rename variables<commit_after><|endoftext|>