<commit_before>/*
Copyright (c) 2016-2017, Robert Ou <rqou@robertou.com>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

use std::marker::PhantomData;

use analyzer::util::*;

// We need this because the Vec can be reallocated around, but we want to keep
// around some kind of reference into the storage that can keep working after
// the reallocation happens.
struct StringPoolIndex {
    start: usize,
    end: usize,
}

struct StringPool {
    storage: Vec<u8>
}

impl StringPool {
    pub fn new() -> StringPool {
        StringPool {storage: Vec::new()}
    }

    // TODO: Might interning strings improve performance in the future?
    // TODO: Do we care about freeing things?
    pub fn add_latin1_str(&mut self, inp: &[u8]) -> StringPoolIndex {
        let addition_begin = self.storage.len();
        let addition_length = inp.len();

        self.storage.extend(inp.iter().cloned());

        StringPoolIndex {
            start: addition_begin,
            end: addition_begin + addition_length
        }
    }

    pub fn retrieve_latin1_str(&self, i: &StringPoolIndex) -> Latin1Str {
        let the_slice = &self.storage[i.start..i.end];
        Latin1Str::new(the_slice)
    }
}

struct ObjPoolIndex<T> {
    i: usize,
    type_marker: PhantomData<T>
}

struct ObjPool<T> {
    storage: Vec<T>
}

impl<T: Default> ObjPool<T> {
    pub fn new() -> ObjPool<T> {
        ObjPool {storage: Vec::new()}
    }

    pub fn alloc(&mut self) -> ObjPoolIndex<T> {
        let i = self.storage.len();
        let o = T::default();

        self.storage.push(o);

        ObjPoolIndex::<T> {i: i, type_marker: PhantomData}
    }

    pub fn get(&self, i: &ObjPoolIndex<T>) -> &T {
        &self.storage[i.i]
    }

    pub fn get_mut(&mut self, i: &ObjPoolIndex<T>) -> &mut T {
        &mut self.storage[i.i]
    }
}

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

    #[test]
    fn stringpool_basic_works() {
        let mut sp = StringPool::new();
        let x = sp.add_latin1_str(b"test1");
        let y = sp.add_latin1_str(b"test2");
        let sx = sp.retrieve_latin1_str(&x);
        let sy = sp.retrieve_latin1_str(&y);
        assert_eq!(sx.raw_name(), b"test1");
        assert_eq!(sy.raw_name(), b"test2");
    }

    #[test]
    fn stringpool_actually_pools() {
        let mut sp = StringPool::new();
        sp.add_latin1_str(b"test1");
        sp.add_latin1_str(b"test2");
        assert_eq!(sp.storage, b"test1test2");
    }

    #[derive(Default)]
    struct ObjPoolTestObject {
        foo: u32
    }

    #[test]
    fn objpool_basic_works() {
        let mut pool = ObjPool::<ObjPoolTestObject>::new();
        let x = pool.alloc();
        let y = pool.alloc();
        {
            let o = pool.get_mut(&x);
            o.foo = 123;
        }
        {
            let o = pool.get_mut(&y);
            o.foo = 456;
        }
        let ox = pool.get(&x);
        let oy = pool.get(&y);
        assert_eq!(ox.foo, 123);
        assert_eq!(oy.foo, 456);
    }
}
<commit_msg>Correctly make object pool indices Copy<commit_after>/*
Copyright (c) 2016-2017, Robert Ou <rqou@robertou.com>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

use std::marker::PhantomData;

use analyzer::util::*;

// We need this because the Vec can be reallocated around, but we want to keep
// around some kind of reference into the storage that can keep working after
// the reallocation happens.
#[derive(Copy, Clone)]
pub struct StringPoolIndex {
    start: usize,
    end: usize,
}

pub struct StringPool {
    storage: Vec<u8>
}

impl StringPool {
    pub fn new() -> StringPool {
        StringPool {storage: Vec::new()}
    }

    // TODO: Might interning strings improve performance in the future?
    // TODO: Do we care about freeing things?
    pub fn add_latin1_str(&mut self, inp: &[u8]) -> StringPoolIndex {
        let addition_begin = self.storage.len();
        let addition_length = inp.len();

        self.storage.extend(inp.iter().cloned());

        StringPoolIndex {
            start: addition_begin,
            end: addition_begin + addition_length
        }
    }

    pub fn retrieve_latin1_str(&self, i: StringPoolIndex) -> Latin1Str {
        let the_slice = &self.storage[i.start..i.end];
        Latin1Str::new(the_slice)
    }
}

pub struct ObjPoolIndex<T> {
    i: usize,
    type_marker: PhantomData<T>
}

impl<T> Copy for ObjPoolIndex<T> { }

impl<T> Clone for ObjPoolIndex<T> {
    fn clone(&self) -> ObjPoolIndex<T> {
        *self
    }
}

pub struct ObjPool<T> {
    storage: Vec<T>
}

impl<T: Default> ObjPool<T> {
    pub fn new() -> ObjPool<T> {
        ObjPool {storage: Vec::new()}
    }

    pub fn alloc(&mut self) -> ObjPoolIndex<T> {
        let i = self.storage.len();
        let o = T::default();

        self.storage.push(o);

        ObjPoolIndex::<T> {i: i, type_marker: PhantomData}
    }

    pub fn get(&self, i: ObjPoolIndex<T>) -> &T {
        &self.storage[i.i]
    }

    pub fn get_mut(&mut self, i: ObjPoolIndex<T>) -> &mut T {
        &mut self.storage[i.i]
    }
}

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

    #[test]
    fn stringpool_basic_works() {
        let mut sp = StringPool::new();
        let x = sp.add_latin1_str(b"test1");
        let y = sp.add_latin1_str(b"test2");
        let sx = sp.retrieve_latin1_str(x);
        let sy = sp.retrieve_latin1_str(y);
        assert_eq!(sx.raw_name(), b"test1");
        assert_eq!(sy.raw_name(), b"test2");
    }

    #[test]
    fn stringpool_actually_pools() {
        let mut sp = StringPool::new();
        sp.add_latin1_str(b"test1");
        sp.add_latin1_str(b"test2");
        assert_eq!(sp.storage, b"test1test2");
    }

    #[derive(Default)]
    struct ObjPoolTestObject {
        foo: u32
    }

    #[test]
    fn objpool_basic_works() {
        let mut pool = ObjPool::<ObjPoolTestObject>::new();
        let x = pool.alloc();
        let y = pool.alloc();
        {
            let o = pool.get_mut(x);
            o.foo = 123;
        }
        {
            let o = pool.get_mut(y);
            o.foo = 456;
        }
        let ox = pool.get(x);
        let oy = pool.get(y);
        assert_eq!(ox.foo, 123);
        assert_eq!(oy.foo, 456);
    }
}
<|endoftext|>


<commit_before>use autograd::function::*;
use tensor::Tensor;
use ::*;

pub type VarList<T> = Vec<Variable<T>>;

pub struct VariableImpl<T> {
    data: Option<Tensor<T>>,
    grad_fn: OptRcMut<Function<T>>,
    grad: OptRcMut<Variable<T>>,
	// version_counter etc ...
}

pub struct Variable<T> {
    value: RcMut<VariableImpl<T>>,
}

impl<T> Clone for Variable<T> {
    fn clone(&self) -> Self {
        Variable { value: self.value.clone() }
    }
}

pub struct SavedVariable<T> {
    data: Box<Tensor<T>>,
    grad_fn: OptRcMut<Function<T>>,
    grad: OptRcMut<Variable<T>>,
	// version_counter etc ...
}

impl<T> Variable<T> {
    pub fn apply(&mut self, callback: fn(&mut Tensor<T>)) {
        let mut v = self.value.borrow_mut();
        if let Some(ref mut t) = v.data {
            callback(&mut *t);
        }
    }
    pub fn view(&self, dims: &[i32]) -> Self {
        self.clone()
    }

}

impl<T> Default for Variable<T> {
    fn default() -> Self {
        let v = VariableImpl {
            data: None,
            grad_fn: None,
            grad: None,
        };
        Variable { value: RcMutNew(v) }
    }
}<commit_msg>add backward & detach stubs<commit_after>use autograd::function::*;
use tensor::Tensor;
use ::*;

pub type VarList<T> = Vec<Variable<T>>;

pub struct VariableImpl<T> {
    data: Option<Tensor<T>>,
    grad_fn: OptRcMut<Function<T>>,
    grad: OptRcMut<Variable<T>>,
	// version_counter etc ...
}

pub struct Variable<T> {
    value: RcMut<VariableImpl<T>>,
}

impl<T> Clone for Variable<T> {
    fn clone(&self) -> Self {
        Variable { value: self.value.clone() }
    }
}

pub struct SavedVariable<T> {
    data: Box<Tensor<T>>,
    grad_fn: OptRcMut<Function<T>>,
    grad: OptRcMut<Variable<T>>,
	// version_counter etc ...
}

pub struct BackwardArgs {}

impl<T> Variable<T> {
    pub fn apply(&mut self, callback: fn(&mut Tensor<T>)) {
        let mut v = self.value.borrow_mut();
        if let Some(ref mut t) = v.data {
            callback(&mut *t);
        }
    }
    pub fn view(&self, dims: &[i32]) -> Self {
        self.clone()
    }
    // Computes the gradient of current variable w.r.t. graph leaves
    pub fn backward(&mut self, args: &BackwardArgs) {}
    // Detach from graph
    pub fn detach_(&mut self) {}
    // return a new variable detached from graph
    pub fn detach(&self) -> Variable<T> {
        self.clone()
    }
}

impl<T> Default for Variable<T> {
    fn default() -> Self {
        let v = VariableImpl {
            data: None,
            grad_fn: None,
            grad: None,
        };
        Variable { value: RcMutNew(v) }
    }
}
<|endoftext|>


<commit_before><commit_msg>add new station<commit_after><|endoftext|>


<commit_before>use hyper::header::common::content_type::ContentType;
use hyper::server::request::Request;

use mime::{Mime, AttrExt, ValueExt};

use super::{MultipartField, TextField, MultipartFile, FileField};

use std::io::{RefReader, BufferedReader, IoError, IoResult, EndOfFile, standard_error, OtherIoError};

use std::kinds::marker;

fn is_multipart_formdata(req: &Request) -> bool {
    use mime::{Multipart, Mime, SubExt};

    req.headers.get::<ContentType>().map(|ct| {
        let ContentType(ref mime) = *ct;
        match *mime {
            Mime(Multipart, SubExt(ref subtype), _) => subtype[] == "form-data",
            _ => false,
        }
    }).unwrap_or(false)
}

fn get_boundary(ct: &ContentType) -> Option<String> {
    let ContentType(ref mime) = *ct;
    let Mime(_, _, ref params) = *mime;

    params.iter().find(|&&(ref name, _)|
        if let AttrExt(ref name) = *name {
            name[] == "boundary"
        } else { false }
    ).and_then(|&(_, ref val)|
        if let ValueExt(ref val) = *val {
            Some(val.clone())
        } else { None }
    )
}

pub struct Multipart {
    source: BoundaryReader,
}

macro_rules! try_find(
    ($haystack:expr, $f:ident, $needle:expr, $err:expr, $line:expr) => (
        try!($haystack.$f($needle).ok_or(line_error($err, $line.clone())))
    )
)

impl Multipart {

    /// If the given `Request` is of `Content-Type: multipart/form-data`, return
    /// the wrapped request as `Ok(Multipart)`, otherwise `Err(Request)`.
    pub fn from_request(req: Request) -> Result<Multipart, Request> {
        if !is_multipart_formdata(&req) { return Err(req); }

        let boundary = if let Some(boundary) = req.headers.get::<ContentType>()
            .and_then(get_boundary) { boundary } else { return Err(req); };

        Ok(Multipart { source: BoundaryReader::from_request(req, boundary) })
    }

    pub fn read_entry<'a>(&'a mut self) -> IoResult<(String, MultipartField<'a>)> {
        let (disp_type, field_name, filename) = try!(self.read_content_disposition());

        if &*disp_type != "form-data" {
            return Err(IoError {
                    kind: OtherIoError,
                    desc: "Content-Disposition value was not \"form-data\"",
                    detail: Some(format!("Content-Disposition: {}", disp_type)),
                });
        }

        if let Some(content_type) = try!(self.read_content_type()) {
            let _ = try!(self.source.reader.read_line()); // Consume empty line
            Ok((field_name, FileField(MultipartFile::from_octet(filename, &mut self.source, content_type[]))))
        } else {
            // Empty line consumed by read_content_type()
            let text = try!(self.source.read_to_string());
            Ok((field_name, TextField(text)))
        }
    }

    /// Call `f` for each entry in the multipart request.
    /// This is a substitute for `Multipart` implementing `Iterator`,
    /// since `Iterator::next()` can't use bound lifetimes.
    /// See https://www.reddit.com/r/rust/comments/2lkk4i/concrete_lifetime_vs_bound_lifetime/
    pub fn foreach_entry(&mut self, f: <'a>|String, MultipartField<'a>|) {
        loop {
            match self.read_entry() {
                Ok((name, field)) => f(name, field),
                Err(err) => {
                    if err.kind != EndOfFile {
                        error!("Error reading Multipart: {}", err);
                    }

                    break;
                },
            }
        }
    }

    fn read_content_disposition(&mut self) -> IoResult<(String, String, Option<String>)> {
        let line = try!(self.source.reader.read_line());

        // Find the end of CONT_DISP in the line
        let disp_type = {
            const CONT_DISP: &'static str = "Content-Disposition:";

            let disp_idx = try_find!(line[], find_str, CONT_DISP,
                "Content-Disposition subheader not found!", line) + CONT_DISP.len();

            let disp_type_end = try_find!(line[disp_idx..], find, ';',
                "Error parsing Content-Disposition value!", line);

            line[disp_idx .. disp_type_end].trim().into_string()
        };

        let field_name = {
            const NAME: &'static str = "name=\"";

            let name_idx = try_find!(line[], find_str, NAME,
                "Error parsing field name!", line) + NAME.len();

            let name_end = try_find!(line[name_idx ..], find, '"',
                "Error parsing field name!", line);

            line[name_idx .. name_end].into_string() // No trim here since it's in quotes.
        };

        let filename = {
            const FILENAME: &'static str = "filename=\"";

            let filename_idx = line[].find_str(FILENAME).map(|idx| idx + FILENAME.len());
            let filename_idxs = with(filename_idx, |&start| line[start ..].find('"'));

            filename_idxs.map(|(start, end)| line[start .. end].into_string())
        };

        Ok((disp_type, field_name, filename))
    }

    fn read_content_type(&mut self) -> IoResult<Option<String>> {
        let line = try!(self.source.reader.read_line());

        const CONTENT_TYPE: &'static str = "Content-Type:";

        let type_idx = (&*line).find_str(CONTENT_TYPE);

        // FIXME Will not properly parse for multiple files!
        // Does not expect boundary=<boundary>
        Ok(type_idx.map(|start| line[start + CONTENT_TYPE.len()..].trim().into_string()))
    }
}

fn with<T, U>(left: Option<T>, right: |&T| -> Option<U>) -> Option<(T, U)> {
    let temp = left.as_ref().and_then(right);
    match (left, temp) {
        (Some(lval), Some(rval)) => Some((lval, rval)),
        _ => None,
    }
}

fn line_error(msg: &'static str, line: String) -> IoError {
    IoError {
        kind: OtherIoError,
        desc: msg,
        detail: Some(line),
    }
}

/* FIXME: Can't have an iterator return a borrowed reference
impl<'a> Iterator<(String, MultipartField<'a>)> for Multipart {
    fn next(&mut self) -> Option<(String, MultipartField<'a>)> {
        match self.read_entry() {
            Ok(ok) => Some(ok),
            Err(err) => {
                if err.kind != EndOfFile {
                    error!("Error reading Multipart: {}", err);
                }

                None
             },
        }
    }
}
*/

/// A `Reader` that will yield bytes until it sees a given sequence.
pub struct BoundaryReader {
    reader: BufferedReader<Request>,
    boundary: Vec<u8>,
    last_search_idx: uint,
    boundary_read: bool,
}

impl BoundaryReader {
    fn from_request(request: Request, mut boundary: String) -> BoundaryReader {
        boundary.prepend("--");

        BoundaryReader {
            reader: BufferedReader::new(request),
            boundary: boundary.into_bytes(),
            last_search_idx: 0,
            boundary_read: false,
        }
    }

    fn read_to_boundary(&mut self) -> IoResult<bool> {
         if !self.boundary_read {
            let lookahead = try!(self.reader.fill_buf());

            self.last_search_idx = lookahead[self.last_search_idx..]
                .position_elem(&b'-').unwrap_or(lookahead.len() - 1);

            Ok(lookahead[self.last_search_idx..].starts_with(self.boundary[]))
        } else if self.last_search_idx == 0 {
            Err(standard_error(EndOfFile))
        } else { Ok(true) }
    }

    fn consume_boundary(&mut self) {
        self.reader.consume(self.last_search_idx + self.boundary.len());
        self.last_search_idx = 0;
        self.boundary_read = false;
    }

    fn set_boundary(&mut self, boundary: String) {
        self.boundary = boundary.into_bytes();
    }
}

impl Reader for BoundaryReader {
    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
        use std::cmp;

        self.boundary_read = try!(self.read_to_boundary());

        let trunc_len = cmp::min(buf.len(), self.last_search_idx);

        let trunc_buf = buf[mut ..trunc_len]; // Truncate the buffer so we don't read ahead

        let bytes_read = self.reader.read(trunc_buf).unwrap();
        self.last_search_idx -= bytes_read;

        Ok(bytes_read)
    }
}

trait Prepend<T> {
    fn prepend(&mut self, t: T);
}

impl<S: Str> Prepend<S> for String {
    fn prepend(&mut self, s: S) {
        unsafe {
            self.as_mut_vec().prepend(s.as_slice().as_bytes());
        }
    }
}

impl<'a, T> Prepend<&'a [T]> for Vec<T> {
    fn prepend(&mut self, slice: &[T]) {
        use std::ptr::copy_memory;

        let old_len = self.len();

        self.reserve(slice.len());

        unsafe {
            self.set_len(old_len + slice.len());
            copy_memory(self[mut slice.len()..].as_mut_ptr(), self[..old_len].as_ptr(), old_len);
            copy_memory(self.as_mut_ptr(), slice.as_ptr(), slice.len());
        }
    }
}

#[test]
fn test_prepend() {
    let mut vec = vec![3u64, 4, 5];
    vec.prepend([1u64, 2]);
    assert_eq!(vec[], [1u64, 2, 3, 4, 5][]);
}

#[test]
fn test_prepend_string() {
    let mut string = "World!".into_string();
    string.prepend("Hello, ");
    assert_eq!(&*string, "Hello, World!");
}

<commit_msg>updated lifetime syntax<commit_after>use hyper::header::common::content_type::ContentType;
use hyper::server::request::Request;

use mime::{Mime, AttrExt, ValueExt};

use super::{MultipartField, TextField, MultipartFile, FileField};

use std::io::{RefReader, BufferedReader, IoError, IoResult, EndOfFile, standard_error, OtherIoError};

use std::kinds::marker;

fn is_multipart_formdata(req: &Request) -> bool {
    use mime::{Multipart, Mime, SubExt};

    req.headers.get::<ContentType>().map(|ct| {
        let ContentType(ref mime) = *ct;
        match *mime {
            Mime(Multipart, SubExt(ref subtype), _) => subtype[] == "form-data",
            _ => false,
        }
    }).unwrap_or(false)
}

fn get_boundary(ct: &ContentType) -> Option<String> {
    let ContentType(ref mime) = *ct;
    let Mime(_, _, ref params) = *mime;

    params.iter().find(|&&(ref name, _)|
        if let AttrExt(ref name) = *name {
            name[] == "boundary"
        } else { false }
    ).and_then(|&(_, ref val)|
        if let ValueExt(ref val) = *val {
            Some(val.clone())
        } else { None }
    )
}

pub struct Multipart {
    source: BoundaryReader,
}

macro_rules! try_find(
    ($haystack:expr, $f:ident, $needle:expr, $err:expr, $line:expr) => (
        try!($haystack.$f($needle).ok_or(line_error($err, $line.clone())))
    )
)

impl Multipart {

    /// If the given `Request` is of `Content-Type: multipart/form-data`, return
    /// the wrapped request as `Ok(Multipart)`, otherwise `Err(Request)`.
    pub fn from_request(req: Request) -> Result<Multipart, Request> {
        if !is_multipart_formdata(&req) { return Err(req); }

        let boundary = if let Some(boundary) = req.headers.get::<ContentType>()
            .and_then(get_boundary) { boundary } else { return Err(req); };

        Ok(Multipart { source: BoundaryReader::from_request(req, boundary) })
    }

    pub fn read_entry<'a>(&'a mut self) -> IoResult<(String, MultipartField<'a>)> {
        let (disp_type, field_name, filename) = try!(self.read_content_disposition());

        if &*disp_type != "form-data" {
            return Err(IoError {
                    kind: OtherIoError,
                    desc: "Content-Disposition value was not \"form-data\"",
                    detail: Some(format!("Content-Disposition: {}", disp_type)),
                });
        }

        if let Some(content_type) = try!(self.read_content_type()) {
            let _ = try!(self.source.reader.read_line()); // Consume empty line
            Ok((field_name, FileField(MultipartFile::from_octet(filename, &mut self.source, content_type[]))))
        } else {
            // Empty line consumed by read_content_type()
            let text = try!(self.source.read_to_string());
            Ok((field_name, TextField(text)))
        }
    }

    /// Call `f` for each entry in the multipart request.
    /// This is a substitute for `Multipart` implementing `Iterator`,
    /// since `Iterator::next()` can't use bound lifetimes.
    /// See https://www.reddit.com/r/rust/comments/2lkk4i/concrete_lifetime_vs_bound_lifetime/
    pub fn foreach_entry(&mut self, f: for<'a>|String, MultipartField<'a>|) {
        loop {
            match self.read_entry() {
                Ok((name, field)) => f(name, field),
                Err(err) => {
                    if err.kind != EndOfFile {
                        error!("Error reading Multipart: {}", err);
                    }

                    break;
                },
            }
        }
    }

    fn read_content_disposition(&mut self) -> IoResult<(String, String, Option<String>)> {
        let line = try!(self.source.reader.read_line());

        // Find the end of CONT_DISP in the line
        let disp_type = {
            const CONT_DISP: &'static str = "Content-Disposition:";

            let disp_idx = try_find!(line[], find_str, CONT_DISP,
                "Content-Disposition subheader not found!", line) + CONT_DISP.len();

            let disp_type_end = try_find!(line[disp_idx..], find, ';',
                "Error parsing Content-Disposition value!", line);

            line[disp_idx .. disp_type_end].trim().into_string()
        };

        let field_name = {
            const NAME: &'static str = "name=\"";

            let name_idx = try_find!(line[], find_str, NAME,
                "Error parsing field name!", line) + NAME.len();

            let name_end = try_find!(line[name_idx ..], find, '"',
                "Error parsing field name!", line);

            line[name_idx .. name_end].into_string() // No trim here since it's in quotes.
        };

        let filename = {
            const FILENAME: &'static str = "filename=\"";

            let filename_idx = line[].find_str(FILENAME).map(|idx| idx + FILENAME.len());
            let filename_idxs = with(filename_idx, |&start| line[start ..].find('"'));

            filename_idxs.map(|(start, end)| line[start .. end].into_string())
        };

        Ok((disp_type, field_name, filename))
    }

    fn read_content_type(&mut self) -> IoResult<Option<String>> {
        let line = try!(self.source.reader.read_line());

        const CONTENT_TYPE: &'static str = "Content-Type:";

        let type_idx = (&*line).find_str(CONTENT_TYPE);

        // FIXME Will not properly parse for multiple files!
        // Does not expect boundary=<boundary>
        Ok(type_idx.map(|start| line[start + CONTENT_TYPE.len()..].trim().into_string()))
    }
}

fn with<T, U>(left: Option<T>, right: |&T| -> Option<U>) -> Option<(T, U)> {
    let temp = left.as_ref().and_then(right);
    match (left, temp) {
        (Some(lval), Some(rval)) => Some((lval, rval)),
        _ => None,
    }
}

fn line_error(msg: &'static str, line: String) -> IoError {
    IoError {
        kind: OtherIoError,
        desc: msg,
        detail: Some(line),
    }
}

/* FIXME: Can't have an iterator return a borrowed reference
impl<'a> Iterator<(String, MultipartField<'a>)> for Multipart {
    fn next(&mut self) -> Option<(String, MultipartField<'a>)> {
        match self.read_entry() {
            Ok(ok) => Some(ok),
            Err(err) => {
                if err.kind != EndOfFile {
                    error!("Error reading Multipart: {}", err);
                }

                None
             },
        }
    }
}
*/

/// A `Reader` that will yield bytes until it sees a given sequence.
pub struct BoundaryReader {
    reader: BufferedReader<Request>,
    boundary: Vec<u8>,
    last_search_idx: uint,
    boundary_read: bool,
}

impl BoundaryReader {
    fn from_request(request: Request, mut boundary: String) -> BoundaryReader {
        boundary.prepend("--");

        BoundaryReader {
            reader: BufferedReader::new(request),
            boundary: boundary.into_bytes(),
            last_search_idx: 0,
            boundary_read: false,
        }
    }

    fn read_to_boundary(&mut self) -> IoResult<bool> {
         if !self.boundary_read {
            let lookahead = try!(self.reader.fill_buf());

            self.last_search_idx = lookahead[self.last_search_idx..]
                .position_elem(&b'-').unwrap_or(lookahead.len() - 1);

            Ok(lookahead[self.last_search_idx..].starts_with(self.boundary[]))
        } else if self.last_search_idx == 0 {
            Err(standard_error(EndOfFile))
        } else { Ok(true) }
    }

    fn consume_boundary(&mut self) {
        self.reader.consume(self.last_search_idx + self.boundary.len());
        self.last_search_idx = 0;
        self.boundary_read = false;
    }

    fn set_boundary(&mut self, boundary: String) {
        self.boundary = boundary.into_bytes();
    }
}

impl Reader for BoundaryReader {
    fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> {
        use std::cmp;

        self.boundary_read = try!(self.read_to_boundary());

        let trunc_len = cmp::min(buf.len(), self.last_search_idx);

        let trunc_buf = buf[mut ..trunc_len]; // Truncate the buffer so we don't read ahead

        let bytes_read = self.reader.read(trunc_buf).unwrap();
        self.last_search_idx -= bytes_read;

        Ok(bytes_read)
    }
}

trait Prepend<T> {
    fn prepend(&mut self, t: T);
}

impl<S: Str> Prepend<S> for String {
    fn prepend(&mut self, s: S) {
        unsafe {
            self.as_mut_vec().prepend(s.as_slice().as_bytes());
        }
    }
}

impl<'a, T> Prepend<&'a [T]> for Vec<T> {
    fn prepend(&mut self, slice: &[T]) {
        use std::ptr::copy_memory;

        let old_len = self.len();

        self.reserve(slice.len());

        unsafe {
            self.set_len(old_len + slice.len());
            copy_memory(self[mut slice.len()..].as_mut_ptr(), self[..old_len].as_ptr(), old_len);
            copy_memory(self.as_mut_ptr(), slice.as_ptr(), slice.len());
        }
    }
}

#[test]
fn test_prepend() {
    let mut vec = vec![3u64, 4, 5];
    vec.prepend([1u64, 2]);
    assert_eq!(vec[], [1u64, 2, 3, 4, 5][]);
}

#[test]
fn test_prepend_string() {
    let mut string = "World!".into_string();
    string.prepend("Hello, ");
    assert_eq!(&*string, "Hello, World!");
}

<|endoftext|>


<commit_before>/// Formatting macro for constructing `Ident`s.
///
///

///
/// # Syntax
///
/// Syntax is copied from the [`format!`] macro, supporting both positional and
/// named arguments.
///
/// Only a limited set of formatting traits are supported. The current mapping
/// of format types to traits is:
///
/// * `{}` ⇒ [`IdentFragment`]
/// * `{:o}` ⇒ [`Octal`](std::fmt::Octal)
/// * `{:x}` ⇒ [`LowerHex`](std::fmt::LowerHex)
/// * `{:X}` ⇒ [`UpperHex`](std::fmt::UpperHex)
/// * `{:b}` ⇒ [`Binary`](std::fmt::Binary)
///
/// See [`std::fmt`] for more information.
///
///

///
/// # IdentFragment
///
/// Unlike `format!`, this macro uses the [`IdentFragment`] formatting trait by
/// default. This trait is like `Display`, with a few differences:
///
/// * `IdentFragment` is only implemented for a limited set of types, such as
///    unsigned integers and strings.
/// * [`Ident`] arguments will have their `r#` prefixes stripped, if present.
///
/// [`Ident`]: proc_macro2::Ident
///
///

///
/// # Hygiene
///
/// The [`Span`] of the first `Ident` argument is used as the span of the final
/// identifier, falling back to [`Span::call_site`] when no identifiers are
/// provided.
///
/// ```
/// # use quote::format_ident;
/// # let ident = format_ident!("Ident");
/// // If `ident` is an Ident, the span of `my_ident` will be inherited from it.
/// let my_ident = format_ident!("My{}{}", ident, "IsCool");
/// assert_eq!(my_ident, "MyIdentIsCool");
/// ```
///
/// Alternatively, the span can be overridden by passing the `span` named
/// argument.
///
/// ```
/// # use quote::format_ident;
/// # const IGNORE_TOKENS: &'static str = stringify! {
/// let my_span = /* ... */;
/// # };
/// # let my_span = proc_macro2::Span::call_site();
/// format_ident!("MyIdent", span = my_span);
/// ```
///
/// [`Span`]: proc_macro2::Span
/// [`Span::call_site`]: proc_macro2::Span::call_site
///
///

///
/// # Panics
///
/// This method will panic if the resulting formatted string is not a valid
/// identifier.
///
///

///
/// # Examples
///
/// Composing raw and non-raw identifiers:
/// ```
/// # use quote::format_ident;
/// let my_ident = format_ident!("My{}", "Ident");
/// assert_eq!(my_ident, "MyIdent");
///
/// let raw = format_ident!("r#Raw");
/// assert_eq!(raw, "r#Raw");
///
/// let my_ident_raw = format_ident!("{}Is{}", my_ident, raw);
/// assert_eq!(my_ident_raw, "MyIdentIsRaw");
/// ```
///
/// Integer formatting options:
/// ```
/// # use quote::format_ident;
/// let num: u32 = 10;
///
/// let decimal = format_ident!("Id_{}", num);
/// assert_eq!(decimal, "Id_10");
///
/// let octal = format_ident!("Id_{:o}", num);
/// assert_eq!(octal, "Id_12");
///
/// let binary = format_ident!("Id_{:b}", num);
/// assert_eq!(binary, "Id_1010");
///
/// let lower_hex = format_ident!("Id_{:x}", num);
/// assert_eq!(lower_hex, "Id_a");
///
/// let upper_hex = format_ident!("Id_{:X}", num);
/// assert_eq!(upper_hex, "Id_A");
/// ```
#[macro_export]
macro_rules! format_ident {
    ($fmt:expr) => {
        $crate::format_ident_impl!([
            ::std::option::Option::None,
            $fmt
        ])
    };

    ($fmt:expr, $($rest:tt)*) => {
        $crate::format_ident_impl!([
            ::std::option::Option::None,
            $fmt
        ] $($rest)*)
    };
}

#[macro_export]
#[doc(hidden)]
macro_rules! format_ident_impl {
    // Final state
    ([$span:expr, $($fmt:tt)*]) => {
        $crate::__private::mk_ident(&format!($($fmt)*), $span)
    };

    // Span argument
    ([$old:expr, $($fmt:tt)*] span = $span:expr) => {
        $crate::format_ident_impl!([$old, $($fmt)*] span = $span,)
    };
    ([$old:expr, $($fmt:tt)*] span = $span:expr, $($rest:tt)*) => {
        $crate::format_ident_impl!([
            ::std::option::Option::Some::<$crate::__private::Span>($span),
            $($fmt)*
        ] $($rest)*)
    };

    // Named argument
    ([$span:expr, $($fmt:tt)*] $name:ident = $arg:expr) => {
        $crate::format_ident_impl!([$span, $($fmt)*] $name = $arg,)
    };
    ([$span:expr, $($fmt:tt)*] $name:ident = $arg:expr, $($rest:tt)*) => {
        match $crate::__private::IdentFragmentAdapter(&$arg) {
            arg => $crate::format_ident_impl!([$span.or(arg.span()), $($fmt)*, $name = arg] $($rest)*),
        }
    };

    // Positional argument
    ([$span:expr, $($fmt:tt)*] $arg:expr) => {
        $crate::format_ident_impl!([$span, $($fmt)*] $arg,)
    };
    ([$span:expr, $($fmt:tt)*] $arg:expr, $($rest:tt)*) => {
        match $crate::__private::IdentFragmentAdapter(&$arg) {
            arg => $crate::format_ident_impl!([$span.or(arg.span()), $($fmt)*, arg] $($rest)*),
        }
    };
}
<commit_msg>Fix broken IdentFragment link in format_ident doc<commit_after>/// Formatting macro for constructing `Ident`s.
///
///

///
/// # Syntax
///
/// Syntax is copied from the [`format!`] macro, supporting both positional and
/// named arguments.
///
/// Only a limited set of formatting traits are supported. The current mapping
/// of format types to traits is:
///
/// * `{}` ⇒ [`IdentFragment`]
/// * `{:o}` ⇒ [`Octal`](std::fmt::Octal)
/// * `{:x}` ⇒ [`LowerHex`](std::fmt::LowerHex)
/// * `{:X}` ⇒ [`UpperHex`](std::fmt::UpperHex)
/// * `{:b}` ⇒ [`Binary`](std::fmt::Binary)
///
/// See [`std::fmt`] for more information.
///
///

///
/// # IdentFragment
///
/// Unlike `format!`, this macro uses the [`IdentFragment`] formatting trait by
/// default. This trait is like `Display`, with a few differences:
///
/// * `IdentFragment` is only implemented for a limited set of types, such as
///    unsigned integers and strings.
/// * [`Ident`] arguments will have their `r#` prefixes stripped, if present.
///
/// [`IdentFragment`]: crate::IdentFragment
/// [`Ident`]: proc_macro2::Ident
///
///

///
/// # Hygiene
///
/// The [`Span`] of the first `Ident` argument is used as the span of the final
/// identifier, falling back to [`Span::call_site`] when no identifiers are
/// provided.
///
/// ```
/// # use quote::format_ident;
/// # let ident = format_ident!("Ident");
/// // If `ident` is an Ident, the span of `my_ident` will be inherited from it.
/// let my_ident = format_ident!("My{}{}", ident, "IsCool");
/// assert_eq!(my_ident, "MyIdentIsCool");
/// ```
///
/// Alternatively, the span can be overridden by passing the `span` named
/// argument.
///
/// ```
/// # use quote::format_ident;
/// # const IGNORE_TOKENS: &'static str = stringify! {
/// let my_span = /* ... */;
/// # };
/// # let my_span = proc_macro2::Span::call_site();
/// format_ident!("MyIdent", span = my_span);
/// ```
///
/// [`Span`]: proc_macro2::Span
/// [`Span::call_site`]: proc_macro2::Span::call_site
///
///

///
/// # Panics
///
/// This method will panic if the resulting formatted string is not a valid
/// identifier.
///
///

///
/// # Examples
///
/// Composing raw and non-raw identifiers:
/// ```
/// # use quote::format_ident;
/// let my_ident = format_ident!("My{}", "Ident");
/// assert_eq!(my_ident, "MyIdent");
///
/// let raw = format_ident!("r#Raw");
/// assert_eq!(raw, "r#Raw");
///
/// let my_ident_raw = format_ident!("{}Is{}", my_ident, raw);
/// assert_eq!(my_ident_raw, "MyIdentIsRaw");
/// ```
///
/// Integer formatting options:
/// ```
/// # use quote::format_ident;
/// let num: u32 = 10;
///
/// let decimal = format_ident!("Id_{}", num);
/// assert_eq!(decimal, "Id_10");
///
/// let octal = format_ident!("Id_{:o}", num);
/// assert_eq!(octal, "Id_12");
///
/// let binary = format_ident!("Id_{:b}", num);
/// assert_eq!(binary, "Id_1010");
///
/// let lower_hex = format_ident!("Id_{:x}", num);
/// assert_eq!(lower_hex, "Id_a");
///
/// let upper_hex = format_ident!("Id_{:X}", num);
/// assert_eq!(upper_hex, "Id_A");
/// ```
#[macro_export]
macro_rules! format_ident {
    ($fmt:expr) => {
        $crate::format_ident_impl!([
            ::std::option::Option::None,
            $fmt
        ])
    };

    ($fmt:expr, $($rest:tt)*) => {
        $crate::format_ident_impl!([
            ::std::option::Option::None,
            $fmt
        ] $($rest)*)
    };
}

#[macro_export]
#[doc(hidden)]
macro_rules! format_ident_impl {
    // Final state
    ([$span:expr, $($fmt:tt)*]) => {
        $crate::__private::mk_ident(&format!($($fmt)*), $span)
    };

    // Span argument
    ([$old:expr, $($fmt:tt)*] span = $span:expr) => {
        $crate::format_ident_impl!([$old, $($fmt)*] span = $span,)
    };
    ([$old:expr, $($fmt:tt)*] span = $span:expr, $($rest:tt)*) => {
        $crate::format_ident_impl!([
            ::std::option::Option::Some::<$crate::__private::Span>($span),
            $($fmt)*
        ] $($rest)*)
    };

    // Named argument
    ([$span:expr, $($fmt:tt)*] $name:ident = $arg:expr) => {
        $crate::format_ident_impl!([$span, $($fmt)*] $name = $arg,)
    };
    ([$span:expr, $($fmt:tt)*] $name:ident = $arg:expr, $($rest:tt)*) => {
        match $crate::__private::IdentFragmentAdapter(&$arg) {
            arg => $crate::format_ident_impl!([$span.or(arg.span()), $($fmt)*, $name = arg] $($rest)*),
        }
    };

    // Positional argument
    ([$span:expr, $($fmt:tt)*] $arg:expr) => {
        $crate::format_ident_impl!([$span, $($fmt)*] $arg,)
    };
    ([$span:expr, $($fmt:tt)*] $arg:expr, $($rest:tt)*) => {
        match $crate::__private::IdentFragmentAdapter(&$arg) {
            arg => $crate::format_ident_impl!([$span.or(arg.span()), $($fmt)*, arg] $($rest)*),
        }
    };
}
<|endoftext|>


<commit_before>//! The traits defined here are implementation details of cell_gc.
//!
//! Application code does not need to use these traits. They are public only so
//! that `#[derive(IntoHeap)]` can use it. Use the friendly macro!

use gc_leaf::GcLeaf;
use gc_ref::GcRef;
use ptr::Pointer;
use std::hash::Hash;
use std::marker::PhantomData;

/// Base trait for values that can be moved into a GC heap.
pub trait IntoHeapBase: Sized {
    /// The type of the value when it is physically stored in the heap.
    ///
    /// GC types come in pairs: an `IntoHeap` type and an `In` type. Ideally
    /// both types would have the same layout, bit for bit, but Rust makes no
    /// promises about struct and enum layout generally, so we can't guarantee
    /// this.
    ///
    /// The `In` type is stored physically inside the heap, and may be packed
    /// with pointer fields and unsafe methods. The `IntoHeap` type is safe, is
    /// used in application code, and lives on the stack.
    ///
    /// *   For primitive types, like `i32`, the two types are the same.
    ///
    /// *   Macro-generated "Ref" types are `IntoHeap` types; the corresponding
    ///     in-heap types are effectively raw pointers.
    ///
    /// *   For user-defined structs and enums, the `#[derive(IntoHeap)]` macro
    ///     autogenerates an `In` type for you. It has identical fields or
    ///     variants, but fields of the `IntoHeap` type are `IntoHeap`, and
    ///     fields of the `In` type are the corresponding `In` types.
    ///
    /// (The word "safe" above means that, as with everything generally in Rust, you
    /// can hack without fear. `IntoHeap` types don't expose raw Rust pointers or
    /// references to GC memory, they don't expose the unsafe in-heap types, and
    /// they obey Rust's safety and aliasing rules.)
    ///
    /// Users never get a direct `&` reference to any in-heap value. All access is
    /// through safe `IntoHeap` types, like the `Ref` type that is automatically
    /// declared for you when you use `#[derive(IntoHeap)]` on a struct or union.
    type In: 'static;

    /// Convert the value to the form it should have in the heap.
    /// This is for cell-gc to call.
    ///
    /// This method must not be called while any direct Rust references to
    /// heap objects exist. (However, user code never runs while such
    /// references exist, so the method is not marked `unsafe`.)
    fn into_heap(self) -> Self::In;

    /// Extract the value from the heap. This turns any raw pointers in the
    /// in-heap value into safe references, so while it's an unsafe function,
    /// the result of a correct call can be safely handed out to user code.
    ///
    /// # Safety
    ///
    /// It is impossible for ordinary users to call this safely, because `self`
    /// must be a direct, unwrapped reference to a value stored in the GC heap,
    /// which ordinary users cannot obtain.
    unsafe fn from_heap(&Self::In) -> Self;

    /// Traverse a value in the heap.
    ///
    /// This calls `tracer.visit(ptr)` for each edge from this value
    /// to other heap values.
    ///
    /// For user-defined structs, this is achieved by calling the
    /// `field.trace(tracer)` method of each field of this value. (They are
    /// typically all `In` types.) The implementation of this method for
    /// `Pointer<T>` calls `tracer.visit()` (if the pointer is non-null?).
    ///
    /// # Safety
    ///
    /// It is impossible for ordinary users to call this safely, because `self`
    /// must be a direct, unwrapped reference to a value stored in the GC heap,
    /// which ordinary users cannot obtain.
    unsafe fn trace<R>(&Self::In, tracer: &mut R)
    where
        R: Tracer;
}

/// Trait for values that can be moved into a GC heap.
///
/// Cell-gc does not support GC allocation of arbitrary values: only values of
/// types that implement `IntoHeap`. This trait is **not** meant to be
/// implemented by hand: use `#[derive(IntoHeap)]` instead. All primitive types
/// and many standard types support `IntoHeap`.
///
/// That is all you need to know in order to use cell-gc. The rest is really
/// implementation detail.
///
/// Implementation note: every type with `'static` lifetime should be safe to
/// store in the heap, because ref types are never `'static`. Unfortunately
/// rustc cannot be made to understand this. It would be *legal* to write this:
///
/// ```ignore
/// unsafe impl<'h, T: Clone + 'static> IntoHeap<'h> for T { ...trivial... }
/// ```
///
/// but alas, Rust thinks this impl conflicts with almost all others, making it
/// impossible to get the macro to work. So instead we `impl IntoHeap for` a
/// lot of individual types by hand.
///
/// **Liveness.** Some `IntoHeap` types ("Ref" types) are effectively smart
/// pointers to in-heap values. To preserve safety, if an `IntoHeap` value is
/// (or contains) a smart pointer to an in-heap value, then that value (and
/// everything reachable from it) is protected from GC.
///
/// # Safety
///
/// Implementing `IntoHeap<'h>` tells cell-gc that a type integrates with
/// garbage collection. All the methods in the type's `IntoHeapBase` impl must
/// be correct or it will explode.
///
/// *   In-heap values are typically full of pointers; if `into_heap` puts
///     garbage into them, GC will crash.
///
/// *   `trace` must be implemented with care in order to preserve the
///     invariants of the GC graph-walking algorithm. Bugs there are very
///     likely to lead to dangling pointers and hard-to-debug crashes down the
///     road.
///
/// *   `GcHeap` implements `Send`. This means any value that can be stored in
///     the heap can be sent to other threads (by sending the whole heap). So
///     don't implement this trait for any type that isn't itself already
///     `Send`. (The reason this trait doesn't *require* `Send` is that at
///     present, `Ref` types must *not* be `Send` but must implement
///     `IntoHeap`.)  It's OK to store non-`Sync` values in the heap.
///
/// *   And this probably goes without saying, but none of these methods may
///     allocate or do anything else that could trigger garbage collection.
///
pub unsafe trait IntoHeap<'h>: IntoHeapBase {}

/// Types that can be allocated in the heap.
pub trait IntoHeapAllocation<'h>: IntoHeap<'h> {
    /// The safe reference type that's returned when a value of this type is
    /// moved into the heap (i.e. when it's allocated).
    type Ref: Hash + IntoHeap<'h>;

    fn wrap_gc_ref(gc_ref: GcRef<'h, Self>) -> Self::Ref;

    fn into_gc_ref(r: Self::Ref) -> GcRef<'h, Self>;
}

pub trait Tracer {
    fn visit<'h, T>(&mut self, Pointer<T::In>)
    where
        T: IntoHeapAllocation<'h>;
}

// === Provided implmentations for primitive types

macro_rules! gc_trivial_impl {
    ($t:ty) => {
        impl IntoHeapBase for $t {
            type In = $t;
            fn into_heap(self) -> $t { self }
            unsafe fn from_heap(storage: &$t) -> $t { storage.clone() }
            unsafe fn trace<R>(_storage: &$t, _tracer: &mut R) where R: Tracer {}
        }
        unsafe impl<'h> IntoHeap<'h> for $t {}
        impl<'h> IntoHeapAllocation<'h> for $t {
            type Ref = GcRef<'h, Self>;
            fn wrap_gc_ref(gc_ref: GcRef<'h, Self>) -> Self::Ref { gc_ref }
            fn into_gc_ref(gc_ref: Self::Ref) -> GcRef<'h, Self> { gc_ref }
        }
    }
}

gc_trivial_impl!(bool);
gc_trivial_impl!(char);
gc_trivial_impl!(i8);
gc_trivial_impl!(u8);
gc_trivial_impl!(i16);
gc_trivial_impl!(u16);
gc_trivial_impl!(i32);
gc_trivial_impl!(u32);
gc_trivial_impl!(i64);
gc_trivial_impl!(u64);
gc_trivial_impl!(isize);
gc_trivial_impl!(usize);
gc_trivial_impl!(f32);
gc_trivial_impl!(f64);

gc_trivial_impl!(String);

macro_rules! gc_generic_trivial_impl {
    (@as_item $it:item) => { $it };
    ([$($x:tt)*] $t:ty) => {
        gc_generic_trivial_impl! {
            @as_item
            impl<$($x)*> IntoHeapBase for $t {
                type In = $t;
                fn into_heap(self) -> $t { self }
                unsafe fn from_heap(storage: &$t) -> $t { (*storage).clone() }
                unsafe fn trace<R>(_storage: &$t, _tracer: &mut R) where R: Tracer {}
            }
        }
        gc_generic_trivial_impl! {
            @as_item
            unsafe impl<'h, $($x)*> IntoHeap<'h> for $t {}
        }
        gc_generic_trivial_impl! {
            @as_item
            impl<'h, $($x)*> IntoHeapAllocation<'h> for $t {
                type Ref = GcRef<'h, Self>;
                fn wrap_gc_ref(gc_ref: GcRef<'h, Self>) -> Self::Ref { gc_ref }
                fn into_gc_ref(gc_ref: Self::Ref) -> GcRef<'h, Self> { gc_ref }
            }
        }
    }
}

gc_generic_trivial_impl!([T: ?Sized + Sync] &'static T);
gc_generic_trivial_impl!([T: Clone + Send + 'static] GcLeaf<T>);
gc_generic_trivial_impl!([T: Clone + Send + 'static] Box<T>);
gc_generic_trivial_impl!([T: Clone + Sync + 'static] ::std::sync::Arc<T>);

/// Currently, `#[derive(IntoHeap)]` only works for types that have a lifetime
/// parameter.  This poses a problem because sometimes you want to store stuff
/// in the heap that doesn't contain any `GcRef`s or other heap lifetimes.
/// As a hackaround, we allow `PhantomData<&'h T>` fields (for now).
impl<'h, T: 'static> IntoHeapBase for PhantomData<&'h T> {
    type In = PhantomData<&'static T>;
    fn into_heap(self) -> Self::In { PhantomData }
    unsafe fn from_heap(_storage: &Self::In) -> Self { PhantomData }
    unsafe fn trace<R: Tracer>(_storage: &Self::In, _tracer: &mut R) {}
}

// GCRef has a special implementation.
impl<'h, T: IntoHeapAllocation<'h>> IntoHeapBase for GcRef<'h, T> {
    type In = Pointer<T::In>;

    fn into_heap(self) -> Self::In {
        self.ptr()
    }

    unsafe fn from_heap(storage: &Self::In) -> Self {
        Self::new(*storage)
    }

    unsafe fn trace<R: Tracer>(storage: &Self::In, tracer: &mut R) {
        tracer.visit::<T>(*storage);
    }
}

unsafe impl<'h, T: IntoHeapAllocation<'h>> IntoHeap<'h> for GcRef<'h, T> {}

// Transitive implementations ("this particular kind of struct/enum is IntoHeap
// if all its fields are") are slightly less trivial.

impl<T: IntoHeapBase> IntoHeapBase for Option<T> {
    type In = Option<T::In>;

    fn into_heap(self) -> Option<T::In> {
        self.map(|t| t.into_heap())
    }

    unsafe fn trace<R>(storage: &Option<T::In>, tracer: &mut R)
    where
        R: Tracer,
    {
        match storage {
            &None => (),
            &Some(ref u) => T::trace(u, tracer),
        }
    }

    unsafe fn from_heap(storage: &Option<T::In>) -> Option<T> {
        match storage {
            &None => None,
            &Some(ref u) => Some(T::from_heap(u)),
        }
    }
}

unsafe impl<'h, T: IntoHeap<'h>> IntoHeap<'h> for Option<T> {}

macro_rules! gc_trivial_tuple_impl {
    (@as_item $it:item) => { $it };
    ($($t:ident),*) => {
        gc_trivial_tuple_impl! {
            @as_item
            impl<$($t: IntoHeapBase,)*> IntoHeapBase for ($($t,)*) {
                type In = ($($t::In,)*);

                #[allow(non_snake_case)]  // because we use the type names as variable names (!)
                fn into_heap(self) -> Self::In {
                    let ($($t,)*) = self;
                    ($($t.into_heap(),)*)
                }

                #[allow(non_snake_case)]
                unsafe fn trace<R>(storage: &Self::In, tracer: &mut R)
                    where R: Tracer
                {
                    let &($(ref $t,)*) = storage;

                    $(
                        <$t as $crate::traits::IntoHeapBase>::trace($t, tracer);
                    )*

                    // If the above `$(...)*` expansion is empty, we need this
                    // to quiet unused variable warnings for `tracer`.
                    let _ = tracer;
                }

                #[allow(non_snake_case)]
                unsafe fn from_heap(storage: &Self::In) -> Self {
                    let &($(ref $t,)*) = storage;
                    ($( <$t as $crate::traits::IntoHeapBase>::from_heap($t), )*)
                }
            }
        }

        gc_trivial_tuple_impl! {
            @as_item
            unsafe impl<'h, $($t: IntoHeap<'h>,)*> IntoHeap<'h> for ($($t,)*) {}
        }
    }
}

gc_trivial_tuple_impl!();
gc_trivial_tuple_impl!(T);
gc_trivial_tuple_impl!(T, U);
gc_trivial_tuple_impl!(T, U, V);
gc_trivial_tuple_impl!(T, U, V, W);
gc_trivial_tuple_impl!(T, U, V, W, X);
gc_trivial_tuple_impl!(T, U, V, W, X, Y);
gc_trivial_tuple_impl!(T, U, V, W, X, Y, Z);
<commit_msg>Inline the most trivial from_heap/into_heap methods.<commit_after>//! The traits defined here are implementation details of cell_gc.
//!
//! Application code does not need to use these traits. They are public only so
//! that `#[derive(IntoHeap)]` can use it. Use the friendly macro!

use gc_leaf::GcLeaf;
use gc_ref::GcRef;
use ptr::Pointer;
use std::hash::Hash;
use std::marker::PhantomData;

/// Base trait for values that can be moved into a GC heap.
pub trait IntoHeapBase: Sized {
    /// The type of the value when it is physically stored in the heap.
    ///
    /// GC types come in pairs: an `IntoHeap` type and an `In` type. Ideally
    /// both types would have the same layout, bit for bit, but Rust makes no
    /// promises about struct and enum layout generally, so we can't guarantee
    /// this.
    ///
    /// The `In` type is stored physically inside the heap, and may be packed
    /// with pointer fields and unsafe methods. The `IntoHeap` type is safe, is
    /// used in application code, and lives on the stack.
    ///
    /// *   For primitive types, like `i32`, the two types are the same.
    ///
    /// *   Macro-generated "Ref" types are `IntoHeap` types; the corresponding
    ///     in-heap types are effectively raw pointers.
    ///
    /// *   For user-defined structs and enums, the `#[derive(IntoHeap)]` macro
    ///     autogenerates an `In` type for you. It has identical fields or
    ///     variants, but fields of the `IntoHeap` type are `IntoHeap`, and
    ///     fields of the `In` type are the corresponding `In` types.
    ///
    /// (The word "safe" above means that, as with everything generally in Rust, you
    /// can hack without fear. `IntoHeap` types don't expose raw Rust pointers or
    /// references to GC memory, they don't expose the unsafe in-heap types, and
    /// they obey Rust's safety and aliasing rules.)
    ///
    /// Users never get a direct `&` reference to any in-heap value. All access is
    /// through safe `IntoHeap` types, like the `Ref` type that is automatically
    /// declared for you when you use `#[derive(IntoHeap)]` on a struct or union.
    type In: 'static;

    /// Convert the value to the form it should have in the heap.
    /// This is for cell-gc to call.
    ///
    /// This method must not be called while any direct Rust references to
    /// heap objects exist. (However, user code never runs while such
    /// references exist, so the method is not marked `unsafe`.)
    fn into_heap(self) -> Self::In;

    /// Extract the value from the heap. This turns any raw pointers in the
    /// in-heap value into safe references, so while it's an unsafe function,
    /// the result of a correct call can be safely handed out to user code.
    ///
    /// # Safety
    ///
    /// It is impossible for ordinary users to call this safely, because `self`
    /// must be a direct, unwrapped reference to a value stored in the GC heap,
    /// which ordinary users cannot obtain.
    unsafe fn from_heap(&Self::In) -> Self;

    /// Traverse a value in the heap.
    ///
    /// This calls `tracer.visit(ptr)` for each edge from this value
    /// to other heap values.
    ///
    /// For user-defined structs, this is achieved by calling the
    /// `field.trace(tracer)` method of each field of this value. (They are
    /// typically all `In` types.) The implementation of this method for
    /// `Pointer<T>` calls `tracer.visit()` (if the pointer is non-null?).
    ///
    /// # Safety
    ///
    /// It is impossible for ordinary users to call this safely, because `self`
    /// must be a direct, unwrapped reference to a value stored in the GC heap,
    /// which ordinary users cannot obtain.
    unsafe fn trace<R>(&Self::In, tracer: &mut R)
    where
        R: Tracer;
}

/// Trait for values that can be moved into a GC heap.
///
/// Cell-gc does not support GC allocation of arbitrary values: only values of
/// types that implement `IntoHeap`. This trait is **not** meant to be
/// implemented by hand: use `#[derive(IntoHeap)]` instead. All primitive types
/// and many standard types support `IntoHeap`.
///
/// That is all you need to know in order to use cell-gc. The rest is really
/// implementation detail.
///
/// Implementation note: every type with `'static` lifetime should be safe to
/// store in the heap, because ref types are never `'static`. Unfortunately
/// rustc cannot be made to understand this. It would be *legal* to write this:
///
/// ```ignore
/// unsafe impl<'h, T: Clone + 'static> IntoHeap<'h> for T { ...trivial... }
/// ```
///
/// but alas, Rust thinks this impl conflicts with almost all others, making it
/// impossible to get the macro to work. So instead we `impl IntoHeap for` a
/// lot of individual types by hand.
///
/// **Liveness.** Some `IntoHeap` types ("Ref" types) are effectively smart
/// pointers to in-heap values. To preserve safety, if an `IntoHeap` value is
/// (or contains) a smart pointer to an in-heap value, then that value (and
/// everything reachable from it) is protected from GC.
///
/// # Safety
///
/// Implementing `IntoHeap<'h>` tells cell-gc that a type integrates with
/// garbage collection. All the methods in the type's `IntoHeapBase` impl must
/// be correct or it will explode.
///
/// *   In-heap values are typically full of pointers; if `into_heap` puts
///     garbage into them, GC will crash.
///
/// *   `trace` must be implemented with care in order to preserve the
///     invariants of the GC graph-walking algorithm. Bugs there are very
///     likely to lead to dangling pointers and hard-to-debug crashes down the
///     road.
///
/// *   `GcHeap` implements `Send`. This means any value that can be stored in
///     the heap can be sent to other threads (by sending the whole heap). So
///     don't implement this trait for any type that isn't itself already
///     `Send`. (The reason this trait doesn't *require* `Send` is that at
///     present, `Ref` types must *not* be `Send` but must implement
///     `IntoHeap`.)  It's OK to store non-`Sync` values in the heap.
///
/// *   And this probably goes without saying, but none of these methods may
///     allocate or do anything else that could trigger garbage collection.
///
pub unsafe trait IntoHeap<'h>: IntoHeapBase {}

/// Types that can be allocated in the heap.
pub trait IntoHeapAllocation<'h>: IntoHeap<'h> {
    /// The safe reference type that's returned when a value of this type is
    /// moved into the heap (i.e. when it's allocated).
    type Ref: Hash + IntoHeap<'h>;

    fn wrap_gc_ref(gc_ref: GcRef<'h, Self>) -> Self::Ref;

    fn into_gc_ref(r: Self::Ref) -> GcRef<'h, Self>;
}

pub trait Tracer {
    fn visit<'h, T>(&mut self, Pointer<T::In>)
    where
        T: IntoHeapAllocation<'h>;
}

// === Provided implmentations for primitive types

macro_rules! gc_trivial_impl {
    ($t:ty) => {
        impl IntoHeapBase for $t {
            type In = $t;
            #[inline] fn into_heap(self) -> $t { self }
            #[inline] unsafe fn from_heap(storage: &$t) -> $t { storage.clone() }
            #[inline] unsafe fn trace<R>(_storage: &$t, _tracer: &mut R) where R: Tracer {}
        }
        unsafe impl<'h> IntoHeap<'h> for $t {}
        impl<'h> IntoHeapAllocation<'h> for $t {
            type Ref = GcRef<'h, Self>;
            #[inline] fn wrap_gc_ref(gc_ref: GcRef<'h, Self>) -> Self::Ref { gc_ref }
            #[inline] fn into_gc_ref(gc_ref: Self::Ref) -> GcRef<'h, Self> { gc_ref }
        }
    }
}

gc_trivial_impl!(bool);
gc_trivial_impl!(char);
gc_trivial_impl!(i8);
gc_trivial_impl!(u8);
gc_trivial_impl!(i16);
gc_trivial_impl!(u16);
gc_trivial_impl!(i32);
gc_trivial_impl!(u32);
gc_trivial_impl!(i64);
gc_trivial_impl!(u64);
gc_trivial_impl!(isize);
gc_trivial_impl!(usize);
gc_trivial_impl!(f32);
gc_trivial_impl!(f64);

gc_trivial_impl!(String);

macro_rules! gc_generic_trivial_impl {
    (@as_item $it:item) => { $it };
    ([$($x:tt)*] $t:ty) => {
        gc_generic_trivial_impl! {
            @as_item
            impl<$($x)*> IntoHeapBase for $t {
                type In = $t;
                fn into_heap(self) -> $t { self }
                unsafe fn from_heap(storage: &$t) -> $t { (*storage).clone() }
                unsafe fn trace<R>(_storage: &$t, _tracer: &mut R) where R: Tracer {}
            }
        }
        gc_generic_trivial_impl! {
            @as_item
            unsafe impl<'h, $($x)*> IntoHeap<'h> for $t {}
        }
        gc_generic_trivial_impl! {
            @as_item
            impl<'h, $($x)*> IntoHeapAllocation<'h> for $t {
                type Ref = GcRef<'h, Self>;
                fn wrap_gc_ref(gc_ref: GcRef<'h, Self>) -> Self::Ref { gc_ref }
                fn into_gc_ref(gc_ref: Self::Ref) -> GcRef<'h, Self> { gc_ref }
            }
        }
    }
}

gc_generic_trivial_impl!([T: ?Sized + Sync] &'static T);
gc_generic_trivial_impl!([T: Clone + Send + 'static] GcLeaf<T>);
gc_generic_trivial_impl!([T: Clone + Send + 'static] Box<T>);
gc_generic_trivial_impl!([T: Clone + Sync + 'static] ::std::sync::Arc<T>);

/// Currently, `#[derive(IntoHeap)]` only works for types that have a lifetime
/// parameter.  This poses a problem because sometimes you want to store stuff
/// in the heap that doesn't contain any `GcRef`s or other heap lifetimes.
/// As a hackaround, we allow `PhantomData<&'h T>` fields (for now).
impl<'h, T: 'static> IntoHeapBase for PhantomData<&'h T> {
    type In = PhantomData<&'static T>;
    fn into_heap(self) -> Self::In { PhantomData }
    unsafe fn from_heap(_storage: &Self::In) -> Self { PhantomData }
    unsafe fn trace<R: Tracer>(_storage: &Self::In, _tracer: &mut R) {}
}

// GCRef has a special implementation.
impl<'h, T: IntoHeapAllocation<'h>> IntoHeapBase for GcRef<'h, T> {
    type In = Pointer<T::In>;

    fn into_heap(self) -> Self::In {
        self.ptr()
    }

    unsafe fn from_heap(storage: &Self::In) -> Self {
        Self::new(*storage)
    }

    unsafe fn trace<R: Tracer>(storage: &Self::In, tracer: &mut R) {
        tracer.visit::<T>(*storage);
    }
}

unsafe impl<'h, T: IntoHeapAllocation<'h>> IntoHeap<'h> for GcRef<'h, T> {}

// Transitive implementations ("this particular kind of struct/enum is IntoHeap
// if all its fields are") are slightly less trivial.

impl<T: IntoHeapBase> IntoHeapBase for Option<T> {
    type In = Option<T::In>;

    fn into_heap(self) -> Option<T::In> {
        self.map(|t| t.into_heap())
    }

    unsafe fn trace<R>(storage: &Option<T::In>, tracer: &mut R)
    where
        R: Tracer,
    {
        match storage {
            &None => (),
            &Some(ref u) => T::trace(u, tracer),
        }
    }

    unsafe fn from_heap(storage: &Option<T::In>) -> Option<T> {
        match storage {
            &None => None,
            &Some(ref u) => Some(T::from_heap(u)),
        }
    }
}

unsafe impl<'h, T: IntoHeap<'h>> IntoHeap<'h> for Option<T> {}

macro_rules! gc_trivial_tuple_impl {
    (@as_item $it:item) => { $it };
    ($($t:ident),*) => {
        gc_trivial_tuple_impl! {
            @as_item
            impl<$($t: IntoHeapBase,)*> IntoHeapBase for ($($t,)*) {
                type In = ($($t::In,)*);

                #[allow(non_snake_case)]  // because we use the type names as variable names (!)
                fn into_heap(self) -> Self::In {
                    let ($($t,)*) = self;
                    ($($t.into_heap(),)*)
                }

                #[allow(non_snake_case)]
                unsafe fn trace<R>(storage: &Self::In, tracer: &mut R)
                    where R: Tracer
                {
                    let &($(ref $t,)*) = storage;

                    $(
                        <$t as $crate::traits::IntoHeapBase>::trace($t, tracer);
                    )*

                    // If the above `$(...)*` expansion is empty, we need this
                    // to quiet unused variable warnings for `tracer`.
                    let _ = tracer;
                }

                #[allow(non_snake_case)]
                unsafe fn from_heap(storage: &Self::In) -> Self {
                    let &($(ref $t,)*) = storage;
                    ($( <$t as $crate::traits::IntoHeapBase>::from_heap($t), )*)
                }
            }
        }

        gc_trivial_tuple_impl! {
            @as_item
            unsafe impl<'h, $($t: IntoHeap<'h>,)*> IntoHeap<'h> for ($($t,)*) {}
        }
    }
}

gc_trivial_tuple_impl!();
gc_trivial_tuple_impl!(T);
gc_trivial_tuple_impl!(T, U);
gc_trivial_tuple_impl!(T, U, V);
gc_trivial_tuple_impl!(T, U, V, W);
gc_trivial_tuple_impl!(T, U, V, W, X);
gc_trivial_tuple_impl!(T, U, V, W, X, Y);
gc_trivial_tuple_impl!(T, U, V, W, X, Y, Z);
<|endoftext|>


<commit_before>use ncurses as nc;
use std::char;

pub fn mvrel(rel_y: i32, rel_x: i32) {
    wmvrel(nc::stdscr(), rel_y, rel_x);
}

pub fn wmvrel(window: nc::WINDOW, rel_y: i32, rel_x: i32) {
    let mut y = 0;
    let mut x = 0;
    nc::getyx(window, &mut y, &mut x);
    nc::wmove(window, y + rel_y, x + rel_x);
}

pub fn getstring() -> String {
    wgetstring(nc::stdscr())
}

pub fn wgetstring(window: nc::WINDOW) -> String {
    nc::noecho();

    let mut string = String::with_capacity(32);
    let mut pos_history = Vec::new();

    let mut y = 0;
    let mut x = 0;

    nc::getyx(window, &mut y, &mut x);
    pos_history.push((y, x));

    let mut ch = nc::wgetch(window);
    while ch != '\n' as i32 && ch != '\r' as i32 {
        if ch == 127 {
            if let Some((y, x)) = pos_history.pop() {
                nc::mvwdelch(window, y, x);
                string.pop();
            }
        }
        else if let Some(c) = char::from_u32(ch as u32) {
            nc::getyx(window, &mut y, &mut x);
            pos_history.push((y, x));
            string.push(c);
            nc::wechochar(window, ch as u64);
        }
        ch = nc::wgetch(window);
    }

    string.shrink_to_fit();
    string
}

pub fn getsecretstring() -> String {
    wgetsecretstring(nc::stdscr())
}

pub fn wgetsecretstring(window: nc::WINDOW) -> String {
    nc::noecho();
    let mut string = String::with_capacity(32);

    let mut ch = nc::wgetch(window);
    while ch != '\n' as i32 && ch != '\r' as i32 {
        if ch == 127 {
            string.pop();
        }
        else if let Some(c) = char::from_u32(ch as u32) {
            string.push(c);
        }
        ch = nc::wgetch(window);
    }

    string.shrink_to_fit();
    string
}

pub fn getchoice() -> i32 {
    wgetchoice(nc::stdscr())
}

pub fn wgetchoice(window: nc::WINDOW) -> i32 {
    wgetstring(window).trim().parse::<i32>().unwrap_or(-1)
}
<commit_msg>Updated casting to char type defined in ncurses-rs<commit_after>use ncurses as nc;
use std::char;

pub fn mvrel(rel_y: i32, rel_x: i32) {
    wmvrel(nc::stdscr(), rel_y, rel_x);
}

pub fn wmvrel(window: nc::WINDOW, rel_y: i32, rel_x: i32) {
    let mut y = 0;
    let mut x = 0;
    nc::getyx(window, &mut y, &mut x);
    nc::wmove(window, y + rel_y, x + rel_x);
}

pub fn getstring() -> String {
    wgetstring(nc::stdscr())
}

pub fn wgetstring(window: nc::WINDOW) -> String {
    nc::noecho();

    let mut string = String::with_capacity(32);
    let mut pos_history = Vec::new();

    let mut y = 0;
    let mut x = 0;

    nc::getyx(window, &mut y, &mut x);
    pos_history.push((y, x));

    let mut ch = nc::wgetch(window);
    while ch != '\n' as i32 && ch != '\r' as i32 {
        if ch == 127 {
            if let Some((y, x)) = pos_history.pop() {
                nc::mvwdelch(window, y, x);
                string.pop();
            }
        }
        else if let Some(c) = char::from_u32(ch as u32) {
            nc::getyx(window, &mut y, &mut x);
            pos_history.push((y, x));
            string.push(c);
            nc::wechochar(window, ch as nc::chtype);
        }
        ch = nc::wgetch(window);
    }

    string.shrink_to_fit();
    string
}

pub fn getsecretstring() -> String {
    wgetsecretstring(nc::stdscr())
}

pub fn wgetsecretstring(window: nc::WINDOW) -> String {
    nc::noecho();
    let mut string = String::with_capacity(32);

    let mut ch = nc::wgetch(window);
    while ch != '\n' as i32 && ch != '\r' as i32 {
        if ch == 127 {
            string.pop();
        }
        else if let Some(c) = char::from_u32(ch as u32) {
            string.push(c);
        }
        ch = nc::wgetch(window);
    }

    string.shrink_to_fit();
    string
}

pub fn getchoice() -> i32 {
    wgetchoice(nc::stdscr())
}

pub fn wgetchoice(window: nc::WINDOW) -> i32 {
    wgetstring(window).trim().parse::<i32>().unwrap_or(-1)
}
<|endoftext|>


<commit_before>#![feature(test)]
extern crate test;
extern crate itertools;

use itertools::Stride;

use itertools::{Zip, ZipTrusted};

use std::iter::repeat;
use std::marker::PhantomData;

#[bench]
fn slice_iter(b: &mut test::Bencher)
{
    let xs: Vec<_> = repeat(1i32).take(20).collect();
    b.iter(|| for elt in xs.iter() {
        test::black_box(elt);
    })
}

#[bench]
fn slice_iter_rev(b: &mut test::Bencher)
{
    let xs: Vec<_> = repeat(1i32).take(20).collect();
    b.iter(|| for elt in xs.iter().rev() {
        test::black_box(elt);
    })
}

#[bench]
fn stride_iter(b: &mut test::Bencher)
{
    let xs: Vec<_> = repeat(1i32).take(20).collect();
    b.iter(|| for elt in Stride::from_slice(&xs, 1) {
        test::black_box(elt);
    })
}

#[bench]
fn stride_iter_rev(b: &mut test::Bencher)
{
    let xs: Vec<_> = repeat(1i32).take(20).collect();
    b.iter(|| for elt in Stride::from_slice(&xs, 1).rev() {
        test::black_box(elt);
    })
}

#[derive(Copy)]
struct ZipSlices<'a, T: 'a, U :'a>
{
    t_ptr: *const T,
    t_end: *const T,
    u_ptr: *const U,
    mark: PhantomData<&'a (T, U)>,
}

impl<'a, T, U> ZipSlices<'a, T, U>
{
    pub fn new(t: &'a [T], u: &'a [U]) -> Self
    {
        assert!(::std::mem::size_of::<T>() != 0);
        assert!(::std::mem::size_of::<U>() != 0);
        let minl = std::cmp::min(t.len(), u.len());
        let end_ptr = unsafe {
            t.as_ptr().offset(minl as isize)
        };
        ZipSlices {
            t_ptr: t.as_ptr(),
            t_end: end_ptr,
            u_ptr: u.as_ptr(),
            mark: PhantomData,
        }
    }
}

impl<'a, T, U> Iterator for ZipSlices<'a, T, U>
{
    type Item = (&'a T, &'a U);

    #[inline]
    fn next(&mut self) -> Option<(&'a T, &'a U)>
    {
        if self.t_ptr == self.t_end {
            return None
        }
        let t_elt: &T;
        let u_elt: &U;
        unsafe {
            t_elt = ::std::mem::transmute(self.t_ptr);
            self.t_ptr = self.t_ptr.offset(1);
            u_elt = ::std::mem::transmute(self.u_ptr);
            self.u_ptr = self.u_ptr.offset(1);
        }
        Some((t_elt, u_elt))
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>)
    {
        let len = self.t_end as usize - self.t_ptr as usize;
        (len, Some(len))
    }
}

#[bench]
fn zip_slices_default_zip(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];

    b.iter(|| for (&x, &y) in xs.iter().zip(ys.iter()) {
        test::black_box(x);
        test::black_box(y);
    })
}

#[bench]
fn zip_slices_default_zip3(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let zs = vec![0; 766];

    b.iter(|| for ((&x, &y), &z) in xs.iter().zip(ys.iter()).zip(zs.iter()) {
        test::black_box(x);
        test::black_box(y);
        test::black_box(z);
    })
}

#[bench]
fn zip_slices_ziptuple(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];

    b.iter(|| for (&x, &y) in Zip::new((xs.iter(), ys.iter())) {
        test::black_box(x);
        test::black_box(y);
    })
}

#[bench]
fn zipslices(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];

    b.iter(|| for (&x, &y) in ZipSlices::new(&xs, &ys) {
        test::black_box(x);
        test::black_box(y);
    })
}

#[bench]
fn ziptrusted(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];

    b.iter(|| for (&x, &y) in ZipTrusted::new((xs.iter(), ys.iter())) {
        test::black_box(x);
        test::black_box(y);
    })
}

#[bench]
fn ziptrusted3(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let zs = vec![0; 766];

    b.iter(|| for (&x, &y, &z) in ZipTrusted::new((xs.iter(), ys.iter(), zs.iter())) {
        test::black_box(x);
        test::black_box(y);
        test::black_box(z);
    })
}

#[bench]
fn zip_loop(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];

    b.iter(|| {
        let len = ::std::cmp::min(xs.len(), ys.len());
        for i in 0..len {
            unsafe {
            let x = *xs.get_unchecked(i);
            let y = *ys.get_unchecked(i);
            test::black_box(x);
            test::black_box(y);
            }
        }
    })
}

#[bench]
fn zip_loop3(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let zs = vec![0; 766];

    b.iter(|| {
        let len = ::std::cmp::min(xs.len(), ::std::cmp::min(ys.len(), zs.len()));
        for i in 0..len {
            unsafe {
            let x = *xs.get_unchecked(i);
            let y = *ys.get_unchecked(i);
            let z = *zs.get_unchecked(i);
            test::black_box(x);
            test::black_box(y);
            test::black_box(z);
            }
        }
    })
}
<commit_msg>Allow benchmarks to run without "cargo bench --features unstable"<commit_after>#![feature(test)]
extern crate test;
extern crate itertools;

use itertools::Stride;

#[cfg(not(feature = "unstable"))]
use itertools::Zip;

#[cfg(feature = "unstable")]
use itertools::{Zip, ZipTrusted};

use std::iter::repeat;
use std::marker::PhantomData;

#[bench]
fn slice_iter(b: &mut test::Bencher)
{
    let xs: Vec<_> = repeat(1i32).take(20).collect();
    b.iter(|| for elt in xs.iter() {
        test::black_box(elt);
    })
}

#[bench]
fn slice_iter_rev(b: &mut test::Bencher)
{
    let xs: Vec<_> = repeat(1i32).take(20).collect();
    b.iter(|| for elt in xs.iter().rev() {
        test::black_box(elt);
    })
}

#[bench]
fn stride_iter(b: &mut test::Bencher)
{
    let xs: Vec<_> = repeat(1i32).take(20).collect();
    b.iter(|| for elt in Stride::from_slice(&xs, 1) {
        test::black_box(elt);
    })
}

#[bench]
fn stride_iter_rev(b: &mut test::Bencher)
{
    let xs: Vec<_> = repeat(1i32).take(20).collect();
    b.iter(|| for elt in Stride::from_slice(&xs, 1).rev() {
        test::black_box(elt);
    })
}

#[derive(Copy, Clone)]
struct ZipSlices<'a, T: 'a, U :'a>
{
    t_ptr: *const T,
    t_end: *const T,
    u_ptr: *const U,
    mark: PhantomData<&'a (T, U)>,
}

impl<'a, T, U> ZipSlices<'a, T, U>
{
    pub fn new(t: &'a [T], u: &'a [U]) -> Self
    {
        assert!(::std::mem::size_of::<T>() != 0);
        assert!(::std::mem::size_of::<U>() != 0);
        let minl = std::cmp::min(t.len(), u.len());
        let end_ptr = unsafe {
            t.as_ptr().offset(minl as isize)
        };
        ZipSlices {
            t_ptr: t.as_ptr(),
            t_end: end_ptr,
            u_ptr: u.as_ptr(),
            mark: PhantomData,
        }
    }
}

impl<'a, T, U> Iterator for ZipSlices<'a, T, U>
{
    type Item = (&'a T, &'a U);

    #[inline]
    fn next(&mut self) -> Option<(&'a T, &'a U)>
    {
        if self.t_ptr == self.t_end {
            return None
        }
        let t_elt: &T;
        let u_elt: &U;
        unsafe {
            t_elt = ::std::mem::transmute(self.t_ptr);
            self.t_ptr = self.t_ptr.offset(1);
            u_elt = ::std::mem::transmute(self.u_ptr);
            self.u_ptr = self.u_ptr.offset(1);
        }
        Some((t_elt, u_elt))
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>)
    {
        let len = self.t_end as usize - self.t_ptr as usize;
        (len, Some(len))
    }
}

#[bench]
fn zip_slices_default_zip(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];

    b.iter(|| for (&x, &y) in xs.iter().zip(ys.iter()) {
        test::black_box(x);
        test::black_box(y);
    })
}

#[bench]
fn zip_slices_default_zip3(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let zs = vec![0; 766];

    b.iter(|| for ((&x, &y), &z) in xs.iter().zip(ys.iter()).zip(zs.iter()) {
        test::black_box(x);
        test::black_box(y);
        test::black_box(z);
    })
}

#[bench]
fn zip_slices_ziptuple(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];

    b.iter(|| for (&x, &y) in Zip::new((xs.iter(), ys.iter())) {
        test::black_box(x);
        test::black_box(y);
    })
}

#[bench]
fn zipslices(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];

    b.iter(|| for (&x, &y) in ZipSlices::new(&xs, &ys) {
        test::black_box(x);
        test::black_box(y);
    })
}

#[cfg(feature = "unstable")]
#[bench]
fn ziptrusted(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];

    b.iter(|| for (&x, &y) in ZipTrusted::new((xs.iter(), ys.iter())) {
        test::black_box(x);
        test::black_box(y);
    })
}

#[cfg(feature = "unstable")]
#[bench]
fn ziptrusted3(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let zs = vec![0; 766];

    b.iter(|| for (&x, &y, &z) in ZipTrusted::new((xs.iter(), ys.iter(), zs.iter())) {
        test::black_box(x);
        test::black_box(y);
        test::black_box(z);
    })
}

#[bench]
fn zip_loop(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];

    b.iter(|| {
        let len = ::std::cmp::min(xs.len(), ys.len());
        for i in 0..len {
            unsafe {
            let x = *xs.get_unchecked(i);
            let y = *ys.get_unchecked(i);
            test::black_box(x);
            test::black_box(y);
            }
        }
    })
}

#[bench]
fn zip_loop3(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let zs = vec![0; 766];

    b.iter(|| {
        let len = ::std::cmp::min(xs.len(), ::std::cmp::min(ys.len(), zs.len()));
        for i in 0..len {
            unsafe {
            let x = *xs.get_unchecked(i);
            let y = *ys.get_unchecked(i);
            let z = *zs.get_unchecked(i);
            test::black_box(x);
            test::black_box(y);
            test::black_box(z);
            }
        }
    })
}
<|endoftext|>


<commit_before>#![cfg_attr(feature = "nightlytests", feature(try_from))]

use std::net::IpAddr;

#[macro_use]
extern crate derive_builder;

#[derive(Debug, Clone, Builder)]
#[builder(try_setter)]
pub struct Lorem {
    source: IpAddr,
    dest: IpAddr,
    name: String,
}

#[derive(Default, Debug, Clone, Builder)]
#[builder(default, setter(prefix = "set", into), try_setter)]
pub struct Ipsum {
    source: Option<IpAddr>,
    name: String,
}

fn main() { }<commit_msg>Revived integration tests<commit_after>#![cfg_attr(feature = "nightlytests", feature(try_from))]

#[macro_use]
extern crate derive_builder;

#[allow(unused_imports)]
mod struct_level {
    #[cfg(feature = "nightlytests")]
    use std::convert::TryFrom;

    use std::net::{IpAddr, AddrParseError};
    use std::str::FromStr;
    use std::string::ToString;

    #[derive(Debug, Clone, PartialEq)]
    pub struct MyAddr(IpAddr);

    impl From<IpAddr> for MyAddr {
        fn from(v: IpAddr) -> Self {
            MyAddr(v)
        }
    }

    #[cfg(feature = "nightlytests")]
    impl<'a> TryFrom<&'a str> for MyAddr {
        type Err = AddrParseError;

        fn try_from(v: &str) -> Result<Self, Self::Err> {
            Ok(MyAddr(v.parse()?))
        }
    }

    #[derive(Debug, PartialEq, Builder)]
    #[builder(try_setter, setter(into))]
    struct Lorem {
        pub source: MyAddr,
        pub dest: MyAddr,
    }

    #[derive(Debug, PartialEq, Builder)]
    #[builder(try_setter, setter(into, prefix = "set"))]
    struct Ipsum {
        pub source: MyAddr
    }

    // Allow dead code here since the test that uses this depends on the try_setter feature.
    #[cfg_attr(not(feature = "nightlytests"), allow(dead_code))]
    fn exact_helper() -> Result<Lorem, String> {
        LoremBuilder::default()
            .source(IpAddr::from_str("1.2.3.4").unwrap())
            .dest(IpAddr::from_str("0.0.0.0").unwrap())
            .build()
    }

    #[cfg(feature = "nightlytests")]
    fn try_helper() -> Result<Lorem, String> {
        LoremBuilder::default()
            .try_source("1.2.3.4").map_err(|e| e.to_string())?
            .try_dest("0.0.0.0").map_err(|e| e.to_string())?
            .build()
    }

    #[test]
    fn infallible_set() {
        let _ = LoremBuilder::default()
            .source(IpAddr::from_str("1.2.3.4").unwrap())
            .dest(IpAddr::from_str("0.0.0.0").unwrap())
            .build();
    }

    #[test]
    #[cfg(feature = "nightlytests")]
    fn fallible_set() {
        let mut builder = LoremBuilder::default();
        let try_result = builder.try_source("1.2.3.4");
        let built = try_result.expect("Passed well-formed address")
            .dest(IpAddr::from_str("0.0.0.0").unwrap())
            .build()
            .unwrap();
        assert_eq!(built, exact_helper().unwrap());
    }

    #[test]
    #[cfg(feature = "nightlytests")]
    fn with_helper() {
        assert_eq!(exact_helper().unwrap(), try_helper().unwrap());
    }

    #[test]
    #[cfg(feature = "nightlytests")]
    fn renamed() {
        IpsumBuilder::default()
            .try_set_source("0.0.0.0")
            .unwrap()
            .build()
            .expect("All fields were provided");
    }
}<|endoftext|>


<commit_before>//! This module implements `LzmaWriter`.
//!
//! `LzmaWriter` implements the LZMA (XZ) compression/decompression algorithm as a generic
//! Writer.  In other words, it behaves similar to BufWriter.  Instead of buffering the `Write`
//! object passed to it, `LzmaWriter` applies compression or decompression to it as it's write.
//!
//!
//! # Examples
//!
//! ```no_run
//! use lzma::LzmaWriter;
//! use std::io::prelude::*;
//! use std::fs::File;
//!
//! let f = File::create("foo.xz").unwrap();
//! let mut f = LzmaWriter::new_compressor(f, 6).unwrap();
//!
//! write!(f, "It's a small world!").unwrap();
//! f.finish().unwrap();
//! ```

use std::io::{self, Write};
use std::ops::Drop;
use lzma_sys::*;
use std;
use error::LzmaError;
use ::Direction;
use lzma_stream_wrapper::LzmaStreamWrapper;

const DEFAULT_BUF_SIZE: usize = 4 * 1024;

pub struct LzmaWriter<T> {
	inner: T,
	stream: LzmaStreamWrapper,
	buffer: Vec<u8>,
	direction: Direction,
}

impl<T: Write> LzmaWriter<T> {
	pub fn new_compressor(inner: T, preset: u32) -> Result<LzmaWriter<T>, LzmaError> {
		LzmaWriter::with_capacity(DEFAULT_BUF_SIZE, inner, Direction::Compress, preset)
	}

	pub fn new_decompressor(inner: T) -> Result<LzmaWriter<T>, LzmaError> {
		LzmaWriter::with_capacity(DEFAULT_BUF_SIZE, inner, Direction::Decompress, 0)
	}

	pub fn with_capacity(capacity: usize, inner: T, direction: Direction, preset: u32) -> Result<LzmaWriter<T>, LzmaError> {
		let mut writer = LzmaWriter {
			inner: inner,
			stream: LzmaStreamWrapper::new(),
			buffer: vec![0; capacity],
			direction: direction,
		};

		match writer.direction {
			Direction::Compress => {
				try!(writer.stream.easy_encoder(preset, lzma_check::LZMA_CHECK_CRC64))
			},
			Direction::Decompress => {
				try!(writer.stream.stream_decoder(std::u64::MAX, 0))
			},
		}

		Ok(writer)
	}
}

impl<T> Drop for LzmaWriter<T> {
	fn drop(&mut self) {
		self.stream.end()
	}
}

impl<W: Write> LzmaWriter<W> {
	/// Finalizes the LZMA stream so that it finishes compressing or decompressing.
	///
	/// This *must* be called after all writing is done to ensure the last pieces of the compressed
	/// or decompressed stream get written out.
	pub fn finish(&mut self) -> Result<(), LzmaError> {
		loop {
			match self.lzma_code_and_write(&[], lzma_action::LZMA_FINISH) {
				Ok((lzma_ret::LZMA_STREAM_END,_)) => break,
				Ok(_) => (),
				Err(err) => return Err(err),
			}
		}

		Ok(())
	}

	fn lzma_code_and_write(&mut self, input: &[u8], action: lzma_action) -> Result<(lzma_ret, usize), LzmaError> {
		let result = self.stream.code(input, &mut self.buffer, action);
		let ret = try!(result.ret);

		if result.bytes_written > 0 {
			try!(Write::write_all(&mut self.inner, &self.buffer[..result.bytes_written]));
		}

		Ok((ret, result.bytes_read))
	}
}

impl<W: Write> Write for LzmaWriter<W> {
	fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
		match self.lzma_code_and_write(buf, lzma_action::LZMA_RUN) {
			Ok((_,bytes_read)) => Ok(bytes_read),
			Err(LzmaError::Io(err)) => return Err(err),
			Err(err) => return Err(io::Error::new(io::ErrorKind::Other, err)),
		}
	}

	fn flush(&mut self) -> io::Result<()> {
		self.inner.flush()
	}
}
<commit_msg>Make `write` implementaion compatible with std::io::Write<commit_after>//! This module implements `LzmaWriter`.
//!
//! `LzmaWriter` implements the LZMA (XZ) compression/decompression algorithm as a generic
//! Writer.  In other words, it behaves similar to BufWriter.  Instead of buffering the `Write`
//! object passed to it, `LzmaWriter` applies compression or decompression to it as it's write.
//!
//!
//! # Examples
//!
//! ```no_run
//! use lzma::LzmaWriter;
//! use std::io::prelude::*;
//! use std::fs::File;
//!
//! let f = File::create("foo.xz").unwrap();
//! let mut f = LzmaWriter::new_compressor(f, 6).unwrap();
//!
//! write!(f, "It's a small world!").unwrap();
//! f.finish().unwrap();
//! ```

use std::io::{self, Write};
use std::ops::Drop;
use lzma_sys::*;
use std;
use error::LzmaError;
use ::Direction;
use lzma_stream_wrapper::{LzmaStreamWrapper, LzmaCodeResult};

const DEFAULT_BUF_SIZE: usize = 4 * 1024;

pub struct LzmaWriter<T> {
	inner: T,
	stream: LzmaStreamWrapper,
	buffer: Vec<u8>,
	direction: Direction,
}

impl<T: Write> LzmaWriter<T> {
	pub fn new_compressor(inner: T, preset: u32) -> Result<LzmaWriter<T>, LzmaError> {
		LzmaWriter::with_capacity(DEFAULT_BUF_SIZE, inner, Direction::Compress, preset)
	}

	pub fn new_decompressor(inner: T) -> Result<LzmaWriter<T>, LzmaError> {
		LzmaWriter::with_capacity(DEFAULT_BUF_SIZE, inner, Direction::Decompress, 0)
	}

	pub fn with_capacity(capacity: usize, inner: T, direction: Direction, preset: u32) -> Result<LzmaWriter<T>, LzmaError> {
		let mut writer = LzmaWriter {
			inner: inner,
			stream: LzmaStreamWrapper::new(),
			buffer: vec![0; capacity],
			direction: direction,
		};

		match writer.direction {
			Direction::Compress => {
				try!(writer.stream.easy_encoder(preset, lzma_check::LZMA_CHECK_CRC64))
			},
			Direction::Decompress => {
				try!(writer.stream.stream_decoder(std::u64::MAX, 0))
			},
		}

		Ok(writer)
	}
}

impl<T> Drop for LzmaWriter<T> {
	fn drop(&mut self) {
		self.stream.end()
	}
}

impl<W: Write> LzmaWriter<W> {
	/// Finalizes the LZMA stream so that it finishes compressing or decompressing.
	///
	/// This *must* be called after all writing is done to ensure the last pieces of the compressed
	/// or decompressed stream get written out.
	pub fn finish(&mut self) -> Result<(), LzmaError> {
		loop {
			match self.lzma_code_and_write(&[], lzma_action::LZMA_FINISH) {
				Ok(LzmaCodeResult {
					ret: Ok(lzma_ret::LZMA_STREAM_END),
					bytes_read: _,
					bytes_written: _,
				}) => break,
				Ok(_) => continue,
				Err(err) => return Err(err),
			}
		}

		Ok(())
	}

	fn lzma_code_and_write(&mut self, input: &[u8], action: lzma_action) -> Result<LzmaCodeResult, LzmaError> {
		let result = self.stream.code(input, &mut self.buffer, action);
		let _ = try!(result.ret);

		if result.bytes_written > 0 {
			try!(Write::write_all(&mut self.inner, &self.buffer[..result.bytes_written]));
		}

		Ok(result)
	}
}

impl<W: Write> Write for LzmaWriter<W> {
	fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
		// Loop until at least one byte from buf was consumed in order to be
		// compliant with std::io::Write trait API.
		loop {
			match self.lzma_code_and_write(buf, lzma_action::LZMA_RUN) {
				Ok(result) => if result.bytes_read == 0 && result.bytes_written > 0 {
					continue
				} else {
					// If result.bytes_read is zero, then neither was something
					// written nor read. This indicates, something went wrong.
					return Ok(result.bytes_read)
				},
				Err(LzmaError::Io(err)) => return Err(err),
				Err(err) => return Err(io::Error::new(io::ErrorKind::Other, err)),
			}
		}
	}

	fn flush(&mut self) -> io::Result<()> {
		self.inner.flush()
	}
}
<|endoftext|>


<commit_before>//
//  SOS: the Stupid Operating System
//  by Hawk Weisman (hi@hawkweisman.me)
//
//  Copyright (c) 2015 Hawk Weisman
//  Released under the terms of the MIT license. See `LICENSE` in the root
//  directory of this repository for more information.
//
pub mod term;

/// This is basically a braindead reimplementation of the standard
/// library's `Read` trait. Most of the methods available on the
/// standard lib's `Read` are not yet implemented.
pub trait Read {
    type Error;
    fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error>;
    fn read_all(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error>;
}

pub trait Write {
    type Error;
    fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error>;
}
<commit_msg>Add a `<<` operator on `Write`ers like on C++ IOStream<commit_after>//
//  SOS: the Stupid Operating System
//  by Hawk Weisman (hi@hawkweisman.me)
//
//  Copyright (c) 2015 Hawk Weisman
//  Released under the terms of the MIT license. See `LICENSE` in the root
//  directory of this repository for more information.
//
pub mod term;
use core::ops;

/// This is basically a braindead reimplementation of the standard
/// library's `Read` trait. Most of the methods available on the
/// standard lib's `Read` are not yet implemented.
pub trait Read {
    type Error;
    fn read(&mut self, buf: &mut [u8])     -> Result<usize, Self::Error>;
    fn read_all(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error>;
}

pub trait Write {
    type Error;
    fn write(&mut self, buf: &[u8])       -> Result<usize, Self::Error>;
}

impl<'a, 'b, E> ops::Shl<&'a [u8]> for &'b mut Write<Error=E> {
    type Output = Self;

    /// Fakes the C++ `<<` operator for IOStreams on Write.
    fn shl(self, _rhs: &'a [u8]) -> Self::Output {
        try!(self.write(_rhs));
        self
    }
}
<|endoftext|>


<commit_before><commit_msg>adds cpu compare to connect<commit_after><|endoftext|>


<commit_before><commit_msg>Handling missed case when tags for a metric are empty but default tags exist<commit_after><|endoftext|>