<commit_before><commit_msg>stat: add fsext.rs<commit_after>extern crate libc;
extern crate time;

use self::time::Timespec;
pub use self::libc::{S_IFMT, S_IFDIR, S_IFCHR, S_IFBLK, S_IFREG, S_IFIFO, S_IFLNK, S_IFSOCK,
                     S_ISUID, S_ISGID, S_ISVTX, S_IRUSR, S_IWUSR, S_IXUSR, S_IRGRP, S_IWGRP,
                     S_IXGRP, S_IROTH, S_IWOTH, S_IXOTH};

#[macro_export]
macro_rules! has {
    ($mode:expr, $perm:expr) => (
        ($mode & $perm != 0)
    )
}

pub fn pretty_time(sec: i64, nsec: i64) -> String {
    let tm = time::at(Timespec::new(sec, nsec as i32));
    time::strftime("%Y-%m-%d %H:%M:%S.%f %z", &tm).unwrap()
}

pub fn pretty_filetype<'a>(mode: u32, size: u64) -> &'a str {
    match mode & S_IFMT {
        S_IFREG => {
            if size != 0 {
                "regular file"
            } else {
                "regular empty file"
            }
        }
        S_IFDIR => "directory",
        S_IFLNK => "symbolic link",
        S_IFCHR => "character special file",
        S_IFBLK => "block special file",
        S_IFIFO => "fifo",
        S_IFSOCK => "socket",
        // TODO: Other file types
        // See coreutils/gnulib/lib/file-type.c
        _ => "weird file",
    }
}

pub fn pretty_access(mode: u32) -> String {
    let mut result = String::with_capacity(10);
    result.push(match mode & S_IFMT {
        S_IFDIR => 'd',
        S_IFCHR => 'c',
        S_IFBLK => 'b',
        S_IFREG => '-',
        S_IFIFO => 'p',
        S_IFLNK => 'l',
        S_IFSOCK => 's',
        // TODO: Other file types
        // See coreutils/gnulib/lib/filemode.c
        _ => '?',
    });

    result.push(if has!(mode, S_IRUSR) {
        'r'
    } else {
        '-'
    });
    result.push(if has!(mode, S_IWUSR) {
        'w'
    } else {
        '-'
    });
    result.push(if has!(mode, S_ISUID as u32) {
        if has!(mode, S_IXUSR) {
            's'
        } else {
            'S'
        }
    } else if has!(mode, S_IXUSR) {
        'x'
    } else {
        '-'
    });

    result.push(if has!(mode, S_IRGRP) {
        'r'
    } else {
        '-'
    });
    result.push(if has!(mode, S_IWGRP) {
        'w'
    } else {
        '-'
    });
    result.push(if has!(mode, S_ISGID as u32) {
        if has!(mode, S_IXGRP) {
            's'
        } else {
            'S'
        }
    } else if has!(mode, S_IXGRP) {
        'x'
    } else {
        '-'
    });

    result.push(if has!(mode, S_IROTH) {
        'r'
    } else {
        '-'
    });
    result.push(if has!(mode, S_IWOTH) {
        'w'
    } else {
        '-'
    });
    result.push(if has!(mode, S_ISVTX as u32) {
        if has!(mode, S_IXOTH) {
            't'
        } else {
            'T'
        }
    } else if has!(mode, S_IXOTH) {
        'x'
    } else {
        '-'
    });

    result
}

use std::mem::{self, transmute};
use std::path::Path;
use std::borrow::Cow;
use std::ffi::CString;
use std::convert::{AsRef, From};

pub struct Statfs {
    pub f_type: i64,
    pub f_bsize: i64,
    pub f_blocks: u64,
    pub f_bfree: u64,
    pub f_bavail: u64,
    pub f_files: u64,
    pub f_ffree: u64,
    pub f_namelen: i64,
    pub f_frsize: i64,
    pub f_fsid: u64,
}

pub fn statfs<P: AsRef<Path>>(path: P) -> Result<Statfs, String>
    where Vec<u8>: From<P>
{
    use std::error::Error;
    match CString::new(path) {
        Ok(p) => {
            let mut buffer = unsafe { mem::zeroed() };
            unsafe {
                match self::libc::statfs(p.as_ptr(), &mut buffer) {
                    0 => {
                        let fsid: u64;
                        if cfg!(unix) {
                            // Linux, SunOS, HP-UX, 4.4BSD, FreeBSD have a system call statfs() that returns
                            // a struct statfs, containing a fsid_t f_fsid, where fsid_t is defined
                            // as struct { int val[2];  }
                            let f_fsid: &[u32; 2] = transmute(&buffer.f_fsid);
                            fsid = (f_fsid[0] as u64) << 32_u64 | f_fsid[1] as u64;
                        } else {
                            // Solaris, Irix and POSIX have a system call statvfs(2) that returns a
                            // struct statvfs, containing an  unsigned  long  f_fsid
                            fsid = 0;
                        }
                        Ok(Statfs {
                            f_type: buffer.f_type as i64,
                            f_bsize: buffer.f_bsize as i64,
                            f_blocks: buffer.f_blocks as u64,
                            f_bfree: buffer.f_bfree as u64,
                            f_bavail: buffer.f_bavail as u64,
                            f_files: buffer.f_files as u64,
                            f_ffree: buffer.f_ffree as u64,
                            f_fsid: fsid,
                            f_namelen: buffer.f_namelen as i64,
                            f_frsize: buffer.f_frsize as i64,
                        })
                    }
                    // TODO: Return explicit error message
                    _ => Err("Unknown error".to_owned()),
                }
            }
        }
        Err(e) => Err(e.description().to_owned()),
    }
}

pub fn pretty_fstype<'a>(fstype: i64) -> Cow<'a, str> {
    match fstype {
        0x61636673 => "acfs".into(),
        0xADF5 => "adfs".into(),
        0xADFF => "affs".into(),
        0x5346414F => "afs".into(),
        0x09041934 => "anon-inode FS".into(),
        0x61756673 => "aufs".into(),
        0x0187 => "autofs".into(),
        0x42465331 => "befs".into(),
        0x62646576 => "bdevfs".into(),
        0x1BADFACE => "bfs".into(),
        0xCAFE4A11 => "bpf_fs".into(),
        0x42494E4D => "binfmt_misc".into(),
        0x9123683E => "btrfs".into(),
        0x73727279 => "btrfs_test".into(),
        0x00C36400 => "ceph".into(),
        0x0027E0EB => "cgroupfs".into(),
        0xFF534D42 => "cifs".into(),
        0x73757245 => "coda".into(),
        0x012FF7B7 => "coh".into(),
        0x62656570 => "configfs".into(),
        0x28CD3D45 => "cramfs".into(),
        0x453DCD28 => "cramfs-wend".into(),
        0x64626720 => "debugfs".into(),
        0x1373 => "devfs".into(),
        0x1CD1 => "devpts".into(),
        0xF15F => "ecryptfs".into(),
        0xDE5E81E4 => "efivarfs".into(),
        0x00414A53 => "efs".into(),
        0x5DF5 => "exofs".into(),
        0x137D => "ext".into(),
        0xEF53 => "ext2/ext3".into(),
        0xEF51 => "ext2".into(),
        0xF2F52010 => "f2fs".into(),
        0x4006 => "fat".into(),
        0x19830326 => "fhgfs".into(),
        0x65735546 => "fuseblk".into(),
        0x65735543 => "fusectl".into(),
        0x0BAD1DEA => "futexfs".into(),
        0x01161970 => "gfs/gfs2".into(),
        0x47504653 => "gpfs".into(),
        0x4244 => "hfs".into(),
        0x482B => "hfs+".into(),
        0x4858 => "hfsx".into(),
        0x00C0FFEE => "hostfs".into(),
        0xF995E849 => "hpfs".into(),
        0x958458F6 => "hugetlbfs".into(),
        0x11307854 => "inodefs".into(),
        0x013111A8 => "ibrix".into(),
        0x2BAD1DEA => "inotifyfs".into(),
        0x9660 => "isofs".into(),
        0x4004 => "isofs".into(),
        0x4000 => "isofs".into(),
        0x07C0 => "jffs".into(),
        0x72B6 => "jffs2".into(),
        0x3153464A => "jfs".into(),
        0x6B414653 => "k-afs".into(),
        0xC97E8168 => "logfs".into(),
        0x0BD00BD0 => "lustre".into(),
        0x5346314D => "m1fs".into(),
        0x137F => "minix".into(),
        0x138F => "minix (30 char.)".into(),
        0x2468 => "minix v2".into(),
        0x2478 => "minix v2 (30 char.)".into(),
        0x4D5A => "minix3".into(),
        0x19800202 => "mqueue".into(),
        0x4D44 => "msdos".into(),
        0x564C => "novell".into(),
        0x6969 => "nfs".into(),
        0x6E667364 => "nfsd".into(),
        0x3434 => "nilfs".into(),
        0x6E736673 => "nsfs".into(),
        0x5346544E => "ntfs".into(),
        0x9FA1 => "openprom".into(),
        0x7461636F => "ocfs2".into(),
        0x794C7630 => "overlayfs".into(),
        0xAAD7AAEA => "panfs".into(),
        0x50495045 => "pipefs".into(),
        0x7C7C6673 => "prl_fs".into(),
        0x9FA0 => "proc".into(),
        0x6165676C => "pstorefs".into(),
        0x002F => "qnx4".into(),
        0x68191122 => "qnx6".into(),
        0x858458F6 => "ramfs".into(),
        0x52654973 => "reiserfs".into(),
        0x7275 => "romfs".into(),
        0x67596969 => "rpc_pipefs".into(),
        0x73636673 => "securityfs".into(),
        0xF97CFF8C => "selinux".into(),
        0x43415D53 => "smackfs".into(),
        0x517B => "smb".into(),
        0xFE534D42 => "smb2".into(),
        0xBEEFDEAD => "snfs".into(),
        0x534F434B => "sockfs".into(),
        0x73717368 => "squashfs".into(),
        0x62656572 => "sysfs".into(),
        0x012FF7B6 => "sysv2".into(),
        0x012FF7B5 => "sysv4".into(),
        0x01021994 => "tmpfs".into(),
        0x74726163 => "tracefs".into(),
        0x24051905 => "ubifs".into(),
        0x15013346 => "udf".into(),
        0x00011954 => "ufs".into(),
        0x54190100 => "ufs".into(),
        0x9FA2 => "usbdevfs".into(),
        0x01021997 => "v9fs".into(),
        0xBACBACBC => "vmhgfs".into(),
        0xA501FCF5 => "vxfs".into(),
        0x565A4653 => "vzfs".into(),
        0x53464846 => "wslfs".into(),
        0xABBA1974 => "xenfs".into(),
        0x012FF7B4 => "xenix".into(),
        0x58465342 => "xfs".into(),
        0x012FD16D => "xia".into(),
        0x2FC12FC1 => "zfs".into(),
        other => format!("UNKNOWN ({:#x})", other).into(),
    }
}

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

    #[test]
    fn test_access() {
        assert_eq!("drwxr-xr-x", pretty_access(S_IFDIR | 0o755));
        assert_eq!("-rw-r--r--", pretty_access(S_IFREG | 0o644));
        assert_eq!("srw-r-----", pretty_access(S_IFSOCK | 0o640));
        assert_eq!("lrw-r-xr-x", pretty_access(S_IFLNK | 0o655));
        assert_eq!("?rw-r-xr-x", pretty_access(0o655));

        assert_eq!("brwSr-xr-x",
                   pretty_access(S_IFBLK | S_ISUID as u32 | 0o655));
        assert_eq!("brwsr-xr-x",
                   pretty_access(S_IFBLK | S_ISUID as u32 | 0o755));

        assert_eq!("prw---sr--",
                   pretty_access(S_IFIFO | S_ISGID as u32 | 0o614));
        assert_eq!("prw---Sr--",
                   pretty_access(S_IFIFO | S_ISGID as u32 | 0o604));

        assert_eq!("c---r-xr-t",
                   pretty_access(S_IFCHR | S_ISVTX as u32 | 0o055));
        assert_eq!("c---r-xr-T",
                   pretty_access(S_IFCHR | S_ISVTX as u32 | 0o054));
    }

    #[test]
    fn test_file_type() {
        assert_eq!("block special file", pretty_filetype(S_IFBLK, 0));
        assert_eq!("character special file", pretty_filetype(S_IFCHR, 0));
        assert_eq!("regular file", pretty_filetype(S_IFREG, 1));
        assert_eq!("regular empty file", pretty_filetype(S_IFREG, 0));
        assert_eq!("weird file", pretty_filetype(0, 0));
    }

    #[test]
    fn test_fs_type() {
        assert_eq!("ext2/ext3", pretty_fstype(0xEF53));
        assert_eq!("tmpfs", pretty_fstype(0x01021994));
        assert_eq!("nfs", pretty_fstype(0x6969));
        assert_eq!("btrfs", pretty_fstype(0x9123683e));
        assert_eq!("xfs", pretty_fstype(0x58465342));
        assert_eq!("zfs", pretty_fstype(0x2FC12FC1));
        assert_eq!("ntfs", pretty_fstype(0x5346544e));
        assert_eq!("fat", pretty_fstype(0x4006));
        assert_eq!("UNKNOWN (0x1234)", pretty_fstype(0x1234));
    }
}
<|endoftext|>


<commit_before>//xfail-test

// this should be illegal but borrowck is not handling
// pattern bindings correctly right now

fn main() {
let x = some(~1);
alt x {
  some(y) {
    let b <- y;
  }
  _ {}
}
}
<commit_msg>unxfail test for #2657<commit_after>fn main() {
let x = some(~1);
alt x {
  some(y) {
    let _b <- y; //! ERROR moving out of pattern binding
  }
  _ {}
}
}
<|endoftext|>


<commit_before><commit_msg>Implement Index and IndexMut on Field<commit_after><|endoftext|>


<commit_before><commit_msg>compute sphere volume<commit_after>// volume of sphere

fn main() {
    let r: f32 = 5.0;
    let pi: f32 = 3.14;
    let v: f32;
    v = 4.0/3.0 * pi * r * r;
    println!("Result = {} ", v);
}
<|endoftext|>


<commit_before><commit_msg>Added an example<commit_after>
extern crate debug;
extern crate freetype;

use freetype::ffi;

static WIDTH: ffi::FT_Int = 32;
static HEIGHT: ffi::FT_Int = 24;

fn draw_bitmap(bitmap: &ffi::FT_Bitmap, x: ffi::FT_Int, y: ffi::FT_Int) -> [[u8, ..WIDTH], ..HEIGHT] {
    let mut image: [[u8, ..WIDTH], ..HEIGHT] = [
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,],
    ];
    let mut p = 0;
    let mut q = 0;
    let x_max = x + bitmap.width;
    let y_max = y + bitmap.rows;

    for i in range(x, x_max) {
        for j in range(y, y_max) {
            if i < 0      || j < 0       ||
               i >= WIDTH || j >= HEIGHT {
                continue;
            }

            unsafe {
                image[j as uint][i as uint] |= *bitmap.buffer.offset((q * bitmap.width + p) as int);
            }
            q += 1;
        }
        q = 0;
        p += 1;
    }

    image
}

fn main() {
    unsafe {
        let args = std::os::args();
        if args.len() != 3 {
            println!("usage: {} font sample-text\n", args.get(0));
            return;
        }

        let filename = args.get(1);
        let text = args.get(2);

        let library: ffi::FT_Library = std::ptr::null();
        let error = ffi::FT_Init_FreeType(&library);
        if error != ffi::FT_Err_Ok {
            println!("Could not initialize freetype.");
            return;
        }

        let face: ffi::FT_Face = std::ptr::null();
        let error = ffi::FT_New_Face(library, filename.as_slice().as_ptr(), 0, &face);
        if error != ffi::FT_Err_Ok {
            println!("Could not load font '{}'. Error Code: {}", filename, error);
            return;
        }

        ffi::FT_Set_Char_Size(face, 40 * 64, 0, 50, 0);
        let slot = &*(*face).glyph;

        let error = ffi::FT_Load_Char(face, text.as_slice()[0] as u64, ffi::FT_LOAD_RENDER);
        if error != ffi::FT_Err_Ok {
            println!("Could not load char.");
            return;
        }

        let image = draw_bitmap(&slot.bitmap, slot.bitmap_left, HEIGHT - slot.bitmap_top);

        for i in range(0, HEIGHT) {
            for j in range(0, WIDTH) {
                std::io::print(if image[i as uint][j as uint] == 0 {
                                   " "
                               } else if image[i as uint][j as uint] < 128 {
                                   "*"
                               } else {
                                   "+"
                               });
            }
            std::io::println("");
        }

        ffi::FT_Done_Face(face);
        ffi::FT_Done_FreeType(library);
    }
}

<|endoftext|>


<commit_before><commit_msg>Revert "Remove GetIter"<commit_after><|endoftext|>


<commit_before><commit_msg> removed filter for testing<commit_after><|endoftext|>


<commit_before><commit_msg>remove useless BTreeMap<commit_after><|endoftext|>


<commit_before><commit_msg>languages/rust/rust-book/3-chapter/32-code.rs<commit_after><|endoftext|>


<commit_before><commit_msg>Attempt at file streaming<commit_after>extern crate bytes;
extern crate futures;
extern crate gopher_core;
extern crate tokio_proto;
extern crate tokio_service;

use futures::{future, Future, BoxFuture, Sink};
use gopher_core::{DirEntity, ItemType};
use gopher_core::{GopherRequest, GopherResponse, GopherStr, Void};
use gopher_core::proto::GopherServer;
use std::io;
use std::io::prelude::*;
use std::thread;
use std::fs::File;
use bytes::Bytes;
use tokio_proto::TcpServer;
use tokio_proto::streaming::{Body, Message};
use tokio_service::Service;

pub struct HelloGopherServer;

impl Service for HelloGopherServer {
    type Request = Message<GopherRequest, Body<Void, io::Error>>;
    type Response = Message<GopherResponse, Body<Bytes, io::Error>>;
    type Error = io::Error;
    type Future = BoxFuture<Self::Response, Self::Error>;

    fn call(&self, message: Self::Request) -> Self::Future {
        let request = match message {
            Message::WithoutBody(request) => request,
            _ => unreachable!(),
        };

        println!("got request {:?}", request);

        let response = match &request.selector[..] {
            b"" => match request.query.as_ref() {
                None => GopherResponse::Menu(vec![
                    DirEntity {
                        item_type: ItemType::File,
                        name: GopherStr::from_latin1(b"Download file"),
                        selector: GopherStr::from_latin1(b"file"),
                        host: GopherStr::from_latin1(b"0.0.0.0"),
                        port: 12345,
                    },
                ]),
                // Compatibility hack for gopher+ clients:
                Some(_) => GopherResponse::GopherPlusRedirect(DirEntity {
                    item_type: ItemType::Dir,
                    name: GopherStr::from_latin1(b"Main menu"),
                    selector: GopherStr::from_latin1(b""),
                    host: GopherStr::from_latin1(b"0.0.0.0"),
                    port: 12345,
                })
            },
            b"file" => {
                let (mut tx, body) = Body::pair();
                thread::spawn(move || {
                    let filename = std::env::args_os().next().unwrap();
                    let mut f = File::open(filename).unwrap();
                    let mut buf = [0; 1024];
                    while let Ok(n) = f.read(&mut buf) {
                        if n == 0 { break }
                        tx = tx.send(Ok(Bytes::from(&buf[..n]))).wait().unwrap();
                    }
                });
                let response = GopherResponse::BinaryFile(Bytes::new());
                return future::ok(Message::WithBody(response, body)).boxed()
            }
            _ => GopherResponse::error(GopherStr::from_latin1(b"File not found")),
        };

        future::ok(Message::WithoutBody(response)).boxed()
    }
}

fn main() {
    println!("listening on port 12345");
    TcpServer::new(GopherServer, "0.0.0.0:12345".parse().unwrap())
        .serve(|| Ok(HelloGopherServer));
}
<|endoftext|>


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

use llvm::ValueRef;
use rustc::middle::ty::{self, Ty, HasTypeFlags};
use rustc::mir::repr as mir;
use rustc::mir::tcx::LvalueTy;
use trans::adt;
use trans::base;
use trans::build;
use trans::common::{self, Block};
use trans::debuginfo::DebugLoc;
use trans::machine;

use std::ptr;

use super::{MirContext, TempRef};

#[derive(Copy, Clone)]
pub struct LvalueRef<'tcx> {
    /// Pointer to the contents of the lvalue
    pub llval: ValueRef,

    /// This lvalue's extra data if it is unsized, or null
    pub llextra: ValueRef,

    /// Monomorphized type of this lvalue, including variant information
    pub ty: LvalueTy<'tcx>,
}

impl<'tcx> LvalueRef<'tcx> {
    pub fn new_sized(llval: ValueRef, lvalue_ty: LvalueTy<'tcx>) -> LvalueRef<'tcx> {
        LvalueRef { llval: llval, llextra: ptr::null_mut(), ty: lvalue_ty }
    }

    pub fn alloca<'bcx>(bcx: Block<'bcx, 'tcx>,
                        ty: Ty<'tcx>,
                        name: &str)
                        -> LvalueRef<'tcx>
    {
        assert!(!ty.has_erasable_regions());
        let lltemp = base::alloc_ty(bcx, ty, name);
        LvalueRef::new_sized(lltemp, LvalueTy::from_ty(ty))
    }
}

impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
    pub fn lvalue_len(&mut self,
                      bcx: Block<'bcx, 'tcx>,
                      lvalue: LvalueRef<'tcx>)
                      -> ValueRef {
        match lvalue.ty.to_ty(bcx.tcx()).sty {
            ty::TyArray(_, n) => common::C_uint(bcx.ccx(), n),
            ty::TySlice(_) | ty::TyStr => {
                assert!(lvalue.llextra != ptr::null_mut());
                lvalue.llextra
            }
            _ => bcx.sess().bug("unexpected type in get_base_and_len"),
        }
    }

    pub fn trans_lvalue(&mut self,
                        bcx: Block<'bcx, 'tcx>,
                        lvalue: &mir::Lvalue<'tcx>)
                        -> LvalueRef<'tcx> {
        debug!("trans_lvalue(lvalue={:?})", lvalue);

        let fcx = bcx.fcx;
        let ccx = fcx.ccx;
        let tcx = bcx.tcx();
        match *lvalue {
            mir::Lvalue::Var(index) => self.vars[index as usize],
            mir::Lvalue::Temp(index) => match self.temps[index as usize] {
                TempRef::Lvalue(lvalue) =>
                    lvalue,
                TempRef::Operand(..) =>
                    tcx.sess.bug(&format!("using operand temp {:?} as lvalue", lvalue)),
            },
            mir::Lvalue::Arg(index) => self.args[index as usize],
            mir::Lvalue::Static(def_id) => {
                let const_ty = self.mir.lvalue_ty(tcx, lvalue);
                LvalueRef::new_sized(
                    common::get_static_val(ccx, def_id, const_ty.to_ty(tcx)),
                    const_ty)
            },
            mir::Lvalue::ReturnPointer => {
                let return_ty = bcx.monomorphize(&self.mir.return_ty);
                let llval = fcx.get_ret_slot(bcx, return_ty, "return");
                LvalueRef::new_sized(llval, LvalueTy::from_ty(return_ty.unwrap()))
            }
            mir::Lvalue::Projection(ref projection) => {
                let tr_base = self.trans_lvalue(bcx, &projection.base);
                let projected_ty = tr_base.ty.projection_ty(tcx, &projection.elem);
                let (llprojected, llextra) = match projection.elem {
                    mir::ProjectionElem::Deref => {
                        let base_ty = tr_base.ty.to_ty(tcx);
                        if common::type_is_sized(tcx, projected_ty.to_ty(tcx)) {
                            (base::load_ty(bcx, tr_base.llval, base_ty),
                             ptr::null_mut())
                        } else {
                            base::load_fat_ptr(bcx, tr_base.llval, base_ty)
                        }
                    }
                    mir::ProjectionElem::Field(ref field) => {
                        let base_ty = tr_base.ty.to_ty(tcx);
                        let base_repr = adt::represent_type(ccx, base_ty);
                        let discr = match tr_base.ty {
                            LvalueTy::Ty { .. } => 0,
                            LvalueTy::Downcast { adt_def: _, substs: _, variant_index: v } => v,
                        };
                        let discr = discr as u64;
                        let is_sized = common::type_is_sized(tcx, projected_ty.to_ty(tcx));
                        let base = if is_sized {
                            adt::MaybeSizedValue::sized(tr_base.llval)
                        } else {
                            adt::MaybeSizedValue::unsized_(tr_base.llval, tr_base.llextra)
                        };
                        (adt::trans_field_ptr(bcx, &base_repr, base, discr, field.index()),
                         if is_sized {
                             ptr::null_mut()
                         } else {
                             tr_base.llextra
                         })
                    }
                    mir::ProjectionElem::Index(ref index) => {
                        let index = self.trans_operand(bcx, index);
                        let llindex = self.prepare_index(bcx, index.immediate());
                        (build::InBoundsGEP(bcx, tr_base.llval, &[llindex]),
                         ptr::null_mut())
                    }
                    mir::ProjectionElem::ConstantIndex { offset,
                                                         from_end: false,
                                                         min_length: _ } => {
                        let lloffset = common::C_u32(bcx.ccx(), offset);
                        let llindex = self.prepare_index(bcx, lloffset);
                        (build::InBoundsGEP(bcx, tr_base.llval, &[llindex]),
                         ptr::null_mut())
                    }
                    mir::ProjectionElem::ConstantIndex { offset,
                                                         from_end: true,
                                                         min_length: _ } => {
                        let lloffset = common::C_u32(bcx.ccx(), offset);
                        let lllen = self.lvalue_len(bcx, tr_base);
                        let llindex = build::Sub(bcx, lllen, lloffset, DebugLoc::None);
                        let llindex = self.prepare_index(bcx, llindex);
                        (build::InBoundsGEP(bcx, tr_base.llval, &[llindex]),
                         ptr::null_mut())
                    }
                    mir::ProjectionElem::Downcast(..) => {
                        (tr_base.llval, tr_base.llextra)
                    }
                };
                LvalueRef {
                    llval: llprojected,
                    llextra: llextra,
                    ty: projected_ty,
                }
            }
        }
    }

    /// Adjust the bitwidth of an index since LLVM is less forgiving
    /// than we are.
    ///
    /// nmatsakis: is this still necessary? Not sure.
    fn prepare_index(&mut self,
                     bcx: Block<'bcx, 'tcx>,
                     llindex: ValueRef)
                     -> ValueRef
    {
        let ccx = bcx.ccx();
        let index_size = machine::llbitsize_of_real(bcx.ccx(), common::val_ty(llindex));
        let int_size = machine::llbitsize_of_real(bcx.ccx(), ccx.int_type());
        if index_size < int_size {
            build::ZExt(bcx, llindex, ccx.int_type())
        } else if index_size > int_size {
            build::Trunc(bcx, llindex, ccx.int_type())
        } else {
            llindex
        }
    }
}
<commit_msg>Fix GEPs for MIR indexing translation<commit_after>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use llvm::ValueRef;
use rustc::middle::ty::{self, Ty, HasTypeFlags};
use rustc::mir::repr as mir;
use rustc::mir::tcx::LvalueTy;
use trans::adt;
use trans::base;
use trans::build;
use trans::common::{self, Block};
use trans::debuginfo::DebugLoc;
use trans::machine;

use std::ptr;

use super::{MirContext, TempRef};

#[derive(Copy, Clone)]
pub struct LvalueRef<'tcx> {
    /// Pointer to the contents of the lvalue
    pub llval: ValueRef,

    /// This lvalue's extra data if it is unsized, or null
    pub llextra: ValueRef,

    /// Monomorphized type of this lvalue, including variant information
    pub ty: LvalueTy<'tcx>,
}

impl<'tcx> LvalueRef<'tcx> {
    pub fn new_sized(llval: ValueRef, lvalue_ty: LvalueTy<'tcx>) -> LvalueRef<'tcx> {
        LvalueRef { llval: llval, llextra: ptr::null_mut(), ty: lvalue_ty }
    }

    pub fn alloca<'bcx>(bcx: Block<'bcx, 'tcx>,
                        ty: Ty<'tcx>,
                        name: &str)
                        -> LvalueRef<'tcx>
    {
        assert!(!ty.has_erasable_regions());
        let lltemp = base::alloc_ty(bcx, ty, name);
        LvalueRef::new_sized(lltemp, LvalueTy::from_ty(ty))
    }
}

impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
    pub fn lvalue_len(&mut self,
                      bcx: Block<'bcx, 'tcx>,
                      lvalue: LvalueRef<'tcx>)
                      -> ValueRef {
        match lvalue.ty.to_ty(bcx.tcx()).sty {
            ty::TyArray(_, n) => common::C_uint(bcx.ccx(), n),
            ty::TySlice(_) | ty::TyStr => {
                assert!(lvalue.llextra != ptr::null_mut());
                lvalue.llextra
            }
            _ => bcx.sess().bug("unexpected type in get_base_and_len"),
        }
    }

    pub fn trans_lvalue(&mut self,
                        bcx: Block<'bcx, 'tcx>,
                        lvalue: &mir::Lvalue<'tcx>)
                        -> LvalueRef<'tcx> {
        debug!("trans_lvalue(lvalue={:?})", lvalue);

        let fcx = bcx.fcx;
        let ccx = fcx.ccx;
        let tcx = bcx.tcx();
        match *lvalue {
            mir::Lvalue::Var(index) => self.vars[index as usize],
            mir::Lvalue::Temp(index) => match self.temps[index as usize] {
                TempRef::Lvalue(lvalue) =>
                    lvalue,
                TempRef::Operand(..) =>
                    tcx.sess.bug(&format!("using operand temp {:?} as lvalue", lvalue)),
            },
            mir::Lvalue::Arg(index) => self.args[index as usize],
            mir::Lvalue::Static(def_id) => {
                let const_ty = self.mir.lvalue_ty(tcx, lvalue);
                LvalueRef::new_sized(
                    common::get_static_val(ccx, def_id, const_ty.to_ty(tcx)),
                    const_ty)
            },
            mir::Lvalue::ReturnPointer => {
                let return_ty = bcx.monomorphize(&self.mir.return_ty);
                let llval = fcx.get_ret_slot(bcx, return_ty, "return");
                LvalueRef::new_sized(llval, LvalueTy::from_ty(return_ty.unwrap()))
            }
            mir::Lvalue::Projection(ref projection) => {
                let tr_base = self.trans_lvalue(bcx, &projection.base);
                let projected_ty = tr_base.ty.projection_ty(tcx, &projection.elem);
                let (llprojected, llextra) = match projection.elem {
                    mir::ProjectionElem::Deref => {
                        let base_ty = tr_base.ty.to_ty(tcx);
                        if common::type_is_sized(tcx, projected_ty.to_ty(tcx)) {
                            (base::load_ty(bcx, tr_base.llval, base_ty),
                             ptr::null_mut())
                        } else {
                            base::load_fat_ptr(bcx, tr_base.llval, base_ty)
                        }
                    }
                    mir::ProjectionElem::Field(ref field) => {
                        let base_ty = tr_base.ty.to_ty(tcx);
                        let base_repr = adt::represent_type(ccx, base_ty);
                        let discr = match tr_base.ty {
                            LvalueTy::Ty { .. } => 0,
                            LvalueTy::Downcast { adt_def: _, substs: _, variant_index: v } => v,
                        };
                        let discr = discr as u64;
                        let is_sized = common::type_is_sized(tcx, projected_ty.to_ty(tcx));
                        let base = if is_sized {
                            adt::MaybeSizedValue::sized(tr_base.llval)
                        } else {
                            adt::MaybeSizedValue::unsized_(tr_base.llval, tr_base.llextra)
                        };
                        (adt::trans_field_ptr(bcx, &base_repr, base, discr, field.index()),
                         if is_sized {
                             ptr::null_mut()
                         } else {
                             tr_base.llextra
                         })
                    }
                    mir::ProjectionElem::Index(ref index) => {
                        let index = self.trans_operand(bcx, index);
                        let llindex = self.prepare_index(bcx, index.immediate());
                        let zero = common::C_uint(bcx.ccx(), 0u64);
                        (build::InBoundsGEP(bcx, tr_base.llval, &[zero, llindex]),
                         ptr::null_mut())
                    }
                    mir::ProjectionElem::ConstantIndex { offset,
                                                         from_end: false,
                                                         min_length: _ } => {
                        let lloffset = common::C_u32(bcx.ccx(), offset);
                        let llindex = self.prepare_index(bcx, lloffset);
                        let zero = common::C_uint(bcx.ccx(), 0u64);
                        (build::InBoundsGEP(bcx, tr_base.llval, &[zero, llindex]),
                         ptr::null_mut())
                    }
                    mir::ProjectionElem::ConstantIndex { offset,
                                                         from_end: true,
                                                         min_length: _ } => {
                        let lloffset = common::C_u32(bcx.ccx(), offset);
                        let lllen = self.lvalue_len(bcx, tr_base);
                        let llindex = build::Sub(bcx, lllen, lloffset, DebugLoc::None);
                        let llindex = self.prepare_index(bcx, llindex);
                        let zero = common::C_uint(bcx.ccx(), 0u64);
                        (build::InBoundsGEP(bcx, tr_base.llval, &[zero, llindex]),
                         ptr::null_mut())
                    }
                    mir::ProjectionElem::Downcast(..) => {
                        (tr_base.llval, tr_base.llextra)
                    }
                };
                LvalueRef {
                    llval: llprojected,
                    llextra: llextra,
                    ty: projected_ty,
                }
            }
        }
    }

    /// Adjust the bitwidth of an index since LLVM is less forgiving
    /// than we are.
    ///
    /// nmatsakis: is this still necessary? Not sure.
    fn prepare_index(&mut self,
                     bcx: Block<'bcx, 'tcx>,
                     llindex: ValueRef)
                     -> ValueRef
    {
        let ccx = bcx.ccx();
        let index_size = machine::llbitsize_of_real(bcx.ccx(), common::val_ty(llindex));
        let int_size = machine::llbitsize_of_real(bcx.ccx(), ccx.int_type());
        if index_size < int_size {
            build::ZExt(bcx, llindex, ccx.int_type())
        } else if index_size > int_size {
            build::Trunc(bcx, llindex, ccx.int_type())
        } else {
            llindex
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Start using L-systems for hierarchy<commit_after>extern crate rand;
extern crate evo;
extern crate petgraph;
extern crate graph_annealing;
extern crate clap;
extern crate crossbeam;
extern crate simple_parallel;
extern crate num_cpus;
extern crate pcg;
extern crate graph_sgf;
extern crate triadic_census;
extern crate time;
extern crate serde_json;
extern crate sexp;
extern crate lindenmayer_system;

use sexp::{Sexp, atom_s};

use std::f32;
use std::fmt::Debug;
use std::str::FromStr;
use clap::{App, Arg};
use rand::{Rng, SeedableRng};
use rand::distributions::{IndependentSample, Range};
use rand::os::OsRng;
use pcg::PcgRng;

use evo::Probability;
use evo::nsga2::{self, FitnessEval, MultiObjective3};
use graph_annealing::repr::edge_ops_genome::{EdgeOpsGenome, Toolbox, parse_weighted_op_list,
                                             to_weighted_vec};
use graph_annealing::helper::draw_graph;
use graph_annealing::goal::Goal;
use simple_parallel::Pool;

use petgraph::{Directed, Graph};
use graph_sgf::{PetgraphReader, Unweighted};
use triadic_census::OptDenseDigraph;

use std::io::BufReader;
use std::fs::File;

#[derive(Debug, Copy, Clone)]
enum FitnessFunction {
    Null,
    ConnectedComponents,
    StronglyConnectedComponents,
    NeighborMatching,
    TriadicDistance,
}

fn apply_fitness_function<N: Clone + Default, E: Clone + Default>(fitfun: FitnessFunction,
                                                                  goal: &Goal<N, E>,
                                                                  g: &OptDenseDigraph<(), ()>)
                                                                  -> f32 {
    match fitfun {
        FitnessFunction::Null => {
            0.0
        }
        FitnessFunction::ConnectedComponents => {
            goal.connected_components_distance(g) as f32
        }
        FitnessFunction::StronglyConnectedComponents => {
            goal.strongly_connected_components_distance(g) as f32
        }
        FitnessFunction::NeighborMatching => {
            goal.neighbor_matching_score(g) as f32
        }
        FitnessFunction::TriadicDistance => {
            goal.triadic_distance(g) as f32
        }
    }
}

struct MyEval<N, E> {
    goal: Goal<N, E>,
    pool: Pool,
    fitness_functions: (FitnessFunction, FitnessFunction, FitnessFunction),
}

#[inline]
fn fitness<N: Clone + Default, E: Clone + Default>(fitness_functions: (FitnessFunction,
                                                                       FitnessFunction,
                                                                       FitnessFunction),
                                                   goal: &Goal<N, E>,
                                                   ind: &EdgeOpsGenome)
                                                   -> MultiObjective3<f32> {
    let g = ind.to_graph();
    MultiObjective3::from((apply_fitness_function(fitness_functions.0, goal, &g),
                           apply_fitness_function(fitness_functions.1, goal, &g),
                           apply_fitness_function(fitness_functions.2, goal, &g)))

}

impl<N:Clone+Sync+Default,E:Clone+Sync+Default> FitnessEval<EdgeOpsGenome, MultiObjective3<f32>> for MyEval<N,E> {
    fn fitness(&mut self, pop: &[EdgeOpsGenome]) -> Vec<MultiObjective3<f32>> {
        let pool = &mut self.pool;
        let goal = &self.goal;

        let fitness_functions = self.fitness_functions;

        crossbeam::scope(|scope| {
            pool.map(scope, pop, |ind| fitness(fitness_functions, goal, ind))
                .collect()
        })
    }
}

#[derive(Debug)]
struct Stat<T: Debug> {
    min: T,
    max: T,
    avg: T,
}

impl Stat<f32> {
    fn for_objectives(fit: &[MultiObjective3<f32>], i: usize) -> Stat<f32> {
        let min = fit.iter().fold(f32::INFINITY, |acc, f| {
            let x = f.objectives[i];
            if x < acc {
                x
            } else {
                acc
            }
        });
        let max = fit.iter().fold(-f32::INFINITY, |acc, f| {
            let x = f.objectives[i];
            if x > acc {
                x
            } else {
                acc
            }
        });
        let sum = fit.iter()
                     .fold(0.0, |acc, f| acc + f.objectives[i]);
        Stat {
            min: min,
            max: max,
            avg: if fit.is_empty() {
                0.0
            } else {
                sum / fit.len() as f32
            },
        }
    }
}

#[allow(non_snake_case)]
fn main() {
    let ncpus = num_cpus::get();
    println!("Using {} CPUs", ncpus);
    let matches = App::new("nsga2_edge")
                      .arg(Arg::with_name("NGEN")
                               .long("ngen")
                               .help("Number of generations to run")
                               .takes_value(true)
                               .required(true))
                      .arg(Arg::with_name("OPS")
                               .long("ops")
                               .help("Edge operation and weight specification, e.g. \
                                      Dup:1,Split:3,Parent:2")
                               .takes_value(true)
                               .required(true))
                      .arg(Arg::with_name("GRAPH")
                               .long("graph")
                               .help("SGF graph file")
                               .takes_value(true)
                               .required(true))
                      .arg(Arg::with_name("MU")
                               .long("mu")
                               .help("Population size")
                               .takes_value(true)
                               .required(true))
                      .arg(Arg::with_name("LAMBDA")
                               .long("lambda")
                               .help("Size of offspring population")
                               .takes_value(true)
                               .required(true))
                      .arg(Arg::with_name("K")
                               .long("k")
                               .help("Tournament selection (default: 2)")
                               .takes_value(true))
                      .arg(Arg::with_name("SEED")
                               .long("seed")
                               .help("Seed value for Rng")
                               .takes_value(true))
                      .arg(Arg::with_name("VAROPS")
                               .long("varops")
                               .help("Variation operators and weight specification, e.g. \
                                      Mutate:1,LinearCrossover2:1,UniformCrossover:2,Copy:0")
                               .takes_value(true)
                               .required(true))
                      .arg(Arg::with_name("MUTOPS")
                               .long("mutops")
                               .help("Mutation operation and weight specification, e.g. \
                                      Insert:1,Remove:1,Replace:2,ModifyOp:0,ModifyParam:2,Copy:\
                                      0")
                               .takes_value(true)
                               .required(true))
                      .arg(Arg::with_name("MUTP")
                               .long("mutp")
                               .help("Probability for element mutation")
                               .takes_value(true)
                               .required(true))
                      .arg(Arg::with_name("ILEN")
                               .long("ilen")
                               .help("Initial genome length (random range)")
                               .takes_value(true)
                               .required(true))
                      .arg(Arg::with_name("OBJECTIVES")
                               .long("objectives")
                               .help("Specify 3 objective functions comma separated (null, cc, \
                                      scc, nm, td), e.g. cc,nm,td")
                               .takes_value(true)
                               .required(true))
                      .arg(Arg::with_name("THRESHOLD")
                               .long("threshold")
                               .help("Abort if for all fitness[i] <= value[i] (default: 0,0,0)")
                               .takes_value(true)
                               .required(false))
                      .get_matches();

    // number of generations
    let NGEN: usize = FromStr::from_str(matches.value_of("NGEN").unwrap()).unwrap();
    println!("NGEN: {}", NGEN);

    // size of population
    let MU: usize = FromStr::from_str(matches.value_of("MU").unwrap()).unwrap();
    println!("MU: {}", MU);

    // size of offspring population
    let LAMBDA: usize = FromStr::from_str(matches.value_of("LAMBDA").unwrap()).unwrap();
    println!("LAMBDA: {}", LAMBDA);

    // tournament selection
    let K: usize = FromStr::from_str(matches.value_of("K").unwrap_or("2")).unwrap();
    assert!(K > 0);
    println!("K: {}", K);

    let seed: Vec<u64>;
    if let Some(seed_str) = matches.value_of("SEED") {
        seed = seed_str.split(",").map(|s| FromStr::from_str(s).unwrap()).collect();
    } else {
        println!("Use OsRng to generate seed..");
        let mut rng = OsRng::new().unwrap();
        seed = (0..2).map(|_| rng.next_u64()).collect();
    }
    println!("SEED: {:?}", seed);

    let MUTP: f32 = FromStr::from_str(matches.value_of("MUTP").unwrap()).unwrap();
    println!("MUTP: {:?}", MUTP);

    // Parse weighted operation choice from command line
    let mutops = parse_weighted_op_list(matches.value_of("MUTOPS").unwrap()).unwrap();
    println!("mut ops: {:?}", mutops);

    let ilen_str = matches.value_of("ILEN").unwrap();
    let ilen: Vec<usize> = ilen_str.split(",").map(|s| FromStr::from_str(s).unwrap()).collect();
    assert!(ilen.len() == 1 || ilen.len() == 2);

    let ilen_from = ilen[0];
    let ilen_to = if ilen.len() == 1 {
        ilen[0]
    } else {
        ilen[1]
    };
    assert!(ilen_from <= ilen_to);

    // read objective functions
    let mut objectives_arr: Vec<FitnessFunction> = Vec::new();
    for s in matches.value_of("OBJECTIVES").unwrap().split(",") {
        objectives_arr.push(match s {
            "null" => {
                FitnessFunction::Null
            }
            "cc" => {
                FitnessFunction::ConnectedComponents
            }
            "scc" => {
                FitnessFunction::StronglyConnectedComponents
            }
            "nm" => {
                FitnessFunction::NeighborMatching
            }
            "td" => {
                FitnessFunction::TriadicDistance
            }
            _ => {
                panic!("Invalid objective function");
            }
        });
    }

    while objectives_arr.len() < 3 {
        objectives_arr.push(FitnessFunction::Null);
    }

    if objectives_arr.len() > 3 {
        panic!("Max 3 objectives allowed");
    }

    println!("objectives={:?}", objectives_arr);

    // read objective functions
    let mut threshold_arr: Vec<f32> = Vec::new();
    for s in matches.value_of("THRESHOLD").unwrap_or("").split(",") {
        let value: f32 = FromStr::from_str(s).unwrap();
        threshold_arr.push(value);
    }

    while threshold_arr.len() < 3 {
        threshold_arr.push(0.0);
    }

    if threshold_arr.len() > 3 {
        panic!("Max 3 threshold values allowed");
    }

    // read graph
    let graph_file = matches.value_of("GRAPH").unwrap();
    println!("Using graph file: {}", graph_file);
    let graph = {
        let mut f = BufReader::new(File::open(graph_file).unwrap());
        let graph: Graph<Unweighted, Unweighted, Directed> = PetgraphReader::from_sgf(&mut f);
        graph
    };

    // Parse weighted operation choice from command line
    let ops = parse_weighted_op_list(matches.value_of("OPS").unwrap()).unwrap();
    println!("edge ops: {:?}", ops);

    // Parse weighted variation operators from command line
    let varops = parse_weighted_op_list(matches.value_of("VAROPS").unwrap()).unwrap();
    println!("var ops: {:?}", varops);

    let w_ops = to_weighted_vec(&ops);
    assert!(w_ops.len() > 0);

    let w_var_ops = to_weighted_vec(&varops);
    assert!(w_var_ops.len() > 0);

    let w_mut_ops = to_weighted_vec(&mutops);
    assert!(w_mut_ops.len() > 0);

    let mut toolbox = Toolbox::new(w_ops, w_var_ops, w_mut_ops, Probability::new(MUTP));

    let mut evaluator = MyEval {
        goal: Goal::new(OptDenseDigraph::from(graph)),
        pool: Pool::new(ncpus),
        fitness_functions: (objectives_arr[0], objectives_arr[1], objectives_arr[2]),
    };

    assert!(seed.len() == 2);
    let mut rng: PcgRng = SeedableRng::from_seed([seed[0], seed[1]]);

    // create initial random population
    let initial_population: Vec<EdgeOpsGenome> = (0..MU)
                                                     .map(|_| {
                                                         let len = if ilen_from == ilen_to {
                                                             ilen_from
                                                         } else {
                                                             Range::new(ilen_from, ilen_to)
                                                                 .ind_sample(&mut rng)
                                                         };
                                                         toolbox.random_genome(&mut rng, len)
                                                     })
                                                     .collect();

    // output initial population to stdout.
    let sexp_pop = Sexp::List(vec![atom_s("Population"),
        Sexp::List(initial_population.iter().map(|ind| ind.to_sexp()).collect()),
    ]);
    println!("{}", sexp_pop);

    // evaluate fitness
    let fitness: Vec<_> = evaluator.fitness(&initial_population[..]);
    assert!(fitness.len() == initial_population.len());

    let mut pop = initial_population;
    let mut fit = fitness;

    for iteration in 0..NGEN {
        print!("# {:>6}", iteration);
        let before = time::precise_time_ns();
        let (new_pop, new_fit) = nsga2::iterate(&mut rng,
                                                pop,
                                                fit,
                                                &mut evaluator,
                                                MU,
                                                LAMBDA,
                                                K,
                                                &mut toolbox);
        let duration = time::precise_time_ns() - before;
        pop = new_pop;
        fit = new_fit;

        // calculate a min/max/avg value for each objective.
        let stat0 = Stat::<f32>::for_objectives(&fit[..], 0);
        let stat1 = Stat::<f32>::for_objectives(&fit[..], 1);
        let stat2 = Stat::<f32>::for_objectives(&fit[..], 2);

        let duration_ms = (duration as f32) / 1_000_000.0;

        let mut num_optima = 0;
        for f in fit.iter() {
            if f.objectives[0] <= threshold_arr[0] && f.objectives[1] <= threshold_arr[1] &&
               f.objectives[2] <= threshold_arr[2] {
                num_optima += 1;
            }
        }

        print!(" | ");
        print!("{:>8.1}", stat0.min);
        print!("{:>9.1}", stat0.avg);
        print!("{:>10.1}", stat0.max);
        print!(" | ");
        print!("{:>8.1}", stat1.min);
        print!("{:>9.1}", stat1.avg);
        print!("{:>10.1}", stat1.max);
        print!(" | ");
        print!("{:>8.1}", stat2.min);
        print!("{:>9.1}", stat2.avg);
        print!("{:>10.1}", stat2.max);

        print!(" | {:>5} | {:>8.0} ms", num_optima, duration_ms);

        println!("");

        if num_optima > 0 {
            println!("Found premature optimum in Iteration {}", iteration);
            break;
        }
    }
    println!("===========================================================");

    // finally evaluate rank and crowding distance (using select()).
    let rank_dist = nsga2::select(&fit[..], MU);
    assert!(rank_dist.len() == MU);

    let mut j = 0;

    for rd in rank_dist.iter() {
        if rd.rank == 0 {
            println!("-------------------------------------------");
            println!("rd: {:?}", rd);
            println!("fitness: {:?}", fit[rd.idx]);
            println!("genome: {:?}", pop[rd.idx]);

            // if fit[rd.idx].objectives[0] < 1.0 {
            draw_graph((&pop[rd.idx].to_graph()).ref_graph(),
                       // XXX: name
                       &format!("nsga2edgeops_g{}_f{}_i{}.svg",
                                NGEN,
                                fit[rd.idx].objectives[1] as usize,
                                j));
            j += 1;
            // }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>update doc string; missing file<commit_after>use std::cell::UnsafeCell;
use std::marker::PhantomData;
use std::rc::Rc;

use futures::{Async, Future, Poll};

use error::Error;
use handler::{FromRequest, Reply, ReplyItem, Responder, RouteHandler};
use http::Method;
use httprequest::HttpRequest;
use httpresponse::HttpResponse;
use middleware::{Finished as MiddlewareFinished, Middleware,
                 Response as MiddlewareResponse, Started as MiddlewareStarted};
use resource::ResourceHandler;
use router::Resource;

type ScopeResources<S> = Rc<Vec<(Resource, Rc<UnsafeCell<ResourceHandler<S>>>)>>;

/// Resources scope
///
/// Scope is a set of resources with common root path.
/// Scopes collect multiple paths under a common path prefix.
/// Scope path can not contain variable path segments as resources.
///
/// ```rust
/// # extern crate actix_web;
/// use actix_web::{http, App, HttpRequest, HttpResponse};
///
/// fn main() {
///     let app = App::new()
///         .scope("/app", |scope| {
///              scope.resource("/path1", |r| r.f(|_| HttpResponse::Ok()))
///                .resource("/path2", |r| r.f(|_| HttpResponse::Ok()))
///                .resource("/path3", |r| r.f(|_| HttpResponse::MethodNotAllowed()))
///         });
/// }
/// ```
///
/// In the above example three routes get registered:
///  * /app/path1 - reponds to all http method
///  * /app/path2 - `GET` requests
///  * /app/path3 - `HEAD` requests
///
pub struct Scope<S: 'static> {
    middlewares: Rc<Vec<Box<Middleware<S>>>>,
    default: Rc<UnsafeCell<ResourceHandler<S>>>,
    resources: ScopeResources<S>,
}

impl<S: 'static> Default for Scope<S> {
    fn default() -> Scope<S> {
        Scope::new()
    }
}

impl<S: 'static> Scope<S> {
    pub fn new() -> Scope<S> {
        Scope {
            resources: Rc::new(Vec::new()),
            middlewares: Rc::new(Vec::new()),
            default: Rc::new(UnsafeCell::new(ResourceHandler::default_not_found())),
        }
    }

    /// Configure route for a specific path.
    ///
    /// This is a simplified version of the `Scope::resource()` method.
    /// Handler functions need to accept one request extractor
    /// argument.
    ///
    /// This method could be called multiple times, in that case
    /// multiple routes would be registered for same resource path.
    ///
    /// ```rust
    /// # extern crate actix_web;
    /// use actix_web::{http, App, HttpRequest, HttpResponse, Path};
    ///
    /// fn index(data: Path<(String, String)>) -> &'static str {
    ///     "Welcome!"
    /// }
    ///
    /// fn main() {
    ///     let app = App::new()
    ///         .scope("/app", |scope| {
    ///             scope.route("/test1", http::Method::GET, index)
    ///                .route("/test2", http::Method::POST,
    ///                    |_: HttpRequest| HttpResponse::MethodNotAllowed())
    ///         });
    /// }
    /// ```
    pub fn route<T, F, R>(mut self, path: &str, method: Method, f: F) -> Scope<S>
    where
        F: Fn(T) -> R + 'static,
        R: Responder + 'static,
        T: FromRequest<S> + 'static,
    {
        // get resource handler
        let slf: &Scope<S> = unsafe { &*(&self as *const _) };
        for &(ref pattern, ref resource) in slf.resources.iter() {
            if pattern.pattern() == path {
                let resource = unsafe { &mut *resource.get() };
                resource.method(method).with(f);
                return self;
            }
        }

        let mut handler = ResourceHandler::default();
        handler.method(method).with(f);
        let pattern = Resource::new(handler.get_name(), path);
        Rc::get_mut(&mut self.resources)
            .expect("Can not use after configuration")
            .push((pattern, Rc::new(UnsafeCell::new(handler))));

        self
    }

    /// Configure resource for a specific path.
    ///
    /// This method is similar to an `App::resource()` method.
    /// Resources may have variable path segments. Resource path uses scope
    /// path as a path prefix.
    ///
    /// ```rust
    /// # extern crate actix_web;
    /// use actix_web::*;
    ///
    /// fn main() {
    ///     let app = App::new()
    ///         .scope("/api", |scope| {
    ///             scope.resource("/users/{userid}/{friend}", |r| {
    ///                 r.get().f(|_| HttpResponse::Ok());
    ///                 r.head().f(|_| HttpResponse::MethodNotAllowed());
    ///                 r.route()
    ///                    .filter(pred::Any(pred::Get()).or(pred::Put()))
    ///                    .filter(pred::Header("Content-Type", "text/plain"))
    ///                    .f(|_| HttpResponse::Ok())
    ///             })
    ///         });
    /// }
    /// ```
    pub fn resource<F, R>(mut self, path: &str, f: F) -> Scope<S>
    where
        F: FnOnce(&mut ResourceHandler<S>) -> R + 'static,
    {
        // add resource handler
        let mut handler = ResourceHandler::default();
        f(&mut handler);

        let pattern = Resource::new(handler.get_name(), path);
        Rc::get_mut(&mut self.resources)
            .expect("Can not use after configuration")
            .push((pattern, Rc::new(UnsafeCell::new(handler))));

        self
    }

    /// Default resource to be used if no matching route could be found.
    pub fn default_resource<F, R>(self, f: F) -> Scope<S>
    where
        F: FnOnce(&mut ResourceHandler<S>) -> R + 'static,
    {
        let default = unsafe { &mut *self.default.as_ref().get() };
        f(default);
        self
    }

    /// Register a scope middleware
    ///
    /// This is similar to `App's` middlewares, but
    /// middlewares get invoked on scope level.
    ///
    /// *Note* `Middleware::finish()` is fired right after response get
    /// prepared. It does not wait until body get sent to peer.
    pub fn middleware<M: Middleware<S>>(mut self, mw: M) -> Scope<S> {
        Rc::get_mut(&mut self.middlewares)
            .expect("Can not use after configuration")
            .push(Box::new(mw));
        self
    }
}

impl<S: 'static> RouteHandler<S> for Scope<S> {
    fn handle(&mut self, mut req: HttpRequest<S>) -> Reply {
        let path = unsafe { &*(&req.match_info()["tail"] as *const _) };
        let path = if path == "" { "/" } else { path };

        for (pattern, resource) in self.resources.iter() {
            if pattern.match_with_params(path, req.match_info_mut()) {
                let default = unsafe { &mut *self.default.as_ref().get() };

                if self.middlewares.is_empty() {
                    let resource = unsafe { &mut *resource.get() };
                    return resource.handle(req, Some(default));
                } else {
                    return Reply::async(Compose::new(
                        req,
                        Rc::clone(&self.middlewares),
                        Rc::clone(&resource),
                        Some(Rc::clone(&self.default)),
                    ));
                }
            }
        }

        let default = unsafe { &mut *self.default.as_ref().get() };
        if self.middlewares.is_empty() {
            default.handle(req, None)
        } else {
            Reply::async(Compose::new(
                req,
                Rc::clone(&self.middlewares),
                Rc::clone(&self.default),
                None,
            ))
        }
    }
}

/// Compose resource level middlewares with route handler.
struct Compose<S: 'static> {
    info: ComposeInfo<S>,
    state: ComposeState<S>,
}

struct ComposeInfo<S: 'static> {
    count: usize,
    req: HttpRequest<S>,
    mws: Rc<Vec<Box<Middleware<S>>>>,
    default: Option<Rc<UnsafeCell<ResourceHandler<S>>>>,
    resource: Rc<UnsafeCell<ResourceHandler<S>>>,
}

enum ComposeState<S: 'static> {
    Starting(StartMiddlewares<S>),
    Handler(WaitingResponse<S>),
    RunMiddlewares(RunMiddlewares<S>),
    Finishing(FinishingMiddlewares<S>),
    Completed(Response<S>),
}

impl<S: 'static> ComposeState<S> {
    fn poll(&mut self, info: &mut ComposeInfo<S>) -> Option<ComposeState<S>> {
        match *self {
            ComposeState::Starting(ref mut state) => state.poll(info),
            ComposeState::Handler(ref mut state) => state.poll(info),
            ComposeState::RunMiddlewares(ref mut state) => state.poll(info),
            ComposeState::Finishing(ref mut state) => state.poll(info),
            ComposeState::Completed(_) => None,
        }
    }
}

impl<S: 'static> Compose<S> {
    fn new(
        req: HttpRequest<S>, mws: Rc<Vec<Box<Middleware<S>>>>,
        resource: Rc<UnsafeCell<ResourceHandler<S>>>,
        default: Option<Rc<UnsafeCell<ResourceHandler<S>>>>,
    ) -> Self {
        let mut info = ComposeInfo {
            count: 0,
            req,
            mws,
            resource,
            default,
        };
        let state = StartMiddlewares::init(&mut info);

        Compose { state, info }
    }
}

impl<S> Future for Compose<S> {
    type Item = HttpResponse;
    type Error = Error;

    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
        loop {
            if let ComposeState::Completed(ref mut resp) = self.state {
                let resp = resp.resp.take().unwrap();
                return Ok(Async::Ready(resp));
            }
            if let Some(state) = self.state.poll(&mut self.info) {
                self.state = state;
            } else {
                return Ok(Async::NotReady);
            }
        }
    }
}

/// Middlewares start executor
struct StartMiddlewares<S> {
    fut: Option<Fut>,
    _s: PhantomData<S>,
}

type Fut = Box<Future<Item = Option<HttpResponse>, Error = Error>>;

impl<S: 'static> StartMiddlewares<S> {
    fn init(info: &mut ComposeInfo<S>) -> ComposeState<S> {
        let len = info.mws.len();
        loop {
            if info.count == len {
                let resource = unsafe { &mut *info.resource.get() };
                let reply = if let Some(ref default) = info.default {
                    let d = unsafe { &mut *default.as_ref().get() };
                    resource.handle(info.req.clone(), Some(d))
                } else {
                    resource.handle(info.req.clone(), None)
                };
                return WaitingResponse::init(info, reply);
            } else {
                match info.mws[info.count].start(&mut info.req) {
                    Ok(MiddlewareStarted::Done) => info.count += 1,
                    Ok(MiddlewareStarted::Response(resp)) => {
                        return RunMiddlewares::init(info, resp)
                    }
                    Ok(MiddlewareStarted::Future(mut fut)) => match fut.poll() {
                        Ok(Async::NotReady) => {
                            return ComposeState::Starting(StartMiddlewares {
                                fut: Some(fut),
                                _s: PhantomData,
                            })
                        }
                        Ok(Async::Ready(resp)) => {
                            if let Some(resp) = resp {
                                return RunMiddlewares::init(info, resp);
                            }
                            info.count += 1;
                        }
                        Err(err) => return Response::init(err.into()),
                    },
                    Err(err) => return Response::init(err.into()),
                }
            }
        }
    }

    fn poll(&mut self, info: &mut ComposeInfo<S>) -> Option<ComposeState<S>> {
        let len = info.mws.len();
        'outer: loop {
            match self.fut.as_mut().unwrap().poll() {
                Ok(Async::NotReady) => return None,
                Ok(Async::Ready(resp)) => {
                    info.count += 1;
                    if let Some(resp) = resp {
                        return Some(RunMiddlewares::init(info, resp));
                    }
                    if info.count == len {
                        let resource = unsafe { &mut *info.resource.get() };
                        let reply = if let Some(ref default) = info.default {
                            let d = unsafe { &mut *default.as_ref().get() };
                            resource.handle(info.req.clone(), Some(d))
                        } else {
                            resource.handle(info.req.clone(), None)
                        };
                        return Some(WaitingResponse::init(info, reply));
                    } else {
                        loop {
                            match info.mws[info.count].start(&mut info.req) {
                                Ok(MiddlewareStarted::Done) => info.count += 1,
                                Ok(MiddlewareStarted::Response(resp)) => {
                                    return Some(RunMiddlewares::init(info, resp));
                                }
                                Ok(MiddlewareStarted::Future(fut)) => {
                                    self.fut = Some(fut);
                                    continue 'outer;
                                }
                                Err(err) => return Some(Response::init(err.into())),
                            }
                        }
                    }
                }
                Err(err) => return Some(Response::init(err.into())),
            }
        }
    }
}

// waiting for response
struct WaitingResponse<S> {
    fut: Box<Future<Item = HttpResponse, Error = Error>>,
    _s: PhantomData<S>,
}

impl<S: 'static> WaitingResponse<S> {
    #[inline]
    fn init(info: &mut ComposeInfo<S>, reply: Reply) -> ComposeState<S> {
        match reply.into() {
            ReplyItem::Message(resp) => RunMiddlewares::init(info, resp),
            ReplyItem::Future(fut) => ComposeState::Handler(WaitingResponse {
                fut,
                _s: PhantomData,
            }),
        }
    }

    fn poll(&mut self, info: &mut ComposeInfo<S>) -> Option<ComposeState<S>> {
        match self.fut.poll() {
            Ok(Async::NotReady) => None,
            Ok(Async::Ready(response)) => Some(RunMiddlewares::init(info, response)),
            Err(err) => Some(RunMiddlewares::init(info, err.into())),
        }
    }
}

/// Middlewares response executor
struct RunMiddlewares<S> {
    curr: usize,
    fut: Option<Box<Future<Item = HttpResponse, Error = Error>>>,
    _s: PhantomData<S>,
}

impl<S: 'static> RunMiddlewares<S> {
    fn init(info: &mut ComposeInfo<S>, mut resp: HttpResponse) -> ComposeState<S> {
        let mut curr = 0;
        let len = info.mws.len();

        loop {
            resp = match info.mws[curr].response(&mut info.req, resp) {
                Err(err) => {
                    info.count = curr + 1;
                    return FinishingMiddlewares::init(info, err.into());
                }
                Ok(MiddlewareResponse::Done(r)) => {
                    curr += 1;
                    if curr == len {
                        return FinishingMiddlewares::init(info, r);
                    } else {
                        r
                    }
                }
                Ok(MiddlewareResponse::Future(fut)) => {
                    return ComposeState::RunMiddlewares(RunMiddlewares {
                        curr,
                        fut: Some(fut),
                        _s: PhantomData,
                    })
                }
            };
        }
    }

    fn poll(&mut self, info: &mut ComposeInfo<S>) -> Option<ComposeState<S>> {
        let len = info.mws.len();

        loop {
            // poll latest fut
            let mut resp = match self.fut.as_mut().unwrap().poll() {
                Ok(Async::NotReady) => return None,
                Ok(Async::Ready(resp)) => {
                    self.curr += 1;
                    resp
                }
                Err(err) => return Some(FinishingMiddlewares::init(info, err.into())),
            };

            loop {
                if self.curr == len {
                    return Some(FinishingMiddlewares::init(info, resp));
                } else {
                    match info.mws[self.curr].response(&mut info.req, resp) {
                        Err(err) => {
                            return Some(FinishingMiddlewares::init(info, err.into()))
                        }
                        Ok(MiddlewareResponse::Done(r)) => {
                            self.curr += 1;
                            resp = r
                        }
                        Ok(MiddlewareResponse::Future(fut)) => {
                            self.fut = Some(fut);
                            break;
                        }
                    }
                }
            }
        }
    }
}

/// Middlewares start executor
struct FinishingMiddlewares<S> {
    resp: Option<HttpResponse>,
    fut: Option<Box<Future<Item = (), Error = Error>>>,
    _s: PhantomData<S>,
}

impl<S: 'static> FinishingMiddlewares<S> {
    fn init(info: &mut ComposeInfo<S>, resp: HttpResponse) -> ComposeState<S> {
        if info.count == 0 {
            Response::init(resp)
        } else {
            let mut state = FinishingMiddlewares {
                resp: Some(resp),
                fut: None,
                _s: PhantomData,
            };
            if let Some(st) = state.poll(info) {
                st
            } else {
                ComposeState::Finishing(state)
            }
        }
    }

    fn poll(&mut self, info: &mut ComposeInfo<S>) -> Option<ComposeState<S>> {
        loop {
            // poll latest fut
            let not_ready = if let Some(ref mut fut) = self.fut {
                match fut.poll() {
                    Ok(Async::NotReady) => true,
                    Ok(Async::Ready(())) => false,
                    Err(err) => {
                        error!("Middleware finish error: {}", err);
                        false
                    }
                }
            } else {
                false
            };
            if not_ready {
                return None;
            }
            self.fut = None;
            info.count -= 1;

            match info.mws[info.count as usize]
                .finish(&mut info.req, self.resp.as_ref().unwrap())
            {
                MiddlewareFinished::Done => {
                    if info.count == 0 {
                        return Some(Response::init(self.resp.take().unwrap()));
                    }
                }
                MiddlewareFinished::Future(fut) => {
                    self.fut = Some(fut);
                }
            }
        }
    }
}

struct Response<S> {
    resp: Option<HttpResponse>,
    _s: PhantomData<S>,
}

impl<S: 'static> Response<S> {
    fn init(resp: HttpResponse) -> ComposeState<S> {
        ComposeState::Completed(Response {
            resp: Some(resp),
            _s: PhantomData,
        })
    }
}

#[cfg(test)]
mod tests {
    use application::App;
    use http::StatusCode;
    use httpresponse::HttpResponse;
    use test::TestRequest;

    #[test]
    fn test_scope() {
        let mut app = App::new()
            .scope("/app", |scope| {
                scope.resource("/path1", |r| r.f(|_| HttpResponse::Ok()))
            })
            .finish();

        let req = TestRequest::with_uri("/app/path1").finish();
        let resp = app.run(req);
        assert_eq!(resp.as_response().unwrap().status(), StatusCode::OK);
    }

    #[test]
    fn test_default_resource() {
        let mut app = App::new()
            .scope("/app", |scope| {
                scope
                    .resource("/path1", |r| r.f(|_| HttpResponse::Ok()))
                    .default_resource(|r| r.f(|_| HttpResponse::BadRequest()))
            })
            .finish();

        let req = TestRequest::with_uri("/app/path2").finish();
        let resp = app.run(req);
        assert_eq!(
            resp.as_response().unwrap().status(),
            StatusCode::BAD_REQUEST
        );

        let req = TestRequest::with_uri("/path2").finish();
        let resp = app.run(req);
        assert_eq!(
            resp.as_response().unwrap().status(),
            StatusCode::NOT_FOUND
        );
    }
}
<|endoftext|>


<commit_before><commit_msg>add explicit 'static lifetime<commit_after><|endoftext|>


<commit_before><commit_msg>refactor state commit method<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.

//! An interface for numeric types
use cmp::Ord;
use ops::{Div, Mul, Neg};
use option::Option;
use kinds::Copy;

pub mod strconv;

pub trait IntConvertible {
    fn to_int(&self) -> int;
    fn from_int(n: int) -> Self;
}

pub trait Zero {
    fn zero() -> Self;
}

pub trait One {
    fn one() -> Self;
}

pub fn abs<T:Ord + Zero + Neg<T>>(v: T) -> T {
    if v < Zero::zero() { v.neg() } else { v }
}

pub trait Round {
    fn round(&self, mode: RoundMode) -> Self;

    fn floor(&self) -> Self;
    fn ceil(&self)  -> Self;
    fn fract(&self) -> Self;
}

pub enum RoundMode {
    RoundDown,
    RoundUp,
    RoundToZero,
    RoundFromZero
}

/**
 * Cast a number the the enclosing type
 *
 * # Example
 *
 * ~~~
 * let twenty: f32 = num::cast(0x14);
 * assert!(twenty == 20f32);
 * ~~~
 */
#[inline(always)]
pub fn cast<T:NumCast,U:NumCast>(n: T) -> U {
    NumCast::from(n)
}

/**
 * An interface for generic numeric type casts
 */
pub trait NumCast {
    fn from<T:NumCast>(n: T) -> Self;

    fn to_u8(&self) -> u8;
    fn to_u16(&self) -> u16;
    fn to_u32(&self) -> u32;
    fn to_u64(&self) -> u64;
    fn to_uint(&self) -> uint;

    fn to_i8(&self) -> i8;
    fn to_i16(&self) -> i16;
    fn to_i32(&self) -> i32;
    fn to_i64(&self) -> i64;
    fn to_int(&self) -> int;

    fn to_f32(&self) -> f32;
    fn to_f64(&self) -> f64;
    fn to_float(&self) -> float;
}

pub trait ToStrRadix {
    pub fn to_str_radix(&self, radix: uint) -> ~str;
}

pub trait FromStrRadix {
    pub fn from_str_radix(str: &str, radix: uint) -> Option<Self>;
}

// Generic math functions:

/**
 * Calculates a power to a given radix, optimized for uint `pow` and `radix`.
 *
 * Returns `radix^pow` as `T`.
 *
 * Note:
 * Also returns `1` for `0^0`, despite that technically being an
 * undefined number. The reason for this is twofold:
 * - If code written to use this function cares about that special case, it's
 *   probably going to catch it before making the call.
 * - If code written to use this function doesn't care about it, it's
 *   probably assuming that `x^0` always equals `1`.
 */
pub fn pow_with_uint<T:NumCast+One+Zero+Copy+Div<T,T>+Mul<T,T>>(
    radix: uint, pow: uint) -> T {
    let _0: T = Zero::zero();
    let _1: T = One::one();

    if pow   == 0u { return _1; }
    if radix == 0u { return _0; }
    let mut my_pow     = pow;
    let mut total      = _1;
    let mut multiplier = cast(radix as int);
    while (my_pow > 0u) {
        if my_pow % 2u == 1u {
            total *= multiplier;
        }
        my_pow     /= 2u;
        multiplier *= multiplier;
    }
    total
}

<commit_msg>Clarify purpose of NumCast trait<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.

//! An interface for numeric types
use cmp::Ord;
use ops::{Div, Mul, Neg};
use option::Option;
use kinds::Copy;

pub mod strconv;

pub trait IntConvertible {
    fn to_int(&self) -> int;
    fn from_int(n: int) -> Self;
}

pub trait Zero {
    fn zero() -> Self;
}

pub trait One {
    fn one() -> Self;
}

pub fn abs<T:Ord + Zero + Neg<T>>(v: T) -> T {
    if v < Zero::zero() { v.neg() } else { v }
}

pub trait Round {
    fn round(&self, mode: RoundMode) -> Self;

    fn floor(&self) -> Self;
    fn ceil(&self)  -> Self;
    fn fract(&self) -> Self;
}

pub enum RoundMode {
    RoundDown,
    RoundUp,
    RoundToZero,
    RoundFromZero
}

/**
 * Cast from one machine scalar to another
 *
 * # Example
 *
 * ~~~
 * let twenty: f32 = num::cast(0x14);
 * assert!(twenty == 20f32);
 * ~~~
 */
#[inline(always)]
pub fn cast<T:NumCast,U:NumCast>(n: T) -> U {
    NumCast::from(n)
}

/**
 * An interface for casting between machine scalars
 */
pub trait NumCast {
    fn from<T:NumCast>(n: T) -> Self;

    fn to_u8(&self) -> u8;
    fn to_u16(&self) -> u16;
    fn to_u32(&self) -> u32;
    fn to_u64(&self) -> u64;
    fn to_uint(&self) -> uint;

    fn to_i8(&self) -> i8;
    fn to_i16(&self) -> i16;
    fn to_i32(&self) -> i32;
    fn to_i64(&self) -> i64;
    fn to_int(&self) -> int;

    fn to_f32(&self) -> f32;
    fn to_f64(&self) -> f64;
    fn to_float(&self) -> float;
}

pub trait ToStrRadix {
    pub fn to_str_radix(&self, radix: uint) -> ~str;
}

pub trait FromStrRadix {
    pub fn from_str_radix(str: &str, radix: uint) -> Option<Self>;
}

// Generic math functions:

/**
 * Calculates a power to a given radix, optimized for uint `pow` and `radix`.
 *
 * Returns `radix^pow` as `T`.
 *
 * Note:
 * Also returns `1` for `0^0`, despite that technically being an
 * undefined number. The reason for this is twofold:
 * - If code written to use this function cares about that special case, it's
 *   probably going to catch it before making the call.
 * - If code written to use this function doesn't care about it, it's
 *   probably assuming that `x^0` always equals `1`.
 */
pub fn pow_with_uint<T:NumCast+One+Zero+Copy+Div<T,T>+Mul<T,T>>(
    radix: uint, pow: uint) -> T {
    let _0: T = Zero::zero();
    let _1: T = One::one();

    if pow   == 0u { return _1; }
    if radix == 0u { return _0; }
    let mut my_pow     = pow;
    let mut total      = _1;
    let mut multiplier = cast(radix as int);
    while (my_pow > 0u) {
        if my_pow % 2u == 1u {
            total *= multiplier;
        }
        my_pow     /= 2u;
        multiplier *= multiplier;
    }
    total
}

<|endoftext|>


<commit_before><commit_msg>vector negation and dot operations<commit_after><|endoftext|>


<commit_before><commit_msg>Added a message send that uses shared chans. They are slower than port selectors, but scale better.<commit_after>// A port of the simplistic benchmark from
//
//    http://github.com/PaulKeeble/ScalaVErlangAgents
//
// I *think* it's the same, more or less.

// This version uses pipes with a shared send endpoint. It should have
// different scalability characteristics compared to the select
// version.

use std;
import io::writer;
import io::writer_util;

import arc::methods;
import pipes::{port, chan};

macro_rules! move {
    { $x:expr } => { unsafe { let y <- *ptr::addr_of($x); y } }
}

enum request {
    get_count,
    bytes(uint),
    stop
}

fn server(requests: port<request>, responses: pipes::chan<uint>) {
    let mut count = 0u;
    let mut done = false;
    while !done {
        alt requests.try_recv() {
          some(get_count) { responses.send(copy count); }
          some(bytes(b)) {
            //#error("server: received %? bytes", b);
            count += b;
          }
          none { done = true; }
          _ { }
        }
    }
    responses.send(count);
    //#error("server exiting");
}

fn run(args: &[str]) {
    let (to_parent, from_child) = pipes::stream();
    let (to_child, from_parent) = pipes::stream();

    let to_child = shared_chan(to_child);

    let size = option::get(uint::from_str(args[1]));
    let workers = option::get(uint::from_str(args[2]));
    let num_bytes = 100;
    let start = std::time::precise_time_s();
    let mut worker_results = ~[];
    for uint::range(0u, workers) |i| {
        let builder = task::builder();
        vec::push(worker_results, task::future_result(builder));
        let to_child = to_child.clone();
        do task::run(builder) {
            for uint::range(0u, size / workers) |_i| {
                //#error("worker %?: sending %? bytes", i, num_bytes);
                to_child.send(bytes(num_bytes));
            }
            //#error("worker %? exiting", i);
        };
    }
    do task::spawn {
        server(from_parent, to_parent);
    }

    vec::iter(worker_results, |r| { future::get(r); } );
    //#error("sending stop message");
    to_child.send(stop);
    move!{to_child};
    let result = from_child.recv();
    let end = std::time::precise_time_s();
    let elapsed = end - start;
    io::stdout().write_str(#fmt("Count is %?\n", result));
    io::stdout().write_str(#fmt("Test took %? seconds\n", elapsed));
    let thruput = ((size / workers * workers) as float) / (elapsed as float);
    io::stdout().write_str(#fmt("Throughput=%f per sec\n", thruput));
    assert result == num_bytes * size;
}

fn main(args: ~[str]) {
    let args = if os::getenv("RUST_BENCH").is_some() {
        ~["", "1000000", "10000"]
    } else if args.len() <= 1u {
        ~["", "10000", "4"]
    } else {
        copy args
    };

    #debug("%?", args);
    run(args);
}

// Treat a whole bunch of ports as one.
class box<T> {
    let mut contents: option<T>;
    new(+x: T) { self.contents = some(x); }

    fn swap(f: fn(+T) -> T) {
        let mut tmp = none;
        self.contents <-> tmp;
        self.contents = some(f(option::unwrap(tmp)));
    }

    fn unwrap() -> T {
        let mut tmp = none;
        self.contents <-> tmp;
        option::unwrap(tmp)
    }
}

class port_set<T: send> {
    let mut ports: ~[pipes::port<T>];

    new() { self.ports = ~[]; }

    fn add(+port: pipes::port<T>) {
        vec::push(self.ports, port)
    }

    fn try_recv() -> option<T> {
        let mut result = none;
        while result == none && self.ports.len() > 0 {
            let i = pipes::wait_many(self.ports.map(|p| p.header()));
            // dereferencing an unsafe pointer nonsense to appease the
            // borrowchecker.
            alt unsafe {(*ptr::addr_of(self.ports[i])).try_recv()} {
              some(m) {
                result = some(move!{m});
              }
              none {
                // Remove this port.
                let mut ports = ~[];
                self.ports <-> ports;
                vec::consume(ports,
                             |j, x| if i != j { vec::push(self.ports, x) });
              }
            }
        }
/*
        while !done {
            do self.ports.swap |ports| {
                if ports.len() > 0 {
                    let old_len = ports.len();
                    let (_, m, ports) = pipes::select(ports);
                    alt m {
                      some(pipes::streamp::data(x, next)) {
                        result = some(move!{x});
                        done = true;
                        assert ports.len() == old_len - 1;
                        vec::append_one(ports, move!{next})
                      }
                      none {
                        //#error("pipe closed");
                        assert ports.len() == old_len - 1;
                        ports
                      }
                    }
                }
                else {
                    //#error("no more pipes");
                    done = true;
                    ~[]
                }
            }
        }
*/
        result
    }

    fn recv() -> T {
        option::unwrap(self.try_recv())
    }
}

impl private_methods/&<T: send> for pipes::port<T> {
    pure fn header() -> *pipes::packet_header unchecked {
        alt self.endp {
          some(endp) {
            endp.header()
          }
          none { fail "peeking empty stream" }
        }
    }
}

type shared_chan<T: send> = arc::exclusive<pipes::chan<T>>;

impl chan<T: send> for shared_chan<T> {
    fn send(+x: T) {
        let mut xx = some(x);
        do self.with |_c, chan| {
            let mut x = none;
            x <-> xx;
            chan.send(option::unwrap(x))
        }
    }
}

fn shared_chan<T:send>(+c: pipes::chan<T>) -> shared_chan<T> {
    arc::exclusive(c)
}<|endoftext|>


<commit_before>use core::ptr;

//
// PAGE_DIRECTORY:
// 1024 dwords pointing to page tables
// PAGE_TABLES:
// 1024 * 1024 dwords pointing to pages
// PAGE_END:
//

pub const PAGE_TABLE_SIZE: usize = 1024;
pub const PAGE_ENTRY_SIZE: usize = 4;
pub const PAGE_SIZE: usize = 4096;

pub const PAGE_DIRECTORY: usize = 0x300000;
pub const PAGE_TABLES: usize = PAGE_DIRECTORY + PAGE_TABLE_SIZE * PAGE_ENTRY_SIZE;
pub const PAGE_END: usize = PAGE_TABLES + PAGE_TABLE_SIZE * PAGE_TABLE_SIZE * PAGE_ENTRY_SIZE;

/// A memory page
pub struct Page {
    /// The virtual address
    virtual_address: usize,
}

impl Page {
    /// Initialize the memory page
    pub unsafe fn init() {
        for table_i in 0..PAGE_TABLE_SIZE {
            ptr::write((PAGE_DIRECTORY + table_i * PAGE_ENTRY_SIZE) as *mut u32,
                       // TODO: Use more restrictive flags
                       (PAGE_TABLES + table_i * PAGE_TABLE_SIZE * PAGE_ENTRY_SIZE) as u32 |
                       0b11 << 1 | 1); //Allow userspace, read/write, present

            for entry_i in 0..PAGE_TABLE_SIZE {
                Page::new((table_i * PAGE_TABLE_SIZE + entry_i) * PAGE_SIZE).map_identity();
            }
        }

        asm!("mov cr3, $0
            mov $0, cr0
            or $0, $1
            mov cr0, $0"
            :
            : "r"(PAGE_DIRECTORY), "r"(0x80000000 as usize)
            : "memory"
            : "intel", "volatile");
    }

    /// Create a new memory page from a virtual address
    pub fn new(virtual_address: usize) -> Self {
        Page { virtual_address: virtual_address }
    }

    /// Get the entry address
    fn entry_address(&self) -> usize {
        let page = self.virtual_address / PAGE_SIZE;
        let table = page / PAGE_TABLE_SIZE;
        let entry = page % PAGE_TABLE_SIZE;

        PAGE_TABLES + (table * PAGE_TABLE_SIZE + entry) * PAGE_ENTRY_SIZE
    }

    /// Flush the memory page
    unsafe fn flush(&self) {
        asm!("invlpg [$0]"
            :
            : "{eax}"(self.virtual_address)
            : "memory"
            : "intel", "volatile");
    }

    /// Get the current physical address
    pub fn phys_addr(&self) -> usize {
        unsafe { (ptr::read(self.entry_address() as *mut u32) & 0xFFFFF000) as usize }
    }

    /// Get the current virtual address
    pub fn virt_addr(&self) -> usize {
        self.virtual_address & 0xFFFFF000
    }

    /// Map the memory page to a given physical memory address
    pub unsafe fn map(&mut self, physical_address: usize) {
        ptr::write(self.entry_address() as *mut u32,
                //TODO: Remove 1 << 2 which is there to allow for userspace arg access
                   (physical_address as u32 & 0xFFFFF000) | 1 << 2 | 1); //read/write, present
        self.flush();
    }

    /// Map the memory page to a given physical memory address, and allow userspace read access
    pub unsafe fn map_user_read(&mut self, physical_address: usize) {
        ptr::write(self.entry_address() as *mut u32,
                   (physical_address as u32 & 0xFFFFF000) | 1 << 2 | 1); //Allow userspace, present
        self.flush();
    }

    /// Map the memory page to a given physical memory address, and allow userspace read/write access
    pub unsafe fn map_user_write(&mut self, physical_address: usize) {
        ptr::write(self.entry_address() as *mut u32,
                   (physical_address as u32 & 0xFFFFF000) | 1 << 2 | 1 << 1 | 1); //Allow userspace, read/write, present
        self.flush();
    }

    /// Map to the virtual address
    pub unsafe fn map_identity(&mut self) {
        let physical_address = self.virtual_address;
        self.map(physical_address);
    }

    /// Unmap the memory page
    pub unsafe fn unmap(&mut self) {
        ptr::write(self.entry_address() as *mut u32, 0);
        self.flush();
    }
}
<commit_msg>Move paging directory down to 0x200000<commit_after>use core::ptr;

//
// PAGE_DIRECTORY:
// 1024 dwords pointing to page tables
// PAGE_TABLES:
// 1024 * 1024 dwords pointing to pages
// PAGE_END:
//

pub const PAGE_TABLE_SIZE: usize = 1024;
pub const PAGE_ENTRY_SIZE: usize = 4;
pub const PAGE_SIZE: usize = 4096;

pub const PAGE_DIRECTORY: usize = 0x200000;
pub const PAGE_TABLES: usize = PAGE_DIRECTORY + PAGE_TABLE_SIZE * PAGE_ENTRY_SIZE;
pub const PAGE_END: usize = PAGE_TABLES + PAGE_TABLE_SIZE * PAGE_TABLE_SIZE * PAGE_ENTRY_SIZE;

/// A memory page
pub struct Page {
    /// The virtual address
    virtual_address: usize,
}

impl Page {
    /// Initialize the memory page
    pub unsafe fn init() {
        for table_i in 0..PAGE_TABLE_SIZE {
            ptr::write((PAGE_DIRECTORY + table_i * PAGE_ENTRY_SIZE) as *mut u32,
                       // TODO: Use more restrictive flags
                       (PAGE_TABLES + table_i * PAGE_TABLE_SIZE * PAGE_ENTRY_SIZE) as u32 |
                       0b11 << 1 | 1); //Allow userspace, read/write, present

            for entry_i in 0..PAGE_TABLE_SIZE {
                Page::new((table_i * PAGE_TABLE_SIZE + entry_i) * PAGE_SIZE).map_identity();
            }
        }

        asm!("mov cr3, $0
            mov $0, cr0
            or $0, $1
            mov cr0, $0"
            :
            : "r"(PAGE_DIRECTORY), "r"(0x80000000 as usize)
            : "memory"
            : "intel", "volatile");
    }

    /// Create a new memory page from a virtual address
    pub fn new(virtual_address: usize) -> Self {
        Page { virtual_address: virtual_address }
    }

    /// Get the entry address
    fn entry_address(&self) -> usize {
        let page = self.virtual_address / PAGE_SIZE;
        let table = page / PAGE_TABLE_SIZE;
        let entry = page % PAGE_TABLE_SIZE;

        PAGE_TABLES + (table * PAGE_TABLE_SIZE + entry) * PAGE_ENTRY_SIZE
    }

    /// Flush the memory page
    unsafe fn flush(&self) {
        asm!("invlpg [$0]"
            :
            : "{eax}"(self.virtual_address)
            : "memory"
            : "intel", "volatile");
    }

    /// Get the current physical address
    pub fn phys_addr(&self) -> usize {
        unsafe { (ptr::read(self.entry_address() as *mut u32) & 0xFFFFF000) as usize }
    }

    /// Get the current virtual address
    pub fn virt_addr(&self) -> usize {
        self.virtual_address & 0xFFFFF000
    }

    /// Map the memory page to a given physical memory address
    pub unsafe fn map(&mut self, physical_address: usize) {
        ptr::write(self.entry_address() as *mut u32,
                //TODO: Remove 1 << 2 which is there to allow for userspace arg access
                   (physical_address as u32 & 0xFFFFF000) | 1 << 2 | 1); //read/write, present
        self.flush();
    }

    /// Map the memory page to a given physical memory address, and allow userspace read access
    pub unsafe fn map_user_read(&mut self, physical_address: usize) {
        ptr::write(self.entry_address() as *mut u32,
                   (physical_address as u32 & 0xFFFFF000) | 1 << 2 | 1); //Allow userspace, present
        self.flush();
    }

    /// Map the memory page to a given physical memory address, and allow userspace read/write access
    pub unsafe fn map_user_write(&mut self, physical_address: usize) {
        ptr::write(self.entry_address() as *mut u32,
                   (physical_address as u32 & 0xFFFFF000) | 1 << 2 | 1 << 1 | 1); //Allow userspace, read/write, present
        self.flush();
    }

    /// Map to the virtual address
    pub unsafe fn map_identity(&mut self) {
        let physical_address = self.virtual_address;
        self.map(physical_address);
    }

    /// Unmap the memory page
    pub unsafe fn unmap(&mut self) {
        ptr::write(self.entry_address() as *mut u32, 0);
        self.flush();
    }
}
<|endoftext|>


<commit_before><commit_msg>tuple example<commit_after>fn main() {
    let test = vec![(1, 1), (2, 1), (2,2)];
    let result:Vec<i32> = test.iter().map(|x| x.1).collect();
    for r in result {
        println!("{}", r);
    }
}
<|endoftext|>


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

// xfail-test

// GDB doesn't know about UTF-32 character encoding and will print a rust char as only its numerical
// value.

// compile-flags:-Z extra-debug-info
// debugger:break zzz
// debugger:run
// debugger:finish

// debugger:print x
// check:$1 = 111102
// debugger:print y
// check:$2 = true

// debugger:continue
// debugger:finish

// debugger:print a
// check:$3 = 2000
// debugger:print b
// check:$4 = 3000

fn main() {

    fun(111102, true);
    nested(2000, 3000);

    fn nested(a: i32, b: i64) -> (i32, i64) {
        zzz()
        (a, b)
    }
}

fn fun(x: int, y: bool) -> (int, bool) {
    zzz();

    (x, y)
}

fn zzz() {()}<|endoftext|>