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

/*!

The `ToBytes` and `IterBytes` traits

*/

use cast;
use container::Container;
use iter::Iterator;
use option::{None, Option, Some};
use str::{Str, StrSlice};
use vec::{Vector, ImmutableVector};

pub type Cb<'self> = &'self fn(buf: &[u8]) -> bool;

///
/// A trait to implement in order to make a type hashable;
/// This works in combination with the trait `std::hash::Hash`, and
/// may in the future be merged with that trait or otherwise
/// modified when default methods and trait inheritance are
/// completed.
///
/// IterBytes should be implemented so that the extent of the
/// produced byte stream can be discovered, given the original
/// type.
/// For example, the IterBytes implementation for vectors emits
/// its length first, and enums should emit their discriminant.
///
pub trait IterBytes {
    /// Call the provided callback `f` one or more times with
    /// byte-slices that should be used when computing a hash
    /// value or otherwise "flattening" the structure into
    /// a sequence of bytes. The `lsb0` parameter conveys
    /// whether the caller is asking for little-endian bytes
    /// (`true`) or big-endian (`false`); this should only be
    /// relevant in implementations that represent a single
    /// multi-byte datum such as a 32 bit integer or 64 bit
    /// floating-point value. It can be safely ignored for
    /// larger structured types as they are usually processed
    /// left-to-right in declaration order, regardless of
    /// underlying memory endianness.
    ///
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool;
}

impl IterBytes for bool {
    #[inline]
    fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool {
        f([
            *self as u8
        ])
    }
}

impl IterBytes for u8 {
    #[inline]
    fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool {
        f([
            *self
        ])
    }
}

impl IterBytes for u16 {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        if lsb0 {
            f([
                *self as u8,
                (*self >> 8) as u8
            ])
        } else {
            f([
                (*self >> 8) as u8,
                *self as u8
            ])
        }
    }
}

impl IterBytes for u32 {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        if lsb0 {
            f([
                *self as u8,
                (*self >> 8) as u8,
                (*self >> 16) as u8,
                (*self >> 24) as u8,
            ])
        } else {
            f([
                (*self >> 24) as u8,
                (*self >> 16) as u8,
                (*self >> 8) as u8,
                *self as u8
            ])
        }
    }
}

impl IterBytes for u64 {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        if lsb0 {
            f([
                *self as u8,
                (*self >> 8) as u8,
                (*self >> 16) as u8,
                (*self >> 24) as u8,
                (*self >> 32) as u8,
                (*self >> 40) as u8,
                (*self >> 48) as u8,
                (*self >> 56) as u8
            ])
        } else {
            f([
                (*self >> 56) as u8,
                (*self >> 48) as u8,
                (*self >> 40) as u8,
                (*self >> 32) as u8,
                (*self >> 24) as u8,
                (*self >> 16) as u8,
                (*self >> 8) as u8,
                *self as u8
            ])
        }
    }
}

impl IterBytes for i8 {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        (*self as u8).iter_bytes(lsb0, f)
    }
}

impl IterBytes for i16 {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        (*self as u16).iter_bytes(lsb0, f)
    }
}

impl IterBytes for i32 {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        (*self as u32).iter_bytes(lsb0, f)
    }
}

impl IterBytes for i64 {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        (*self as u64).iter_bytes(lsb0, f)
    }
}

impl IterBytes for char {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        (*self as u32).iter_bytes(lsb0, f)
    }
}

#[cfg(target_word_size = "32")]
impl IterBytes for uint {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        (*self as u32).iter_bytes(lsb0, f)
    }
}

#[cfg(target_word_size = "64")]
impl IterBytes for uint {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        (*self as u64).iter_bytes(lsb0, f)
    }
}

impl IterBytes for int {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        (*self as uint).iter_bytes(lsb0, f)
    }
}

impl IterBytes for f32 {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        let i: u32 = unsafe {
            // 0.0 == -0.0 so they should also have the same hashcode
            cast::transmute(if *self == -0.0 { 0.0 } else { *self })
        };
        i.iter_bytes(lsb0, f)
    }
}

impl IterBytes for f64 {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        let i: u64 = unsafe {
            // 0.0 == -0.0 so they should also have the same hashcode
            cast::transmute(if *self == -0.0 { 0.0 } else { *self })
        };
        i.iter_bytes(lsb0, f)
    }
}

impl<'self,A:IterBytes> IterBytes for &'self [A] {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        self.len().iter_bytes(lsb0, |b| f(b)) &&
        self.iter().advance(|elt| elt.iter_bytes(lsb0, |b| f(b)))
    }
}

impl<A: IterBytes> IterBytes for (A, ) {
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        match *self {
            (ref a, ) => a.iter_bytes(lsb0, |b| f(b))
        }
    }
}

macro_rules! iter_bytes_tuple(
    ($($A:ident),+) => (
        impl<$($A: IterBytes),+> IterBytes for ($($A),+) {
            fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
                match *self {
                    ($(ref $A),+) => {
                        $(
                            $A .iter_bytes(lsb0, |b| f(b))
                        )&&+
                    }
                }
            }
        }
    )
)

iter_bytes_tuple!(A, B)
iter_bytes_tuple!(A, B, C)
iter_bytes_tuple!(A, B, C, D)
iter_bytes_tuple!(A, B, C, D, E)
iter_bytes_tuple!(A, B, C, D, E, F)
iter_bytes_tuple!(A, B, C, D, E, F, G)
iter_bytes_tuple!(A, B, C, D, E, F, G, H)

impl<A:IterBytes> IterBytes for ~[A] {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        self.as_slice().iter_bytes(lsb0, f)
    }
}

impl<A:IterBytes> IterBytes for @[A] {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        self.as_slice().iter_bytes(lsb0, f)
    }
}

impl<'self> IterBytes for &'self str {
    #[inline]
    fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool {
        // Terminate the string with a byte that does not appear in UTF-8
        f(self.as_bytes()) && f([0xFF])
    }
}

impl IterBytes for ~str {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        self.as_slice().iter_bytes(lsb0, f)
    }
}

impl IterBytes for @str {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        self.as_slice().iter_bytes(lsb0, f)
    }
}

impl<A:IterBytes> IterBytes for Option<A> {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        match *self {
          Some(ref a) => 0u8.iter_bytes(lsb0, |b| f(b)) && a.iter_bytes(lsb0, |b| f(b)),
          None => 1u8.iter_bytes(lsb0, f)
        }
    }
}

impl<'self,A:IterBytes> IterBytes for &'self A {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        (**self).iter_bytes(lsb0, f)
    }
}

impl<A:IterBytes> IterBytes for @A {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        (**self).iter_bytes(lsb0, f)
    }
}

impl<A:IterBytes> IterBytes for @mut A {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        (**self).iter_bytes(lsb0, f)
    }
}

impl<A:IterBytes> IterBytes for ~A {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        (**self).iter_bytes(lsb0, f)
    }
}

// NB: raw-pointer IterBytes does _not_ dereference
// to the target; it just gives you the pointer-bytes.
impl<A> IterBytes for *A {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        (*self as uint).iter_bytes(lsb0, f)
    }
}

impl<A> IterBytes for *mut A {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        (*self as uint).iter_bytes(lsb0, f)
    }
}

/// A trait for converting a value to a list of bytes.
pub trait ToBytes {
    /// Converts the current value to a list of bytes. This is equivalent to
    /// invoking iter_bytes on a type and collecting all yielded values in an
    /// array
    fn to_bytes(&self, lsb0: bool) -> ~[u8];
}

impl<A:IterBytes> ToBytes for A {
    fn to_bytes(&self, lsb0: bool) -> ~[u8] {
        use io::mem;
        use io::Writer;

        do mem::with_mem_writer |wr| {
            do self.iter_bytes(lsb0) |bytes| {
                wr.write(bytes);
                true
            };
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;
    // just test to see if it compiles:
    #[test] fn iterbytes_compiles () {
        takes_iterbytes((3,4,5,false));
    }
    fn takes_iterbytes<T : IterBytes>(_x : T) {}
}
<commit_msg>Implement IterBytes for Rc<T>.<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.

/*!

The `ToBytes` and `IterBytes` traits

*/

use cast;
use container::Container;
use iter::Iterator;
use option::{None, Option, Some};
use rc::Rc;
use str::{Str, StrSlice};
use vec::{Vector, ImmutableVector};

pub type Cb<'self> = &'self fn(buf: &[u8]) -> bool;

///
/// A trait to implement in order to make a type hashable;
/// This works in combination with the trait `std::hash::Hash`, and
/// may in the future be merged with that trait or otherwise
/// modified when default methods and trait inheritance are
/// completed.
///
/// IterBytes should be implemented so that the extent of the
/// produced byte stream can be discovered, given the original
/// type.
/// For example, the IterBytes implementation for vectors emits
/// its length first, and enums should emit their discriminant.
///
pub trait IterBytes {
    /// Call the provided callback `f` one or more times with
    /// byte-slices that should be used when computing a hash
    /// value or otherwise "flattening" the structure into
    /// a sequence of bytes. The `lsb0` parameter conveys
    /// whether the caller is asking for little-endian bytes
    /// (`true`) or big-endian (`false`); this should only be
    /// relevant in implementations that represent a single
    /// multi-byte datum such as a 32 bit integer or 64 bit
    /// floating-point value. It can be safely ignored for
    /// larger structured types as they are usually processed
    /// left-to-right in declaration order, regardless of
    /// underlying memory endianness.
    ///
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool;
}

impl IterBytes for bool {
    #[inline]
    fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool {
        f([
            *self as u8
        ])
    }
}

impl IterBytes for u8 {
    #[inline]
    fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool {
        f([
            *self
        ])
    }
}

impl IterBytes for u16 {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        if lsb0 {
            f([
                *self as u8,
                (*self >> 8) as u8
            ])
        } else {
            f([
                (*self >> 8) as u8,
                *self as u8
            ])
        }
    }
}

impl IterBytes for u32 {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        if lsb0 {
            f([
                *self as u8,
                (*self >> 8) as u8,
                (*self >> 16) as u8,
                (*self >> 24) as u8,
            ])
        } else {
            f([
                (*self >> 24) as u8,
                (*self >> 16) as u8,
                (*self >> 8) as u8,
                *self as u8
            ])
        }
    }
}

impl IterBytes for u64 {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        if lsb0 {
            f([
                *self as u8,
                (*self >> 8) as u8,
                (*self >> 16) as u8,
                (*self >> 24) as u8,
                (*self >> 32) as u8,
                (*self >> 40) as u8,
                (*self >> 48) as u8,
                (*self >> 56) as u8
            ])
        } else {
            f([
                (*self >> 56) as u8,
                (*self >> 48) as u8,
                (*self >> 40) as u8,
                (*self >> 32) as u8,
                (*self >> 24) as u8,
                (*self >> 16) as u8,
                (*self >> 8) as u8,
                *self as u8
            ])
        }
    }
}

impl IterBytes for i8 {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        (*self as u8).iter_bytes(lsb0, f)
    }
}

impl IterBytes for i16 {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        (*self as u16).iter_bytes(lsb0, f)
    }
}

impl IterBytes for i32 {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        (*self as u32).iter_bytes(lsb0, f)
    }
}

impl IterBytes for i64 {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        (*self as u64).iter_bytes(lsb0, f)
    }
}

impl IterBytes for char {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        (*self as u32).iter_bytes(lsb0, f)
    }
}

#[cfg(target_word_size = "32")]
impl IterBytes for uint {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        (*self as u32).iter_bytes(lsb0, f)
    }
}

#[cfg(target_word_size = "64")]
impl IterBytes for uint {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        (*self as u64).iter_bytes(lsb0, f)
    }
}

impl IterBytes for int {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        (*self as uint).iter_bytes(lsb0, f)
    }
}

impl IterBytes for f32 {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        let i: u32 = unsafe {
            // 0.0 == -0.0 so they should also have the same hashcode
            cast::transmute(if *self == -0.0 { 0.0 } else { *self })
        };
        i.iter_bytes(lsb0, f)
    }
}

impl IterBytes for f64 {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        let i: u64 = unsafe {
            // 0.0 == -0.0 so they should also have the same hashcode
            cast::transmute(if *self == -0.0 { 0.0 } else { *self })
        };
        i.iter_bytes(lsb0, f)
    }
}

impl<'self,A:IterBytes> IterBytes for &'self [A] {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        self.len().iter_bytes(lsb0, |b| f(b)) &&
        self.iter().advance(|elt| elt.iter_bytes(lsb0, |b| f(b)))
    }
}

impl<A: IterBytes> IterBytes for (A, ) {
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        match *self {
            (ref a, ) => a.iter_bytes(lsb0, |b| f(b))
        }
    }
}

macro_rules! iter_bytes_tuple(
    ($($A:ident),+) => (
        impl<$($A: IterBytes),+> IterBytes for ($($A),+) {
            fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
                match *self {
                    ($(ref $A),+) => {
                        $(
                            $A .iter_bytes(lsb0, |b| f(b))
                        )&&+
                    }
                }
            }
        }
    )
)

iter_bytes_tuple!(A, B)
iter_bytes_tuple!(A, B, C)
iter_bytes_tuple!(A, B, C, D)
iter_bytes_tuple!(A, B, C, D, E)
iter_bytes_tuple!(A, B, C, D, E, F)
iter_bytes_tuple!(A, B, C, D, E, F, G)
iter_bytes_tuple!(A, B, C, D, E, F, G, H)

impl<A:IterBytes> IterBytes for ~[A] {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        self.as_slice().iter_bytes(lsb0, f)
    }
}

impl<A:IterBytes> IterBytes for @[A] {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        self.as_slice().iter_bytes(lsb0, f)
    }
}

impl<'self> IterBytes for &'self str {
    #[inline]
    fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool {
        // Terminate the string with a byte that does not appear in UTF-8
        f(self.as_bytes()) && f([0xFF])
    }
}

impl IterBytes for ~str {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        self.as_slice().iter_bytes(lsb0, f)
    }
}

impl IterBytes for @str {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        self.as_slice().iter_bytes(lsb0, f)
    }
}

impl<A:IterBytes> IterBytes for Option<A> {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        match *self {
          Some(ref a) => 0u8.iter_bytes(lsb0, |b| f(b)) && a.iter_bytes(lsb0, |b| f(b)),
          None => 1u8.iter_bytes(lsb0, f)
        }
    }
}

impl<'self,A:IterBytes> IterBytes for &'self A {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        (**self).iter_bytes(lsb0, f)
    }
}

impl<A:IterBytes> IterBytes for @A {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        (**self).iter_bytes(lsb0, f)
    }
}

impl<A:IterBytes> IterBytes for @mut A {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        (**self).iter_bytes(lsb0, f)
    }
}

impl<A:IterBytes> IterBytes for Rc<A> {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        self.borrow().iter_bytes(lsb0, f)
    }
}

impl<A:IterBytes> IterBytes for ~A {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        (**self).iter_bytes(lsb0, f)
    }
}

// NB: raw-pointer IterBytes does _not_ dereference
// to the target; it just gives you the pointer-bytes.
impl<A> IterBytes for *A {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        (*self as uint).iter_bytes(lsb0, f)
    }
}

impl<A> IterBytes for *mut A {
    #[inline]
    fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
        (*self as uint).iter_bytes(lsb0, f)
    }
}

/// A trait for converting a value to a list of bytes.
pub trait ToBytes {
    /// Converts the current value to a list of bytes. This is equivalent to
    /// invoking iter_bytes on a type and collecting all yielded values in an
    /// array
    fn to_bytes(&self, lsb0: bool) -> ~[u8];
}

impl<A:IterBytes> ToBytes for A {
    fn to_bytes(&self, lsb0: bool) -> ~[u8] {
        use io::mem;
        use io::Writer;

        do mem::with_mem_writer |wr| {
            do self.iter_bytes(lsb0) |bytes| {
                wr.write(bytes);
                true
            };
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;
    // just test to see if it compiles:
    #[test] fn iterbytes_compiles () {
        takes_iterbytes((3,4,5,false));
    }
    fn takes_iterbytes<T : IterBytes>(_x : T) {}
}
<|endoftext|>


<commit_before>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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 layers;
use layers::{ARGB32Format, ContainerLayerKind, TextureLayerKind, Image, ImageLayerKind, RGB24Format};
use layers::{TiledImageLayerKind};
use scene::Scene;

use geom::matrix::{Matrix4, ortho};
use opengles::gl2::{ARRAY_BUFFER, COLOR_BUFFER_BIT, CLAMP_TO_EDGE, COMPILE_STATUS};
use opengles::gl2::{FRAGMENT_SHADER, LINK_STATUS, LINEAR, NO_ERROR, RGB, RGBA, BGRA};
use opengles::gl2::{STATIC_DRAW, TEXTURE_2D, TEXTURE_MAG_FILTER, TEXTURE_MIN_FILTER};
use opengles::gl2::{TEXTURE_WRAP_S, TEXTURE_WRAP_T, TEXTURE0};
use opengles::gl2::{TRIANGLE_STRIP, UNPACK_ALIGNMENT, UNPACK_CLIENT_STORAGE_APPLE};
use opengles::gl2::{UNPACK_ROW_LENGTH, UNSIGNED_BYTE, UNSIGNED_INT_8_8_8_8_REV, VERTEX_SHADER};
use opengles::gl2::{GLenum, GLint, GLsizei, GLuint, attach_shader, bind_buffer};
use opengles::gl2::{bind_texture, buffer_data, create_program, clear, clear_color};
use opengles::gl2::{compile_shader, create_shader, draw_arrays, enable};
use opengles::gl2::{enable_vertex_attrib_array, gen_buffers, gen_textures};
use opengles::gl2::{get_attrib_location, get_error, get_program_iv};
use opengles::gl2::{get_shader_info_log, get_shader_iv, active_texture};
use opengles::gl2::{get_uniform_location, link_program, pixel_store_i, shader_source};
use opengles::gl2::{tex_image_2d, tex_parameter_i, uniform_1i, uniform_matrix_4fv, use_program};
use opengles::gl2::{vertex_attrib_pointer_f32, viewport};

use std::libc::c_int;

pub fn FRAGMENT_SHADER_SOURCE() -> ~str {
    ~"
        #ifdef GLES2
            precision mediump float;
        #endif

        varying vec2 vTextureCoord;

        uniform sampler2D uSampler;

        void main(void) {
            gl_FragColor = texture2D(uSampler, vTextureCoord);
        }
    "
}

pub fn VERTEX_SHADER_SOURCE() -> ~str {
    ~"
        attribute vec3 aVertexPosition;
        attribute vec2 aTextureCoord;

        uniform mat4 uMVMatrix;
        uniform mat4 uPMatrix;

        varying vec2 vTextureCoord;

        void main(void) {
            gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
            vTextureCoord = aTextureCoord;
        }
    "
}

pub fn load_shader(source_string: ~str, shader_type: GLenum) -> GLuint {
    let shader_id = create_shader(shader_type);
    shader_source(shader_id, [ source_string.as_bytes().to_owned() ]);
    compile_shader(shader_id);

    if get_error() != NO_ERROR {
        println(fmt!("error: %d", get_error() as int));
        fail!(~"failed to compile shader");
    }

    if get_shader_iv(shader_id, COMPILE_STATUS) == (0 as GLint) {
        println(fmt!("shader info log: %s", get_shader_info_log(shader_id)));
        fail!(~"failed to compile shader");
    }

    return shader_id;
}

pub struct RenderContext {
    program: GLuint,
    vertex_position_attr: c_int,
    texture_coord_attr: c_int,
    modelview_uniform: c_int,
    projection_uniform: c_int,
    sampler_uniform: c_int,
    vertex_buffer: GLuint,
    texture_coord_buffer: GLuint,
}

pub fn RenderContext(program: GLuint) -> RenderContext {
    let (vertex_buffer, texture_coord_buffer) = init_buffers();
    let rc = RenderContext {
        program: program,
        vertex_position_attr: get_attrib_location(program, ~"aVertexPosition"),
        texture_coord_attr: get_attrib_location(program, ~"aTextureCoord"),
        modelview_uniform: get_uniform_location(program, ~"uMVMatrix"),
        projection_uniform: get_uniform_location(program, ~"uPMatrix"),
        sampler_uniform: get_uniform_location(program, ~"uSampler"),
        vertex_buffer: vertex_buffer,
        texture_coord_buffer: texture_coord_buffer,
    };

    enable_vertex_attrib_array(rc.vertex_position_attr as GLuint);
    enable_vertex_attrib_array(rc.texture_coord_attr as GLuint);

    rc
}

pub fn init_render_context() -> RenderContext {
    let vertex_shader = load_shader(VERTEX_SHADER_SOURCE(), VERTEX_SHADER);
    let fragment_shader = load_shader(FRAGMENT_SHADER_SOURCE(), FRAGMENT_SHADER);

    let program = create_program();
    attach_shader(program, vertex_shader);
    attach_shader(program, fragment_shader);
    link_program(program);

    if get_program_iv(program, LINK_STATUS) == (0 as GLint) {
        fail!(~"failed to initialize program");
    }

    use_program(program);
    enable(TEXTURE_2D);

    return RenderContext(program);
}

pub fn init_buffers() -> (GLuint, GLuint) {
    let triangle_vertex_buffer = gen_buffers(1 as GLsizei)[0];
    bind_buffer(ARRAY_BUFFER, triangle_vertex_buffer);

    let (_0, _1) = (0.0f32, 1.0f32);
    let vertices = ~[
        _0, _0, _0,
        _0, _1, _0,
        _1, _0, _0,
        _1, _1, _0
    ];

    buffer_data(ARRAY_BUFFER, vertices, STATIC_DRAW);

    let texture_coord_buffer = gen_buffers(1 as GLsizei)[0];
    bind_buffer(ARRAY_BUFFER, texture_coord_buffer);

    return (triangle_vertex_buffer, texture_coord_buffer);
}

pub fn create_texture_for_image_if_necessary(image: @mut Image) {
    match image.texture {
        None => {}
        Some(_) => { return; /* Nothing to do. */ }
    }

    let texture = gen_textures(1 as GLsizei)[0];

    //XXXjdm This block is necessary to avoid a task failure that occurs
    //       when |image.data| is borrowed and we mutate |image.texture|.
    {
    let data = &mut image.data;
    debug!("making texture, id=%d, format=%?", texture as int, data.format());

    bind_texture(TEXTURE_2D, texture);

    // FIXME: This makes the lifetime requirements somewhat complex...
    pixel_store_i(UNPACK_CLIENT_STORAGE_APPLE, 1);

    let size = data.size();
    let stride = data.stride() as GLsizei;

    tex_parameter_i(TEXTURE_2D, TEXTURE_MAG_FILTER, LINEAR as GLint);
    tex_parameter_i(TEXTURE_2D, TEXTURE_MIN_FILTER, LINEAR as GLint);

    tex_parameter_i(TEXTURE_2D, TEXTURE_WRAP_S, CLAMP_TO_EDGE as GLint);
    tex_parameter_i(TEXTURE_2D, TEXTURE_WRAP_T, CLAMP_TO_EDGE as GLint);

    // These two are needed for DMA on the Mac. Don't touch them unless you know what you're doing!
    pixel_store_i(UNPACK_ALIGNMENT, 4);
    pixel_store_i(UNPACK_ROW_LENGTH, size.width as GLint);
    if stride % 32 != 0 {
        info!("rust-layers: suggest using stride multiples of 32 for DMA on the Mac");
    }

    debug!("rust-layers stride is %u", stride as uint);

    match data.format() {
        RGB24Format => {
            do data.with_data |data| {
                tex_image_2d(TEXTURE_2D, 0 as GLint, RGB as GLint,
                             size.width as GLsizei, size.height as GLsizei, 0 as GLint, RGB,
                             UNSIGNED_BYTE, Some(data));
            }
        }
        ARGB32Format => {
            do data.with_data |data| {
                tex_image_2d(TEXTURE_2D, 0 as GLint, RGBA as GLint,
                             size.width as GLsizei, size.height as GLsizei, 0 as GLint, BGRA,
                             UNSIGNED_INT_8_8_8_8_REV, Some(data));
            }
        }
    }
    } //XXXjdm This block avoids a segfault. See opening comment.

    image.texture = Some(texture);
}

pub fn bind_and_render_quad(render_context: RenderContext, texture: GLuint) {
    active_texture(TEXTURE0);
    bind_texture(TEXTURE_2D, texture);

    uniform_1i(render_context.sampler_uniform, 0);

    bind_buffer(ARRAY_BUFFER, render_context.vertex_buffer);
    vertex_attrib_pointer_f32(render_context.vertex_position_attr as GLuint, 3, false, 0, 0);

    // Create the texture coordinate array.
    bind_buffer(ARRAY_BUFFER, render_context.texture_coord_buffer);

    let vertices = [
        0.0f32, 1.0f32,
        0.0f32, 0.0f32,
        1.0f32, 1.0f32,
        1.0f32, 0.0f32,
    ];
    buffer_data(ARRAY_BUFFER, vertices, STATIC_DRAW);
    vertex_attrib_pointer_f32(render_context.texture_coord_attr as GLuint, 2, false, 0, 0);
    draw_arrays(TRIANGLE_STRIP, 0, 4);
    bind_texture(TEXTURE_2D, 0);
}

// Layer rendering

pub trait Render {
    fn render(@mut self, render_context: RenderContext, transform: Matrix4<f32>);
}

impl Render for layers::ContainerLayer {
    fn render(@mut self, render_context: RenderContext, transform: Matrix4<f32>) {
        let transform = transform.mul(&self.common.transform);
        for self.each_child |child| {
            render_layer(render_context, transform, child);
        }
    }
}

impl Render for layers::TextureLayer {
    fn render(@mut self, render_context: RenderContext, transform: Matrix4<f32>) {
        let transform = transform.mul(&self.common.transform);
        uniform_matrix_4fv(render_context.modelview_uniform, false, transform.to_array());

        bind_and_render_quad(render_context, self.manager.get_texture());
    }
}

impl Render for layers::ImageLayer {
    fn render(@mut self, render_context: RenderContext, transform: Matrix4<f32>) {
        create_texture_for_image_if_necessary(self.image);

        let transform = transform.mul(&self.common.transform);
        uniform_matrix_4fv(render_context.modelview_uniform, false, transform.to_array());
        bind_and_render_quad(render_context, self.image.texture.get());
    }
}

impl Render for layers::TiledImageLayer {
    fn render(@mut self, render_context: RenderContext, transform: Matrix4<f32>) {
        let tiles_down = self.tiles.len() / self.tiles_across;
        for (*self.tiles).iter().enumerate().advance |(i, tile)| {
            create_texture_for_image_if_necessary(*tile);

            let x = ((i % self.tiles_across) as f32);
            let y = ((i / self.tiles_across) as f32);

            let transform = transform.mul(&self.common.transform);
            let transform = transform.scale(1.0 / (self.tiles_across as f32),
                                            1.0 / (tiles_down as f32),
                                            1.0);
            let transform = transform.translate(x, y, 0.0);

            uniform_matrix_4fv(render_context.modelview_uniform, false, transform.to_array());
            bind_and_render_quad(render_context, tile.texture.get());
        }
    }
}

fn render_layer(render_context: RenderContext, transform: Matrix4<f32>, layer: layers::Layer) {
    match layer {
        ContainerLayerKind(container_layer) => {
            container_layer.render(render_context, transform);
        }
        TextureLayerKind(texture_layer) => {
            texture_layer.render(render_context, transform);
        }
        ImageLayerKind(image_layer) => {
            image_layer.render(render_context, transform);
        }
        TiledImageLayerKind(tiled_image_layer) => {
            tiled_image_layer.render(render_context, transform);
        }
    }
}

pub fn render_scene(render_context: RenderContext, scene: &Scene) {
    // Set the viewport.
    viewport(0 as GLint, 0 as GLint, scene.size.width as GLsizei, scene.size.height as GLsizei);

    // Clear the screen.
    clear_color(0.38f32, 0.36f32, 0.36f32, 1.0f32);
    clear(COLOR_BUFFER_BIT);

    // Set the projection matrix.
    let projection_matrix = ortho(0.0, scene.size.width, scene.size.height, 0.0, -10.0, 10.0);
    uniform_matrix_4fv(render_context.projection_uniform, false, projection_matrix.to_array());

    // Set up the initial modelview matrix.
    let transform = scene.transform;

    // Render the root layer.
    render_layer(render_context, transform, scene.root);
}

<commit_msg>support android build<commit_after>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// 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 layers;
use layers::{ARGB32Format, ContainerLayerKind, TextureLayerKind, Image, ImageLayerKind, RGB24Format};
use layers::{TiledImageLayerKind};
use scene::Scene;

use geom::matrix::{Matrix4, ortho};
use opengles::gl2::{ARRAY_BUFFER, COLOR_BUFFER_BIT, CLAMP_TO_EDGE, COMPILE_STATUS};
use opengles::gl2::{FRAGMENT_SHADER, LINK_STATUS, LINEAR, NO_ERROR, RGB, RGBA, BGRA};
use opengles::gl2::{STATIC_DRAW, TEXTURE_2D, TEXTURE_MAG_FILTER, TEXTURE_MIN_FILTER};
use opengles::gl2::{TEXTURE_WRAP_S, TEXTURE_WRAP_T, TEXTURE0};
use opengles::gl2::{TRIANGLE_STRIP, UNPACK_ALIGNMENT, UNPACK_CLIENT_STORAGE_APPLE};
use opengles::gl2::{UNPACK_ROW_LENGTH, UNSIGNED_BYTE, UNSIGNED_INT_8_8_8_8_REV, VERTEX_SHADER};
use opengles::gl2::{GLenum, GLint, GLsizei, GLuint, attach_shader, bind_buffer};
use opengles::gl2::{bind_texture, buffer_data, create_program, clear, clear_color};
use opengles::gl2::{compile_shader, create_shader, draw_arrays, enable};
use opengles::gl2::{enable_vertex_attrib_array, gen_buffers, gen_textures};
use opengles::gl2::{get_attrib_location, get_error, get_program_iv};
use opengles::gl2::{get_shader_info_log, get_shader_iv, active_texture};
use opengles::gl2::{get_uniform_location, link_program, pixel_store_i, shader_source};
use opengles::gl2::{tex_image_2d, tex_parameter_i, uniform_1i, uniform_matrix_4fv, use_program};
use opengles::gl2::{vertex_attrib_pointer_f32, viewport};

use std::libc::c_int;
use std::libc::c_uint;

pub fn FRAGMENT_SHADER_SOURCE() -> ~str {
    ~"
        #ifdef GL_ES
            precision mediump float;
        #endif

        varying vec2 vTextureCoord;

        uniform sampler2D uSampler;

        void main(void) {
            gl_FragColor = texture2D(uSampler, vTextureCoord);
        }
    "
}

pub fn VERTEX_SHADER_SOURCE() -> ~str {
    ~"
        attribute vec3 aVertexPosition;
        attribute vec2 aTextureCoord;

        uniform mat4 uMVMatrix;
        uniform mat4 uPMatrix;

        varying vec2 vTextureCoord;

        void main(void) {
            gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
            vTextureCoord = aTextureCoord;
        }
    "
}

pub fn load_shader(source_string: ~str, shader_type: GLenum) -> GLuint {
    let shader_id = create_shader(shader_type);
    shader_source(shader_id, [ source_string.as_bytes().to_owned() ]);
    compile_shader(shader_id);

    if get_error() != NO_ERROR {
        println(fmt!("error: %d", get_error() as int));
        fail!(~"failed to compile shader");
    }

    if get_shader_iv(shader_id, COMPILE_STATUS) == (0 as GLint) {
        println(fmt!("shader info log: %s", get_shader_info_log(shader_id)));
        fail!(~"failed to compile shader");
    }

    return shader_id;
}

pub struct RenderContext {
    program: GLuint,
    vertex_position_attr: c_int,
    texture_coord_attr: c_int,
    modelview_uniform: c_int,
    projection_uniform: c_int,
    sampler_uniform: c_int,
    vertex_buffer: GLuint,
    texture_coord_buffer: GLuint,
}

pub fn RenderContext(program: GLuint) -> RenderContext {
    let (vertex_buffer, texture_coord_buffer) = init_buffers();
    let rc = RenderContext {
        program: program,
        vertex_position_attr: get_attrib_location(program, ~"aVertexPosition"),
        texture_coord_attr: get_attrib_location(program, ~"aTextureCoord"),
        modelview_uniform: get_uniform_location(program, ~"uMVMatrix"),
        projection_uniform: get_uniform_location(program, ~"uPMatrix"),
        sampler_uniform: get_uniform_location(program, ~"uSampler"),
        vertex_buffer: vertex_buffer,
        texture_coord_buffer: texture_coord_buffer,
    };

    enable_vertex_attrib_array(rc.vertex_position_attr as GLuint);
    enable_vertex_attrib_array(rc.texture_coord_attr as GLuint);

    rc
}

pub fn init_render_context() -> RenderContext {
    let vertex_shader = load_shader(VERTEX_SHADER_SOURCE(), VERTEX_SHADER);
    let fragment_shader = load_shader(FRAGMENT_SHADER_SOURCE(), FRAGMENT_SHADER);

    let program = create_program();
    attach_shader(program, vertex_shader);
    attach_shader(program, fragment_shader);
    link_program(program);

    if get_program_iv(program, LINK_STATUS) == (0 as GLint) {
        fail!(~"failed to initialize program");
    }

    use_program(program);
    enable(TEXTURE_2D);

    return RenderContext(program);
}

pub fn init_buffers() -> (GLuint, GLuint) {
    let triangle_vertex_buffer = gen_buffers(1 as GLsizei)[0];
    bind_buffer(ARRAY_BUFFER, triangle_vertex_buffer);

    let (_0, _1) = (0.0f32, 1.0f32);
    let vertices = ~[
        _0, _0, _0,
        _0, _1, _0,
        _1, _0, _0,
        _1, _1, _0
    ];

    buffer_data(ARRAY_BUFFER, vertices, STATIC_DRAW);

    let texture_coord_buffer = gen_buffers(1 as GLsizei)[0];
    bind_buffer(ARRAY_BUFFER, texture_coord_buffer);

    return (triangle_vertex_buffer, texture_coord_buffer);
}

pub fn create_texture_for_image_if_necessary(image: @mut Image) {
    #[cfg(target_os = "android")]
    fn colorspace() -> c_uint {
        RGBA
    }
    #[cfg(not(target_os = "android"))]
    fn colorspace() -> c_uint {
        BGRA
    }
    #[cfg(target_os = "android")]
    fn datatype() -> c_uint {
        UNSIGNED_BYTE
    }
    #[cfg(not(target_os = "android"))]
    fn datatype() -> c_uint {
        UNSIGNED_INT_8_8_8_8_REV
    }

    match image.texture {
        None => {}
        Some(_) => { return; /* Nothing to do. */ }
    }

    let texture = gen_textures(1 as GLsizei)[0];

    //XXXjdm This block is necessary to avoid a task failure that occurs
    //       when |image.data| is borrowed and we mutate |image.texture|.
    {
    let data = &mut image.data;
    debug!("making texture, id=%d, format=%?", texture as int, data.format());

    bind_texture(TEXTURE_2D, texture);

    // FIXME: This makes the lifetime requirements somewhat complex...
    pixel_store_i(UNPACK_CLIENT_STORAGE_APPLE, 1);

    let size = data.size();
    let stride = data.stride() as GLsizei;

    tex_parameter_i(TEXTURE_2D, TEXTURE_MAG_FILTER, LINEAR as GLint);
    tex_parameter_i(TEXTURE_2D, TEXTURE_MIN_FILTER, LINEAR as GLint);

    tex_parameter_i(TEXTURE_2D, TEXTURE_WRAP_S, CLAMP_TO_EDGE as GLint);
    tex_parameter_i(TEXTURE_2D, TEXTURE_WRAP_T, CLAMP_TO_EDGE as GLint);

    // These two are needed for DMA on the Mac. Don't touch them unless you know what you're doing!
    pixel_store_i(UNPACK_ALIGNMENT, 4);
    pixel_store_i(UNPACK_ROW_LENGTH, size.width as GLint);
    if stride % 32 != 0 {
        info!("rust-layers: suggest using stride multiples of 32 for DMA on the Mac");
    }

    debug!("rust-layers stride is %u", stride as uint);

    match data.format() {
        RGB24Format => {
            do data.with_data |data| {
                tex_image_2d(TEXTURE_2D, 0 as GLint, RGB as GLint,
                             size.width as GLsizei, size.height as GLsizei, 0 as GLint, RGB,
                             UNSIGNED_BYTE, Some(data));
            }
        }
        ARGB32Format => {
            do data.with_data |data| {
                tex_image_2d(TEXTURE_2D, 0 as GLint, RGBA as GLint,
                             size.width as GLsizei, size.height as GLsizei, 0 as GLint, colorspace(),
                             datatype(), Some(data));
            }
        }
    }
    } //XXXjdm This block avoids a segfault. See opening comment.

    image.texture = Some(texture);
}

pub fn bind_and_render_quad(render_context: RenderContext, texture: GLuint) {
    active_texture(TEXTURE0);
    bind_texture(TEXTURE_2D, texture);

    uniform_1i(render_context.sampler_uniform, 0);

    bind_buffer(ARRAY_BUFFER, render_context.vertex_buffer);
    vertex_attrib_pointer_f32(render_context.vertex_position_attr as GLuint, 3, false, 0, 0);

    // Create the texture coordinate array.
    bind_buffer(ARRAY_BUFFER, render_context.texture_coord_buffer);

    let vertices = [
        0.0f32, 1.0f32,
        0.0f32, 0.0f32,
        1.0f32, 1.0f32,
        1.0f32, 0.0f32,
    ];
    buffer_data(ARRAY_BUFFER, vertices, STATIC_DRAW);
    vertex_attrib_pointer_f32(render_context.texture_coord_attr as GLuint, 2, false, 0, 0);
    draw_arrays(TRIANGLE_STRIP, 0, 4);
    bind_texture(TEXTURE_2D, 0);
}

// Layer rendering

pub trait Render {
    fn render(@mut self, render_context: RenderContext, transform: Matrix4<f32>);
}

impl Render for layers::ContainerLayer {
    fn render(@mut self, render_context: RenderContext, transform: Matrix4<f32>) {
        let transform = transform.mul(&self.common.transform);
        for self.each_child |child| {
            render_layer(render_context, transform, child);
        }
    }
}

impl Render for layers::TextureLayer {
    fn render(@mut self, render_context: RenderContext, transform: Matrix4<f32>) {
        let transform = transform.mul(&self.common.transform);
        uniform_matrix_4fv(render_context.modelview_uniform, false, transform.to_array());

        bind_and_render_quad(render_context, self.manager.get_texture());
    }
}

impl Render for layers::ImageLayer {
    fn render(@mut self, render_context: RenderContext, transform: Matrix4<f32>) {
        create_texture_for_image_if_necessary(self.image);

        let transform = transform.mul(&self.common.transform);
        uniform_matrix_4fv(render_context.modelview_uniform, false, transform.to_array());
        bind_and_render_quad(render_context, self.image.texture.get());
    }
}

impl Render for layers::TiledImageLayer {
    fn render(@mut self, render_context: RenderContext, transform: Matrix4<f32>) {
        let tiles_down = self.tiles.len() / self.tiles_across;
        for (*self.tiles).iter().enumerate().advance |(i, tile)| {
            create_texture_for_image_if_necessary(*tile);

            let x = ((i % self.tiles_across) as f32);
            let y = ((i / self.tiles_across) as f32);

            let transform = transform.mul(&self.common.transform);
            let transform = transform.scale(1.0 / (self.tiles_across as f32),
                                            1.0 / (tiles_down as f32),
                                            1.0);
            let transform = transform.translate(x, y, 0.0);

            uniform_matrix_4fv(render_context.modelview_uniform, false, transform.to_array());
            bind_and_render_quad(render_context, tile.texture.get());
        }
    }
}

fn render_layer(render_context: RenderContext, transform: Matrix4<f32>, layer: layers::Layer) {
    match layer {
        ContainerLayerKind(container_layer) => {
            container_layer.render(render_context, transform);
        }
        TextureLayerKind(texture_layer) => {
            texture_layer.render(render_context, transform);
        }
        ImageLayerKind(image_layer) => {
            image_layer.render(render_context, transform);
        }
        TiledImageLayerKind(tiled_image_layer) => {
            tiled_image_layer.render(render_context, transform);
        }
    }
}

pub fn render_scene(render_context: RenderContext, scene: &Scene) {
    // Set the viewport.
    viewport(0 as GLint, 0 as GLint, scene.size.width as GLsizei, scene.size.height as GLsizei);

    // Clear the screen.
    clear_color(0.38f32, 0.36f32, 0.36f32, 1.0f32);
    clear(COLOR_BUFFER_BIT);

    // Set the projection matrix.
    let projection_matrix = ortho(0.0, scene.size.width, scene.size.height, 0.0, -10.0, 10.0);
    uniform_matrix_4fv(render_context.projection_uniform, false, projection_matrix.to_array());

    // Set up the initial modelview matrix.
    let transform = scene.transform;

    // Render the root layer.
    render_layer(render_context, transform, scene.root);
}

<|endoftext|>


<commit_before><commit_msg>test: Add a test for #1697<commit_after>// Testing that we don't fail abnormally after hitting the errors

import unresolved::*; //! ERROR unresolved modulename
//!^ ERROR unresolved does not name a module

fn main() {
}<|endoftext|>


<commit_before><commit_msg>test for pure fn vs impure fn etc subtyping<commit_after>// Test rules governing higher-order pure fns.

fn assign_to_pure(x: pure fn(), y: fn(), z: unsafe fn()) {
    let a: pure fn() = x;
    let b: pure fn() = y; //! ERROR expected pure fn but found impure fn
    let c: pure fn() = z; //! ERROR expected pure fn but found unsafe fn
}

fn assign_to_impure(x: pure fn(), y: fn(), z: unsafe fn()) {
    let h: fn() = x;
    let i: fn() = y;
    let j: fn() = z; //! ERROR expected impure fn but found unsafe fn
}

fn assign_to_unsafe(x: pure fn(), y: fn(), z: unsafe fn()) {
    let m: unsafe fn() = x;
    let n: unsafe fn() = y;
    let o: unsafe fn() = z;
}

fn main() {
}<|endoftext|>


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

// compile-pass

// Bastion of the Turbofish
// ------------------------
// Beware travellers, lest you venture into waters callous and unforgiving,
// where hope must be abandoned, ere it is cruelly torn from you. For here
// stands the bastion of the Turbofish: an impenetrable fortress holding
// unshaking against those who would dare suggest the supererogation of the
// Turbofish.
//
// Once I was young and foolish and had the impudence to imagine that I could
// shake free from the coils by which that creature had us tightly bound. I
// dared to suggest that there was a better way: a brighter future, in which
// Rustaceans both new and old could be rid of that vile beast. But alas! In
// my foolhardiness my ignorance was unveiled and my dreams were dashed
// unforgivingly against the rock of syntactic ambiguity.
//
// This humble program, small and insignificant though it might seem,
// demonstrates that to which we had previously cast a blind eye: an ambiguity
// in permitting generic arguments to be provided without the consent of the
// Great Turbofish. Should you be so naïve as to try to revolt against its
// mighty clutches, here shall its wrath be indomitably displayed. This
// program must pass for all eternity, fundamentally at odds with an impetuous
// rebellion against the Turbofish.
//
// My heart aches in sorrow, for I know I am defeated. Let this be a warning
// to all those who come after. Here stands the bastion of the Turbofish.

fn main() {
    let (oh, woe, is, me) = ("the", "Turbofish", "remains", "undefeated");
    let _: (bool, bool) = (oh<woe, is>(me));
}
<|endoftext|>


<commit_before><commit_msg>Hacky Rustlang solution for can_scramble<commit_after>use std::collections::HashMap;

fn can_scramble(input: &str, output: &str) -> bool {
  let mut input_counter = HashMap::new();
  for c in input.chars() {
    let new_count = match input_counter.get(&c) {
      Some(count) => count +1,
      None => 1
    };
    input_counter.insert(c, new_count);
  }
  for c in output.chars() {
    let new_count = match input_counter.get(&c) {
      Some(count) => count -1,
      None => -1
    };
    if new_count < 0 {
      return false;
    }
    input_counter.insert(c, new_count);
  }
  true
}

fn main() {
  assert_eq!(can_scramble("abc", "cab"), true);
}
<|endoftext|>


<commit_before><commit_msg>rustfmt<commit_after><|endoftext|>


<commit_before>#![feature(core, std_misc, collections, old_io, old_path)]

extern crate getopts;
extern crate image;

use std::default::Default;
use std::old_io::fs::File;

mod css;
mod dom;
mod html;
mod layout;
mod style;
mod painting;
mod pdf;

fn main() {
    // Parse command-line options:
    let mut opts = getopts::Options::new();
    opts.optopt("h", "html", "HTML document", "FILENAME");
    opts.optopt("c", "css", "CSS stylesheet", "FILENAME");
    opts.optopt("o", "output", "Output file", "FILENAME");
    opts.optopt("f", "format", "Output file format", "png | pdf");

    let matches = match opts.parse(std::env::args().skip(1)) {
        Ok(m) => m,
        Err(f) => panic!(f.to_string())
    };

    let png = match matches.opt_str("f") {
        None => true,
        Some(format) => match &*format {
            "png" => true,
            "pdf" => false,
            _ => panic!("Unknown output format: {}", format),
        }
    };

    // Read input files:
    let read_source = |arg_filename: Option<String>, default_filename: &str| {
        let path = match arg_filename {
            Some(ref filename) => &**filename,
            None => default_filename,
        };
        File::open(&Path::new(path)).read_to_string().unwrap()
    };
    let html = read_source(matches.opt_str("h"), "examples/test.html");
    let css  = read_source(matches.opt_str("c"), "examples/test.css");

    // Since we don't have an actual window, hard-code the "viewport" size.
    let initial_containing_block = layout::Dimensions {
        content: layout::Rect { x: 0.0, y: 0.0, width: 800.0, height: 600.0 },
        padding: Default::default(),
        border: Default::default(),
        margin: Default::default(),
    };

    // Parsing and rendering:
    let root_node = html::parse(html);
    let stylesheet = css::parse(css);
    let style_root = style::style_tree(&root_node, &stylesheet);
    let layout_root = layout::layout_tree(&style_root, initial_containing_block);

    // Create the output file:
    let default_filename = if png { "output.png" } else { "output.pdf" };
    let filename = matches.opt_str("o").unwrap_or(default_filename.to_string());
    let mut file = File::create(&Path::new(&*filename)).unwrap();

    let result_ok;
    if png {
        let canvas = painting::paint(&layout_root, initial_containing_block.content);

        // Save an image:
        let (w, h) = (canvas.width as u32, canvas.height as u32);
        let img = image::ImageBuffer::from_fn(w, h, move |x, y| {
            let color = canvas.pixels[(y * w + x) as usize];
            image::Pixel::from_channels(color.r, color.g, color.b, color.a)
        });

        result_ok = image::ImageRgba8(img).save(&mut file, image::PNG).is_ok();
    } else {
        result_ok = pdf::render(&layout_root, initial_containing_block.content, &mut file).is_ok();
    }

    if result_ok {
        println!("Saved output as {}", filename)
    } else {
        println!("Error saving output as {}", filename)
    }
}
<commit_msg>Silence deprecation warnings<commit_after>#![feature(core, std_misc, collections, old_io, old_path)]
#![allow(deprecated)] // for old_io

extern crate getopts;
extern crate image;

use std::default::Default;
use std::old_io::fs::File;

mod css;
mod dom;
mod html;
mod layout;
mod style;
mod painting;
mod pdf;

fn main() {
    // Parse command-line options:
    let mut opts = getopts::Options::new();
    opts.optopt("h", "html", "HTML document", "FILENAME");
    opts.optopt("c", "css", "CSS stylesheet", "FILENAME");
    opts.optopt("o", "output", "Output file", "FILENAME");
    opts.optopt("f", "format", "Output file format", "png | pdf");

    let matches = match opts.parse(std::env::args().skip(1)) {
        Ok(m) => m,
        Err(f) => panic!(f.to_string())
    };

    let png = match matches.opt_str("f") {
        None => true,
        Some(format) => match &*format {
            "png" => true,
            "pdf" => false,
            _ => panic!("Unknown output format: {}", format),
        }
    };

    // Read input files:
    let read_source = |arg_filename: Option<String>, default_filename: &str| {
        let path = match arg_filename {
            Some(ref filename) => &**filename,
            None => default_filename,
        };
        File::open(&Path::new(path)).read_to_string().unwrap()
    };
    let html = read_source(matches.opt_str("h"), "examples/test.html");
    let css  = read_source(matches.opt_str("c"), "examples/test.css");

    // Since we don't have an actual window, hard-code the "viewport" size.
    let initial_containing_block = layout::Dimensions {
        content: layout::Rect { x: 0.0, y: 0.0, width: 800.0, height: 600.0 },
        padding: Default::default(),
        border: Default::default(),
        margin: Default::default(),
    };

    // Parsing and rendering:
    let root_node = html::parse(html);
    let stylesheet = css::parse(css);
    let style_root = style::style_tree(&root_node, &stylesheet);
    let layout_root = layout::layout_tree(&style_root, initial_containing_block);

    // Create the output file:
    let default_filename = if png { "output.png" } else { "output.pdf" };
    let filename = matches.opt_str("o").unwrap_or(default_filename.to_string());
    let mut file = File::create(&Path::new(&*filename)).unwrap();

    let result_ok;
    if png {
        let canvas = painting::paint(&layout_root, initial_containing_block.content);

        // Save an image:
        let (w, h) = (canvas.width as u32, canvas.height as u32);
        let img = image::ImageBuffer::from_fn(w, h, move |x, y| {
            let color = canvas.pixels[(y * w + x) as usize];
            image::Pixel::from_channels(color.r, color.g, color.b, color.a)
        });

        result_ok = image::ImageRgba8(img).save(&mut file, image::PNG).is_ok();
    } else {
        result_ok = pdf::render(&layout_root, initial_containing_block.content, &mut file).is_ok();
    }

    if result_ok {
        println!("Saved output as {}", filename)
    } else {
        println!("Error saving output as {}", filename)
    }
}
<|endoftext|>


<commit_before><commit_msg>Cleaning up acquisition functions.<commit_after><|endoftext|>


<commit_before><commit_msg>Remove junk<commit_after><|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.

//! The compiler code necessary to implement the `#[derive(Encodable)]`
//! (and `Decodable`, in decodable.rs) extension.  The idea here is that
//! type-defining items may be tagged with `#[derive(Encodable, Decodable)]`.
//!
//! For example, a type like:
//!
//! ```
//! #[derive(Encodable, Decodable)]
//! struct Node { id: usize }
//! ```
//!
//! would generate two implementations like:
//!
//! ```
//! # struct Node { id: usize }
//! impl<S: Encoder<E>, E> Encodable<S, E> for Node {
//!     fn encode(&self, s: &mut S) -> Result<(), E> {
//!         s.emit_struct("Node", 1, |this| {
//!             this.emit_struct_field("id", 0, |this| {
//!                 Encodable::encode(&self.id, this)
//!                 /* this.emit_usize(self.id) can also be used */
//!             })
//!         })
//!     }
//! }
//!
//! impl<D: Decoder<E>, E> Decodable<D, E> for Node {
//!     fn decode(d: &mut D) -> Result<Node, E> {
//!         d.read_struct("Node", 1, |this| {
//!             match this.read_struct_field("id", 0, |this| Decodable::decode(this)) {
//!                 Ok(id) => Ok(Node { id: id }),
//!                 Err(e) => Err(e),
//!             }
//!         })
//!     }
//! }
//! ```
//!
//! Other interesting scenarios are when the item has type parameters or
//! references other non-built-in types.  A type definition like:
//!
//! ```
//! # #[derive(Encodable, Decodable)] struct Span;
//! #[derive(Encodable, Decodable)]
//! struct Spanned<T> { node: T, span: Span }
//! ```
//!
//! would yield functions like:
//!
//! ```
//! # #[derive(Encodable, Decodable)] struct Span;
//! # struct Spanned<T> { node: T, span: Span }
//! impl<
//!     S: Encoder<E>,
//!     E,
//!     T: Encodable<S, E>
//! > Encodable<S, E> for Spanned<T> {
//!     fn encode(&self, s: &mut S) -> Result<(), E> {
//!         s.emit_struct("Spanned", 2, |this| {
//!             this.emit_struct_field("node", 0, |this| self.node.encode(this))
//!                 .unwrap();
//!             this.emit_struct_field("span", 1, |this| self.span.encode(this))
//!         })
//!     }
//! }
//!
//! impl<
//!     D: Decoder<E>,
//!     E,
//!     T: Decodable<D, E>
//! > Decodable<D, E> for Spanned<T> {
//!     fn decode(d: &mut D) -> Result<Spanned<T>, E> {
//!         d.read_struct("Spanned", 2, |this| {
//!             Ok(Spanned {
//!                 node: this.read_struct_field("node", 0, |this| Decodable::decode(this))
//!                     .unwrap(),
//!                 span: this.read_struct_field("span", 1, |this| Decodable::decode(this))
//!                     .unwrap(),
//!             })
//!         })
//!     }
//! }
//! ```

use deriving::{self, pathvec_std};
use deriving::generic::*;
use deriving::generic::ty::*;
use deriving::warn_if_deprecated;

use syntax::ast::{Expr, ExprKind, MetaItem, Mutability};
use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ext::build::AstBuilder;
use syntax::ptr::P;
use syntax::symbol::Symbol;
use syntax_pos::Span;

pub fn expand_deriving_rustc_encodable(cx: &mut ExtCtxt,
                                       span: Span,
                                       mitem: &MetaItem,
                                       item: &Annotatable,
                                       push: &mut FnMut(Annotatable)) {
    expand_deriving_encodable_imp(cx, span, mitem, item, push, "rustc_serialize")
}

pub fn expand_deriving_encodable(cx: &mut ExtCtxt,
                                 span: Span,
                                 mitem: &MetaItem,
                                 item: &Annotatable,
                                 push: &mut FnMut(Annotatable)) {
    warn_if_deprecated(cx, span, "Encodable");
    expand_deriving_encodable_imp(cx, span, mitem, item, push, "serialize")
}

fn expand_deriving_encodable_imp(cx: &mut ExtCtxt,
                                 span: Span,
                                 mitem: &MetaItem,
                                 item: &Annotatable,
                                 push: &mut FnMut(Annotatable),
                                 krate: &'static str) {
    let typaram = &*deriving::hygienic_type_parameter(item, "__S");

    let trait_def = TraitDef {
        span,
        attributes: Vec::new(),
        path: Path::new_(vec![krate, "Encodable"], None, vec![], PathKind::Global),
        additional_bounds: Vec::new(),
        generics: LifetimeBounds::empty(),
        is_unsafe: false,
        supports_unions: false,
        methods: vec![
            MethodDef {
                name: "encode",
                generics: LifetimeBounds {
                    lifetimes: Vec::new(),
                    bounds: vec![
                        (typaram,
                         vec![Path::new_(vec![krate, "Encoder"], None, vec![], PathKind::Global)])
                    ],
                },
                explicit_self: borrowed_explicit_self(),
                args: vec![Ptr(Box::new(Literal(Path::new_local(typaram))),
                           Borrowed(None, Mutability::Mutable))],
                ret_ty: Literal(Path::new_(
                    pathvec_std!(cx, result::Result),
                    None,
                    vec![Box::new(Tuple(Vec::new())), Box::new(Literal(Path::new_(
                        vec![typaram, "Error"], None, vec![], PathKind::Local
                    )))],
                    PathKind::Std
                )),
                attributes: Vec::new(),
                is_unsafe: false,
                unify_fieldless_variants: false,
                combine_substructure: combine_substructure(Box::new(|a, b, c| {
                    encodable_substructure(a, b, c, krate)
                })),
            }
        ],
        associated_types: Vec::new(),
    };

    trait_def.expand(cx, mitem, item, push)
}

fn encodable_substructure(cx: &mut ExtCtxt,
                          trait_span: Span,
                          substr: &Substructure,
                          krate: &'static str)
                          -> P<Expr> {
    let encoder = substr.nonself_args[0].clone();
    // throw an underscore in front to suppress unused variable warnings
    let blkarg = cx.ident_of("_e");
    let blkencoder = cx.expr_ident(trait_span, blkarg);
    let fn_path = cx.expr_path(cx.path_global(trait_span,
                                              vec![cx.ident_of(krate),
                                                   cx.ident_of("Encodable"),
                                                   cx.ident_of("encode")]));

    return match *substr.fields {
        Struct(_, ref fields) => {
            let emit_struct_field = cx.ident_of("emit_struct_field");
            let mut stmts = Vec::new();
            for (i, &FieldInfo { name, ref self_, span, attrs, .. }) in fields.iter().enumerate() {
                let name = match name {
                    Some(id) => id.name,
                    None => Symbol::intern(&format!("_field{}", i)),
                };
                let self_ref = cx.expr_addr_of(span, self_.clone());
                let enc = cx.expr_call(span, fn_path.clone(), vec![self_ref, blkencoder.clone()]);
                let lambda = cx.lambda1(span, enc, blkarg);
                let call = cx.expr_method_call(span,
                                               blkencoder.clone(),
                                               emit_struct_field,
                                               vec![cx.expr_str(span, name),
                                                    cx.expr_usize(span, i),
                                                    lambda]);

                // last call doesn't need a try!
                let last = fields.len() - 1;
                let call = if i != last {
                    cx.expr_try(span, call)
                } else {
                    cx.expr(span, ExprKind::Ret(Some(call)))
                };

                // This exists for https://github.com/rust-lang/rust/pull/47540
                //
                // If we decide to stabilize that flag this can be removed
                let expr = if attrs.iter().any(|a| a.check_name("rustc_serialize_exclude_null")) {
                    let is_some = cx.ident_of("is_some");
                    let condition = cx.expr_method_call(span, self_.clone(), is_some, vec![]);
                    cx.expr_if(span, condition, call, None)
                } else {
                    call
                };
                let stmt = cx.stmt_expr(expr);
                stmts.push(stmt);
            }

            // unit structs have no fields and need to return Ok()
            if stmts.is_empty() {
                let ok = cx.expr_ok(trait_span, cx.expr_tuple(trait_span, vec![]));
                let ret_ok = cx.expr(trait_span, ExprKind::Ret(Some(ok)));
                stmts.push(cx.stmt_expr(ret_ok));
            }

            let blk = cx.lambda_stmts_1(trait_span, stmts, blkarg);
            cx.expr_method_call(trait_span,
                                encoder,
                                cx.ident_of("emit_struct"),
                                vec![cx.expr_str(trait_span, substr.type_ident.name),
                                     cx.expr_usize(trait_span, fields.len()),
                                     blk])
        }

        EnumMatching(idx, _, variant, ref fields) => {
            // We're not generating an AST that the borrow checker is expecting,
            // so we need to generate a unique local variable to take the
            // mutable loan out on, otherwise we get conflicts which don't
            // actually exist.
            let me = cx.stmt_let(trait_span, false, blkarg, encoder);
            let encoder = cx.expr_ident(trait_span, blkarg);
            let emit_variant_arg = cx.ident_of("emit_enum_variant_arg");
            let mut stmts = Vec::new();
            if !fields.is_empty() {
                let last = fields.len() - 1;
                for (i, &FieldInfo { ref self_, span, .. }) in fields.iter().enumerate() {
                    let self_ref = cx.expr_addr_of(span, self_.clone());
                    let enc =
                        cx.expr_call(span, fn_path.clone(), vec![self_ref, blkencoder.clone()]);
                    let lambda = cx.lambda1(span, enc, blkarg);
                    let call = cx.expr_method_call(span,
                                                   blkencoder.clone(),
                                                   emit_variant_arg,
                                                   vec![cx.expr_usize(span, i), lambda]);
                    let call = if i != last {
                        cx.expr_try(span, call)
                    } else {
                        cx.expr(span, ExprKind::Ret(Some(call)))
                    };
                    stmts.push(cx.stmt_expr(call));
                }
            } else {
                let ok = cx.expr_ok(trait_span, cx.expr_tuple(trait_span, vec![]));
                let ret_ok = cx.expr(trait_span, ExprKind::Ret(Some(ok)));
                stmts.push(cx.stmt_expr(ret_ok));
            }

            let blk = cx.lambda_stmts_1(trait_span, stmts, blkarg);
            let name = cx.expr_str(trait_span, variant.node.name.name);
            let call = cx.expr_method_call(trait_span,
                                           blkencoder,
                                           cx.ident_of("emit_enum_variant"),
                                           vec![name,
                                                cx.expr_usize(trait_span, idx),
                                                cx.expr_usize(trait_span, fields.len()),
                                                blk]);
            let blk = cx.lambda1(trait_span, call, blkarg);
            let ret = cx.expr_method_call(trait_span,
                                          encoder,
                                          cx.ident_of("emit_enum"),
                                          vec![cx.expr_str(trait_span ,substr.type_ident.name),
                                               blk]);
            cx.expr_block(cx.block(trait_span, vec![me, cx.stmt_expr(ret)]))
        }

        _ => cx.bug("expected Struct or EnumMatching in derive(Encodable)"),
    };
}
<commit_msg>Optimise decode return expression for unit structs<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.

//! The compiler code necessary to implement the `#[derive(Encodable)]`
//! (and `Decodable`, in decodable.rs) extension.  The idea here is that
//! type-defining items may be tagged with `#[derive(Encodable, Decodable)]`.
//!
//! For example, a type like:
//!
//! ```
//! #[derive(Encodable, Decodable)]
//! struct Node { id: usize }
//! ```
//!
//! would generate two implementations like:
//!
//! ```
//! # struct Node { id: usize }
//! impl<S: Encoder<E>, E> Encodable<S, E> for Node {
//!     fn encode(&self, s: &mut S) -> Result<(), E> {
//!         s.emit_struct("Node", 1, |this| {
//!             this.emit_struct_field("id", 0, |this| {
//!                 Encodable::encode(&self.id, this)
//!                 /* this.emit_usize(self.id) can also be used */
//!             })
//!         })
//!     }
//! }
//!
//! impl<D: Decoder<E>, E> Decodable<D, E> for Node {
//!     fn decode(d: &mut D) -> Result<Node, E> {
//!         d.read_struct("Node", 1, |this| {
//!             match this.read_struct_field("id", 0, |this| Decodable::decode(this)) {
//!                 Ok(id) => Ok(Node { id: id }),
//!                 Err(e) => Err(e),
//!             }
//!         })
//!     }
//! }
//! ```
//!
//! Other interesting scenarios are when the item has type parameters or
//! references other non-built-in types.  A type definition like:
//!
//! ```
//! # #[derive(Encodable, Decodable)] struct Span;
//! #[derive(Encodable, Decodable)]
//! struct Spanned<T> { node: T, span: Span }
//! ```
//!
//! would yield functions like:
//!
//! ```
//! # #[derive(Encodable, Decodable)] struct Span;
//! # struct Spanned<T> { node: T, span: Span }
//! impl<
//!     S: Encoder<E>,
//!     E,
//!     T: Encodable<S, E>
//! > Encodable<S, E> for Spanned<T> {
//!     fn encode(&self, s: &mut S) -> Result<(), E> {
//!         s.emit_struct("Spanned", 2, |this| {
//!             this.emit_struct_field("node", 0, |this| self.node.encode(this))
//!                 .unwrap();
//!             this.emit_struct_field("span", 1, |this| self.span.encode(this))
//!         })
//!     }
//! }
//!
//! impl<
//!     D: Decoder<E>,
//!     E,
//!     T: Decodable<D, E>
//! > Decodable<D, E> for Spanned<T> {
//!     fn decode(d: &mut D) -> Result<Spanned<T>, E> {
//!         d.read_struct("Spanned", 2, |this| {
//!             Ok(Spanned {
//!                 node: this.read_struct_field("node", 0, |this| Decodable::decode(this))
//!                     .unwrap(),
//!                 span: this.read_struct_field("span", 1, |this| Decodable::decode(this))
//!                     .unwrap(),
//!             })
//!         })
//!     }
//! }
//! ```

use deriving::{self, pathvec_std};
use deriving::generic::*;
use deriving::generic::ty::*;
use deriving::warn_if_deprecated;

use syntax::ast::{Expr, ExprKind, MetaItem, Mutability};
use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ext::build::AstBuilder;
use syntax::ptr::P;
use syntax::symbol::Symbol;
use syntax_pos::Span;

pub fn expand_deriving_rustc_encodable(cx: &mut ExtCtxt,
                                       span: Span,
                                       mitem: &MetaItem,
                                       item: &Annotatable,
                                       push: &mut FnMut(Annotatable)) {
    expand_deriving_encodable_imp(cx, span, mitem, item, push, "rustc_serialize")
}

pub fn expand_deriving_encodable(cx: &mut ExtCtxt,
                                 span: Span,
                                 mitem: &MetaItem,
                                 item: &Annotatable,
                                 push: &mut FnMut(Annotatable)) {
    warn_if_deprecated(cx, span, "Encodable");
    expand_deriving_encodable_imp(cx, span, mitem, item, push, "serialize")
}

fn expand_deriving_encodable_imp(cx: &mut ExtCtxt,
                                 span: Span,
                                 mitem: &MetaItem,
                                 item: &Annotatable,
                                 push: &mut FnMut(Annotatable),
                                 krate: &'static str) {
    let typaram = &*deriving::hygienic_type_parameter(item, "__S");

    let trait_def = TraitDef {
        span,
        attributes: Vec::new(),
        path: Path::new_(vec![krate, "Encodable"], None, vec![], PathKind::Global),
        additional_bounds: Vec::new(),
        generics: LifetimeBounds::empty(),
        is_unsafe: false,
        supports_unions: false,
        methods: vec![
            MethodDef {
                name: "encode",
                generics: LifetimeBounds {
                    lifetimes: Vec::new(),
                    bounds: vec![
                        (typaram,
                         vec![Path::new_(vec![krate, "Encoder"], None, vec![], PathKind::Global)])
                    ],
                },
                explicit_self: borrowed_explicit_self(),
                args: vec![Ptr(Box::new(Literal(Path::new_local(typaram))),
                           Borrowed(None, Mutability::Mutable))],
                ret_ty: Literal(Path::new_(
                    pathvec_std!(cx, result::Result),
                    None,
                    vec![Box::new(Tuple(Vec::new())), Box::new(Literal(Path::new_(
                        vec![typaram, "Error"], None, vec![], PathKind::Local
                    )))],
                    PathKind::Std
                )),
                attributes: Vec::new(),
                is_unsafe: false,
                unify_fieldless_variants: false,
                combine_substructure: combine_substructure(Box::new(|a, b, c| {
                    encodable_substructure(a, b, c, krate)
                })),
            }
        ],
        associated_types: Vec::new(),
    };

    trait_def.expand(cx, mitem, item, push)
}

fn encodable_substructure(cx: &mut ExtCtxt,
                          trait_span: Span,
                          substr: &Substructure,
                          krate: &'static str)
                          -> P<Expr> {
    let encoder = substr.nonself_args[0].clone();
    // throw an underscore in front to suppress unused variable warnings
    let blkarg = cx.ident_of("_e");
    let blkencoder = cx.expr_ident(trait_span, blkarg);
    let fn_path = cx.expr_path(cx.path_global(trait_span,
                                              vec![cx.ident_of(krate),
                                                   cx.ident_of("Encodable"),
                                                   cx.ident_of("encode")]));

    return match *substr.fields {
        Struct(_, ref fields) => {
            let emit_struct_field = cx.ident_of("emit_struct_field");
            let mut stmts = Vec::new();
            for (i, &FieldInfo { name, ref self_, span, attrs, .. }) in fields.iter().enumerate() {
                let name = match name {
                    Some(id) => id.name,
                    None => Symbol::intern(&format!("_field{}", i)),
                };
                let self_ref = cx.expr_addr_of(span, self_.clone());
                let enc = cx.expr_call(span, fn_path.clone(), vec![self_ref, blkencoder.clone()]);
                let lambda = cx.lambda1(span, enc, blkarg);
                let call = cx.expr_method_call(span,
                                               blkencoder.clone(),
                                               emit_struct_field,
                                               vec![cx.expr_str(span, name),
                                                    cx.expr_usize(span, i),
                                                    lambda]);

                // last call doesn't need a try!
                let last = fields.len() - 1;
                let call = if i != last {
                    cx.expr_try(span, call)
                } else {
                    cx.expr(span, ExprKind::Ret(Some(call)))
                };

                // This exists for https://github.com/rust-lang/rust/pull/47540
                //
                // If we decide to stabilize that flag this can be removed
                let expr = if attrs.iter().any(|a| a.check_name("rustc_serialize_exclude_null")) {
                    let is_some = cx.ident_of("is_some");
                    let condition = cx.expr_method_call(span, self_.clone(), is_some, vec![]);
                    cx.expr_if(span, condition, call, None)
                } else {
                    call
                };
                let stmt = cx.stmt_expr(expr);
                stmts.push(stmt);
            }

            // unit structs have no fields and need to return Ok()
            let blk = if stmts.is_empty() {
                let ok = cx.expr_ok(trait_span, cx.expr_tuple(trait_span, vec![]));
                cx.lambda1(trait_span, ok, blkarg)
            } else {
                cx.lambda_stmts_1(trait_span, stmts, blkarg)
            };

            cx.expr_method_call(trait_span,
                                encoder,
                                cx.ident_of("emit_struct"),
                                vec![cx.expr_str(trait_span, substr.type_ident.name),
                                     cx.expr_usize(trait_span, fields.len()),
                                     blk])
        }

        EnumMatching(idx, _, variant, ref fields) => {
            // We're not generating an AST that the borrow checker is expecting,
            // so we need to generate a unique local variable to take the
            // mutable loan out on, otherwise we get conflicts which don't
            // actually exist.
            let me = cx.stmt_let(trait_span, false, blkarg, encoder);
            let encoder = cx.expr_ident(trait_span, blkarg);
            let emit_variant_arg = cx.ident_of("emit_enum_variant_arg");
            let mut stmts = Vec::new();
            if !fields.is_empty() {
                let last = fields.len() - 1;
                for (i, &FieldInfo { ref self_, span, .. }) in fields.iter().enumerate() {
                    let self_ref = cx.expr_addr_of(span, self_.clone());
                    let enc =
                        cx.expr_call(span, fn_path.clone(), vec![self_ref, blkencoder.clone()]);
                    let lambda = cx.lambda1(span, enc, blkarg);
                    let call = cx.expr_method_call(span,
                                                   blkencoder.clone(),
                                                   emit_variant_arg,
                                                   vec![cx.expr_usize(span, i), lambda]);
                    let call = if i != last {
                        cx.expr_try(span, call)
                    } else {
                        cx.expr(span, ExprKind::Ret(Some(call)))
                    };
                    stmts.push(cx.stmt_expr(call));
                }
            } else {
                let ok = cx.expr_ok(trait_span, cx.expr_tuple(trait_span, vec![]));
                let ret_ok = cx.expr(trait_span, ExprKind::Ret(Some(ok)));
                stmts.push(cx.stmt_expr(ret_ok));
            }

            let blk = cx.lambda_stmts_1(trait_span, stmts, blkarg);
            let name = cx.expr_str(trait_span, variant.node.name.name);
            let call = cx.expr_method_call(trait_span,
                                           blkencoder,
                                           cx.ident_of("emit_enum_variant"),
                                           vec![name,
                                                cx.expr_usize(trait_span, idx),
                                                cx.expr_usize(trait_span, fields.len()),
                                                blk]);
            let blk = cx.lambda1(trait_span, call, blkarg);
            let ret = cx.expr_method_call(trait_span,
                                          encoder,
                                          cx.ident_of("emit_enum"),
                                          vec![cx.expr_str(trait_span ,substr.type_ident.name),
                                               blk]);
            cx.expr_block(cx.block(trait_span, vec![me, cx.stmt_expr(ret)]))
        }

        _ => cx.bug("expected Struct or EnumMatching in derive(Encodable)"),
    };
}
<|endoftext|>


<commit_before><commit_msg>Add tuples and tuple_windows benchmark<commit_after>#![feature(test)]

extern crate test;
extern crate itertools;

use test::{black_box, Bencher};
use itertools::Itertools;

#[bench]
fn tuples_2(b: &mut Bencher) {
    b.iter(|| {
        for (a, b) in (0..20_000).tuples() {
            black_box(a + b);
        }
    })
}

#[bench]
fn tuples_3(b: &mut Bencher) {
    b.iter(|| {
        for (a, b, c) in (0..30_000).tuples() {
            black_box(a + b + c);
        }
    })
}

#[bench]
fn tuples_4(b: &mut Bencher) {
    b.iter(|| {
        for (a, b, c, d) in (0..40_000).tuples() {
            black_box(a + b + c + d);
        }
    })
}

#[bench]
fn tuple_windows_2(b: &mut Bencher) {
    b.iter(|| {
        for (a, b) in (0..10_000).tuple_windows() {
            black_box(a + b);
        }
    })
}

#[bench]
fn tuple_windows_3(b: &mut Bencher) {
    b.iter(|| {
        for (a, b, c) in (0..10_000).tuple_windows() {
            black_box(a + b + c);
        }
    })
}

#[bench]
fn tuple_windows_4(b: &mut Bencher) {
    b.iter(|| {
        for (a, b, c, d) in (0..10_000).tuple_windows() {
            black_box(a + b + c + d);
        }
    })
}
<|endoftext|>


<commit_before><commit_msg>feat(geektime_algo): add 31 graph, dfs and bfs<commit_after>use std::collections::LinkedList;
use std::collections::VecDeque;

// 无向图
#[derive(Debug)]
struct Graph {
    v:   i32,
    linked_vec: Vec<LinkedList<i32>>, // 邻接表
}

impl Graph {
    fn new(v: i32) -> Self {
        Graph {
            v: v,
            linked_vec: vec![LinkedList::new(); v as usize],
        }
    }

    // 无向图的每条边存两次
    fn add_edge(&mut self, s: i32, t: i32) {
        self.linked_vec[s as usize].push_back(t);
        self.linked_vec[t as usize].push_back(s);
    }

    fn bfs(&self, s: i32, t: i32) {
        if s == t { return; }

        let mut prev    = vec![-1; self.v as usize];
        let mut visited = vec![false; self.v as usize];
        let mut queue   = VecDeque::new();

        visited[s as usize] = true;
        queue.push_back(s);

        while !queue.is_empty() {
            let w = queue.pop_front().unwrap();
            for item in self.linked_vec[w as usize].iter() {
                if visited[*item as usize] { continue; }
                prev[*item as usize] = w;
                if *item == t {
                    self.draw(&prev, s, t);
                    return;
                }
                visited[*item as usize] = true;
                queue.push_back(*item);
            }
        }
    }

    fn dfs(&self, s: i32, t: i32) {
        let mut found   = false;
        let mut prev    = vec![-1; self.v as usize];
        let mut visited = vec![false; self.v as usize];

        self.recur_dfs(s, t, &mut visited, &mut prev, &mut found);
        self.draw(&prev, s, t);
    }

    fn recur_dfs(&self, s: i32, t: i32, visited: &mut Vec<bool>, prev: &mut Vec<i32>, found: &mut bool) {
        if *found == true { return; }
        visited[s as usize] = true;
        if s == t {
            *found = true;
            return;
        }
        for item in self.linked_vec[s as usize].iter() {
            if visited[*item as usize] { continue; }
            prev[*item as usize] = s;
            self.recur_dfs(*item, t, visited, prev, found);
        }
    }

    // 递归打印路径
    fn draw(&self, prev: &Vec<i32>, s: i32, t: i32) {
        if prev[t as usize] != -1 && s != t {
            self.draw(prev, s, prev[t as usize]);
        }

        println!("{} ->", t);
    }
}

fn main() {
    let mut graph = Graph::new(8);
    graph.add_edge(0, 1);
    graph.add_edge(0, 3);
    graph.add_edge(1, 2);
    graph.add_edge(1, 4);
    graph.add_edge(2, 5);
    graph.add_edge(3, 4);
    graph.add_edge(4, 5);
    graph.add_edge(4, 6);
    graph.add_edge(5, 7);
    graph.add_edge(6, 7);

    // Graph { v: 8, linked_vec: [[1, 3], [0, 2, 4], [1, 5], [0, 4], [1, 3, 5, 6], [2, 4, 7], [4, 7], [5, 6]] }
    println!("{:?}", graph);
    graph.bfs(0, 7);
    println!("bfs=============");
    graph.bfs(1, 3);
    println!("bfs=============");

    graph.dfs(0, 7);
    println!("dfs=============");
    graph.dfs(1, 3);
    println!("dfs=============");
}
<|endoftext|>


<commit_before><commit_msg>Add a really basic example<commit_after>extern mod glfw;
extern mod gl;

#[start]
fn start(argc: int, argv: **u8, crate_map: *u8) -> int {
    // Run GLFW on the main thread
    std::rt::start_on_main_thread(argc, argv, crate_map, main)
}

fn main() {
    do glfw::set_error_callback |_, description| {
        printfln!("GLFW Error: %s", description);
    }

    do glfw::start {
        // Choose a GL profile that is compatible with OS X 10.7+
        glfw::window_hint::context_version(3, 2);
        glfw::window_hint::opengl_profile(glfw::OPENGL_CORE_PROFILE);
        glfw::window_hint::opengl_forward_compat(true);

        let window = glfw::Window::create(800, 600, "OpenGL", glfw::Windowed).unwrap();
        window.make_context_current();

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

        while !window.should_close() {
            // Poll events
            glfw::poll_events();

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

            // Swap buffers
            window.swap_buffers();
        }
    }
}
<|endoftext|>