<commit_before>use redox::{self, cmp, env, BMPFile, Color};
use redox::collections::BTreeMap;
use redox::event::{self, EventOption, MouseEvent};
use redox::fs::File;
use redox::io::{Read, Seek, SeekFrom};
use redox::orbital::Window;
use redox::time::{self, Duration};
use redox::vec::Vec;
use redox::string::{String, ToString};

pub struct FileType {
    description: String,
    icon: BMPFile,
}

impl FileType {
    pub fn new(desc: &str, icon: &str) -> FileType {
        FileType { description: desc.to_string(), icon: load_icon(icon) }
    }

}

pub struct FileManager {
    file_types: BTreeMap<String, FileType>,
    files: Vec<String>,
    file_sizes: Vec<String>,
    selected: isize,
    last_mouse_event: MouseEvent,
    click_time: Duration,
}

fn load_icon(path: &str) -> BMPFile {
    let mut vec: Vec<u8> = Vec::new();
    if let Some(mut file) = File::open(&("file:///ui/mimetypes/".to_string() + path + ".bmp")) {
        file.read_to_end(&mut vec);
    }
    BMPFile::from_data(&vec)
}

impl FileManager {
    pub fn new() -> Self {
        FileManager {
            file_types: {
                let mut file_types = BTreeMap::<String, FileType>::new();
                file_types.insert("/".to_string(),
                                  FileType::new("Folder", "inode-directory"));
                file_types.insert("wav".to_string(),
                                  FileType::new("WAV audio", "audio-x-wav"));
                file_types.insert("bin".to_string(),
                                  FileType::new("Executable", "application-x-executable"));
                file_types.insert("bmp".to_string(),
                                  FileType::new("Bitmap Image", "image-x-generic"));
                file_types.insert("rs".to_string(),
                                  FileType::new("Rust source code", "text-x-makefile"));
                file_types.insert("crate".to_string(),
                                  FileType::new("Rust crate", "application-x-archive"));
                file_types.insert("rlib".to_string(),
                                  FileType::new("Static Rust library", "application-x-object"));
                file_types.insert("asm".to_string(),
                                  FileType::new("Assembly source", "text-x-makefile"));
                file_types.insert("list".to_string(),
                                  FileType::new("Disassembly source", "text-x-makefile"));
                file_types.insert("c".to_string(),
                                  FileType::new("C source code", "text-x-csrc"));
                file_types.insert("cpp".to_string(),
                                  FileType::new("C++ source code", "text-x-c++src"));
                file_types.insert("h".to_string(),
                                  FileType::new("C header", "text-x-chdr"));
                file_types.insert("sh".to_string(),
                                  FileType::new("Shell script", "text-x-script"));
                file_types.insert("lua".to_string(),
                                  FileType::new("Lua script", "text-x-script"));
                file_types.insert("txt".to_string(),
                                  FileType::new("Plain text document", "text-x-generic"));
                file_types.insert("md".to_string(),
                                  FileType::new("Markdown document", "text-x-generic"));
                file_types.insert("toml".to_string(),
                                  FileType::new("TOML document", "text-x-generic"));
                file_types.insert("json".to_string(),
                                  FileType::new("JSON document", "text-x-generic"));
                file_types.insert("REDOX".to_string(),
                                  FileType::new("Redox package", "text-x-generic"));
                file_types.insert(String::new(),
                                  FileType::new("Unknown file", "unknown"));
                file_types
            },
            files: Vec::new(),
            file_sizes: Vec::new(),
            selected: -1,
            last_mouse_event: MouseEvent {
                x: 0,
                y: 0,
                left_button: false,
                middle_button: false,
                right_button: false,
            },
            click_time: Duration::new(0, 0),
        }
    }

    fn load_icon_with(&self, file_name: &str, row: isize, window: &mut Window) {
        if file_name.ends_with('/') {
            window.image(0,
                         32 * row as isize,
                         self.file_types["/"].icon.width(),
                         self.file_types["/"].icon.height(),
                         self.file_types["/"].icon.as_slice());
        } else {
            let pos = file_name.rfind('.').unwrap_or(0) + 1;
            match self.file_types.get(&file_name[pos..]) {
                Some(file_type) => {
                    window.image(0,
                                 32 * row,
                                 file_type.icon.width(),
                                 file_type.icon.height(),
                                 file_type.icon.as_slice());
                }
                None => {
                    window.image(0,
                                 32 * row,
                                 self.file_types[""].icon.width(),
                                 self.file_types[""].icon.height(),
                                 self.file_types[""].icon.as_slice());
                }
            }
        }
    }

    fn get_description(&self, file_name: &str) -> String {
        if file_name.ends_with('/') {
            self.file_types["/"].description.clone()
        } else {
            let pos = file_name.rfind('.').unwrap_or(0) + 1;
            match self.file_types.get(&file_name[pos..]) {
                Some(file_type) => file_type.description.clone(),
                None => self.file_types[""].description.clone(),
            }
        }
    }

    fn draw_content(&mut self, window: &mut Window) {
        window.set(Color::WHITE);

        let mut i = 0;
        let mut row = 0;
        let column = {
            let mut tmp = [0, 0];
            for string in self.files.iter() {
                if tmp[0] < string.len() {
                    tmp[0] = string.len();
                }
            }

            tmp[0] += 1;

            for file_size in self.file_sizes.iter() {
                if tmp[1] < file_size.len() {
                    tmp[1] = file_size.len();
                }
            }

            tmp[1] += tmp[0] + 1;
            tmp
        };
        for (file_name, file_size) in self.files.iter().zip(self.file_sizes.iter()) {
            if i == self.selected {
                let width = window.width();
                window.rect(0, 32 * row as isize, width, 32, Color::rgba(224, 224, 224, 255));
            }

            self.load_icon_with(&file_name, row as isize, window);

            let mut col = 0;
            for c in file_name.chars() {
                if c == '\n' {
                    col = 0;
                    row += 1;
                } else if c == '\t' {
                    col += 8 - col % 8;
                } else {
                    if col < window.width() / 8 && row < window.height() / 32 {
                        window.char(8 * col as isize + 40,
                                    32 * row as isize + 8,
                                    c,
                                    Color::BLACK);
                        col += 1;
                    }
                }
                if col >= window.width() / 8 {
                    col = 0;
                    row += 1;
                }
            }

            col = column[0];

            for c in file_size.chars() {
                if c == '\n' {
                    col = 0;
                    row += 1;
                } else if c == '\t' {
                    col += 8 - col % 8;
                } else {
                    if col < window.width() / 8 && row < window.height() / 32 {
                        window.char(8 * col as isize + 40,
                                    32 * row as isize + 8,
                                    c,
                                    Color::BLACK);
                        col += 1;
                    }
                }
                if col >= window.width() / 8 {
                    col = 0;
                    row += 1;
                }
            }

            col = column[1];

            for c in self.get_description(file_name).chars() {
                if c == '\n' {
                    col = 0;
                    row += 1;
                } else if c == '\t' {
                    col += 8 - col % 8;
                } else {
                    if col < window.width() / 8 && row < window.height() / 32 {
                        window.char(8 * col as isize + 40,
                                    32 * row as isize + 8,
                                    c,
                                    Color::BLACK);
                        col += 1;
                    }
                }
                if col >= window.width() / 8 {
                    col = 0;
                    row += 1;
                }
            }

            row += 1;
            i += 1;
        }

        window.sync();
    }

    fn main(&mut self, path: &str) {
        let mut width = [48, 48, 48];
        let mut height = 0;
        if let Some(mut file) = File::open(path) {
            let mut list = String::new();
            file.read_to_string(&mut list);

            for entry in list.split('\n') {
                self.files.push(entry.to_string());
                self.file_sizes.push(
                    match File::open(&(path.to_string() + entry)) {
                        Some(mut file) => {
                            // When the entry is a folder
                            if entry.ends_with('/') {
                                let mut string = String::new();
                                file.read_to_string(&mut string);

                                let count = string.split('\n').count();
                                if count == 1 {
                                    "1 entry".to_string()
                                } else {
                                    format!("{} entries", count)
                                }
                            } else {
                                match file.seek(SeekFrom::End(0)) {
                                    Some(size) => {
                                        if size >= 1_000_000_000 {
                                            format!("{:.1} GB", (size as f64)/1_000_000_000.0)
                                        } else if size >= 1_000_000 {
                                            format!("{:.1} MB", (size as f64)/1_000_000.0)
                                        } else if size >= 1_000 {
                                            format!("{:.1} KB", (size as f64)/1_000.0)
                                        } else {
                                            format!("{:.1} bytes", size)
                                        }
                                    }
                                    None => "Failed to seek".to_string()
                                }
                            }
                        },
                        None => "Failed to open".to_string(),
                    }
                );
                // Unwrapping the last file size will not panic since it has
                // been at least pushed once in the vector
                width[0] = cmp::max(width[0], 48 + (entry.len()) * 8);
                width[1] = cmp::max(width[1], 8 + (self.file_sizes.last().unwrap().len()) * 8);
                width[2] = cmp::max(width[2], 8 + (self.get_description(entry).len()) * 8);
            }

            if height < self.files.len() * 32 {
                height = self.files.len() * 32;
            }
        }

        let mut window = Window::new((redox::rand() % 400 + 50) as isize,
                                     (redox::rand() % 300 + 50) as isize,
                                     width.iter().sum(),
                                     height,
                                     &path).unwrap();

        self.draw_content(&mut window);

        while let Some(event) = window.poll() {
            match event.to_option() {
                EventOption::Key(key_event) => {
                    if key_event.pressed {
                        match key_event.scancode {
                            event::K_ESC => break,
                            event::K_HOME => self.selected = 0,
                            event::K_UP => if self.selected > 0 {
                                self.selected -= 1;
                            },
                            event::K_END => self.selected = self.files.len() as isize - 1,
                            event::K_DOWN => if self.selected < self.files.len() as isize - 1 {
                                self.selected += 1;
                            },
                            _ => match key_event.character {
                                '\0' => (),
                                '\n' => {
                                    if self.selected >= 0 &&
                                       self.selected < self.files.len() as isize {
                                        match self.files.get(self.selected as usize) {
                                            Some(file) => {
                                                File::exec(&(path.to_string() + &file));
                                            },
                                            None => (),
                                        }
                                    }
                                }
                                _ => {
                                    let mut i = 0;
                                    for file in self.files.iter() {
                                        if file.starts_with(key_event.character) {
                                            self.selected = i;
                                            break;
                                        }
                                        i += 1;
                                    }
                                }
                            },
                        }

                        self.draw_content(&mut window);
                    }
                }
                EventOption::Mouse(mouse_event) => {
                    let mut redraw = false;
                    let mut i = 0;
                    let mut row = 0;
                    for file in self.files.iter() {
                        let mut col = 0;
                        for c in file.chars() {
                            if mouse_event.y >= 32 * row as isize &&
                               mouse_event.y < 32 * row as isize + 32 {
                                self.selected = i;
                                redraw = true;
                            }

                            if c == '\n' {
                                col = 0;
                                row += 1;
                            } else if c == '\t' {
                                col += 8 - col % 8;
                            } else {
                                if col < window.width() / 8 && row < window.height() / 32 {
                                    col += 1;
                                }
                            }
                            if col >= window.width() / 8 {
                                col = 0;
                                row += 1;
                            }
                        }
                        row += 1;
                        i += 1;
                    }

                    if redraw {
                        self.draw_content(&mut window);
                    }

                    //Check for double click
                    if mouse_event.left_button {
                        let click_time = Duration::realtime();

                        if click_time - self.click_time < Duration::new(0, 500 * time::NANOS_PER_MILLI)
                            && self.last_mouse_event.x == mouse_event.x
                            && self.last_mouse_event.y == mouse_event.y {
                            if self.selected >= 0 && self.selected < self.files.len() as isize {
                                if let Some(file) = self.files.get(self.selected as usize) {
                                    File::exec(&(path.to_string() + &file));
                                }
                            }
                            self.click_time = Duration::new(0, 0);
                        } else {
                            self.click_time = click_time;
                        }
                    }
                    self.last_mouse_event = mouse_event;
                }
                EventOption::Quit(quit_event) => break,
                _ => (),
            }
        }
    }
}

pub fn main() {
    match env::args().get(1) {
        Some(arg) => FileManager::new().main(arg),
        None => FileManager::new().main("file:///"),
    }
}
<commit_msg>File manager will now use read_dir<commit_after>use redox::{self, cmp, env, BMPFile, Color};
use redox::collections::BTreeMap;
use redox::event::{self, EventOption, MouseEvent};
use redox::fs::{self, File};
use redox::io::{Read, Seek, SeekFrom};
use redox::orbital::Window;
use redox::time::{self, Duration};
use redox::vec::Vec;
use redox::string::{String, ToString};

pub struct FileType {
    description: String,
    icon: BMPFile,
}

impl FileType {
    pub fn new(desc: &str, icon: &str) -> FileType {
        FileType { description: desc.to_string(), icon: load_icon(icon) }
    }

}

pub struct FileManager {
    file_types: BTreeMap<String, FileType>,
    files: Vec<String>,
    file_sizes: Vec<String>,
    selected: isize,
    last_mouse_event: MouseEvent,
    click_time: Duration,
}

fn load_icon(path: &str) -> BMPFile {
    let mut vec: Vec<u8> = Vec::new();
    if let Some(mut file) = File::open(&("file:///ui/mimetypes/".to_string() + path + ".bmp")) {
        file.read_to_end(&mut vec);
    }
    BMPFile::from_data(&vec)
}

impl FileManager {
    pub fn new() -> Self {
        FileManager {
            file_types: {
                let mut file_types = BTreeMap::<String, FileType>::new();
                file_types.insert("/".to_string(),
                                  FileType::new("Folder", "inode-directory"));
                file_types.insert("wav".to_string(),
                                  FileType::new("WAV audio", "audio-x-wav"));
                file_types.insert("bin".to_string(),
                                  FileType::new("Executable", "application-x-executable"));
                file_types.insert("bmp".to_string(),
                                  FileType::new("Bitmap Image", "image-x-generic"));
                file_types.insert("rs".to_string(),
                                  FileType::new("Rust source code", "text-x-makefile"));
                file_types.insert("crate".to_string(),
                                  FileType::new("Rust crate", "application-x-archive"));
                file_types.insert("rlib".to_string(),
                                  FileType::new("Static Rust library", "application-x-object"));
                file_types.insert("asm".to_string(),
                                  FileType::new("Assembly source", "text-x-makefile"));
                file_types.insert("list".to_string(),
                                  FileType::new("Disassembly source", "text-x-makefile"));
                file_types.insert("c".to_string(),
                                  FileType::new("C source code", "text-x-csrc"));
                file_types.insert("cpp".to_string(),
                                  FileType::new("C++ source code", "text-x-c++src"));
                file_types.insert("h".to_string(),
                                  FileType::new("C header", "text-x-chdr"));
                file_types.insert("sh".to_string(),
                                  FileType::new("Shell script", "text-x-script"));
                file_types.insert("lua".to_string(),
                                  FileType::new("Lua script", "text-x-script"));
                file_types.insert("txt".to_string(),
                                  FileType::new("Plain text document", "text-x-generic"));
                file_types.insert("md".to_string(),
                                  FileType::new("Markdown document", "text-x-generic"));
                file_types.insert("toml".to_string(),
                                  FileType::new("TOML document", "text-x-generic"));
                file_types.insert("json".to_string(),
                                  FileType::new("JSON document", "text-x-generic"));
                file_types.insert("REDOX".to_string(),
                                  FileType::new("Redox package", "text-x-generic"));
                file_types.insert(String::new(),
                                  FileType::new("Unknown file", "unknown"));
                file_types
            },
            files: Vec::new(),
            file_sizes: Vec::new(),
            selected: -1,
            last_mouse_event: MouseEvent {
                x: 0,
                y: 0,
                left_button: false,
                middle_button: false,
                right_button: false,
            },
            click_time: Duration::new(0, 0),
        }
    }

    fn load_icon_with(&self, file_name: &str, row: isize, window: &mut Window) {
        if file_name.ends_with('/') {
            window.image(0,
                         32 * row as isize,
                         self.file_types["/"].icon.width(),
                         self.file_types["/"].icon.height(),
                         self.file_types["/"].icon.as_slice());
        } else {
            let pos = file_name.rfind('.').unwrap_or(0) + 1;
            match self.file_types.get(&file_name[pos..]) {
                Some(file_type) => {
                    window.image(0,
                                 32 * row,
                                 file_type.icon.width(),
                                 file_type.icon.height(),
                                 file_type.icon.as_slice());
                }
                None => {
                    window.image(0,
                                 32 * row,
                                 self.file_types[""].icon.width(),
                                 self.file_types[""].icon.height(),
                                 self.file_types[""].icon.as_slice());
                }
            }
        }
    }

    fn get_description(&self, file_name: &str) -> String {
        if file_name.ends_with('/') {
            self.file_types["/"].description.clone()
        } else {
            let pos = file_name.rfind('.').unwrap_or(0) + 1;
            match self.file_types.get(&file_name[pos..]) {
                Some(file_type) => file_type.description.clone(),
                None => self.file_types[""].description.clone(),
            }
        }
    }

    fn draw_content(&mut self, window: &mut Window) {
        window.set(Color::WHITE);

        let mut i = 0;
        let mut row = 0;
        let column = {
            let mut tmp = [0, 0];
            for string in self.files.iter() {
                if tmp[0] < string.len() {
                    tmp[0] = string.len();
                }
            }

            tmp[0] += 1;

            for file_size in self.file_sizes.iter() {
                if tmp[1] < file_size.len() {
                    tmp[1] = file_size.len();
                }
            }

            tmp[1] += tmp[0] + 1;
            tmp
        };
        for (file_name, file_size) in self.files.iter().zip(self.file_sizes.iter()) {
            if i == self.selected {
                let width = window.width();
                window.rect(0, 32 * row as isize, width, 32, Color::rgba(224, 224, 224, 255));
            }

            self.load_icon_with(&file_name, row as isize, window);

            let mut col = 0;
            for c in file_name.chars() {
                if c == '\n' {
                    col = 0;
                    row += 1;
                } else if c == '\t' {
                    col += 8 - col % 8;
                } else {
                    if col < window.width() / 8 && row < window.height() / 32 {
                        window.char(8 * col as isize + 40,
                                    32 * row as isize + 8,
                                    c,
                                    Color::BLACK);
                        col += 1;
                    }
                }
                if col >= window.width() / 8 {
                    col = 0;
                    row += 1;
                }
            }

            col = column[0];

            for c in file_size.chars() {
                if c == '\n' {
                    col = 0;
                    row += 1;
                } else if c == '\t' {
                    col += 8 - col % 8;
                } else {
                    if col < window.width() / 8 && row < window.height() / 32 {
                        window.char(8 * col as isize + 40,
                                    32 * row as isize + 8,
                                    c,
                                    Color::BLACK);
                        col += 1;
                    }
                }
                if col >= window.width() / 8 {
                    col = 0;
                    row += 1;
                }
            }

            col = column[1];

            for c in self.get_description(file_name).chars() {
                if c == '\n' {
                    col = 0;
                    row += 1;
                } else if c == '\t' {
                    col += 8 - col % 8;
                } else {
                    if col < window.width() / 8 && row < window.height() / 32 {
                        window.char(8 * col as isize + 40,
                                    32 * row as isize + 8,
                                    c,
                                    Color::BLACK);
                        col += 1;
                    }
                }
                if col >= window.width() / 8 {
                    col = 0;
                    row += 1;
                }
            }

            row += 1;
            i += 1;
        }

        window.sync();
    }

    fn main(&mut self, path: &str) {
        let mut width = [48, 48, 48];
        let mut height = 0;
        if let Some(readdir) = fs::read_dir(path) {
            for entry in readdir {
                self.files.push(entry.path().to_string());
                self.file_sizes.push(
                    // When the entry is a folder
                    if entry.path().ends_with('/') {
                        let count = match fs::read_dir(&(path.to_string() + entry.path())) {
                            Some(entry_readdir) => entry_readdir.count(),
                            None => 0
                        };

                        if count == 1 {
                            "1 entry".to_string()
                        } else {
                            format!("{} entries", count)
                        }
                    } else {
                        match File::open(&(path.to_string() + entry.path())) {
                            Some(mut file) => match file.seek(SeekFrom::End(0)) {
                                Some(size) => {
                                    if size >= 1_000_000_000 {
                                        format!("{:.1} GB", (size as f64)/1_000_000_000.0)
                                    } else if size >= 1_000_000 {
                                        format!("{:.1} MB", (size as f64)/1_000_000.0)
                                    } else if size >= 1_000 {
                                        format!("{:.1} KB", (size as f64)/1_000.0)
                                    } else {
                                        format!("{:.1} bytes", size)
                                    }
                                }
                                None => "Failed to seek".to_string()
                            },
                            None => "Failed to open".to_string()
                        }
                    }
                );
                // Unwrapping the last file size will not panic since it has
                // been at least pushed once in the vector
                width[0] = cmp::max(width[0], 48 + (entry.path().len()) * 8);
                width[1] = cmp::max(width[1], 8 + (self.file_sizes.last().unwrap().len()) * 8);
                width[2] = cmp::max(width[2], 8 + (self.get_description(entry.path()).len()) * 8);
            }

            if height < self.files.len() * 32 {
                height = self.files.len() * 32;
            }
        }

        let mut window = Window::new((redox::rand() % 400 + 50) as isize,
                                     (redox::rand() % 300 + 50) as isize,
                                     width.iter().sum(),
                                     height,
                                     &path).unwrap();

        self.draw_content(&mut window);

        while let Some(event) = window.poll() {
            match event.to_option() {
                EventOption::Key(key_event) => {
                    if key_event.pressed {
                        match key_event.scancode {
                            event::K_ESC => break,
                            event::K_HOME => self.selected = 0,
                            event::K_UP => if self.selected > 0 {
                                self.selected -= 1;
                            },
                            event::K_END => self.selected = self.files.len() as isize - 1,
                            event::K_DOWN => if self.selected < self.files.len() as isize - 1 {
                                self.selected += 1;
                            },
                            _ => match key_event.character {
                                '\0' => (),
                                '\n' => {
                                    if self.selected >= 0 &&
                                       self.selected < self.files.len() as isize {
                                        match self.files.get(self.selected as usize) {
                                            Some(file) => {
                                                File::exec(&(path.to_string() + &file));
                                            },
                                            None => (),
                                        }
                                    }
                                }
                                _ => {
                                    let mut i = 0;
                                    for file in self.files.iter() {
                                        if file.starts_with(key_event.character) {
                                            self.selected = i;
                                            break;
                                        }
                                        i += 1;
                                    }
                                }
                            },
                        }

                        self.draw_content(&mut window);
                    }
                }
                EventOption::Mouse(mouse_event) => {
                    let mut redraw = false;
                    let mut i = 0;
                    let mut row = 0;
                    for file in self.files.iter() {
                        let mut col = 0;
                        for c in file.chars() {
                            if mouse_event.y >= 32 * row as isize &&
                               mouse_event.y < 32 * row as isize + 32 {
                                self.selected = i;
                                redraw = true;
                            }

                            if c == '\n' {
                                col = 0;
                                row += 1;
                            } else if c == '\t' {
                                col += 8 - col % 8;
                            } else {
                                if col < window.width() / 8 && row < window.height() / 32 {
                                    col += 1;
                                }
                            }
                            if col >= window.width() / 8 {
                                col = 0;
                                row += 1;
                            }
                        }
                        row += 1;
                        i += 1;
                    }

                    if redraw {
                        self.draw_content(&mut window);
                    }

                    //Check for double click
                    if mouse_event.left_button {
                        let click_time = Duration::realtime();

                        if click_time - self.click_time < Duration::new(0, 500 * time::NANOS_PER_MILLI)
                            && self.last_mouse_event.x == mouse_event.x
                            && self.last_mouse_event.y == mouse_event.y {
                            if self.selected >= 0 && self.selected < self.files.len() as isize {
                                if let Some(file) = self.files.get(self.selected as usize) {
                                    File::exec(&(path.to_string() + &file));
                                }
                            }
                            self.click_time = Duration::new(0, 0);
                        } else {
                            self.click_time = click_time;
                        }
                    }
                    self.last_mouse_event = mouse_event;
                }
                EventOption::Quit(quit_event) => break,
                _ => (),
            }
        }
    }
}

pub fn main() {
    match env::args().get(1) {
        Some(arg) => FileManager::new().main(arg),
        None => FileManager::new().main("file:///"),
    }
}
<|endoftext|>


<commit_before>// Dynamic arenas.

export arena, arena_with_size;

import list;

type chunk = {data: [u8], mut fill: uint};
type arena = {mut chunks: list::list<@chunk>};

fn chunk(size: uint) -> @chunk {
    @{ data: vec::from_elem(size, 0u8), mut fill: 0u }
}

fn arena_with_size(initial_size: uint) -> arena {
    ret {mut chunks: list::cons(chunk(initial_size), @list::nil)};
}

fn arena() -> arena {
    arena_with_size(32u)
}

impl arena for arena {
    fn alloc(n_bytes: uint, align: uint) -> *() {
        let alignm1 = align - 1u;
        let mut head = list::head(self.chunks);

        let mut start = head.fill;
        start = (start + alignm1) & !alignm1;
        let mut end = start + n_bytes;

        if end > vec::len(head.data) {
            // Allocate a new chunk.
            let new_min_chunk_size = uint::max(n_bytes, vec::len(head.data));
            head = chunk(uint::next_power_of_two(new_min_chunk_size));
            self.chunks = list::cons(head, @self.chunks);
            start = 0u;
            end = n_bytes;
        }

        unsafe {
            let p = ptr::offset(vec::unsafe::to_ptr(head.data), start);
            head.fill = end;
            ret unsafe::reinterpret_cast(p);
        }
    }
}

<commit_msg>rustc: Don't zero out arena chunks with vec::from_elem; that's slow because it calls the glue.<commit_after>// Dynamic arenas.

export arena, arena_with_size;

import list;

type chunk = {data: [u8], mut fill: uint};
type arena = {mut chunks: list::list<@chunk>};

fn chunk(size: uint) -> @chunk {
    let mut v = [];
    vec::reserve(v, size);
    @{ data: v, mut fill: 0u }
}

fn arena_with_size(initial_size: uint) -> arena {
    ret {mut chunks: list::cons(chunk(initial_size), @list::nil)};
}

fn arena() -> arena {
    arena_with_size(32u)
}

impl arena for arena {
    fn alloc(n_bytes: uint, align: uint) -> *() {
        let alignm1 = align - 1u;
        let mut head = list::head(self.chunks);

        let mut start = head.fill;
        start = (start + alignm1) & !alignm1;
        let mut end = start + n_bytes;

        if end > vec::len(head.data) {
            // Allocate a new chunk.
            let new_min_chunk_size = uint::max(n_bytes, vec::len(head.data));
            head = chunk(uint::next_power_of_two(new_min_chunk_size));
            self.chunks = list::cons(head, @self.chunks);
            start = 0u;
            end = n_bytes;
        }

        unsafe {
            let p = ptr::offset(vec::unsafe::to_ptr(head.data), start);
            head.fill = end;
            ret unsafe::reinterpret_cast(p);
        }
    }
}

<|endoftext|>


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

use core::container::{Container, Mutable};
use core::cmp::Eq;
use core::prelude::*;
use core::uint;
use core::vec;

const initial_capacity: uint = 32u; // 2^5

pub struct Deque<T> {
    priv nelts: uint,
    priv lo: uint,
    priv hi: uint,
    priv elts: ~[Option<T>]
}

impl<T> Container for Deque<T> {
    pure fn len(&self) -> uint { self.nelts }
    pure fn is_empty(&self) -> bool { self.len() == 0 }
}

impl<T: Copy> Deque<T> {
    static pure fn new() -> Deque<T> {
        Deque{nelts: 0, lo: 0, hi: 0,
              elts: vec::from_fn(initial_capacity, |_| None)}
    }

    fn add_front(&mut self, t: T) {
        let oldlo: uint = self.lo;
        if self.lo == 0u {
            self.lo = self.elts.len() - 1u;
        } else { self.lo -= 1u; }
        if self.lo == self.hi {
            self.elts = grow(self.nelts, oldlo, self.elts);
            self.lo = self.elts.len() - 1u;
            self.hi = self.nelts;
        }
        self.elts[self.lo] = Some(t);
        self.nelts += 1u;
    }

    fn add_back(&mut self, t: T) {
        if self.lo == self.hi && self.nelts != 0u {
            self.elts = grow(self.nelts, self.lo, self.elts);
            self.lo = 0u;
            self.hi = self.nelts;
        }
        self.elts[self.hi] = Some(t);
        self.hi = (self.hi + 1u) % self.elts.len();
        self.nelts += 1u;
    }

    fn pop_front(&mut self) -> T {
        let t: T = get(self.elts, self.lo);
        self.elts[self.lo] = None;
        self.lo = (self.lo + 1u) % self.elts.len();
        self.nelts -= 1u;
        return t;
    }

    fn pop_back(&mut self) -> T {
        if self.hi == 0u {
            self.hi = self.elts.len() - 1u;
        } else { self.hi -= 1u; }
        let t: T = get(self.elts, self.hi);
        self.elts[self.hi] = None;
        self.nelts -= 1u;
        return t;
    }

    fn peek_front(&self) -> T { return get(self.elts, self.lo); }

    fn peek_back(&self) -> T { return get(self.elts, self.hi - 1u); }

    fn get(&self, i: int) -> T {
        let idx = (self.lo + (i as uint)) % self.elts.len();
        return get(self.elts, idx);
    }
}

/// Grow is only called on full elts, so nelts is also len(elts), unlike
/// elsewhere.
fn grow<T: Copy>(nelts: uint, lo: uint, elts: &[Option<T>]) -> ~[Option<T>] {
    assert nelts == elts.len();
    let mut rv = ~[];

    let mut i = 0u;
    let nalloc = uint::next_power_of_two(nelts + 1u);
    while i < nalloc {
        if i < nelts {
            rv.push(elts[(lo + i) % nelts]);
        } else { rv.push(None); }
        i += 1u;
    }

    rv
}

fn get<T: Copy>(elts: &[Option<T>], i: uint) -> T {
    match elts[i] { Some(t) => t, _ => fail!() }
}

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

    #[test]
    fn test_simple() {
        let mut d = Deque::new();
        assert (d.len() == 0u);
        d.add_front(17);
        d.add_front(42);
        d.add_back(137);
        assert (d.len() == 3u);
        d.add_back(137);
        assert (d.len() == 4u);
        log(debug, d.peek_front());
        assert (d.peek_front() == 42);
        log(debug, d.peek_back());
        assert (d.peek_back() == 137);
        let mut i: int = d.pop_front();
        log(debug, i);
        assert (i == 42);
        i = d.pop_back();
        log(debug, i);
        assert (i == 137);
        i = d.pop_back();
        log(debug, i);
        assert (i == 137);
        i = d.pop_back();
        log(debug, i);
        assert (i == 17);
        assert (d.len() == 0u);
        d.add_back(3);
        assert (d.len() == 1u);
        d.add_front(2);
        assert (d.len() == 2u);
        d.add_back(4);
        assert (d.len() == 3u);
        d.add_front(1);
        assert (d.len() == 4u);
        log(debug, d.get(0));
        log(debug, d.get(1));
        log(debug, d.get(2));
        log(debug, d.get(3));
        assert (d.get(0) == 1);
        assert (d.get(1) == 2);
        assert (d.get(2) == 3);
        assert (d.get(3) == 4);
    }

    #[test]
    fn test_boxes() {
        let a: @int = @5;
        let b: @int = @72;
        let c: @int = @64;
        let d: @int = @175;

        let mut deq = Deque::new();
        assert (deq.len() == 0u);
        deq.add_front(a);
        deq.add_front(b);
        deq.add_back(c);
        assert (deq.len() == 3u);
        deq.add_back(d);
        assert (deq.len() == 4u);
        assert (deq.peek_front() == b);
        assert (deq.peek_back() == d);
        assert (deq.pop_front() == b);
        assert (deq.pop_back() == d);
        assert (deq.pop_back() == c);
        assert (deq.pop_back() == a);
        assert (deq.len() == 0u);
        deq.add_back(c);
        assert (deq.len() == 1u);
        deq.add_front(b);
        assert (deq.len() == 2u);
        deq.add_back(d);
        assert (deq.len() == 3u);
        deq.add_front(a);
        assert (deq.len() == 4u);
        assert (deq.get(0) == a);
        assert (deq.get(1) == b);
        assert (deq.get(2) == c);
        assert (deq.get(3) == d);
    }

    fn test_parameterized<T: Copy Eq Durable>(a: T, b: T, c: T, d: T) {
        let mut deq = Deque::new();
        assert (deq.len() == 0u);
        deq.add_front(a);
        deq.add_front(b);
        deq.add_back(c);
        assert (deq.len() == 3u);
        deq.add_back(d);
        assert (deq.len() == 4u);
        assert deq.peek_front() == b;
        assert deq.peek_back() == d;
        assert deq.pop_front() == b;
        assert deq.pop_back() == d;
        assert deq.pop_back() == c;
        assert deq.pop_back() == a;
        assert (deq.len() == 0u);
        deq.add_back(c);
        assert (deq.len() == 1u);
        deq.add_front(b);
        assert (deq.len() == 2u);
        deq.add_back(d);
        assert (deq.len() == 3u);
        deq.add_front(a);
        assert (deq.len() == 4u);
        assert deq.get(0) == a;
        assert deq.get(1) == b;
        assert deq.get(2) == c;
        assert deq.get(3) == d;
    }

    #[deriving_eq]
    enum Taggy { One(int), Two(int, int), Three(int, int, int), }

    #[deriving_eq]
    enum Taggypar<T> {
        Onepar(int), Twopar(int, int), Threepar(int, int, int),
    }

    #[deriving_eq]
    struct RecCy {
        x: int,
        y: int,
        t: Taggy
    }

    #[test]
    fn test_param_int() {
        test_parameterized::<int>(5, 72, 64, 175);
    }

    #[test]
    fn test_param_at_int() {
        test_parameterized::<@int>(@5, @72, @64, @175);
    }

    #[test]
    fn test_param_taggy() {
        test_parameterized::<Taggy>(One(1), Two(1, 2), Three(1, 2, 3),
                                    Two(17, 42));
    }

    #[test]
    fn test_param_taggypar() {
        test_parameterized::<Taggypar<int>>(Onepar::<int>(1),
                                            Twopar::<int>(1, 2),
                                            Threepar::<int>(1, 2, 3),
                                            Twopar::<int>(17, 42));
    }

    #[test]
    fn test_param_reccy() {
        let reccy1 = RecCy { x: 1, y: 2, t: One(1) };
        let reccy2 = RecCy { x: 345, y: 2, t: Two(1, 2) };
        let reccy3 = RecCy { x: 1, y: 777, t: Three(1, 2, 3) };
        let reccy4 = RecCy { x: 19, y: 252, t: Two(17, 42) };
        test_parameterized::<RecCy>(reccy1, reccy2, reccy3, reccy4);
    }
}
<commit_msg>add a Mutable implementation (clear) to std::deque<commit_after>// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use core::container::{Container, Mutable};
use core::cmp::Eq;
use core::prelude::*;
use core::uint;
use core::vec;

const initial_capacity: uint = 32u; // 2^5

pub struct Deque<T> {
    priv nelts: uint,
    priv lo: uint,
    priv hi: uint,
    priv elts: ~[Option<T>]
}

impl<T> Container for Deque<T> {
    pure fn len(&self) -> uint { self.nelts }
    pure fn is_empty(&self) -> bool { self.len() == 0 }
}

impl<T> Mutable for Deque<T> {
    fn clear(&mut self) {
        for vec::each_mut(self.elts) |x| { *x = None }
        self.nelts = 0;
        self.lo = 0;
        self.hi = 0;
    }
}

impl<T: Copy> Deque<T> {
    static pure fn new() -> Deque<T> {
        Deque{nelts: 0, lo: 0, hi: 0,
              elts: vec::from_fn(initial_capacity, |_| None)}
    }

    fn add_front(&mut self, t: T) {
        let oldlo: uint = self.lo;
        if self.lo == 0u {
            self.lo = self.elts.len() - 1u;
        } else { self.lo -= 1u; }
        if self.lo == self.hi {
            self.elts = grow(self.nelts, oldlo, self.elts);
            self.lo = self.elts.len() - 1u;
            self.hi = self.nelts;
        }
        self.elts[self.lo] = Some(t);
        self.nelts += 1u;
    }

    fn add_back(&mut self, t: T) {
        if self.lo == self.hi && self.nelts != 0u {
            self.elts = grow(self.nelts, self.lo, self.elts);
            self.lo = 0u;
            self.hi = self.nelts;
        }
        self.elts[self.hi] = Some(t);
        self.hi = (self.hi + 1u) % self.elts.len();
        self.nelts += 1u;
    }

    fn pop_front(&mut self) -> T {
        let t: T = get(self.elts, self.lo);
        self.elts[self.lo] = None;
        self.lo = (self.lo + 1u) % self.elts.len();
        self.nelts -= 1u;
        return t;
    }

    fn pop_back(&mut self) -> T {
        if self.hi == 0u {
            self.hi = self.elts.len() - 1u;
        } else { self.hi -= 1u; }
        let t: T = get(self.elts, self.hi);
        self.elts[self.hi] = None;
        self.nelts -= 1u;
        return t;
    }

    fn peek_front(&self) -> T { return get(self.elts, self.lo); }

    fn peek_back(&self) -> T { return get(self.elts, self.hi - 1u); }

    fn get(&self, i: int) -> T {
        let idx = (self.lo + (i as uint)) % self.elts.len();
        return get(self.elts, idx);
    }
}

/// Grow is only called on full elts, so nelts is also len(elts), unlike
/// elsewhere.
fn grow<T: Copy>(nelts: uint, lo: uint, elts: &[Option<T>]) -> ~[Option<T>] {
    assert nelts == elts.len();
    let mut rv = ~[];

    let mut i = 0u;
    let nalloc = uint::next_power_of_two(nelts + 1u);
    while i < nalloc {
        if i < nelts {
            rv.push(elts[(lo + i) % nelts]);
        } else { rv.push(None); }
        i += 1u;
    }

    rv
}

fn get<T: Copy>(elts: &[Option<T>], i: uint) -> T {
    match elts[i] { Some(t) => t, _ => fail!() }
}

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

    #[test]
    fn test_simple() {
        let mut d = Deque::new();
        assert (d.len() == 0u);
        d.add_front(17);
        d.add_front(42);
        d.add_back(137);
        assert (d.len() == 3u);
        d.add_back(137);
        assert (d.len() == 4u);
        log(debug, d.peek_front());
        assert (d.peek_front() == 42);
        log(debug, d.peek_back());
        assert (d.peek_back() == 137);
        let mut i: int = d.pop_front();
        log(debug, i);
        assert (i == 42);
        i = d.pop_back();
        log(debug, i);
        assert (i == 137);
        i = d.pop_back();
        log(debug, i);
        assert (i == 137);
        i = d.pop_back();
        log(debug, i);
        assert (i == 17);
        assert (d.len() == 0u);
        d.add_back(3);
        assert (d.len() == 1u);
        d.add_front(2);
        assert (d.len() == 2u);
        d.add_back(4);
        assert (d.len() == 3u);
        d.add_front(1);
        assert (d.len() == 4u);
        log(debug, d.get(0));
        log(debug, d.get(1));
        log(debug, d.get(2));
        log(debug, d.get(3));
        assert (d.get(0) == 1);
        assert (d.get(1) == 2);
        assert (d.get(2) == 3);
        assert (d.get(3) == 4);
    }

    #[test]
    fn test_boxes() {
        let a: @int = @5;
        let b: @int = @72;
        let c: @int = @64;
        let d: @int = @175;

        let mut deq = Deque::new();
        assert (deq.len() == 0u);
        deq.add_front(a);
        deq.add_front(b);
        deq.add_back(c);
        assert (deq.len() == 3u);
        deq.add_back(d);
        assert (deq.len() == 4u);
        assert (deq.peek_front() == b);
        assert (deq.peek_back() == d);
        assert (deq.pop_front() == b);
        assert (deq.pop_back() == d);
        assert (deq.pop_back() == c);
        assert (deq.pop_back() == a);
        assert (deq.len() == 0u);
        deq.add_back(c);
        assert (deq.len() == 1u);
        deq.add_front(b);
        assert (deq.len() == 2u);
        deq.add_back(d);
        assert (deq.len() == 3u);
        deq.add_front(a);
        assert (deq.len() == 4u);
        assert (deq.get(0) == a);
        assert (deq.get(1) == b);
        assert (deq.get(2) == c);
        assert (deq.get(3) == d);
    }

    fn test_parameterized<T: Copy Eq Durable>(a: T, b: T, c: T, d: T) {
        let mut deq = Deque::new();
        assert (deq.len() == 0u);
        deq.add_front(a);
        deq.add_front(b);
        deq.add_back(c);
        assert (deq.len() == 3u);
        deq.add_back(d);
        assert (deq.len() == 4u);
        assert deq.peek_front() == b;
        assert deq.peek_back() == d;
        assert deq.pop_front() == b;
        assert deq.pop_back() == d;
        assert deq.pop_back() == c;
        assert deq.pop_back() == a;
        assert (deq.len() == 0u);
        deq.add_back(c);
        assert (deq.len() == 1u);
        deq.add_front(b);
        assert (deq.len() == 2u);
        deq.add_back(d);
        assert (deq.len() == 3u);
        deq.add_front(a);
        assert (deq.len() == 4u);
        assert deq.get(0) == a;
        assert deq.get(1) == b;
        assert deq.get(2) == c;
        assert deq.get(3) == d;
    }

    #[deriving_eq]
    enum Taggy { One(int), Two(int, int), Three(int, int, int), }

    #[deriving_eq]
    enum Taggypar<T> {
        Onepar(int), Twopar(int, int), Threepar(int, int, int),
    }

    #[deriving_eq]
    struct RecCy {
        x: int,
        y: int,
        t: Taggy
    }

    #[test]
    fn test_param_int() {
        test_parameterized::<int>(5, 72, 64, 175);
    }

    #[test]
    fn test_param_at_int() {
        test_parameterized::<@int>(@5, @72, @64, @175);
    }

    #[test]
    fn test_param_taggy() {
        test_parameterized::<Taggy>(One(1), Two(1, 2), Three(1, 2, 3),
                                    Two(17, 42));
    }

    #[test]
    fn test_param_taggypar() {
        test_parameterized::<Taggypar<int>>(Onepar::<int>(1),
                                            Twopar::<int>(1, 2),
                                            Threepar::<int>(1, 2, 3),
                                            Twopar::<int>(17, 42));
    }

    #[test]
    fn test_param_reccy() {
        let reccy1 = RecCy { x: 1, y: 2, t: One(1) };
        let reccy2 = RecCy { x: 345, y: 2, t: Two(1, 2) };
        let reccy3 = RecCy { x: 1, y: 777, t: Three(1, 2, 3) };
        let reccy4 = RecCy { x: 19, y: 252, t: Two(17, 42) };
        test_parameterized::<RecCy>(reccy1, reccy2, reccy3, reccy4);
    }
}
<|endoftext|>


<commit_before><commit_msg>Implementing the File struct<commit_after>pub enum File {
    FileId(&str),
    Url(&str),
    File(&str),
}
<|endoftext|>


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


<commit_before><commit_msg>attempt<commit_after><|endoftext|>


<commit_before><commit_msg>pair parsing<commit_after>use std::io::{BufRead, BufWriter, Write};
use std::fs::File;
use std::mem;

fn main() {
    println!("usage: parse-pairs <target>");
    println!("will overwrite <target>.pairs");
    let target = std::env::args().skip(1).next().unwrap();
    println!("target: {}", target);

    let mut pairs_writer = BufWriter::new(File::create(format!("{}.pairs", target)).unwrap());

    let input = std::io::stdin();
    for line in input.lock().lines().map(|x| x.unwrap()).filter(|x| !x.starts_with('#')) {
        let elts: Vec<&str> = line[..].split("\t").collect();
        let source: u32 = elts[0].parse().ok().expect("malformed source");
        let target: u32 = elts[1].parse().ok().expect("malformed target");
        pairs_writer.write(&unsafe { mem::transmute::<_, [u8; 4]>(source) }).unwrap();
        pairs_writer.write(&unsafe { mem::transmute::<_, [u8; 4]>(target) }).unwrap();
    }
}
<|endoftext|>


<commit_before><commit_msg>start new<commit_after>fn main() {}
<|endoftext|>


<commit_before><commit_msg>add regression test for issue #78632<commit_after>// check-pass
//
// Regression test for issue #78632

#![crate_type = "lib"]

pub trait Corge<T> {
    type Fred;
}

impl Corge<u8> for () {
    type Fred = u32;
}

pub trait Waldo {
    type Quax;
}

impl Waldo for u32 {
    type Quax = u8;
}

pub trait Grault
where
    (): Corge<Self::Thud>,
{
    type Thud;
    fn bar(_: <() as Corge<Self::Thud>>::Fred) {}
}

impl<T> Grault for T
where
    T: Waldo,
    (): Corge<T::Quax>,
    <() as Corge<T::Quax>>::Fred: Waldo,
{
    type Thud = u8;
}

pub trait Plugh<I> {
    fn baz();
}

#[derive(Copy, Clone, Debug)]
pub struct Qiz<T> {
    foo: T,
}

impl<T> Plugh<<() as Corge<T::Thud>>::Fred> for Qiz<T>
where
    T: Grault,
    (): Corge<T::Thud>,
{
    fn baz() {}
}

pub fn test() {
    <Qiz<u32> as Plugh<u32>>::baz();
}
<|endoftext|>


<commit_before><commit_msg>Add codegen test checking binary_search allows eliding bound checks<commit_after>// min-llvm-version: 11.0.0
// compile-flags: -O
// ignore-debug: the debug assertions get in the way
#![crate_type = "lib"]

// Make sure no bounds checks are emitted when slicing or indexing
// with an index from `binary_search`.

// CHECK-LABEL: @binary_search_index_no_bounds_check
#[no_mangle]
pub fn binary_search_index_no_bounds_check(s: &[u8]) -> u8 {
    // CHECK-NOT: panic
    // CHECK-NOT: slice_index_len_fail
    if let Ok(idx) = s.binary_search(&b'\\') {
        s[idx]
    } else {
        42
    }
}
<|endoftext|>


<commit_before><commit_msg>Add `Connection::new` function<commit_after><|endoftext|>


<commit_before><commit_msg>ported comma quibbling<commit_after>// http://rosettacode.org/wiki/Comma_quibbling
fn quibble(seq: &[&str]) -> String {
    match seq {
        [] => "{}".to_string(),
        [word] => format!("{{{}}}", word ),
        _ => format!("{{{} and {}}}", seq.init().connect(", "), seq.last().unwrap())
    }
}

#[cfg(not(test))]
fn main() {
    println!("{}", quibble([]));
    println!("{}", quibble(["ABC"]));
    println!("{}", quibble(["ABC", "DEF"]));
    println!("{}", quibble(["ABC", "DEF", "G", "H"]));
}

#[test]
fn output() {
    assert_eq!(quibble([]), "{}".to_string());
    assert_eq!(quibble(["ABC"]), "{ABC}".to_string());
    assert_eq!(quibble(["ABC", "DEF"]), "{ABC and DEF}".to_string());
    assert_eq!(quibble(["ABC", "DEF", "G", "H"]), "{ABC, DEF, G and H}".to_string());
}<|endoftext|>


<commit_before><commit_msg>Step 3<commit_after>extern crate mal;
use mal::{types, env, reader, readline};
use mal::types::{MalValue, MalResult, MalError, new_symbol, new_function,
        new_integer, err_str, err_string};
use mal::types::MalType::*;

fn read(string: &str) -> MalResult {
    reader::read_str(string)
}

fn eval_ast(ast: MalValue, env: &env::Env) -> MalResult {
    match *ast {
        Symbol(_) => env::get(&env, &ast),
        List(ref seq) | Vector(ref seq) => {
            let mut ast_ev = vec!();
            for value in seq {
                ast_ev.push(try!(eval(value.clone(), env)));
            }
            Ok(match *ast { List(_) => types::new_list(ast_ev),
                                 _  => types::new_vector(ast_ev)})
        },
        _ => Ok(ast.clone()),
    }
}

fn eval(ast: MalValue, env: &env::Env) -> MalResult {
    let ast_temp = ast.clone();
    let (arg0_symbol, args): (Option<&str>, &Vec<MalValue>) = match *ast_temp {
        List(ref seq) => {
            if seq.len() == 0 { return Ok(ast); }
            match *seq[0] {
                Symbol(ref symbol) => (Some(&symbol[..]), seq),
                _                  => (None, seq),
            }
        },
        _ => return eval_ast(ast, env)
    };

    match arg0_symbol {
        Some(slice) => {
            match slice {
                // (def! key value) ; key must be a Symbol
                // bind the evaluated value in env with the unevaluated key
                "def!" => {
                    if args.len() != 3 {
                        return err_str("wrong arity for \"def!\", should be 2");
                    }
                    let key = args[1].clone();
                    let value = try!(eval(args[2].clone(), env));
                    match *key {
                        Symbol(_) => {
                            env::set(env, key, value.clone());
                            return Ok(value);
                        },
                        _         => {
                            return err_str("def! with non-symbol as a key");
                        },
                    }
                },
                // (let* (key0 value0 key1 value1 ...) value)
                // evaluate value in a temporary sub-environment where
                // the given (key: Symbol / value: _) pairs are set
                "let*" => {
                    if args.len() != 3 {
                        return err_str("wrong arity for \"let*\", should be 2");
                    }
                    let env_let = env::new(Some(env.clone()));
                    let bindings = args[1].clone();
                    match *bindings {
                        List(ref bindings_seq) => {
                            if bindings_seq.len() % 2 != 0 {
                                return err_str(concat!("missing key or value ",
                                    "in the let* binding list"));
                            }
                            let mut it = bindings_seq.iter();
                            while it.len() >= 2 {
                                let key = it.next().unwrap();
                                let expr = it.next().unwrap();
                                match **key {
                                    Symbol(_) => {
                                        let value = try!(eval(expr.clone(), &env_let));
                                        env::set(&env_let, key.clone(), value);
                                    },
                                    _ => return err_str("non-symbol key in the let* binding list"),
                                }
                            }
                        },
                        _ => return err_str("let* with non-list binding"),
                    }
                    return eval(args[2].clone(), &env_let);
                },
        // otherwise : apply the first item to the other
                _ => (),
            }
        },
        None => (),
    }

    let list_ev = try!(eval_ast(ast.clone(), env));
    let items = match *list_ev {
        List(ref seq) => seq,
        _             => return types::err_str("can only apply on a list"),
    };
    if items.len() == 0 { return Ok(list_ev.clone()); }
    let ref f = items[0];
    f.apply(items[1..].to_vec())
}

fn print(expr: MalValue) -> String {
    expr.pr_str(true)
}

fn rep(string: &str, env: &env::Env) -> Result<String, MalError> {
    let ast = try!(read(string.into()));
    let expr = try!(eval(ast, env));
    Ok(print(expr))
}

fn int_op<F>(f: F, args: Vec<MalValue>) -> MalResult
    where F: FnOnce(i32, i32) -> i32 {
    if args.len() != 2 {
        return err_string(
            format!("wrong arity ({}) for operation between 2 integers",
                    args.len()));
    }
    match *args[0] {
        Integer(left) => match *args[1] {
            Integer(right) => Ok(new_integer(f(left, right))),
            _ => err_str("right argument must be an integer"),
        },
        _ => err_str("left argument must be an integer")
    }
}
fn add(args: Vec<MalValue>) -> MalResult { int_op(|a, b| { a+b }, args) }
fn sub(args: Vec<MalValue>) -> MalResult { int_op(|a, b| { a-b }, args) }
fn mul(args: Vec<MalValue>) -> MalResult { int_op(|a, b| { a*b }, args) }

fn div(args: Vec<MalValue>) -> MalResult {
    if args.len() != 2 {
        return err_string(format!(
            "wrong arity ({}) for operation between 2 integers", args.len()));
    }
    match *args[0] {
        Integer(left) => match *args[1] {
            Integer(right) => {
                if right == 0 { err_str("cannot divide by 0") }
                else { Ok(types::new_integer(left / right)) }
            },
            _ => err_str("right argument must be an integer"),
        },
        _ => err_str("left argument must be an integer")
    }
}

fn main() {
    // REPL environment
    let repl_env = env::new(None);
    env::set(&repl_env, new_symbol("+".into()), new_function(add, 2, "+"));
    env::set(&repl_env, new_symbol("-".into()), new_function(sub, 2, "+"));
    env::set(&repl_env, new_symbol("*".into()), new_function(mul, 2, "+"));
    env::set(&repl_env, new_symbol("/".into()), new_function(div, 2, "+"));

    // REPL
    let prompt = "user> ";
    let mut input = String::new();
    'repl: loop {
        readline::read_line(prompt, &mut input);
        match rep(&input, &repl_env) {
            Ok(result) => println!("{}", result),
            Err(MalError::ErrEmptyLine) => continue,
            Err(MalError::ErrString(why)) => println!("error : {}", why),
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Structures for containing raw authentication messages<commit_after><|endoftext|>


<commit_before><commit_msg>Add simple command parsing<commit_after><|endoftext|>


<commit_before><commit_msg>Fix the descriptor pool sizes, incorrect as evidenced by trying out a swapchain with 8 images<commit_after><|endoftext|>


<commit_before><commit_msg>Remove stray TODO comment<commit_after><|endoftext|>


<commit_before><commit_msg>Add a FuturesUnordered benchmark<commit_after>#![feature(test)]

extern crate futures;
extern crate test;

use futures::*;
use futures::stream::FuturesUnordered;
use futures::sync::oneshot;

use test::Bencher;

use std::collections::VecDeque;
use std::thread;

#[bench]
fn oneshots(b: &mut Bencher) {
    const NUM: usize = 10_000;

    b.iter(|| {
        let mut txs = VecDeque::with_capacity(NUM);
        let mut rxs = FuturesUnordered::new();

        for _ in 0..NUM {
            let (tx, rx) = oneshot::channel();
            txs.push_back(tx);
            rxs.push(rx);
        }

        thread::spawn(move || {
            while let Some(tx) = txs.pop_front() {
                let _ = tx.send("hello");
            }
        });

        future::lazy(move || {
            loop {
                if let Ok(Async::Ready(None)) = rxs.poll() {
                    return Ok::<(), ()>(());
                }
            }
        }).wait().unwrap();
    });
}
<|endoftext|>


<commit_before><commit_msg>Add regression test for issue #55846<commit_after>// run-pass

// Regression test for #55846, which once caused an ICE.

use std::marker::PhantomData;

struct Foo;

struct Bar<A> {
    a: PhantomData<A>,
}

impl Fooifier for Foo {
    type Assoc = Foo;
}

trait Fooifier {
    type Assoc;
}

trait Barifier<H> {
    fn barify();
}

impl<H> Barifier<H> for Bar<H> {
    fn barify() {
        println!("All correct!");
    }
}

impl Bar<<Foo as Fooifier>::Assoc> {
    fn this_shouldnt_crash() {
        <Self as Barifier<<Foo as Fooifier>::Assoc>>::barify();
    }
}

fn main() {
    Bar::<Foo>::this_shouldnt_crash();
}
<|endoftext|>


<commit_before><commit_msg>sync_events: Make all fields in the response optional except next_batch.<commit_after><|endoftext|>


<commit_before><commit_msg>set content type to json for iron response<commit_after><|endoftext|>


<commit_before><commit_msg>AST of finite domain constraints. Should be extracted outside later, just for experiments and tests purposes.<commit_after>// Copyright 2015 Pierre Talbot (IRCAM)

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//     http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

enum Domain {
  Interval(i32, i32),
  Singleton(i32)
}

enum Constraint {
  XEqualY(String, String),
  XNotEqualY(String, String),
  XLessThanY(String, String),
}
<|endoftext|>


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

// Logic and data structures related to impl specialization, explained in
// greater detail below.
//
// At the moment, this implementation support only the simple "chain" rule:
// If any two impls overlap, one must be a strict subset of the other.
//
// See traits/README.md for a bit more detail on how specialization
// fits together with the rest of the trait machinery.

use super::{util, build_selcx, SelectionContext};

use middle::cstore::CrateStore;
use middle::def_id::DefId;
use middle::infer::{self, InferCtxt, TypeOrigin};
use middle::region;
use middle::subst::{Subst, Substs};
use middle::traits;
use middle::ty;
use syntax::codemap::DUMMY_SP;

pub mod specialization_graph;

/// Information pertinent to an overlapping impl error.
pub struct Overlap<'a, 'tcx: 'a> {
    pub in_context: InferCtxt<'a, 'tcx>,
    pub with_impl: DefId,
    pub on_trait_ref: ty::TraitRef<'tcx>,
}

/// Given a subst for the requested impl, translate it to a subst
/// appropriate for the actual item definition (whether it be in that impl,
/// a parent impl, or the trait).
pub fn translate_substs<'tcx>(tcx: &ty::ctxt<'tcx>,
                              from_impl: DefId,
                              from_impl_substs: Substs<'tcx>,
                              to_node: specialization_graph::Node)
                              -> Substs<'tcx> {
    match to_node {
        specialization_graph::Node::Impl(to_impl) => {
            // no need to translate if we're targetting the impl we started with
            if from_impl == to_impl {
                return from_impl_substs;
            }

            translate_substs_between_impls(tcx, from_impl, from_impl_substs, to_impl)

        }
        specialization_graph::Node::Trait(..) => {
            translate_substs_from_impl_to_trait(tcx, from_impl, from_impl_substs)
        }
    }
}

/// When we have selected one impl, but are actually using item definitions from
/// a parent impl providing a default, we need a way to translate between the
/// type parameters of the two impls. Here the `source_impl` is the one we've
/// selected, and `source_substs` is a substitution of its generics (and possibly
/// some relevant `FnSpace` variables as well). And `target_impl` is the impl
/// we're actually going to get the definition from.
fn translate_substs_between_impls<'tcx>(tcx: &ty::ctxt<'tcx>,
                                        source_impl: DefId,
                                        source_substs: Substs<'tcx>,
                                        target_impl: DefId)
                                        -> Substs<'tcx> {

    // We need to build a subst that covers all the generics of
    // `target_impl`. Start by introducing fresh infer variables:
    let target_generics = tcx.lookup_item_type(target_impl).generics;
    let mut infcx = infer::normalizing_infer_ctxt(tcx, &tcx.tables);
    let mut target_substs = infcx.fresh_substs_for_generics(DUMMY_SP, &target_generics);
    if source_substs.regions.is_erased() {
        target_substs = target_substs.erase_regions()
    }

    if !fulfill_implication(&mut infcx,
                            source_impl,
                            source_substs.clone(),
                            target_impl,
                            target_substs.clone()) {
        tcx.sess
           .bug("When translating substitutions for specialization, the expected specializaiton \
                 failed to hold")
    }

    // Now resolve the *substitution* we built for the target earlier, replacing
    // the inference variables inside with whatever we got from fulfillment. We
    // also carry along any FnSpace substitutions, which don't need to be
    // adjusted when mapping from one impl to another.
    infcx.resolve_type_vars_if_possible(&target_substs)
         .with_method_from_subst(&source_substs)
}

/// When we've selected an impl but need to use an item definition provided by
/// the trait itself, we need to translate the substitution applied to the impl
/// to one that makes sense for the trait.
fn translate_substs_from_impl_to_trait<'tcx>(tcx: &ty::ctxt<'tcx>,
                                             source_impl: DefId,
                                             source_substs: Substs<'tcx>)
                                             -> Substs<'tcx> {

    let source_trait_ref = tcx.impl_trait_ref(source_impl).unwrap().subst(tcx, &source_substs);

    let mut new_substs = source_trait_ref.substs.clone();
    if source_substs.regions.is_erased() {
        new_substs = new_substs.erase_regions()
    }

    // Carry any FnSpace substitutions along; they don't need to be adjusted
    new_substs.with_method_from_subst(&source_substs)
}

fn skolemizing_subst_for_impl<'a>(tcx: &ty::ctxt<'a>, impl_def_id: DefId) -> Substs<'a> {
    let impl_generics = tcx.lookup_item_type(impl_def_id).generics;

    let types = impl_generics.types.map(|def| tcx.mk_param_from_def(def));

    // FIXME: figure out what we actually want here
    let regions = impl_generics.regions.map(|_| ty::Region::ReStatic);
    // |d| infcx.next_region_var(infer::RegionVariableOrigin::EarlyBoundRegion(span, d.name)));

    Substs::new(types, regions)
}

/// Is impl1 a specialization of impl2?
///
/// Specialization is determined by the sets of types to which the impls apply;
/// impl1 specializes impl2 if it applies to a subset of the types impl2 applies
/// to.
pub fn specializes(tcx: &ty::ctxt, impl1_def_id: DefId, impl2_def_id: DefId) -> bool {
    if !tcx.sess.features.borrow().specialization {
        return false;
    }

    // We determine whether there's a subset relationship by:
    //
    // - skolemizing impl1,
    // - instantiating impl2 with fresh inference variables,
    // - assuming the where clauses for impl1,
    // - unifying,
    // - attempting to prove the where clauses for impl2
    //
    // The last three steps are essentially checking for an implication between two impls
    // after appropriate substitutions. This is what `fulfill_implication` checks for.
    //
    // See RFC 1210 for more details and justification.

    let mut infcx = infer::normalizing_infer_ctxt(tcx, &tcx.tables);

    let impl1_substs = skolemizing_subst_for_impl(tcx, impl1_def_id);
    let impl2_substs = util::fresh_type_vars_for_impl(&infcx, DUMMY_SP, impl2_def_id);

    fulfill_implication(&mut infcx,
                        impl1_def_id,
                        impl1_substs,
                        impl2_def_id,
                        impl2_substs)
}

/// Does impl1 (instantiated with the impl1_substs) imply impl2
/// (instantiated with impl2_substs)?
///
/// Mutates the `infcx` in two ways:
/// - by adding the obligations of impl1 to the parameter environment
/// - via fulfillment, so that if the implication holds the various unifications
fn fulfill_implication<'a, 'tcx>(infcx: &mut InferCtxt<'a, 'tcx>,
                                 impl1_def_id: DefId,
                                 impl1_substs: Substs<'tcx>,
                                 impl2_def_id: DefId,
                                 impl2_substs: Substs<'tcx>)
                                 -> bool {
    let tcx = &infcx.tcx;

    let (impl1_trait_ref, impl1_obligations) = {
        let selcx = &mut SelectionContext::new(&infcx);
        util::impl_trait_ref_and_oblig(selcx, impl1_def_id, &impl1_substs)
    };

    let impl1_predicates: Vec<_> = impl1_obligations.iter()
                                                    .cloned()
                                                    .map(|oblig| oblig.predicate)
                                                    .collect();

    infcx.parameter_environment = ty::ParameterEnvironment {
        tcx: tcx,
        free_substs: impl1_substs,
        implicit_region_bound: ty::ReEmpty, // FIXME: is this OK?
        caller_bounds: impl1_predicates,
        selection_cache: traits::SelectionCache::new(),
        evaluation_cache: traits::EvaluationCache::new(),
        free_id_outlive: region::DUMMY_CODE_EXTENT, // FIXME: is this OK?
    };

    let selcx = &mut build_selcx(&infcx).project_topmost().build();
    let (impl2_trait_ref, impl2_obligations) = util::impl_trait_ref_and_oblig(selcx,
                                                                              impl2_def_id,
                                                                              &impl2_substs);

    // do the impls unify? If not, no specialization.
    if let Err(_) = infer::mk_eq_trait_refs(&infcx,
                                            true,
                                            TypeOrigin::Misc(DUMMY_SP),
                                            impl1_trait_ref,
                                            impl2_trait_ref) {
        debug!("fulfill_implication: {:?} does not unify with {:?}",
               impl1_trait_ref,
               impl2_trait_ref);
        return false;
    }

    let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut();

    // attempt to prove all of the predicates for impl2 given those for impl1
    // (which are packed up in penv)

    for oblig in impl2_obligations.into_iter() {
        fulfill_cx.register_predicate_obligation(&infcx, oblig);
    }

    if let Err(errors) = infer::drain_fulfillment_cx(&infcx, &mut fulfill_cx, &()) {
        // no dice!
        debug!("fulfill_implication: for impls on {:?} and {:?}, could not fulfill: {:?} given \
                {:?}",
               impl1_trait_ref,
               impl2_trait_ref,
               errors,
               infcx.parameter_environment.caller_bounds);
        false
    } else {
        debug!("fulfill_implication: an impl for {:?} specializes {:?} (`where` clauses elided)",
               impl1_trait_ref,
               impl2_trait_ref);
        true
    }
}
<commit_msg>Add more commentary for subst translation<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Logic and data structures related to impl specialization, explained in
// greater detail below.
//
// At the moment, this implementation support only the simple "chain" rule:
// If any two impls overlap, one must be a strict subset of the other.
//
// See traits/README.md for a bit more detail on how specialization
// fits together with the rest of the trait machinery.

use super::{util, build_selcx, SelectionContext};

use middle::cstore::CrateStore;
use middle::def_id::DefId;
use middle::infer::{self, InferCtxt, TypeOrigin};
use middle::region;
use middle::subst::{Subst, Substs};
use middle::traits;
use middle::ty;
use syntax::codemap::DUMMY_SP;

pub mod specialization_graph;

/// Information pertinent to an overlapping impl error.
pub struct Overlap<'a, 'tcx: 'a> {
    pub in_context: InferCtxt<'a, 'tcx>,
    pub with_impl: DefId,
    pub on_trait_ref: ty::TraitRef<'tcx>,
}

/// Given a subst for the requested impl, translate it to a subst
/// appropriate for the actual item definition (whether it be in that impl,
/// a parent impl, or the trait).
pub fn translate_substs<'tcx>(tcx: &ty::ctxt<'tcx>,
                              from_impl: DefId,
                              from_impl_substs: Substs<'tcx>,
                              to_node: specialization_graph::Node)
                              -> Substs<'tcx> {
    match to_node {
        specialization_graph::Node::Impl(to_impl) => {
            // no need to translate if we're targetting the impl we started with
            if from_impl == to_impl {
                return from_impl_substs;
            }

            translate_substs_between_impls(tcx, from_impl, from_impl_substs, to_impl)

        }
        specialization_graph::Node::Trait(..) => {
            translate_substs_from_impl_to_trait(tcx, from_impl, from_impl_substs)
        }
    }
}

/// When we have selected one impl, but are actually using item definitions from
/// a parent impl providing a default, we need a way to translate between the
/// type parameters of the two impls. Here the `source_impl` is the one we've
/// selected, and `source_substs` is a substitution of its generics (and
/// possibly some relevant `FnSpace` variables as well). And `target_impl` is
/// the impl we're actually going to get the definition from. The resulting
/// substitution will map from `target_impl`'s generics to `source_impl`'s
/// generics as instantiated by `source_subst`.
///
/// For example, consider the following scenario:
///
/// ```rust
/// trait Foo { ... }
/// impl<T, U> Foo for (T, U) { ... }  // target impl
/// impl<V> Foo for (V, V) { ... }     // source impl
/// ```
///
/// Suppose we have selected "source impl" with `V` instantiated with `u32`.
/// This function will produce a substitution with `T` and `U` both mapping to `u32`.
///
/// Where clauses add some trickiness here, because they can be used to "define"
/// an argument indirectly:
///
/// ```rust
/// impl<'a, I, T: 'a> Iterator for Cloned<I>
///    where I: Iterator<Item=&'a T>, T: Clone
/// ```
///
/// In a case like this, the substitution for `T` is determined indirectly,
/// through associated type projection. We deal with such cases by using
/// *fulfillment* to relate the two impls, requiring that all projections are
/// resolved.
fn translate_substs_between_impls<'tcx>(tcx: &ty::ctxt<'tcx>,
                                        source_impl: DefId,
                                        source_substs: Substs<'tcx>,
                                        target_impl: DefId)
                                        -> Substs<'tcx> {

    // We need to build a subst that covers all the generics of
    // `target_impl`. Start by introducing fresh infer variables:
    let target_generics = tcx.lookup_item_type(target_impl).generics;
    let mut infcx = infer::normalizing_infer_ctxt(tcx, &tcx.tables);
    let mut target_substs = infcx.fresh_substs_for_generics(DUMMY_SP, &target_generics);
    if source_substs.regions.is_erased() {
        target_substs = target_substs.erase_regions()
    }

    if !fulfill_implication(&mut infcx,
                            source_impl,
                            source_substs.clone(),
                            target_impl,
                            target_substs.clone()) {
        tcx.sess
           .bug("When translating substitutions for specialization, the expected specializaiton \
                 failed to hold")
    }

    // Now resolve the *substitution* we built for the target earlier, replacing
    // the inference variables inside with whatever we got from fulfillment. We
    // also carry along any FnSpace substitutions, which don't need to be
    // adjusted when mapping from one impl to another.
    infcx.resolve_type_vars_if_possible(&target_substs)
         .with_method_from_subst(&source_substs)
}

/// When we've selected an impl but need to use an item definition provided by
/// the trait itself, we need to translate the substitution applied to the impl
/// to one that makes sense for the trait.
fn translate_substs_from_impl_to_trait<'tcx>(tcx: &ty::ctxt<'tcx>,
                                             source_impl: DefId,
                                             source_substs: Substs<'tcx>)
                                             -> Substs<'tcx> {

    let source_trait_ref = tcx.impl_trait_ref(source_impl).unwrap().subst(tcx, &source_substs);

    let mut new_substs = source_trait_ref.substs.clone();
    if source_substs.regions.is_erased() {
        new_substs = new_substs.erase_regions()
    }

    // Carry any FnSpace substitutions along; they don't need to be adjusted
    new_substs.with_method_from_subst(&source_substs)
}

fn skolemizing_subst_for_impl<'a>(tcx: &ty::ctxt<'a>, impl_def_id: DefId) -> Substs<'a> {
    let impl_generics = tcx.lookup_item_type(impl_def_id).generics;

    let types = impl_generics.types.map(|def| tcx.mk_param_from_def(def));

    // FIXME: figure out what we actually want here
    let regions = impl_generics.regions.map(|_| ty::Region::ReStatic);
    // |d| infcx.next_region_var(infer::RegionVariableOrigin::EarlyBoundRegion(span, d.name)));

    Substs::new(types, regions)
}

/// Is impl1 a specialization of impl2?
///
/// Specialization is determined by the sets of types to which the impls apply;
/// impl1 specializes impl2 if it applies to a subset of the types impl2 applies
/// to.
pub fn specializes(tcx: &ty::ctxt, impl1_def_id: DefId, impl2_def_id: DefId) -> bool {
    if !tcx.sess.features.borrow().specialization {
        return false;
    }

    // We determine whether there's a subset relationship by:
    //
    // - skolemizing impl1,
    // - instantiating impl2 with fresh inference variables,
    // - assuming the where clauses for impl1,
    // - unifying,
    // - attempting to prove the where clauses for impl2
    //
    // The last three steps are essentially checking for an implication between two impls
    // after appropriate substitutions. This is what `fulfill_implication` checks for.
    //
    // See RFC 1210 for more details and justification.

    let mut infcx = infer::normalizing_infer_ctxt(tcx, &tcx.tables);

    let impl1_substs = skolemizing_subst_for_impl(tcx, impl1_def_id);
    let impl2_substs = util::fresh_type_vars_for_impl(&infcx, DUMMY_SP, impl2_def_id);

    fulfill_implication(&mut infcx,
                        impl1_def_id,
                        impl1_substs,
                        impl2_def_id,
                        impl2_substs)
}

/// Does impl1 (instantiated with the impl1_substs) imply impl2
/// (instantiated with impl2_substs)?
///
/// Mutates the `infcx` in two ways:
/// - by adding the obligations of impl1 to the parameter environment
/// - via fulfillment, so that if the implication holds the various unifications
fn fulfill_implication<'a, 'tcx>(infcx: &mut InferCtxt<'a, 'tcx>,
                                 impl1_def_id: DefId,
                                 impl1_substs: Substs<'tcx>,
                                 impl2_def_id: DefId,
                                 impl2_substs: Substs<'tcx>)
                                 -> bool {
    let tcx = &infcx.tcx;

    let (impl1_trait_ref, impl1_obligations) = {
        let selcx = &mut SelectionContext::new(&infcx);
        util::impl_trait_ref_and_oblig(selcx, impl1_def_id, &impl1_substs)
    };

    let impl1_predicates: Vec<_> = impl1_obligations.iter()
                                                    .cloned()
                                                    .map(|oblig| oblig.predicate)
                                                    .collect();

    infcx.parameter_environment = ty::ParameterEnvironment {
        tcx: tcx,
        free_substs: impl1_substs,
        implicit_region_bound: ty::ReEmpty, // FIXME: is this OK?
        caller_bounds: impl1_predicates,
        selection_cache: traits::SelectionCache::new(),
        evaluation_cache: traits::EvaluationCache::new(),
        free_id_outlive: region::DUMMY_CODE_EXTENT, // FIXME: is this OK?
    };

    let selcx = &mut build_selcx(&infcx).project_topmost().build();
    let (impl2_trait_ref, impl2_obligations) = util::impl_trait_ref_and_oblig(selcx,
                                                                              impl2_def_id,
                                                                              &impl2_substs);

    // do the impls unify? If not, no specialization.
    if let Err(_) = infer::mk_eq_trait_refs(&infcx,
                                            true,
                                            TypeOrigin::Misc(DUMMY_SP),
                                            impl1_trait_ref,
                                            impl2_trait_ref) {
        debug!("fulfill_implication: {:?} does not unify with {:?}",
               impl1_trait_ref,
               impl2_trait_ref);
        return false;
    }

    let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut();

    // attempt to prove all of the predicates for impl2 given those for impl1
    // (which are packed up in penv)

    for oblig in impl2_obligations.into_iter() {
        fulfill_cx.register_predicate_obligation(&infcx, oblig);
    }

    if let Err(errors) = infer::drain_fulfillment_cx(&infcx, &mut fulfill_cx, &()) {
        // no dice!
        debug!("fulfill_implication: for impls on {:?} and {:?}, could not fulfill: {:?} given \
                {:?}",
               impl1_trait_ref,
               impl2_trait_ref,
               errors,
               infcx.parameter_environment.caller_bounds);
        false
    } else {
        debug!("fulfill_implication: an impl for {:?} specializes {:?} (`where` clauses elided)",
               impl1_trait_ref,
               impl2_trait_ref);
        true
    }
}
<|endoftext|>


<commit_before><commit_msg>Skeleton for problem 2451<commit_after>// https://leetcode.com/problems/odd-string-difference/
pub fn odd_string(words: Vec<String>) -> String {
    todo!()
}

fn main() {
    println!(
        "{}",
        odd_string(vec![
            "adc".to_string(),
            "wzy".to_string(),
            "abc".to_string()
        ])
    ); // "abc"
    println!(
        "{}",
        odd_string(vec![
            "aaa".to_string(),
            "bob".to_string(),
            "ccc".to_string(),
            "ddd".to_string()
        ])
    ); // "bob"
}
<|endoftext|>


<commit_before><commit_msg>Make one of the examples have no return value<commit_after><|endoftext|>


<commit_before><commit_msg>Add a Bluestein algorithm<commit_after>use std::sync::Arc;

use num_complex::Complex;
use num_traits::Zero;

use common::{FFTnum, verify_length, verify_length_divisible};

use ::{Length, IsInverse, FFT};

/// Implementation of Rader's Algorithm
///
/// This algorithm computes a prime-sized FFT in O(nlogn) time. It does this by converting this size n FFT into a
/// size (n - 1) FFT, which is guaranteed to be composite.
///
/// The worst case for this algorithm is when (n - 1) is 2 * prime, resulting in a
/// [Cunningham Chain](https://en.wikipedia.org/wiki/Cunningham_chain)
///
/// ~~~
/// // Computes a forward FFT of size 1201 (prime number), using Rader's Algorithm
/// use rustfft::algorithm::RadersAlgorithm;
/// use rustfft::{FFT, FFTplanner};
/// use rustfft::num_complex::Complex;
/// use rustfft::num_traits::Zero;
///
/// let mut input:  Vec<Complex<f32>> = vec![Zero::zero(); 1201];
/// let mut output: Vec<Complex<f32>> = vec![Zero::zero(); 1201];
///
/// // plan a FFT of size n - 1 = 1200
/// let mut planner = FFTplanner::new(false);
/// let inner_fft = planner.plan_fft(1200);
///
/// let fft = RadersAlgorithm::new(1201, inner_fft);
/// fft.process(&mut input, &mut output);
/// ~~~
///
/// Rader's Algorithm is relatively expensive compared to other FFT algorithms. Benchmarking shows that it is up to
/// an order of magnitude slower than similar composite sizes. In the example size above of 1201, benchmarking shows
/// that it takes 2.5x more time to compute than a FFT of size 1200.

pub struct Bluesteins<T> {
    len: usize,
    inner_fft_fw: Arc<FFT<T>>,
    inner_fft_inv: Arc<FFT<T>>,
    w_forward: Box<[Complex<T>]>,
    w_inverse: Box<[Complex<T>]>,
    x_forward: Box<[Complex<T>]>,
    x_inverse: Box<[Complex<T>]>,
    //scratch_a: Box<[Complex<T>]>,
    //scratch_b: Box<[Complex<T>]>,
    inverse: bool,
}

fn compute_half_twiddle<T: FFTnum>(index: f64, size: usize) -> Complex<T> {
    let theta = index * core::f64::consts::PI / size as f64;
    Complex::new(
        T::from_f64(theta.cos()).unwrap(),
        T::from_f64(-theta.sin()).unwrap(),
    )
}

/// Initialize the "w" twiddles.
fn initialize_w_twiddles<T: FFTnum>(
    len: usize,
    fft: &Arc<FFT<T>>,
    forward_twiddles: &mut [Complex<T>],
    inverse_twiddles: &mut [Complex<T>],
) {
    let mut forward_twiddles_temp = vec![Complex::zero(); fft.len()];
    let mut inverse_twiddles_temp = vec![Complex::zero(); fft.len()];
    for i in 0..fft.len() {
        if let Some(index) = {
            if i < len {
                Some((i as f64).powi(2))
            } else if i > fft.len() - len {
                Some(((i as f64) - (fft.len() as f64)).powi(2))
            } else {
                None
            }
        } {
            let twiddle = compute_half_twiddle(index, len);
            forward_twiddles_temp[i] = twiddle.conj();
            inverse_twiddles_temp[i] = twiddle;
        } else {
            forward_twiddles_temp[i] = Complex::zero();
            inverse_twiddles_temp[i] = Complex::zero();
        }
    }
    fft.process(&mut forward_twiddles_temp, &mut forward_twiddles[..]);
    fft.process(&mut inverse_twiddles_temp, &mut inverse_twiddles[..]);
}

/// Initialize the "x" twiddles.
fn initialize_x_twiddles<T: FFTnum>(
    len: usize,
    forward_twiddles: &mut [Complex<T>],
    inverse_twiddles: &mut [Complex<T>],
) {
    for i in 0..len {
        let twiddle = compute_half_twiddle(-(i as f64).powi(2), len);
        forward_twiddles[i] = twiddle.conj();
        inverse_twiddles[i] = twiddle;
    }
}

impl<T: FFTnum > Bluesteins<T> {
    /// Creates a FFT instance which will process inputs/outputs of size `len`. `inner_fft.len()` must be `len - 1`
    ///
    /// Note that this constructor is quite expensive to run; This algorithm must run a FFT of size n - 1 within the
    /// constructor. This further underlines the fact that Rader's Algorithm is more expensive to run than other
    /// FFT algorithms
    ///
    /// Note also that if `len` is not prime, this algorithm may silently produce garbage output
    pub fn new(len: usize, inner_fft_fw: Arc<FFT<T>>, inner_fft_inv: Arc<FFT<T>>, inverse: bool) -> Self {
        let inner_fft_len = (2 * len - 1).checked_next_power_of_two().unwrap();
        assert_eq!(inner_fft_len, inner_fft_fw.len(), "For Bluesteins algorithm, inner_fft.len() must be a power of to larger than or equal to 2*self.len() - 1. Expected {}, got {}", inner_fft_len, inner_fft_fw.len());

        let mut w_forward = vec![Complex::zero(); inner_fft_len];
        let mut w_inverse = vec![Complex::zero(); inner_fft_len];
        let mut x_forward = vec![Complex::zero(); len];
        let mut x_inverse = vec![Complex::zero(); len];
        //let mut scratch_a = vec![Complex::zero(); inner_fft_len];
        //let mut scratch_b = vec![Complex::zero(); inner_fft_len];
        initialize_w_twiddles(len, &inner_fft_fw, &mut w_forward, &mut w_inverse);
        initialize_x_twiddles(len, &mut x_forward, &mut x_inverse);
        //println!("w_forward");
        //for tw in w_forward.iter() {
        //    println!("{:?}, {:?}", tw.re, tw.im);
        //}
        //println!("w_inverse");
        //for tw in w_inverse.iter() {
        //    println!("{:?}, {:?}", tw.re, tw.im);
        //}
        //println!("x_forward");
        //for tw in x_forward.iter() {
        //    println!("{:?}, {:?}", tw.re, tw.im);
        //}
        //println!("x_inverse");
        //for tw in x_inverse.iter() {
        //    println!("{:?}, {:?}", tw.re, tw.im);
        //}
        Self {
            len,
            inner_fft_fw: inner_fft_fw,
            inner_fft_inv: inner_fft_inv,
            w_forward: w_forward.into_boxed_slice(),
            w_inverse: w_inverse.into_boxed_slice(),
            x_forward: x_forward.into_boxed_slice(),
            x_inverse: x_inverse.into_boxed_slice(),
            //scratch_a: scratch_a.into_boxed_slice(),
            //scratch_b: scratch_b.into_boxed_slice(),
            inverse,
        }
    }

    fn perform_fft(&self, input: &mut [Complex<T>], output: &mut [Complex<T>]) {
        //assert_eq!(self.x_forward.len(), input.len());

        let size = input.len();
        let mut scratch_a = vec![Complex::zero(); self.inner_fft_fw.len()];
        let mut scratch_b = vec![Complex::zero(); self.inner_fft_fw.len()];
        if !self.inverse {
            for (w, (x, i)) in scratch_a.iter_mut().zip(self.x_forward.iter().zip(input.iter())) {
                *w = x * i;
            }
            //for w in scratch_a[size..].iter_mut() {
            //    *w = Complex::zero();
            //}
            self.inner_fft_fw.process(&mut scratch_a, &mut scratch_b);
            for (w, wi) in scratch_b.iter_mut().zip(self.w_forward.iter()) {
                *w = *w * wi;
            }
            self.inner_fft_inv.process(&mut scratch_b, &mut scratch_a);
            let scale = T::one() / T::from_usize(self.inner_fft_inv.len()).unwrap();
            for (i, (w, xi)) in output.iter_mut().zip(scratch_a.iter().zip(self.x_forward.iter())) {
                *i = w * xi * scale;
            }
        }
        else {
            for (w, (x, i)) in scratch_a.iter_mut().zip(self.x_inverse.iter().zip(input.iter())) {
                *w = x * i;
            }
            //for w in scratch_a[size..].iter_mut() {
            //    *w = Complex::zero();
            //}
            self.inner_fft_fw.process(&mut scratch_a, &mut scratch_b);
            for (w, wi) in scratch_b.iter_mut().zip(self.w_inverse.iter()) {
                *w = *w * wi;
            }
            self.inner_fft_inv.process(&mut scratch_b, &mut scratch_a);
            let scale = T::one() / T::from_usize(self.inner_fft_inv.len()).unwrap();
            for (i, (w, xi)) in output.iter_mut().zip(scratch_a.iter().zip(self.x_inverse.iter())) {
                *i = w * xi * scale;
            }
        }
    }

}

impl<T: FFTnum> FFT<T> for Bluesteins<T> {
    fn process(&self, input: &mut [Complex<T>], output: &mut [Complex<T>]) {
        verify_length(input, output, self.len());

        self.perform_fft(input, output);
    }
    fn process_multi(&self, input: &mut [Complex<T>], output: &mut [Complex<T>]) {
        verify_length_divisible(input, output, self.len());

        for (in_chunk, out_chunk) in input.chunks_mut(self.len()).zip(output.chunks_mut(self.len())) {
            self.perform_fft(in_chunk, out_chunk);
        }
    }
}
impl<T> Length for Bluesteins<T> {
    #[inline(always)]
    fn len(&self) -> usize {
        self.len
    }
}
impl<T> IsInverse for Bluesteins<T> {
    #[inline(always)]
    fn is_inverse(&self) -> bool {
        self.inverse
    }
}

#[cfg(test)]
mod unit_tests {
    use super::*;
    use std::sync::Arc;
    use test_utils::check_fft_algorithm;
    use algorithm::DFT;

    #[test]
    fn test_bluestein() {
        for &len in &[3,5,7,11,13] {
            test_bluestein_with_length(len, false);
            test_bluestein_with_length(len, true);
        }
    }

    fn test_bluestein_with_length(len: usize, inverse: bool) {
        let inner_fft_len = (2 * len - 1).checked_next_power_of_two().unwrap();
        let inner_fft_fw = Arc::new(DFT::new(inner_fft_len, false));
        let inner_fft_inv = Arc::new(DFT::new(inner_fft_len, true));
        let fft = Bluesteins::new(len, inner_fft_fw, inner_fft_inv, inverse);

        check_fft_algorithm(&fft, len, inverse);
    }
}
<|endoftext|>


<commit_before><commit_msg>Add test for #32119<commit_after><|endoftext|>