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

//! ncurses-compatible database discovery
//!
//! Does not support hashed database, only filesystem!

use std::env;
use std::fs;
use std::path::PathBuf;

/// Return path to database entry for `term`
#[allow(deprecated)]
pub fn get_dbpath_for_term(term: &str) -> Option<PathBuf> {
    let mut dirs_to_search = Vec::new();
    let first_char = match term.chars().next() {
        Some(c) => c,
        None => return None,
    };

    // Find search directory
    match env::var_os("TERMINFO") {
        Some(dir) => dirs_to_search.push(PathBuf::from(dir)),
        None => {
            if let Some(mut homedir) = env::home_dir() {
                // ncurses compatibility;
                homedir.push(".terminfo");
                dirs_to_search.push(homedir)
            }
            match env::var("TERMINFO_DIRS") {
                Ok(dirs) => {
                    for i in dirs.split(':') {
                        if i == "" {
                            dirs_to_search.push(PathBuf::from("/usr/share/terminfo"));
                        } else {
                            dirs_to_search.push(PathBuf::from(i));
                        }
                    }
                }
                // Found nothing in TERMINFO_DIRS, use the default paths:
                // According to  /etc/terminfo/README, after looking at
                // ~/.terminfo, ncurses will search /etc/terminfo, then
                // /lib/terminfo, and eventually /usr/share/terminfo.
                // On Haiku the database can be found at /boot/system/data/terminfo
                Err(..) => {
                    dirs_to_search.push(PathBuf::from("/etc/terminfo"));
                    dirs_to_search.push(PathBuf::from("/lib/terminfo"));
                    dirs_to_search.push(PathBuf::from("/usr/share/terminfo"));
                    dirs_to_search.push(PathBuf::from("/boot/system/data/terminfo"));
                }
            }
        }
    };

    // Look for the terminal in all of the search directories
    for mut p in dirs_to_search {
        if fs::metadata(&p).is_ok() {
            p.push(&first_char.to_string());
            p.push(&term);
            if fs::metadata(&p).is_ok() {
                return Some(p);
            }
            p.pop();
            p.pop();

            // on some installations the dir is named after the hex of the char
            // (e.g. OS X)
            p.push(&format!("{:x}", first_char as usize));
            p.push(term);
            if fs::metadata(&p).is_ok() {
                return Some(p);
            }
        }
    }
    None
}

#[test]
#[ignore(reason = "buildbots don't have ncurses installed and I can't mock everything I need")]
fn test_get_dbpath_for_term() {
    // woefully inadequate test coverage
    // note: current tests won't work with non-standard terminfo hierarchies (e.g. OS X's)
    use std::env;
    // FIXME (#9639): This needs to handle non-utf8 paths
    fn x(t: &str) -> String {
        let p = get_dbpath_for_term(t).expect("no terminfo entry found");
        p.to_str().unwrap().to_string()
    }
    assert!(x("screen") == "/usr/share/terminfo/s/screen");
    assert!(get_dbpath_for_term("") == None);
    env::set_var("TERMINFO_DIRS", ":");
    assert!(x("screen") == "/usr/share/terminfo/s/screen");
    env::remove_var("TERMINFO_DIRS");
}
<commit_msg>Fix terminfo database search path<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! ncurses-compatible database discovery
//!
//! Does not support hashed database, only filesystem!

use std::env;
use std::fs;
use std::path::PathBuf;

/// Return path to database entry for `term`
#[allow(deprecated)]
pub fn get_dbpath_for_term(term: &str) -> Option<PathBuf> {
    let mut dirs_to_search = Vec::new();
    let first_char = match term.chars().next() {
        Some(c) => c,
        None => return None,
    };

    // Find search directory
    if let Some(dir) = env::var_os("TERMINFO") {
        dirs_to_search.push(PathBuf::from(dir));
    }

    if let Ok(dirs) = env::var("TERMINFO_DIRS") {
        for i in dirs.split(':') {
            if i == "" {
                dirs_to_search.push(PathBuf::from("/usr/share/terminfo"));
            } else {
                dirs_to_search.push(PathBuf::from(i));
            }
        }
    } else {
        // Found nothing in TERMINFO_DIRS, use the default paths:
        // According to  /etc/terminfo/README, after looking at
        // ~/.terminfo, ncurses will search /etc/terminfo, then
        // /lib/terminfo, and eventually /usr/share/terminfo.
        // On Haiku the database can be found at /boot/system/data/terminfo
        if let Some(mut homedir) = env::home_dir() {
            homedir.push(".terminfo");
            dirs_to_search.push(homedir)
        }

        dirs_to_search.push(PathBuf::from("/etc/terminfo"));
        dirs_to_search.push(PathBuf::from("/lib/terminfo"));
        dirs_to_search.push(PathBuf::from("/usr/share/terminfo"));
        dirs_to_search.push(PathBuf::from("/boot/system/data/terminfo"));
    }

    // Look for the terminal in all of the search directories
    for mut p in dirs_to_search {
        if fs::metadata(&p).is_ok() {
            p.push(&first_char.to_string());
            p.push(&term);
            if fs::metadata(&p).is_ok() {
                return Some(p);
            }
            p.pop();
            p.pop();

            // on some installations the dir is named after the hex of the char
            // (e.g. OS X)
            p.push(&format!("{:x}", first_char as usize));
            p.push(term);
            if fs::metadata(&p).is_ok() {
                return Some(p);
            }
        }
    }
    None
}

#[test]
#[ignore(reason = "buildbots don't have ncurses installed and I can't mock everything I need")]
fn test_get_dbpath_for_term() {
    // woefully inadequate test coverage
    // note: current tests won't work with non-standard terminfo hierarchies (e.g. OS X's)
    use std::env;
    // FIXME (#9639): This needs to handle non-utf8 paths
    fn x(t: &str) -> String {
        let p = get_dbpath_for_term(t).expect("no terminfo entry found");
        p.to_str().unwrap().to_string()
    }
    assert!(x("screen") == "/usr/share/terminfo/s/screen");
    assert!(get_dbpath_for_term("") == None);
    env::set_var("TERMINFO_DIRS", ":");
    assert!(x("screen") == "/usr/share/terminfo/s/screen");
    env::remove_var("TERMINFO_DIRS");
}
<|endoftext|>


<commit_before><commit_msg>Auto merge of #10139 - hi-rustin:rustin-patch-clippy, r=Eh2406<commit_after><|endoftext|>


<commit_before><commit_msg>Add more fields to multiboot_info, print bootloader name<commit_after><|endoftext|>


<commit_before><commit_msg>Refactor(syncfile): fix a "let _" todo<commit_after><|endoftext|>


<commit_before><commit_msg>Fix ShaderGlsl uniform buffer unit test after adding strides<commit_after><|endoftext|>


<commit_before><commit_msg>Add IntoIter for &Category<commit_after><|endoftext|>


<commit_before><commit_msg>Refactor deploy to not use matches<commit_after><|endoftext|>


<commit_before><commit_msg>Add test for spsc<commit_after>extern crate ruyi;
extern crate futures;

use std::thread;
use std::time::Duration;

use futures::Stream;

use ruyi::channel::spsc;
use ruyi::reactor::{self, IntoStream};

#[test]
fn spsc() {
    let (tx, rx) = spsc::sync_channel::<usize>(1).unwrap();
    let handle = thread::spawn(move || {
                                   let task = rx.into_stream().for_each(|_| Ok(()));
                                   reactor::run(task).unwrap();
                               });
    tx.send(1).unwrap();
    thread::sleep(Duration::from_millis(100));
    drop(tx);
    handle.join().unwrap();
}
<|endoftext|>


<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

// Manage the linear volume that stores metadata on pool levels 5-7.

use std::convert::From;
use std::error::Error;
use std::fs::{create_dir, OpenOptions, read_dir, remove_file, rename};
use std::io::ErrorKind;
use std::io::prelude::*;
use std::os::unix::io::AsRawFd;
use std::path::{Path, PathBuf};

use nix;
use nix::mount::{MsFlags, mount, umount};
use nix::unistd::fsync;
use serde_json;

use devicemapper::{DmDevice, DM, LinearDev};

use super::super::engine::HasUuid;
use super::super::errors::EngineResult;
use super::super::types::{FilesystemUuid, PoolUuid};

use super::filesystem::{create_fs, StratFilesystem};
use super::serde_structs::{FilesystemSave, Recordable};

// TODO: Monitor fs size and extend linear and fs if needed
// TODO: Document format of stuff on MDV in SWDD (currently ad-hoc)

const DEV_PATH: &'static str = "/dev/stratis";

const FILESYSTEM_DIR: &'static str = "filesystems";

#[derive(Debug)]
pub struct MetadataVol {
    dev: LinearDev,
    mount_pt: PathBuf,
}

/// A helper struct that borrows the MetadataVol and ensures that the MDV is
/// mounted as long as it is borrowed, and then unmounted.
#[derive(Debug)]
struct MountedMDV<'a> {
    mdv: &'a MetadataVol,
}

impl<'a> MountedMDV<'a> {
    /// Borrow the MDV and ensure it's mounted.
    fn mount(mdv: &MetadataVol) -> EngineResult<MountedMDV> {
        match mount(Some(&mdv.dev.devnode()),
                    &mdv.mount_pt,
                    Some("xfs"),
                    MsFlags::empty(),
                    None as Option<&str>) {
            Err(nix::Error::Sys(nix::Errno::EBUSY)) => {
                // The device is already mounted at the specified mountpoint
                Ok(())
            }
            Err(err) => Err(err),
            Ok(_) => Ok(()),
        }?;

        Ok(MountedMDV { mdv })
    }

    fn mount_pt(&self) -> &Path {
        &self.mdv.mount_pt
    }
}

impl<'a> Drop for MountedMDV<'a> {
    fn drop(&mut self) {
        if let Err(err) = umount(&self.mdv.mount_pt) {
            warn!("Could not unmount MDV: {}", err)
        }
    }
}

impl MetadataVol {
    /// Initialize a new Metadata Volume.
    pub fn initialize(pool_uuid: &PoolUuid, dev: LinearDev) -> EngineResult<MetadataVol> {
        create_fs(dev.devnode().as_path())?;
        MetadataVol::setup(pool_uuid, dev)
    }

    /// Set up an existing Metadata Volume.
    pub fn setup(pool_uuid: &PoolUuid, dev: LinearDev) -> EngineResult<MetadataVol> {
        if let Err(err) = create_dir(DEV_PATH) {
            if err.kind() != ErrorKind::AlreadyExists {
                return Err(From::from(err));
            }
        }

        let filename = format!(".mdv-{}", pool_uuid.simple());
        let mount_pt: PathBuf = vec![DEV_PATH, &filename].iter().collect();

        if let Err(err) = create_dir(&mount_pt) {
            if err.kind() != ErrorKind::AlreadyExists {
                return Err(From::from(err));
            }
        }

        let mdv = MetadataVol { dev, mount_pt };

        {
            let mount = MountedMDV::mount(&mdv)?;

            if let Err(err) = create_dir(mount.mount_pt().join(FILESYSTEM_DIR)) {
                if err.kind() != ErrorKind::AlreadyExists {
                    return Err(From::from(err));
                }
            }

            for dir_e in read_dir(mount.mount_pt().join(FILESYSTEM_DIR))? {
                let dir_e = dir_e?;

                // Clean up any lingering .temp files. These should only
                // exist if there was a crash during save_fs().
                if dir_e.path().ends_with(".temp") {
                    match remove_file(dir_e.path()) {
                        Err(err) => {
                            debug!("could not remove file {:?}: {}",
                                   dir_e.path(),
                                   err.description())
                        }
                        Ok(_) => debug!("Cleaning up temp file {:?}", dir_e.path()),
                    }
                }
            }
        }

        Ok(mdv)
    }

    /// Save info on a new filesystem to persistent storage, or update
    /// the existing info on a filesystem.
    // Write to a temp file and then rename to actual filename, to
    // ensure file contents are not truncated if operation is
    // interrupted.
    pub fn save_fs(&self, fs: &StratFilesystem) -> EngineResult<()> {
        let data = serde_json::to_string(&fs.record())?;
        let path = self.mount_pt
            .join(FILESYSTEM_DIR)
            .join(fs.uuid().simple().to_string())
            .with_extension("json");

        let temp_path = path.clone().with_extension("temp");

        let _mount = MountedMDV::mount(self)?;

        // Braces to ensure f is closed before renaming
        {
            let mut f = OpenOptions::new()
                .write(true)
                .create(true)
                .open(&temp_path)?;
            f.write_all(data.as_bytes())?;

            // Try really hard to make sure it goes to disk
            f.flush()?;
            fsync(f.as_raw_fd())?;
        }

        rename(temp_path, path)?;

        Ok(())
    }

    /// Remove info on a filesystem from persistent storage.
    pub fn rm_fs(&self, fs_uuid: &FilesystemUuid) -> EngineResult<()> {
        let fs_path = self.mount_pt
            .join(FILESYSTEM_DIR)
            .join(fs_uuid.simple().to_string())
            .with_extension("json");

        let _mount = MountedMDV::mount(self)?;

        if let Err(err) = remove_file(fs_path) {
            if err.kind() != ErrorKind::NotFound {
                return Err(From::from(err));
            }
        }

        Ok(())
    }

    /// Get list of filesystems stored on the MDV.
    pub fn filesystems(&self) -> EngineResult<Vec<FilesystemSave>> {
        let mut filesystems = Vec::new();

        let mount = MountedMDV::mount(self)?;

        for dir_e in read_dir(mount.mount_pt().join(FILESYSTEM_DIR))? {
            let dir_e = dir_e?;

            if dir_e.path().ends_with(".temp") {
                continue;
            }

            let mut f = OpenOptions::new().read(true).open(&dir_e.path())?;
            let mut data = Vec::new();
            f.read_to_end(&mut data)?;

            filesystems.push(serde_json::from_slice(&data)?);
        }

        Ok(filesystems)
    }

    /// Tear down a Metadata Volume.
    pub fn teardown(self, dm: &DM) -> EngineResult<()> {
        self.dev.teardown(dm)?;

        Ok(())
    }
}
<commit_msg>Replace temp-file-removing block of code with a function<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

// Manage the linear volume that stores metadata on pool levels 5-7.

use std::convert::From;
use std::fs::{create_dir, OpenOptions, read_dir, remove_file, rename};
use std::io::ErrorKind;
use std::io::prelude::*;
use std::os::unix::io::AsRawFd;
use std::path::{Path, PathBuf};

use nix;
use nix::mount::{MsFlags, mount, umount};
use nix::unistd::fsync;
use serde_json;

use devicemapper::{DmDevice, DM, LinearDev};

use super::super::engine::HasUuid;
use super::super::errors::EngineResult;
use super::super::types::{FilesystemUuid, PoolUuid};

use super::filesystem::{create_fs, StratFilesystem};
use super::serde_structs::{FilesystemSave, Recordable};

// TODO: Monitor fs size and extend linear and fs if needed
// TODO: Document format of stuff on MDV in SWDD (currently ad-hoc)

const DEV_PATH: &'static str = "/dev/stratis";

const FILESYSTEM_DIR: &'static str = "filesystems";

#[derive(Debug)]
pub struct MetadataVol {
    dev: LinearDev,
    mount_pt: PathBuf,
}

/// A helper struct that borrows the MetadataVol and ensures that the MDV is
/// mounted as long as it is borrowed, and then unmounted.
#[derive(Debug)]
struct MountedMDV<'a> {
    mdv: &'a MetadataVol,
}

impl<'a> MountedMDV<'a> {
    /// Borrow the MDV and ensure it's mounted.
    fn mount(mdv: &MetadataVol) -> EngineResult<MountedMDV> {
        match mount(Some(&mdv.dev.devnode()),
                    &mdv.mount_pt,
                    Some("xfs"),
                    MsFlags::empty(),
                    None as Option<&str>) {
            Err(nix::Error::Sys(nix::Errno::EBUSY)) => {
                // The device is already mounted at the specified mountpoint
                Ok(())
            }
            Err(err) => Err(err),
            Ok(_) => Ok(()),
        }?;

        Ok(MountedMDV { mdv })
    }

    fn mount_pt(&self) -> &Path {
        &self.mdv.mount_pt
    }
}

impl<'a> Drop for MountedMDV<'a> {
    fn drop(&mut self) {
        if let Err(err) = umount(&self.mdv.mount_pt) {
            warn!("Could not unmount MDV: {}", err)
        }
    }
}

impl MetadataVol {
    /// Initialize a new Metadata Volume.
    pub fn initialize(pool_uuid: &PoolUuid, dev: LinearDev) -> EngineResult<MetadataVol> {
        create_fs(dev.devnode().as_path())?;
        MetadataVol::setup(pool_uuid, dev)
    }

    /// Set up an existing Metadata Volume.
    pub fn setup(pool_uuid: &PoolUuid, dev: LinearDev) -> EngineResult<MetadataVol> {
        if let Err(err) = create_dir(DEV_PATH) {
            if err.kind() != ErrorKind::AlreadyExists {
                return Err(From::from(err));
            }
        }

        let filename = format!(".mdv-{}", pool_uuid.simple());
        let mount_pt: PathBuf = vec![DEV_PATH, &filename].iter().collect();

        if let Err(err) = create_dir(&mount_pt) {
            if err.kind() != ErrorKind::AlreadyExists {
                return Err(From::from(err));
            }
        }

        let mdv = MetadataVol { dev, mount_pt };

        {
            let mount = MountedMDV::mount(&mdv)?;
            let filesystem_path = mount.mount_pt().join(FILESYSTEM_DIR);

            if let Err(err) = create_dir(&filesystem_path) {
                if err.kind() != ErrorKind::AlreadyExists {
                    return Err(From::from(err));
                }
            }

            let _ = remove_temp_files(&filesystem_path)?;
        }

        Ok(mdv)
    }

    /// Save info on a new filesystem to persistent storage, or update
    /// the existing info on a filesystem.
    // Write to a temp file and then rename to actual filename, to
    // ensure file contents are not truncated if operation is
    // interrupted.
    pub fn save_fs(&self, fs: &StratFilesystem) -> EngineResult<()> {
        let data = serde_json::to_string(&fs.record())?;
        let path = self.mount_pt
            .join(FILESYSTEM_DIR)
            .join(fs.uuid().simple().to_string())
            .with_extension("json");

        let temp_path = path.clone().with_extension("temp");

        let _mount = MountedMDV::mount(self)?;

        // Braces to ensure f is closed before renaming
        {
            let mut f = OpenOptions::new()
                .write(true)
                .create(true)
                .open(&temp_path)?;
            f.write_all(data.as_bytes())?;

            // Try really hard to make sure it goes to disk
            f.flush()?;
            fsync(f.as_raw_fd())?;
        }

        rename(temp_path, path)?;

        Ok(())
    }

    /// Remove info on a filesystem from persistent storage.
    pub fn rm_fs(&self, fs_uuid: &FilesystemUuid) -> EngineResult<()> {
        let fs_path = self.mount_pt
            .join(FILESYSTEM_DIR)
            .join(fs_uuid.simple().to_string())
            .with_extension("json");

        let _mount = MountedMDV::mount(self)?;

        if let Err(err) = remove_file(fs_path) {
            if err.kind() != ErrorKind::NotFound {
                return Err(From::from(err));
            }
        }

        Ok(())
    }

    /// Get list of filesystems stored on the MDV.
    pub fn filesystems(&self) -> EngineResult<Vec<FilesystemSave>> {
        let mut filesystems = Vec::new();

        let mount = MountedMDV::mount(self)?;

        for dir_e in read_dir(mount.mount_pt().join(FILESYSTEM_DIR))? {
            let dir_e = dir_e?;

            if dir_e.path().ends_with(".temp") {
                continue;
            }

            let mut f = OpenOptions::new().read(true).open(&dir_e.path())?;
            let mut data = Vec::new();
            f.read_to_end(&mut data)?;

            filesystems.push(serde_json::from_slice(&data)?);
        }

        Ok(filesystems)
    }

    /// Tear down a Metadata Volume.
    pub fn teardown(self, dm: &DM) -> EngineResult<()> {
        self.dev.teardown(dm)?;

        Ok(())
    }
}

/// Remove temp files from the designated directory.
/// Returns an error if the directory can not be read.
/// Persists if an individual directory entry can not be read due to an
/// intermittent IO error.
/// Returns the following summary values:
///  * the number of temp files found
///  * paths of those unremoved, if any
fn remove_temp_files(dir: &Path) -> EngineResult<(u64, Vec<PathBuf>)> {
    let mut found = 0;
    let mut failed = Vec::new();
    for path in read_dir(dir)?
    .filter_map(|e| e.ok()) // Just ignore entry on intermittent IO error
    .map(|e| e.path())
    .filter(|p| p.ends_with(".temp")) {
        found += 1;
        remove_file(&path).unwrap_or_else(|_| failed.push(path));
    }
    Ok((found, failed))
}
<|endoftext|>


<commit_before><commit_msg>shortening the code using `use` keyword<commit_after><|endoftext|>


<commit_before><commit_msg>Fixing import warning in lu module<commit_after><|endoftext|>


<commit_before><commit_msg>Note we are processing a file at info.<commit_after><|endoftext|>


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

struct Foo<'a>(&'a str);

enum Bar {
    A,
    B,
    C,
}

struct Baz<'a> {
    foo: Foo,
    //~^ ERROR E0107
    //~| expected 1 lifetime parameter
    bar: Bar<'a>,
    //~^ ERROR E0107
    //~| unexpected lifetime parameter
}

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

struct Foo<'a>(&'a str);
struct Buzz<'a, 'b>(&'a str, &'b str);

enum Bar {
    A,
    B,
    C,
}

struct Baz<'a, 'b, 'c> {
    foo: Foo,
    //~^ ERROR E0107
    //~| expected 1 lifetime parameter
    buzz: Buzz<'a>,
    //~^ ERROR E0107
    //~| expected 2 lifetime parameters
    bar: Bar<'a>,
    //~^ ERROR E0107
    //~| unexpected lifetime parameter
    foo2: Foo<'a, 'b, 'c>,
    //~^ ERROR E0107
    //~| 2 unexpected lifetime parameters
}

fn main() {
}
<|endoftext|>


<commit_before>
import util::common::ty_mach;
import util::common::ty_mach_to_str;
import util::common::new_str_hash;
import util::data::interner;
import std::int;
import std::uint;
import std::str;

type str_num = uint;

tag binop {
    PLUS;
    MINUS;
    STAR;
    SLASH;
    PERCENT;
    CARET;
    AND;
    OR;
    LSL;
    LSR;
    ASR;
}

tag token {

    /* Expression-operator symbols. */
    EQ;
    LT;
    LE;
    EQEQ;
    NE;
    GE;
    GT;
    ANDAND;
    OROR;
    NOT;
    TILDE;
    BINOP(binop);
    BINOPEQ(binop);

    /* Structural symbols */
    AT;
    DOT;
    COMMA;
    SEMI;
    COLON;
    MOD_SEP;
    QUES;
    RARROW;
    SEND;
    RECV;
    LARROW;
    DARROW;
    LPAREN;
    RPAREN;
    LBRACKET;
    RBRACKET;
    LBRACE;
    RBRACE;
    POUND;

    /* Literals */
    LIT_INT(int);
    LIT_UINT(uint);
    LIT_MACH_INT(ty_mach, int);
    LIT_FLOAT(str_num);
    LIT_MACH_FLOAT(ty_mach, str_num);
    LIT_STR(str_num);
    LIT_CHAR(char);
    LIT_BOOL(bool);

    /* Name components */
    IDENT(str_num, bool);
    IDX(int);
    UNDERSCORE;
    BRACEQUOTE(str_num);
    EOF;
}

fn binop_to_str(binop o) -> str {
    alt (o) {
        case (PLUS) { ret "+"; }
        case (MINUS) { ret "-"; }
        case (STAR) { ret "*"; }
        case (SLASH) { ret "/"; }
        case (PERCENT) { ret "%"; }
        case (CARET) { ret "^"; }
        case (AND) { ret "&"; }
        case (OR) { ret "|"; }
        case (LSL) { ret "<<"; }
        case (LSR) { ret ">>"; }
        case (ASR) { ret ">>>"; }
    }
}

fn to_str(lexer::reader r, token t) -> str {
    alt (t) {
        case (EQ) { ret "="; }
        case (LT) { ret "<"; }
        case (LE) { ret "<="; }
        case (EQEQ) { ret "=="; }
        case (NE) { ret "!="; }
        case (GE) { ret ">="; }
        case (GT) { ret ">"; }
        case (NOT) { ret "!"; }
        case (TILDE) { ret "~"; }
        case (OROR) { ret "||"; }
        case (ANDAND) { ret "&&"; }
        case (BINOP(?op)) { ret binop_to_str(op); }
        case (BINOPEQ(?op)) { ret binop_to_str(op) + "="; }
        case (
             /* Structural symbols */
             AT) {
            ret "@";
        }
        case (DOT) { ret "."; }
        case (COMMA) { ret ","; }
        case (SEMI) { ret ";"; }
        case (COLON) { ret ":"; }
        case (MOD_SEP) { ret "::"; }
        case (QUES) { ret "?"; }
        case (RARROW) { ret "->"; }
        case (SEND) { ret "<|"; }
        case (RECV) { ret "|>"; }
        case (LARROW) { ret "<-"; }
        case (DARROW) { ret "<->"; }
        case (LPAREN) { ret "("; }
        case (RPAREN) { ret ")"; }
        case (LBRACKET) { ret "["; }
        case (RBRACKET) { ret "]"; }
        case (LBRACE) { ret "{"; }
        case (RBRACE) { ret "}"; }
        case (POUND) { ret "#"; }
        case (
             /* Literals */
             LIT_INT(?i)) {
            ret int::to_str(i, 10u);
        }
        case (LIT_UINT(?u)) { ret uint::to_str(u, 10u); }
        case (LIT_MACH_INT(?tm, ?i)) {
            ret int::to_str(i, 10u) + "_" + ty_mach_to_str(tm);
        }
        case (LIT_MACH_FLOAT(?tm, ?s)) {
            ret interner::get[str](*r.get_interner(), s) + "_" +
                    ty_mach_to_str(tm);
        }
        case (LIT_FLOAT(?s)) { ret interner::get[str](*r.get_interner(), s); }
        case (LIT_STR(?s)) {
            // FIXME: escape.

            ret "\"" + interner::get[str](*r.get_interner(), s) + "\"";
        }
        case (LIT_CHAR(?c)) {
            // FIXME: escape.

            auto tmp = "'";
            str::push_char(tmp, c);
            str::push_byte(tmp, '\'' as u8);
            ret tmp;
        }
        case (LIT_BOOL(?b)) { if (b) { ret "true"; } else { ret "false"; } }
        case (
             /* Name components */
             IDENT(?s, _)) {
            ret interner::get[str](*r.get_interner(), s);
        }
        case (IDX(?i)) { ret "_" + int::to_str(i, 10u); }
        case (UNDERSCORE) { ret "_"; }
        case (BRACEQUOTE(_)) { ret "<bracequote>"; }
        case (EOF) { ret "<eof>"; }
    }
}
// Local Variables:
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
<commit_msg>Add a predicate that determines whether a token can begin an expression<commit_after>
import util::common::ty_mach;
import util::common::ty_mach_to_str;
import util::common::new_str_hash;
import util::data::interner;
import std::int;
import std::uint;
import std::str;

type str_num = uint;

tag binop {
    PLUS;
    MINUS;
    STAR;
    SLASH;
    PERCENT;
    CARET;
    AND;
    OR;
    LSL;
    LSR;
    ASR;
}

tag token {

    /* Expression-operator symbols. */
    EQ;
    LT;
    LE;
    EQEQ;
    NE;
    GE;
    GT;
    ANDAND;
    OROR;
    NOT;
    TILDE;
    BINOP(binop);
    BINOPEQ(binop);

    /* Structural symbols */
    AT;
    DOT;
    COMMA;
    SEMI;
    COLON;
    MOD_SEP;
    QUES;
    RARROW;
    SEND;
    RECV;
    LARROW;
    DARROW;
    LPAREN;
    RPAREN;
    LBRACKET;
    RBRACKET;
    LBRACE;
    RBRACE;
    POUND;

    /* Literals */
    LIT_INT(int);
    LIT_UINT(uint);
    LIT_MACH_INT(ty_mach, int);
    LIT_FLOAT(str_num);
    LIT_MACH_FLOAT(ty_mach, str_num);
    LIT_STR(str_num);
    LIT_CHAR(char);
    LIT_BOOL(bool);

    /* Name components */
    IDENT(str_num, bool);
    IDX(int);
    UNDERSCORE;
    BRACEQUOTE(str_num);
    EOF;
}

fn binop_to_str(binop o) -> str {
    alt (o) {
        case (PLUS) { ret "+"; }
        case (MINUS) { ret "-"; }
        case (STAR) { ret "*"; }
        case (SLASH) { ret "/"; }
        case (PERCENT) { ret "%"; }
        case (CARET) { ret "^"; }
        case (AND) { ret "&"; }
        case (OR) { ret "|"; }
        case (LSL) { ret "<<"; }
        case (LSR) { ret ">>"; }
        case (ASR) { ret ">>>"; }
    }
}

fn to_str(lexer::reader r, token t) -> str {
    alt (t) {
        case (EQ) { ret "="; }
        case (LT) { ret "<"; }
        case (LE) { ret "<="; }
        case (EQEQ) { ret "=="; }
        case (NE) { ret "!="; }
        case (GE) { ret ">="; }
        case (GT) { ret ">"; }
        case (NOT) { ret "!"; }
        case (TILDE) { ret "~"; }
        case (OROR) { ret "||"; }
        case (ANDAND) { ret "&&"; }
        case (BINOP(?op)) { ret binop_to_str(op); }
        case (BINOPEQ(?op)) { ret binop_to_str(op) + "="; }
        case (
             /* Structural symbols */
             AT) {
            ret "@";
        }
        case (DOT) { ret "."; }
        case (COMMA) { ret ","; }
        case (SEMI) { ret ";"; }
        case (COLON) { ret ":"; }
        case (MOD_SEP) { ret "::"; }
        case (QUES) { ret "?"; }
        case (RARROW) { ret "->"; }
        case (SEND) { ret "<|"; }
        case (RECV) { ret "|>"; }
        case (LARROW) { ret "<-"; }
        case (DARROW) { ret "<->"; }
        case (LPAREN) { ret "("; }
        case (RPAREN) { ret ")"; }
        case (LBRACKET) { ret "["; }
        case (RBRACKET) { ret "]"; }
        case (LBRACE) { ret "{"; }
        case (RBRACE) { ret "}"; }
        case (POUND) { ret "#"; }
        case (
             /* Literals */
             LIT_INT(?i)) {
            ret int::to_str(i, 10u);
        }
        case (LIT_UINT(?u)) { ret uint::to_str(u, 10u); }
        case (LIT_MACH_INT(?tm, ?i)) {
            ret int::to_str(i, 10u) + "_" + ty_mach_to_str(tm);
        }
        case (LIT_MACH_FLOAT(?tm, ?s)) {
            ret interner::get[str](*r.get_interner(), s) + "_" +
                    ty_mach_to_str(tm);
        }
        case (LIT_FLOAT(?s)) { ret interner::get[str](*r.get_interner(), s); }
        case (LIT_STR(?s)) {
            // FIXME: escape.

            ret "\"" + interner::get[str](*r.get_interner(), s) + "\"";
        }
        case (LIT_CHAR(?c)) {
            // FIXME: escape.

            auto tmp = "'";
            str::push_char(tmp, c);
            str::push_byte(tmp, '\'' as u8);
            ret tmp;
        }
        case (LIT_BOOL(?b)) { if (b) { ret "true"; } else { ret "false"; } }
        case (
             /* Name components */
             IDENT(?s, _)) {
            ret interner::get[str](*r.get_interner(), s);
        }
        case (IDX(?i)) { ret "_" + int::to_str(i, 10u); }
        case (UNDERSCORE) { ret "_"; }
        case (BRACEQUOTE(_)) { ret "<bracequote>"; }
        case (EOF) { ret "<eof>"; }
    }
}

pred can_begin_expr(token t) -> bool {
    alt (t) {
        case (LPAREN) { true }
        case (LBRACE) { true }
        case (IDENT(_,_)) { true }
        case (UNDERSCORE) { true }
        case (TILDE) { true }
        case (LIT_INT(_)) { true }
        case (LIT_UINT(_)) { true }
        case (LIT_MACH_INT(_,_)) { true }
        case (LIT_FLOAT(_)) { true }
        case (LIT_MACH_FLOAT(_,_)) { true }
        case (LIT_STR(_)) { true }
        case (LIT_CHAR(_)) { true }
        case (POUND) { true }
        case (AT) { true }
        case (_) { false }
    }
}
// Local Variables:
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
<|endoftext|>


<commit_before><commit_msg>Fix spanish string for "This code is editable and runnable" in example.rs<commit_after><|endoftext|>


<commit_before><commit_msg>refactor<commit_after><|endoftext|>


<commit_before><commit_msg>Create an example of using the checks API<commit_after>extern crate env_logger;
extern crate hubcaps;
extern crate jsonwebtoken as jwt;
extern crate serde_json;
extern crate tokio;

use std::env;
use std::fs::File;
use std::io::Read;

use tokio::runtime::Runtime;

use hubcaps::checks::{
    Action, Annotation, AnnotationLevel, CheckRunOptions, Conclusion, Image, Output,
};
use hubcaps::git::GetReferenceResponse;
use hubcaps::{Credentials, Github, InstallationTokenGenerator, JWTCredentials, Result};

fn var(name: &str) -> Result<String> {
    if let Some(v) = env::var(name).ok() {
        Ok(v)
    } else {
        Err(format!("example missing {}", name).into())
    }
}

const USER_AGENT: &str = concat!(env!("CARGO_PKG_NAME"), "/", env!("CARGO_PKG_VERSION"));

fn main() -> Result<()> {
    env_logger::init();
    let key_file = var("GH_APP_KEY")?;
    let app_id = var("GH_APP_ID")?;
    let user_name = var("GH_USERNAME")?;
    let repo = var("GH_REPO")?;
    let branch = var("GH_BRANCH")?;
    let mut rt = Runtime::new()?;

    let mut key = Vec::new();
    File::open(&key_file)?.read_to_end(&mut key)?;
    let cred = JWTCredentials::new(app_id.parse().expect("Bad GH_APP_ID"), key)?;

    let mut github = Github::new(USER_AGENT, Credentials::JWT(cred.clone()));
    let installation = rt
        .block_on(
            github
                .app()
                .find_repo_installation(user_name.clone(), repo.clone()),
        ).unwrap();

    github.set_credentials(Credentials::InstallationToken(
        InstallationTokenGenerator::new(installation.id, cred),
    ));

    let repo = github.repo(user_name, repo);
    let reference = repo.git().reference(format!("heads/{}", &branch));
    let sha = match rt.block_on(reference).unwrap() {
        GetReferenceResponse::Exact(r) => r.object.sha,
        GetReferenceResponse::StartWith(_) => panic!("Branch {} not found", &branch),
    };

    let checks = repo.checkruns();
    let options = &CheckRunOptions {
        actions: Some(vec![
            Action {
                description: "click to do a thing".to_string(),
                identifier: "the thing".to_string(),
                label: "nix-build -A pkgA".to_string(),
            },
            Action {
                description: "click to do a different thing".to_string(),
                identifier: "the different thing".to_string(),
                label: "nix-build -A pkgB".to_string(),
            },
        ]),
        completed_at: Some("2018-01-01T01:01:01Z".to_string()),
        started_at: Some("2018-08-01T01:01:01Z".to_string()),
        conclusion: Some(Conclusion::Neutral),
        details_url: Some("https://nix.ci/status/hi".to_string()),
        external_id: Some("heyyy".to_string()),
        head_sha: sha,
        name: "nix-build . -A pkgA".to_string(),
        output: Some(Output {
            annotations: Some(vec![
                Annotation {
                    annotation_level: AnnotationLevel::Warning,
                    start_line: 4,
                    end_line: 4,
                    start_column: Some(4),
                    end_column: Some(6),
                    message: "Trailing whitespace".to_string(),
                    path: "bogus".to_string(),
                    raw_details: "".to_string(),
                    title: "Whitespace".to_string(),
                },
                Annotation {
                    annotation_level: AnnotationLevel::Warning,
                    start_line: 7,
                    end_line: 7,
                    start_column: Some(4),
                    end_column: Some(8),
                    message: "not sure you meant this letter".to_string(),
                    path: "bogus".to_string(),
                    raw_details: "rawdeetshere\n  is\n   some\n    text".to_string(),
                    title: "hiiii".to_string(),
                },
            ]),
            images: Some(vec![Image {
                alt: "alt text".to_string(),
                caption: Some("caption text".to_string()),
                image_url: "https://nix.ci/nix.ci.svg".to_string(),
            }]),
            summary: "build failed".to_string(),
            text: Some("texthere\n  is\n   some\n    text".to_string()),
            title: "build failed".to_string(),
        }),
        status: None,
    };

    println!("{}", serde_json::to_string(options).unwrap());
    println!("{:?}", rt.block_on(checks.create(options)));
    Ok(())
}
<|endoftext|>


<commit_before><commit_msg>Add example/solveh.rs<commit_after>
extern crate ndarray;
extern crate ndarray_linalg;

use ndarray::*;
use ndarray_linalg::*;

// Solve `Ax=b` for Hermite matrix A
fn solve() -> Result<(), error::LinalgError> {
    let a: Array2<c64> = random_hermite(3); // complex Hermite positive definite matrix
    let b: Array1<c64> = random(3);
    println!("b = {:?}", &b);
    let f = a.factorizeh()?; // DK factorize
    let x = f.solveh(b)?;
    println!("Ax = {:?}", a.dot(&x));;
    Ok(())
}

// Solve `Ax=b` for many b with fixed A
fn factorize() -> Result<(), error::LinalgError> {
    let a: Array2<f64> = random_hpd(3);
    let f = a.factorizeh_into()?;
    // once factorized, you can use it several times:
    for _ in 0..10 {
        let b: Array1<f64> = random(3);
        let _x = f.solveh(b)?;
    }
    Ok(())
}

fn main() {
    solve().unwrap();
    factorize().unwrap();
}
<|endoftext|>


<commit_before><commit_msg>Regression test for issue 85435.<commit_after>// check-pass

// This is issue #85435. But the real story is reflected in issue #85561, where
// a bug in the implementation of feature(capture_disjoint_fields) () was
// exposed to non-feature-gated code by a diagnostic changing PR that removed
// the gating in one case.

// This test is double-checking that the case of interest continues to work as
// expected in the *absence* of that feature gate. At the time of this writing,
// enabling the feature gate will cause this test to fail. We obviously cannot
// stabilize that feature until it can correctly handle this test.

fn main() {
    let val: u8 = 5;
    let u8_ptr: *const u8 = &val;
    let _closure = || {
        unsafe {
            // Fails compilation with:
            // error[E0133]: dereference of raw pointer is unsafe and
            //               requires unsafe function or block
            let tmp = *u8_ptr;
            tmp

            // Just dereferencing and returning directly compiles fine:
            // *u8_ptr
        }
    };
}
<|endoftext|>


<commit_before><commit_msg>Fixed index cycling by cutting the loop off when the index has reached the start value again<commit_after><|endoftext|>


<commit_before><commit_msg>New 8bpp decoding method.<commit_after><|endoftext|>


<commit_before><commit_msg>Use is_sign_negative rather than check against zero<commit_after><|endoftext|>


<commit_before><commit_msg>Update rc4 to use wrapping arithmetic functions<commit_after><|endoftext|>


<commit_before><commit_msg>Add initial xml loader generator test<commit_after>#[link(name = "glgen",
       vers = "0.1")];
#[comment = "OpenGL function loader generator."];

// Requires libxml2

// This will be used to generate the loader from the [registry xml files]
// (https://cvs.khronos.org/svn/repos/ogl/trunk/doc/registry/public/api/)

use std::cast::transmute;
use std::libc::*;
use std::ptr::null;
use std::str::raw::{from_buf, from_buf_len, from_c_str};

pub mod libxml2 {
    use std::libc::*;

    pub type xmlChar = c_uchar;

    // These can be found in libxml/parser.h

    pub static XML_SAX2_MAGIC: c_uint = 0xDEEDBEAF;

    pub type internalSubsetSAXFunc          = *u8;
    pub type isStandaloneSAXFunc            = *u8;
    pub type hasInternalSubsetSAXFunc       = *u8;
    pub type hasExternalSubsetSAXFunc       = *u8;
    pub type resolveEntitySAXFunc           = *u8;
    pub type getEntitySAXFunc               = *u8;
    pub type entityDeclSAXFunc              = *u8;
    pub type notationDeclSAXFunc            = *u8;
    pub type attributeDeclSAXFunc           = *u8;
    pub type elementDeclSAXFunc             = *u8;
    pub type unparsedEntityDeclSAXFunc      = *u8;
    pub type setDocumentLocatorSAXFunc      = *u8;
    pub type startDocumentSAXFunc           = *u8;
    pub type endDocumentSAXFunc             = *u8;
    pub type startElementSAXFunc            = *u8;  // typedef void (*startElementSAXFunc) (void *ctx, const xmlChar *name, const xmlChar **atts);
    pub type endElementSAXFunc              = *u8;  // typedef void (*endElementSAXFunc) (void *ctx, const xmlChar *name);
    pub type referenceSAXFunc               = *u8;  // typedef void (*referenceSAXFunc) (void *ctx, const xmlChar *name);
    pub type charactersSAXFunc              = *u8;  // typedef void (*charactersSAXFunc) (void *ctx, const xmlChar *ch, int len);
    pub type ignorableWhitespaceSAXFunc     = *u8;  // typedef void (*ignorableWhitespaceSAXFunc) (void *ctx, const xmlChar *ch, int len);
    pub type processingInstructionSAXFunc   = *u8;  // typedef void (*processingInstructionSAXFunc) (void *ctx, const xmlChar *target, const xmlChar *data);
    pub type commentSAXFunc                 = *u8;  // typedef void (*commentSAXFunc) (void *ctx, const xmlChar *value);
    pub type warningSAXFunc                 = *u8;  // typedef void (XMLCDECL *warningSAXFunc) (void *ctx, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
    pub type errorSAXFunc                   = *u8;  // typedef void (XMLCDECL *errorSAXFunc) (void *ctx, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
    pub type fatalErrorSAXFunc              = *u8;  // typedef void (XMLCDECL *fatalErrorSAXFunc) (void *ctx, const char *msg, ...) LIBXML_ATTR_FORMAT(2,3);
    pub type getParameterEntitySAXFunc      = *u8;
    pub type cdataBlockSAXFunc              = *u8;
    pub type externalSubsetSAXFunc          = *u8;
    pub type startElementNsSAX2Func         = *u8;  // typedef void (*startElementNsSAX2Func) (void *ctx, const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI, int nb_namespaces, const xmlChar **namespaces, int nb_attributes, int nb_defaulted, const xmlChar **attributes);
    pub type endElementNsSAX2Func           = *u8;  // typedef void (*endElementNsSAX2Func)   (void *ctx, const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI);
    pub type xmlStructuredErrorFunc         = *u8;

    pub struct xmlSAXHandler {
        internalSubset:         internalSubsetSAXFunc,
        isStandalone:           isStandaloneSAXFunc,
        hasInternalSubset:      hasInternalSubsetSAXFunc,
        hasExternalSubset:      hasExternalSubsetSAXFunc,
        resolveEntity:          resolveEntitySAXFunc,
        getEntity:              getEntitySAXFunc,
        entityDecl:             entityDeclSAXFunc,
        notationDecl:           notationDeclSAXFunc,
        attributeDecl:          attributeDeclSAXFunc,
        elementDecl:            elementDeclSAXFunc,
        unparsedEntityDecl:     unparsedEntityDeclSAXFunc,
        setDocumentLocator:     setDocumentLocatorSAXFunc,
        startDocument:          startDocumentSAXFunc,
        endDocument:            endDocumentSAXFunc,
        startElement:           startElementSAXFunc,
        endElement:             endElementSAXFunc,
        reference:              referenceSAXFunc,
        characters:             charactersSAXFunc,
        ignorableWhitespace:    ignorableWhitespaceSAXFunc,
        processingInstruction:  processingInstructionSAXFunc,
        comment:                commentSAXFunc,
        warning:                warningSAXFunc,
        error:                  errorSAXFunc,
        fatalError:             fatalErrorSAXFunc,
        getParameterEntity:     getParameterEntitySAXFunc,
        cdataBlock:             cdataBlockSAXFunc,
        externalSubset:         externalSubsetSAXFunc,
        initialized:            c_uint,
        _private:               *c_void,
        startElementNs:         startElementNsSAX2Func,
        endElementNs:           endElementNsSAX2Func,
        serror:                 xmlStructuredErrorFunc,
    }

    #[link_args="-lxml2"]
    pub extern "C" {
        fn xmlCleanupParser();
        fn xmlSAXUserParseMemory(sax: *xmlSAXHandler, user_data: *c_void, buffer: *c_char, size: c_int) -> c_int;
    }
}

struct Registry {
    enums: ~[Enums],
    commands: ~[Commands]
}

struct Enums {
    namespace: ~str,
    etype: ~str,
    enums: ~[Enum],
}

struct Enum {
    name: ~str,
    value: ~str,
}

struct Commands {
    namespace: ~str,
    commands: ~[Command],
}

struct Command {
    name: ~str,
    rtype: ~str,
    params: ~[Param]
}

struct Param {
    ptype: ~str,
    name: ~str,
}

impl Registry {
    pub fn parse(xml: &str) -> Registry {
        do xml.as_c_str |data| {
            let sax_handler = &libxml2::xmlSAXHandler {
                internalSubset:         null(),
                isStandalone:           null(),
                hasInternalSubset:      null(),
                hasExternalSubset:      null(),
                resolveEntity:          null(),
                getEntity:              null(),
                entityDecl:             null(),
                notationDecl:           null(),
                attributeDecl:          null(),
                elementDecl:            null(),
                unparsedEntityDecl:     null(),
                setDocumentLocator:     null(),
                startDocument:          null(),
                endDocument:            null(),
                startElement:           start_element,
                endElement:             end_element,
                reference:              null(),
                characters:             characters,
                ignorableWhitespace:    null(),
                processingInstruction:  null(),
                comment:                null(),
                warning:                warning,
                error:                  error,
                fatalError:             null(),
                getParameterEntity:     null(),
                cdataBlock:             null(),
                externalSubset:         null(),
                initialized:            libxml2::XML_SAX2_MAGIC,
                _private:               null(),
                startElementNs:         null(),
                endElementNs:           null(),
                serror:                 null(),
            };

            let registry = Registry {
                enums: ~[],
                commands: ~[],
            };
            unsafe {
                libxml2::xmlSAXUserParseMemory(sax_handler,
                                               transmute(&registry),
                                               data, xml.len() as c_int);
                libxml2::xmlCleanupParser();
            }
            registry
        }
    }

    pub unsafe fn from_c_void(ptr: *c_void) -> &mut Registry {
        transmute(ptr)
    }
}

extern "C" fn warning(_ctx: *c_void, msg: *c_char) {
    unsafe { println(fmt!("warning: %s", from_c_str(msg))) }
}

extern "C" fn error(_ctx: *c_void, msg: *c_char) {
    unsafe { println(fmt!("error: %s", from_c_str(msg))) }
}

extern "C" fn start_element(_ctx: *c_void, name: *libxml2::xmlChar, _atts: **libxml2::xmlChar) {
    unsafe { println(fmt!("start_element: %s", from_buf(name))) }
}

extern "C" fn end_element(_ctx: *c_void, name: *libxml2::xmlChar) {
    unsafe { println(fmt!("end_element: %s", from_buf(name))) }
}

extern "C" fn characters(_ctx: *c_void, ch: *libxml2::xmlChar, len: c_int) {
    unsafe { println(fmt!("characters: %s", from_buf_len(ch, len as uint))) }
}

fn main() {
    let _ = Registry::parse("<enum name=\"foo\">hiya</enum>");
}
<|endoftext|>


<commit_before><commit_msg>fix: fixes single line block comment bug<commit_after><|endoftext|>


<commit_before><commit_msg>add example for gqtp client<commit_after>extern crate ruroonga_client as groonga;
extern crate json_flex;

fn main() {
    let req = groonga::GQTPRequest::new();
    let result_string = req.call("status").unwrap();
    println!("{:?}", result_string);

    let data = json_flex::decode(result_string);
    println!("{:?}", data);
}
<|endoftext|>


<commit_before><commit_msg>Added example with bit modelling of adventure game<commit_after>//! An adventure story modeled as actions on bits.
//!
//! Each state in the story is a sequence of bits, each representing something that happened.
//! There are two numbers stored for each state, one for the state and one for the options.
//! This type of modeling can be used to experiment with a story in an explorative way.
//!
//! By applying filtering to the data, one could build stories as abstractions
//! and reuse them in contexts where one needs control of the events.

type Data = Vec<(u64, u64)>;
type Actions = Vec<&'static str>;

fn is_set(state: u64, i: u64) -> bool {
    ((state >> i) & 0b1) == 0b1
}

fn set(state: u64, i: u64) -> u64 {
    state ^ (0b1 << i)
}

/// Computes the changed bit and whether it is inverse or not.
///
/// Returns index and whether it is inverted.
fn change(state: u64, prev_state: u64) -> uint {
    let diff = state ^ prev_state;
    for i in range(0u64, 64) {
        if is_set(diff, i) {
            if ((prev_state >> i) & 0b1) == 0b1 {
                fail!("Can not invert action.");
            } else {
                return i as uint;
            }
        }
    }

    fail!("State differs more or less than one bit");
}

fn with_options(state: u64, data: &Data, f: |u64|) {
    for &(id, options) in data.iter() {
        if id != state { continue; }
        for i in range(0u64, 64) {
            if is_set(options, i) {
                f(set(state, i))
            }
        }
    }
}

fn main() {
    let actions: Actions = vec!(
        "I used to live each summer in a house by the ocean.",
        "One day I went on a fishing trip but came out for a storm.",
        "The storm crushed my boat against a lonely island.",
        "Luckily a big boat picked me up before I sank.",

        // _0000
        "The boat was owned by am old fisherman.",
        "I search the whole island for water, but could not find any.",
        "Finally I settle down for the night in front of a fire.",
        "Suddenly I heard a roar in the dark.",

        // _0000_0000
        "A huge troll charged against me with a liften axe.",
        "Needless to say, the troll was soon dead.",
        "I climbed up in a tree faster than a squirrel in flight.",
        "Unfortunately the tree was no match for the troll's axe.",

        // _0000_0000_0000
        "I thanked him for his bravery.",
        "'You're welcome' he said and smiled with pointed teeth.",
        "That sight made me jump overboard and sim as fast as I could away from the boat.",
        "Fortunately the closest island was not far away.",

        // _0000_0000_0000_0000
        "Before I had time to reflect uppon the situation, I heard a squeeky sound.",
        "I looked down and saw a small troll grabbing my boots.",
        "A rope had tangled my feet and dragged me underwater.",
        "For a moment I could hold my breath, but then everything went black.",

        // _0000_0000_0000_0000_0000
        "I woke up in a strange place.",
        "There were people around me, but they were not quite human.",
        "Instead of arms and legs, they had fins.",
        "They told me every human that drown ends up here.",

        // _0000_0000_0000_0000_0000_0000
        "The tree hit the ground slowly enough for me to run.",
        "In the dark I did not saw where I was headed.",
        "My body fell down a cliff and everything went black.",
        "Instead of arms and legs, they had wings.",

        // _0000_0000_0000_0000_0000_0000_0000
        "They told me every human that falls down a cliff ends up here.",
        "Next day I looked in every direction, but there was no signs of land.",
        "I built a boat of the troll's skeleton.",
    );
	let data: Data = vec!(
        (0b0, 0b1),
        (0b1, 0b10),
        (0b11, 0b100_0000_0000_0000_1100),
        (0b_1011, 0b1_0000),
        (0b111, 0b10_0000),
        (0b10_0111, 0b100_0000),
        (0b110_0111, 0b1000_0000),
        (0b1110_0111, 0b1_0000_0000),
        (0b1_1110_0111, 0b110_0000_0000),
        (0b101_1110_0111, 0b1000_0000_0000),
        (0b11011, 0b1_0000_0000_0000),
        (0b1_0000_0001_1011, 0b10_0000_0000_0000),
        (0b11_0000_0001_1011, 0b100_0000_0000_0000),
        (0b111_0000_0001_1011, 0b1000_0000_0000_0000),
        (0b1111_0000_0001_1011, 0b1_0000_0000_0000_0000),
        (0b1_1111_0000_0001_1011, 0b10_0000_0000_0000_0000),
        (0b11_1111_0000_0001_1011, 0b1000_0000),
        (0b11_1111_0000_1001_1011, 0b1_0000_0000),
        (0b100_0000_0000_0000_0011, 0b1000_0000_0000_0000_0000),
        (0b1100_0000_0000_0000_0011, 0b1_0000_0000_0000_0000_0000),
        (0b1_1100_0000_0000_0000_0011, 0b10_0000_0000_0000_0000_0000),
        (0b11_1100_0000_0000_0000_0011, 0b100_0000_0000_0000_0000_0000),
        (0b111_1100_0000_0000_0000_0011, 0b1000_0000_0000_0000_0000_0000),
        (0b1101_1110_0111, 0b1_0000_0000_0000_0000_0000_0000),
        (0b1_0000_0000_0000_1101_1110_0111, 0b10_0000_0000_0000_0000_0000_0000),
        (0b11_0000_0000_0000_1101_1110_0111, 0b100_0000_0000_0000_0000_0000_0000),
        (0b111_0000_0000_0000_1101_1110_0111, 0b1_0000_0000_0000_0000_0000),
        (0b111_0001_0000_0000_1101_1110_0111, 0b10_0000_0000_0000_0000_0000),
        (0b111_0011_0000_0000_1101_1110_0111, 0b1000_0000_0000_0000_0000_0000_0000),
        (0b1111_0011_0000_0000_1101_1110_0111, 0b1_0000_0000_0000_0000_0000_0000_0000),
        (0b11_1110_0111, 0b10_0000_0000_0000_0000_0000_0000_0000),
        (0b10_0000_0000_0000_0000_0011_1110_0111, 0b100_0000_0000_0000_0000_0000_0000_0000),
    );
    let states: Vec<u64> = vec!(
        0b0,
        0b1,
        0b11,

            0b111,
            0b10_0111,
            0b110_0111,
            0b1110_0111,
            0b1_1110_0111,

                0b11_1110_0111,
                0b10_0000_0000_0000_0000_0011_1110_0111, // building a boat of the troll's skeleton

                // 0b101_1110_0111,
                // 0b1101_1110_0111,
                // 0b1_0000_0000_0000_1101_1110_0111,
                // 0b11_0000_0000_0000_1101_1110_0111,
                // 0b111_0000_0000_0000_1101_1110_0111,
                // 0b111_0001_0000_0000_1101_1110_0111,
                // 0b111_0011_0000_0000_1101_1110_0111, // waking up with bird people
                // 0b1111_0011_0000_0000_1101_1110_0111,

            // 0b_1011,
            // 0b1_1011, // the old fisherman picked me up.
            // 0b1_0000_0001_1011,
            // 0b11_0000_0001_1011,
            // 0b111_0000_0001_1011,
            // 0b1111_0000_0001_1011, // squeeky sound
            // 0b1_1111_0000_0001_1011,
            // 0b11_1111_0000_0001_1011,
            // 0b11_1111_0000_1001_1011,

            // 0b100_0000_0000_0000_0011, // dragged down under water
            // 0b1100_0000_0000_0000_0011,
            // 0b1_1100_0000_0000_0000_0011,
            // 0b11_1100_0000_0000_0000_0011,
            // 0b111_1100_0000_0000_0000_0011,
    );
    let mut i = 0;
    for state in states.as_slice().windows(2) {
        let ch = change(state[1], state[0]);
        println!("{}", actions.get(ch));
        if i == states.len() - 2 {
            with_options(state[1], &data, |opt: u64| {
                let opt_ch = change(opt, state[1]);
                println!("0b{:t}: {}", opt, actions.get(opt_ch));
            });
        }
        i += 1;
    }
    println!("0b{:t}", *states.get(states.len() - 1));
}

<|endoftext|>


<commit_before>// Dynamic Vector
//
// A growable vector that makes use of unique pointers so that the
// result can be sent between tasks and so forth.
//
// Note that recursive use is not permitted.

import dvec_iter::extensions;
import unsafe::reinterpret_cast;
import ptr::{null, extensions};

export dvec;
export from_elt;
export from_vec;
export extensions;
export unwrap;

/**
 * A growable, modifiable vector type that accumulates elements into a
 * unique vector.
 *
 * # Limitations on recursive use
 *
 * This class works by swapping the unique vector out of the data
 * structure whenever it is to be used.  Therefore, recursive use is not
 * permitted.  That is, while iterating through a vector, you cannot
 * access the vector in any other way or else the program will fail.  If
 * you wish, you can use the `swap()` method to gain access to the raw
 * vector and transform it or use it any way you like.  Eventually, we
 * may permit read-only access during iteration or other use.
 *
 * # WARNING
 *
 * For maximum performance, this type is implemented using some rather
 * unsafe code.  In particular, this innocent looking `[mut A]/~` pointer
 * *may be null!*  Therefore, it is important you not reach into the
 * data structure manually but instead use the provided extensions.
 *
 * The reason that I did not use an unsafe pointer in the structure
 * itself is that I wanted to ensure that the vector would be freed when
 * the dvec is dropped.  The reason that I did not use an `option<T>`
 * instead of a nullable pointer is that I found experimentally that it
 * becomes approximately 50% slower. This can probably be improved
 * through optimization.  You can run your own experiments using
 * `src/test/bench/vec-append.rs`. My own tests found that using null
 * pointers achieved about 103 million pushes/second.  Using an option
 * type could only produce 47 million pushes/second.
 */
type dvec<A> = {
    mut data: ~[mut A]
};

/// Creates a new, empty dvec
fn dvec<A>() -> dvec<A> {
    {mut data: ~[mut]}
}

/// Creates a new dvec with a single element
fn from_elt<A>(+e: A) -> dvec<A> {
    {mut data: ~[mut e]}
}

/// Creates a new dvec with the contents of a vector
fn from_vec<A>(+v: ~[mut A]) -> dvec<A> {
    {mut data: v}
}

/// Consumes the vector and returns its contents
fn unwrap<A>(-d: dvec<A>) -> ~[mut A] {
    let {data: v} <- d;
    ret v;
}

impl private_methods<A> for dvec<A> {
    fn check_not_borrowed() {
        unsafe {
            let data: *() = unsafe::reinterpret_cast(self.data);
            if data.is_null() {
                fail "Recursive use of dvec";
            }
        }
    }

    #[inline(always)]
    fn borrow<B>(f: fn(-~[mut A]) -> B) -> B {
        unsafe {
            let mut data = unsafe::reinterpret_cast(null::<()>());
            data <-> self.data;
            let data_ptr: *() = unsafe::reinterpret_cast(data);
            if data_ptr.is_null() { fail "Recursive use of dvec"; }
            ret f(data);
        }
    }

    #[inline(always)]
    fn return(-data: ~[mut A]) {
        unsafe {
            self.data <- data;
        }
    }
}

// In theory, most everything should work with any A, but in practice
// almost nothing works without the copy bound due to limitations
// around closures.
impl extensions<A> for dvec<A> {
    /**
     * Swaps out the current vector and hands it off to a user-provided
     * function `f`.  The function should transform it however is desired
     * and return a new vector to replace it with.
     */
    #[inline(always)]
    fn swap(f: fn(-~[mut A]) -> ~[mut A]) {
        self.borrow(|v| self.return(f(v)))
    }

    /// Returns the number of elements currently in the dvec
    fn len() -> uint {
        do self.borrow |v| {
            let l = v.len();
            self.return(v);
            l
        }
    }

    /// Overwrite the current contents
    fn set(+w: ~[mut A]) {
        self.check_not_borrowed();
        self.data <- w;
    }

    /// Remove and return the last element
    fn pop() -> A {
        do self.borrow |v| {
            let mut v <- v;
            let result = vec::pop(v);
            self.return(v);
            result
        }
    }

    /// Insert a single item at the front of the list
    fn unshift(-t: A) {
        unsafe {
            let mut data = unsafe::reinterpret_cast(null::<()>());
            data <-> self.data;
            let data_ptr: *() = unsafe::reinterpret_cast(data);
            if data_ptr.is_null() { fail "Recursive use of dvec"; }
            log(error, "a");
            self.data <- ~[mut t];
            vec::push_all_move(self.data, data);
            log(error, "b");
        }
    }

    /// Append a single item to the end of the list
    fn push(+t: A) {
        self.check_not_borrowed();
        vec::push(self.data, t);
    }

    /// Remove and return the first element
    fn shift() -> A {
        do self.borrow |v| {
            let mut v = vec::from_mut(v);
            let result = vec::shift(v);
            self.return(vec::to_mut(v));
            result
        }
    }
}

impl extensions<A:copy> for dvec<A> {
    /**
     * Append all elements of a vector to the end of the list
     *
     * Equivalent to `append_iter()` but potentially more efficient.
     */
    fn push_all(ts: &[const A]) {
        self.push_slice(ts, 0u, vec::len(ts));
    }

    /// Appends elements from `from_idx` to `to_idx` (exclusive)
    fn push_slice(ts: &[const A], from_idx: uint, to_idx: uint) {
        do self.swap |v| {
            let mut v <- v;
            let new_len = vec::len(v) + to_idx - from_idx;
            vec::reserve(v, new_len);
            let mut i = from_idx;
            while i < to_idx {
                vec::push(v, ts[i]);
                i += 1u;
            }
            v
        }
    }

    /*
    /**
     * Append all elements of an iterable.
     *
     * Failure will occur if the iterable's `each()` method
     * attempts to access this vector.
     */
    fn append_iter<A, I:iter::base_iter<A>>(ts: I) {
        do self.swap |v| {
           let mut v = alt ts.size_hint() {
             none { v }
             some(h) {
               let len = v.len() + h;
               let mut v <- v;
               vec::reserve(v, len);
               v
            }
           };

        for ts.each |t| { vec::push(v, t) };
           v
        }
    }
    */

    /**
     * Gets a copy of the current contents.
     *
     * See `unwrap()` if you do not wish to copy the contents.
     */
    fn get() -> ~[A] {
        do self.borrow |v| {
            let w = vec::from_mut(copy v);
            self.return(v);
            w
        }
    }

    /// Copy out an individual element
    #[inline(always)]
    fn [](idx: uint) -> A {
        self.get_elt(idx)
    }

    /// Copy out an individual element
    #[inline(always)]
    fn get_elt(idx: uint) -> A {
        self.check_not_borrowed();
        ret self.data[idx];
    }

    /// Overwrites the contents of the element at `idx` with `a`
    fn set_elt(idx: uint, a: A) {
        self.check_not_borrowed();
        self.data[idx] = a;
    }

    /**
     * Overwrites the contents of the element at `idx` with `a`,
     * growing the vector if necessary.  New elements will be initialized
     * with `initval`
     */
    fn grow_set_elt(idx: uint, initval: A, val: A) {
        do self.swap |v| {
            let mut v <- v;
            vec::grow_set(v, idx, initval, val);
            v
        }
    }

    /// Returns the last element, failing if the vector is empty
    #[inline(always)]
    fn last() -> A {
        self.check_not_borrowed();

        let length = self.len();
        if length == 0u {
            fail "attempt to retrieve the last element of an empty vector";
        }

        ret self.data[length - 1u];
    }

    /// Iterates over the elements in reverse order
    #[inline(always)]
    fn reach(f: fn(A) -> bool) {
        let length = self.len();
        let mut i = 0u;
        while i < length {
            if !f(self.get_elt(i)) {
                break;
            }
            i += 1u;
        }
    }
}
<commit_msg>Rename dvec::from_elt to dvec::from_elem. Closes #2792.<commit_after>// Dynamic Vector
//
// A growable vector that makes use of unique pointers so that the
// result can be sent between tasks and so forth.
//
// Note that recursive use is not permitted.

import dvec_iter::extensions;
import unsafe::reinterpret_cast;
import ptr::{null, extensions};

export dvec;
export from_elem;
export from_vec;
export extensions;
export unwrap;

/**
 * A growable, modifiable vector type that accumulates elements into a
 * unique vector.
 *
 * # Limitations on recursive use
 *
 * This class works by swapping the unique vector out of the data
 * structure whenever it is to be used.  Therefore, recursive use is not
 * permitted.  That is, while iterating through a vector, you cannot
 * access the vector in any other way or else the program will fail.  If
 * you wish, you can use the `swap()` method to gain access to the raw
 * vector and transform it or use it any way you like.  Eventually, we
 * may permit read-only access during iteration or other use.
 *
 * # WARNING
 *
 * For maximum performance, this type is implemented using some rather
 * unsafe code.  In particular, this innocent looking `[mut A]/~` pointer
 * *may be null!*  Therefore, it is important you not reach into the
 * data structure manually but instead use the provided extensions.
 *
 * The reason that I did not use an unsafe pointer in the structure
 * itself is that I wanted to ensure that the vector would be freed when
 * the dvec is dropped.  The reason that I did not use an `option<T>`
 * instead of a nullable pointer is that I found experimentally that it
 * becomes approximately 50% slower. This can probably be improved
 * through optimization.  You can run your own experiments using
 * `src/test/bench/vec-append.rs`. My own tests found that using null
 * pointers achieved about 103 million pushes/second.  Using an option
 * type could only produce 47 million pushes/second.
 */
type dvec<A> = {
    mut data: ~[mut A]
};

/// Creates a new, empty dvec
fn dvec<A>() -> dvec<A> {
    {mut data: ~[mut]}
}

/// Creates a new dvec with a single element
fn from_elem<A>(+e: A) -> dvec<A> {
    {mut data: ~[mut e]}
}

/// Creates a new dvec with the contents of a vector
fn from_vec<A>(+v: ~[mut A]) -> dvec<A> {
    {mut data: v}
}

/// Consumes the vector and returns its contents
fn unwrap<A>(-d: dvec<A>) -> ~[mut A] {
    let {data: v} <- d;
    ret v;
}

impl private_methods<A> for dvec<A> {
    fn check_not_borrowed() {
        unsafe {
            let data: *() = unsafe::reinterpret_cast(self.data);
            if data.is_null() {
                fail "Recursive use of dvec";
            }
        }
    }

    #[inline(always)]
    fn borrow<B>(f: fn(-~[mut A]) -> B) -> B {
        unsafe {
            let mut data = unsafe::reinterpret_cast(null::<()>());
            data <-> self.data;
            let data_ptr: *() = unsafe::reinterpret_cast(data);
            if data_ptr.is_null() { fail "Recursive use of dvec"; }
            ret f(data);
        }
    }

    #[inline(always)]
    fn return(-data: ~[mut A]) {
        unsafe {
            self.data <- data;
        }
    }
}

// In theory, most everything should work with any A, but in practice
// almost nothing works without the copy bound due to limitations
// around closures.
impl extensions<A> for dvec<A> {
    /**
     * Swaps out the current vector and hands it off to a user-provided
     * function `f`.  The function should transform it however is desired
     * and return a new vector to replace it with.
     */
    #[inline(always)]
    fn swap(f: fn(-~[mut A]) -> ~[mut A]) {
        self.borrow(|v| self.return(f(v)))
    }

    /// Returns the number of elements currently in the dvec
    fn len() -> uint {
        do self.borrow |v| {
            let l = v.len();
            self.return(v);
            l
        }
    }

    /// Overwrite the current contents
    fn set(+w: ~[mut A]) {
        self.check_not_borrowed();
        self.data <- w;
    }

    /// Remove and return the last element
    fn pop() -> A {
        do self.borrow |v| {
            let mut v <- v;
            let result = vec::pop(v);
            self.return(v);
            result
        }
    }

    /// Insert a single item at the front of the list
    fn unshift(-t: A) {
        unsafe {
            let mut data = unsafe::reinterpret_cast(null::<()>());
            data <-> self.data;
            let data_ptr: *() = unsafe::reinterpret_cast(data);
            if data_ptr.is_null() { fail "Recursive use of dvec"; }
            log(error, "a");
            self.data <- ~[mut t];
            vec::push_all_move(self.data, data);
            log(error, "b");
        }
    }

    /// Append a single item to the end of the list
    fn push(+t: A) {
        self.check_not_borrowed();
        vec::push(self.data, t);
    }

    /// Remove and return the first element
    fn shift() -> A {
        do self.borrow |v| {
            let mut v = vec::from_mut(v);
            let result = vec::shift(v);
            self.return(vec::to_mut(v));
            result
        }
    }
}

impl extensions<A:copy> for dvec<A> {
    /**
     * Append all elements of a vector to the end of the list
     *
     * Equivalent to `append_iter()` but potentially more efficient.
     */
    fn push_all(ts: &[const A]) {
        self.push_slice(ts, 0u, vec::len(ts));
    }

    /// Appends elements from `from_idx` to `to_idx` (exclusive)
    fn push_slice(ts: &[const A], from_idx: uint, to_idx: uint) {
        do self.swap |v| {
            let mut v <- v;
            let new_len = vec::len(v) + to_idx - from_idx;
            vec::reserve(v, new_len);
            let mut i = from_idx;
            while i < to_idx {
                vec::push(v, ts[i]);
                i += 1u;
            }
            v
        }
    }

    /*
    /**
     * Append all elements of an iterable.
     *
     * Failure will occur if the iterable's `each()` method
     * attempts to access this vector.
     */
    fn append_iter<A, I:iter::base_iter<A>>(ts: I) {
        do self.swap |v| {
           let mut v = alt ts.size_hint() {
             none { v }
             some(h) {
               let len = v.len() + h;
               let mut v <- v;
               vec::reserve(v, len);
               v
            }
           };

        for ts.each |t| { vec::push(v, t) };
           v
        }
    }
    */

    /**
     * Gets a copy of the current contents.
     *
     * See `unwrap()` if you do not wish to copy the contents.
     */
    fn get() -> ~[A] {
        do self.borrow |v| {
            let w = vec::from_mut(copy v);
            self.return(v);
            w
        }
    }

    /// Copy out an individual element
    #[inline(always)]
    fn [](idx: uint) -> A {
        self.get_elt(idx)
    }

    /// Copy out an individual element
    #[inline(always)]
    fn get_elt(idx: uint) -> A {
        self.check_not_borrowed();
        ret self.data[idx];
    }

    /// Overwrites the contents of the element at `idx` with `a`
    fn set_elt(idx: uint, a: A) {
        self.check_not_borrowed();
        self.data[idx] = a;
    }

    /**
     * Overwrites the contents of the element at `idx` with `a`,
     * growing the vector if necessary.  New elements will be initialized
     * with `initval`
     */
    fn grow_set_elt(idx: uint, initval: A, val: A) {
        do self.swap |v| {
            let mut v <- v;
            vec::grow_set(v, idx, initval, val);
            v
        }
    }

    /// Returns the last element, failing if the vector is empty
    #[inline(always)]
    fn last() -> A {
        self.check_not_borrowed();

        let length = self.len();
        if length == 0u {
            fail "attempt to retrieve the last element of an empty vector";
        }

        ret self.data[length - 1u];
    }

    /// Iterates over the elements in reverse order
    #[inline(always)]
    fn reach(f: fn(A) -> bool) {
        let length = self.len();
        let mut i = 0u;
        while i < length {
            if !f(self.get_elt(i)) {
                break;
            }
            i += 1u;
        }
    }
}
<|endoftext|>


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

//! A radix trie for storing integers in sorted order

use prelude::*;

// FIXME: #3469: need to manually update TrieNode when SHIFT changes
const SHIFT: uint = 4;
const SIZE: uint = 1 << SHIFT;
const MASK: uint = SIZE - 1;

enum Child<T> {
    Internal(~TrieNode<T>),
    External(uint, T),
    Nothing
}

pub struct TrieMap<T> {
    priv root: TrieNode<T>,
    priv length: uint
}

impl<T> BaseIter<(uint, &T)> for TrieMap<T> {
    /// Visit all key-value pairs in order
    #[inline(always)]
    pure fn each(&self, f: fn(&(uint, &self/T)) -> bool) {
        self.root.each(f);
    }
    #[inline(always)]
    pure fn size_hint(&self) -> Option<uint> { Some(self.len()) }
}

impl<T> ReverseIter<(uint, &T)> for TrieMap<T> {
    /// Visit all key-value pairs in reverse order
    #[inline(always)]
    pure fn each_reverse(&self, f: fn(&(uint, &self/T)) -> bool) {
        self.root.each_reverse(f);
    }
}

impl<T> Container for TrieMap<T> {
    /// Return the number of elements in the map
    #[inline(always)]
    pure fn len(&self) -> uint { self.length }

    /// Return true if the map contains no elements
    #[inline(always)]
    pure fn is_empty(&self) -> bool { self.len() == 0 }
}

impl<T: Copy> Mutable for TrieMap<T> {
    /// Clear the map, removing all values.
    #[inline(always)]
    fn clear(&mut self) {
        self.root = TrieNode::new();
        self.length = 0;
    }
}

impl<T: Copy> Map<uint, T> for TrieMap<T> {
    /// Return true if the map contains a value for the specified key
    #[inline(always)]
    pure fn contains_key(&self, key: &uint) -> bool {
        self.find(key).is_some()
    }

    /// Visit all keys in order
    #[inline(always)]
    pure fn each_key(&self, f: fn(&uint) -> bool) {
        self.each(|&(k, _)| f(&k))
    }

    /// Visit all values in order
    #[inline(always)]
    pure fn each_value(&self, f: fn(&T) -> bool) { self.each(|&(_, v)| f(v)) }

    /// Return the value corresponding to the key in the map
    #[inline(hint)]
    pure fn find(&self, key: &uint) -> Option<&self/T> {
        let mut node: &self/TrieNode<T> = &self.root;
        let mut idx = 0;
        loop {
            match node.children[chunk(*key, idx)] {
              Internal(ref x) => node = &**x,
              External(stored, ref value) => {
                if stored == *key {
                    return Some(value)
                } else {
                    return None
                }
              }
              Nothing => return None
            }
            idx += 1;
        }
    }

    /// Insert a key-value pair into the map. An existing value for a
    /// key is replaced by the new value. Return true if the key did
    /// not already exist in the map.
    #[inline(always)]
    fn insert(&mut self, key: uint, value: T) -> bool {
        let ret = insert(&mut self.root.count,
                         &mut self.root.children[chunk(key, 0)],
                         key, value, 1);
        if ret { self.length += 1 }
        ret
    }

    /// Remove a key-value pair from the map. Return true if the key
    /// was present in the map, otherwise false.
    #[inline(always)]
    fn remove(&mut self, key: &uint) -> bool {
        let ret = remove(&mut self.root.count,
                         &mut self.root.children[chunk(*key, 0)],
                         *key, 1);
        if ret { self.length -= 1 }
        ret
    }
}

impl<T: Copy> TrieMap<T> {
    #[inline(always)]
    static pure fn new() -> TrieMap<T> {
        TrieMap{root: TrieNode::new(), length: 0}
    }
}

impl<T> TrieMap<T> {
    /// Visit all keys in reverse order
    #[inline(always)]
    pure fn each_key_reverse(&self, f: fn(&uint) -> bool) {
        self.each_reverse(|&(k, _)| f(&k))
    }

    /// Visit all values in reverse order
    #[inline(always)]
    pure fn each_value_reverse(&self, f: fn(&T) -> bool) {
        self.each_reverse(|&(_, v)| f(v))
    }

    /// Iterate over the map and mutate the contained values
    fn mutate_values(&mut self, f: fn(uint, &mut T) -> bool) {
        self.root.mutate_values(f);
    }
}

pub struct TrieSet {
    priv map: TrieMap<()>
}

impl BaseIter<uint> for TrieSet {
    /// Visit all values in order
    pure fn each(&self, f: fn(&uint) -> bool) { self.map.each_key(f) }
    pure fn size_hint(&self) -> Option<uint> { Some(self.len()) }
}

impl ReverseIter<uint> for TrieSet {
    /// Visit all values in reverse order
    pure fn each_reverse(&self, f: fn(&uint) -> bool) {
        self.map.each_key_reverse(f)
    }
}

impl Container for TrieSet {
    /// Return the number of elements in the set
    #[inline(always)]
    pure fn len(&self) -> uint { self.map.len() }

    /// Return true if the set contains no elements
    #[inline(always)]
    pure fn is_empty(&self) -> bool { self.map.is_empty() }
}

impl Mutable for TrieSet {
    /// Clear the set, removing all values.
    #[inline(always)]
    fn clear(&mut self) { self.map.clear() }
}

impl TrieSet {
    /// Return true if the set contains a value
    #[inline(always)]
    pure fn contains(&self, value: &uint) -> bool {
        self.map.contains_key(value)
    }

    /// Add a value to the set. Return true if the value was not already
    /// present in the set.
    #[inline(always)]
    fn insert(&mut self, value: uint) -> bool { self.map.insert(value, ()) }

    /// Remove a value from the set. Return true if the value was
    /// present in the set.
    #[inline(always)]
    fn remove(&mut self, value: &uint) -> bool { self.map.remove(value) }
}

struct TrieNode<T> {
    count: uint,
    children: [Child<T> * 16] // FIXME: #3469: can't use the SIZE constant yet
}

impl<T: Copy> TrieNode<T> {
    #[inline(always)]
    static pure fn new() -> TrieNode<T> {
        TrieNode{count: 0, children: [Nothing, ..SIZE]}
    }
}

impl<T> TrieNode<T> {
    pure fn each(&self, f: fn(&(uint, &self/T)) -> bool) -> bool {
        for uint::range(0, self.children.len()) |idx| {
            match self.children[idx] {
                Internal(ref x) => if !x.each(f) { return false },
                External(k, ref v) => if !f(&(k, v)) { return false },
                Nothing => ()
            }
        }
        true
    }

    pure fn each_reverse(&self, f: fn(&(uint, &self/T)) -> bool) -> bool {
        for uint::range_rev(self.children.len(), 0) |idx| {
            match self.children[idx - 1] {
                Internal(ref x) => if !x.each_reverse(f) { return false },
                External(k, ref v) => if !f(&(k, v)) { return false },
                Nothing => ()
            }
        }
        true
    }

    fn mutate_values(&mut self, f: fn(uint, &mut T) -> bool) -> bool {
        for vec::each_mut(self.children) |child| {
            match *child {
                Internal(ref mut x) => if !x.mutate_values(f) {
                    return false
                },
                External(k, ref mut v) => if !f(k, v) { return false },
                Nothing => ()
            }
        }
        true
    }
}

// if this was done via a trait, the key could be generic
#[inline(always)]
pure fn chunk(n: uint, idx: uint) -> uint {
    let real_idx = uint::bytes - 1 - idx;
    (n >> (SHIFT * real_idx)) & MASK
}

fn insert<T: Copy>(count: &mut uint, child: &mut Child<T>, key: uint,
                   value: T, idx: uint) -> bool {
    match *child {
      External(stored_key, stored_value) => {
          if stored_key == key {
              false // already in the trie
          } else {
              // conflict - split the node
              let mut new = ~TrieNode::new();
              insert(&mut new.count,
                     &mut new.children[chunk(stored_key, idx)],
                     stored_key, stored_value, idx + 1);
              insert(&mut new.count, &mut new.children[chunk(key, idx)], key,
                     value, idx + 1);
              *child = Internal(new);
              true
          }
      }
      Internal(ref mut x) => {
        insert(&mut x.count, &mut x.children[chunk(key, idx)], key, value,
               idx + 1)
      }
      Nothing => {
        *count += 1;
        *child = External(key, value);
        true
      }
    }
}

fn remove<T>(count: &mut uint, child: &mut Child<T>, key: uint,
             idx: uint) -> bool {
    let (ret, this) = match *child {
      External(stored, _) => {
          if stored == key { (true, true) } else { (false, false) }
      }
      Internal(ref mut x) => {
          let ret = remove(&mut x.count, &mut x.children[chunk(key, idx)],
                           key, idx + 1);
          (ret, x.count == 0)
      }
      Nothing => (false, false)
    };

    if this {
        *child = Nothing;
        *count -= 1;
    }
    ret
}

#[cfg(test)]
pub fn check_integrity<T>(trie: &TrieNode<T>) {
    assert trie.count != 0;

    let mut sum = 0;

    for trie.children.each |x| {
        match *x {
          Nothing => (),
          Internal(ref y) => {
              check_integrity(&**y);
              sum += 1
          }
          External(_, _) => { sum += 1 }
        }
    }

    assert sum == trie.count;
}

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

    #[test]
    fn test_step() {
        let mut trie = TrieMap::new();
        let n = 300;

        for uint::range_step(1, n, 2) |x| {
            assert trie.insert(x, x + 1);
            assert trie.contains_key(&x);
            check_integrity(&trie.root);
        }

        for uint::range_step(0, n, 2) |x| {
            assert !trie.contains_key(&x);
            assert trie.insert(x, x + 1);
            check_integrity(&trie.root);
        }

        for uint::range(0, n) |x| {
            assert trie.contains_key(&x);
            assert !trie.insert(x, x + 1);
            check_integrity(&trie.root);
        }

        for uint::range_step(1, n, 2) |x| {
            assert trie.remove(&x);
            assert !trie.contains_key(&x);
            check_integrity(&trie.root);
        }

        for uint::range_step(0, n, 2) |x| {
            assert trie.contains_key(&x);
            assert !trie.insert(x, x + 1);
            check_integrity(&trie.root);
        }
    }

    #[test]
    fn test_each() {
        let mut m = TrieMap::new();

        assert m.insert(3, 6);
        assert m.insert(0, 0);
        assert m.insert(4, 8);
        assert m.insert(2, 4);
        assert m.insert(1, 2);

        let mut n = 0;
        for m.each |&(k, v)| {
            assert k == n;
            assert *v == n * 2;
            n += 1;
        }
    }

    #[test]
    fn test_each_break() {
        let mut m = TrieMap::new();

        for uint::range_rev(uint::max_value, uint::max_value - 10000) |x| {
            m.insert(x, x / 2);
        }

        let mut n = uint::max_value - 9999;
        for m.each |&(k, v)| {
            if n == uint::max_value - 5000 { break }
            assert n < uint::max_value - 5000;

            assert k == n;
            assert *v == n / 2;
            n += 1;
        }
    }

    #[test]
    fn test_each_reverse() {
        let mut m = TrieMap::new();

        assert m.insert(3, 6);
        assert m.insert(0, 0);
        assert m.insert(4, 8);
        assert m.insert(2, 4);
        assert m.insert(1, 2);

        let mut n = 4;
        for m.each_reverse |&(k, v)| {
            assert k == n;
            assert *v == n * 2;
            n -= 1;
        }
    }

    #[test]
    fn test_each_reverse_break() {
        let mut m = TrieMap::new();

        for uint::range_rev(uint::max_value, uint::max_value - 10000) |x| {
            m.insert(x, x / 2);
        }

        let mut n = uint::max_value;
        for m.each_reverse |&(k, v)| {
            if n == uint::max_value - 5000 { break }
            assert n > uint::max_value - 5000;

            assert k == n;
            assert *v == n / 2;
            n -= 1;
        }
    }
}
<commit_msg>auto merge of #5245 : thestinger/rust/trie, r=graydon<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! A radix trie for storing integers in sorted order

use prelude::*;

// FIXME: #3469: need to manually update TrieNode when SHIFT changes
// FIXME: #5244: need to manually update the TrieNode constructor
const SHIFT: uint = 4;
const SIZE: uint = 1 << SHIFT;
const MASK: uint = SIZE - 1;

enum Child<T> {
    Internal(~TrieNode<T>),
    External(uint, T),
    Nothing
}

pub struct TrieMap<T> {
    priv root: TrieNode<T>,
    priv length: uint
}

impl<T> BaseIter<(uint, &T)> for TrieMap<T> {
    /// Visit all key-value pairs in order
    #[inline(always)]
    pure fn each(&self, f: fn(&(uint, &self/T)) -> bool) {
        self.root.each(f);
    }
    #[inline(always)]
    pure fn size_hint(&self) -> Option<uint> { Some(self.len()) }
}

impl<T> ReverseIter<(uint, &T)> for TrieMap<T> {
    /// Visit all key-value pairs in reverse order
    #[inline(always)]
    pure fn each_reverse(&self, f: fn(&(uint, &self/T)) -> bool) {
        self.root.each_reverse(f);
    }
}

impl<T> Container for TrieMap<T> {
    /// Return the number of elements in the map
    #[inline(always)]
    pure fn len(&self) -> uint { self.length }

    /// Return true if the map contains no elements
    #[inline(always)]
    pure fn is_empty(&self) -> bool { self.len() == 0 }
}

impl<T> Mutable for TrieMap<T> {
    /// Clear the map, removing all values.
    #[inline(always)]
    fn clear(&mut self) {
        self.root = TrieNode::new();
        self.length = 0;
    }
}

impl<T> Map<uint, T> for TrieMap<T> {
    /// Return true if the map contains a value for the specified key
    #[inline(always)]
    pure fn contains_key(&self, key: &uint) -> bool {
        self.find(key).is_some()
    }

    /// Visit all keys in order
    #[inline(always)]
    pure fn each_key(&self, f: fn(&uint) -> bool) {
        self.each(|&(k, _)| f(&k))
    }

    /// Visit all values in order
    #[inline(always)]
    pure fn each_value(&self, f: fn(&T) -> bool) { self.each(|&(_, v)| f(v)) }

    /// Return the value corresponding to the key in the map
    #[inline(hint)]
    pure fn find(&self, key: &uint) -> Option<&self/T> {
        let mut node: &self/TrieNode<T> = &self.root;
        let mut idx = 0;
        loop {
            match node.children[chunk(*key, idx)] {
              Internal(ref x) => node = &**x,
              External(stored, ref value) => {
                if stored == *key {
                    return Some(value)
                } else {
                    return None
                }
              }
              Nothing => return None
            }
            idx += 1;
        }
    }

    /// Insert a key-value pair into the map. An existing value for a
    /// key is replaced by the new value. Return true if the key did
    /// not already exist in the map.
    #[inline(always)]
    fn insert(&mut self, key: uint, value: T) -> bool {
        let ret = insert(&mut self.root.count,
                         &mut self.root.children[chunk(key, 0)],
                         key, value, 1);
        if ret { self.length += 1 }
        ret
    }

    /// Remove a key-value pair from the map. Return true if the key
    /// was present in the map, otherwise false.
    #[inline(always)]
    fn remove(&mut self, key: &uint) -> bool {
        let ret = remove(&mut self.root.count,
                         &mut self.root.children[chunk(*key, 0)],
                         *key, 1);
        if ret { self.length -= 1 }
        ret
    }
}

impl<T> TrieMap<T> {
    #[inline(always)]
    static pure fn new() -> TrieMap<T> {
        TrieMap{root: TrieNode::new(), length: 0}
    }
}

impl<T> TrieMap<T> {
    /// Visit all keys in reverse order
    #[inline(always)]
    pure fn each_key_reverse(&self, f: fn(&uint) -> bool) {
        self.each_reverse(|&(k, _)| f(&k))
    }

    /// Visit all values in reverse order
    #[inline(always)]
    pure fn each_value_reverse(&self, f: fn(&T) -> bool) {
        self.each_reverse(|&(_, v)| f(v))
    }

    /// Iterate over the map and mutate the contained values
    fn mutate_values(&mut self, f: fn(uint, &mut T) -> bool) {
        self.root.mutate_values(f);
    }
}

pub struct TrieSet {
    priv map: TrieMap<()>
}

impl BaseIter<uint> for TrieSet {
    /// Visit all values in order
    pure fn each(&self, f: fn(&uint) -> bool) { self.map.each_key(f) }
    pure fn size_hint(&self) -> Option<uint> { Some(self.len()) }
}

impl ReverseIter<uint> for TrieSet {
    /// Visit all values in reverse order
    pure fn each_reverse(&self, f: fn(&uint) -> bool) {
        self.map.each_key_reverse(f)
    }
}

impl Container for TrieSet {
    /// Return the number of elements in the set
    #[inline(always)]
    pure fn len(&self) -> uint { self.map.len() }

    /// Return true if the set contains no elements
    #[inline(always)]
    pure fn is_empty(&self) -> bool { self.map.is_empty() }
}

impl Mutable for TrieSet {
    /// Clear the set, removing all values.
    #[inline(always)]
    fn clear(&mut self) { self.map.clear() }
}

impl TrieSet {
    /// Return true if the set contains a value
    #[inline(always)]
    pure fn contains(&self, value: &uint) -> bool {
        self.map.contains_key(value)
    }

    /// Add a value to the set. Return true if the value was not already
    /// present in the set.
    #[inline(always)]
    fn insert(&mut self, value: uint) -> bool { self.map.insert(value, ()) }

    /// Remove a value from the set. Return true if the value was
    /// present in the set.
    #[inline(always)]
    fn remove(&mut self, value: &uint) -> bool { self.map.remove(value) }
}

struct TrieNode<T> {
    count: uint,
    children: [Child<T> * 16] // FIXME: #3469: can't use the SIZE constant yet
}

impl<T> TrieNode<T> {
    #[inline(always)]
    static pure fn new() -> TrieNode<T> {
        // FIXME: #5244: [Nothing, ..SIZE] should be possible without Copy
        TrieNode{count: 0,
                 children: [Nothing, Nothing, Nothing, Nothing,
                            Nothing, Nothing, Nothing, Nothing,
                            Nothing, Nothing, Nothing, Nothing,
                            Nothing, Nothing, Nothing, Nothing]}
    }
}

impl<T> TrieNode<T> {
    pure fn each(&self, f: fn(&(uint, &self/T)) -> bool) -> bool {
        for uint::range(0, self.children.len()) |idx| {
            match self.children[idx] {
                Internal(ref x) => if !x.each(f) { return false },
                External(k, ref v) => if !f(&(k, v)) { return false },
                Nothing => ()
            }
        }
        true
    }

    pure fn each_reverse(&self, f: fn(&(uint, &self/T)) -> bool) -> bool {
        for uint::range_rev(self.children.len(), 0) |idx| {
            match self.children[idx - 1] {
                Internal(ref x) => if !x.each_reverse(f) { return false },
                External(k, ref v) => if !f(&(k, v)) { return false },
                Nothing => ()
            }
        }
        true
    }

    fn mutate_values(&mut self, f: fn(uint, &mut T) -> bool) -> bool {
        for vec::each_mut(self.children) |child| {
            match *child {
                Internal(ref mut x) => if !x.mutate_values(f) {
                    return false
                },
                External(k, ref mut v) => if !f(k, v) { return false },
                Nothing => ()
            }
        }
        true
    }
}

// if this was done via a trait, the key could be generic
#[inline(always)]
pure fn chunk(n: uint, idx: uint) -> uint {
    let real_idx = uint::bytes - 1 - idx;
    (n >> (SHIFT * real_idx)) & MASK
}

fn insert<T>(count: &mut uint, child: &mut Child<T>, key: uint,
                   value: T, idx: uint) -> bool {
    let mut tmp = Nothing;
    tmp <-> *child;
    let mut added = false;

    *child = match tmp {
      External(stored_key, stored_value) => {
          if stored_key == key {
              External(stored_key, value)
          } else {
              // conflict - split the node
              let mut new = ~TrieNode::new();
              insert(&mut new.count,
                     &mut new.children[chunk(stored_key, idx)],
                     stored_key, stored_value, idx + 1);
              insert(&mut new.count, &mut new.children[chunk(key, idx)], key,
                     value, idx + 1);
              added = true;
              Internal(new)
          }
      }
      Internal(x) => {
        let mut x = x;
        added = insert(&mut x.count, &mut x.children[chunk(key, idx)], key,
                       value, idx + 1);
        Internal(x)

      }
      Nothing => {
        *count += 1;
        added = true;
        External(key, value)
      }
    };
    added
}

fn remove<T>(count: &mut uint, child: &mut Child<T>, key: uint,
             idx: uint) -> bool {
    let (ret, this) = match *child {
      External(stored, _) => {
          if stored == key { (true, true) } else { (false, false) }
      }
      Internal(ref mut x) => {
          let ret = remove(&mut x.count, &mut x.children[chunk(key, idx)],
                           key, idx + 1);
          (ret, x.count == 0)
      }
      Nothing => (false, false)
    };

    if this {
        *child = Nothing;
        *count -= 1;
    }
    ret
}

#[cfg(test)]
pub fn check_integrity<T>(trie: &TrieNode<T>) {
    assert trie.count != 0;

    let mut sum = 0;

    for trie.children.each |x| {
        match *x {
          Nothing => (),
          Internal(ref y) => {
              check_integrity(&**y);
              sum += 1
          }
          External(_, _) => { sum += 1 }
        }
    }

    assert sum == trie.count;
}

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

    #[test]
    fn test_step() {
        let mut trie = TrieMap::new();
        let n = 300;

        for uint::range_step(1, n, 2) |x| {
            assert trie.insert(x, x + 1);
            assert trie.contains_key(&x);
            check_integrity(&trie.root);
        }

        for uint::range_step(0, n, 2) |x| {
            assert !trie.contains_key(&x);
            assert trie.insert(x, x + 1);
            check_integrity(&trie.root);
        }

        for uint::range(0, n) |x| {
            assert trie.contains_key(&x);
            assert !trie.insert(x, x + 1);
            check_integrity(&trie.root);
        }

        for uint::range_step(1, n, 2) |x| {
            assert trie.remove(&x);
            assert !trie.contains_key(&x);
            check_integrity(&trie.root);
        }

        for uint::range_step(0, n, 2) |x| {
            assert trie.contains_key(&x);
            assert !trie.insert(x, x + 1);
            check_integrity(&trie.root);
        }
    }

    #[test]
    fn test_each() {
        let mut m = TrieMap::new();

        assert m.insert(3, 6);
        assert m.insert(0, 0);
        assert m.insert(4, 8);
        assert m.insert(2, 4);
        assert m.insert(1, 2);

        let mut n = 0;
        for m.each |&(k, v)| {
            assert k == n;
            assert *v == n * 2;
            n += 1;
        }
    }

    #[test]
    fn test_each_break() {
        let mut m = TrieMap::new();

        for uint::range_rev(uint::max_value, uint::max_value - 10000) |x| {
            m.insert(x, x / 2);
        }

        let mut n = uint::max_value - 9999;
        for m.each |&(k, v)| {
            if n == uint::max_value - 5000 { break }
            assert n < uint::max_value - 5000;

            assert k == n;
            assert *v == n / 2;
            n += 1;
        }
    }

    #[test]
    fn test_each_reverse() {
        let mut m = TrieMap::new();

        assert m.insert(3, 6);
        assert m.insert(0, 0);
        assert m.insert(4, 8);
        assert m.insert(2, 4);
        assert m.insert(1, 2);

        let mut n = 4;
        for m.each_reverse |&(k, v)| {
            assert k == n;
            assert *v == n * 2;
            n -= 1;
        }
    }

    #[test]
    fn test_each_reverse_break() {
        let mut m = TrieMap::new();

        for uint::range_rev(uint::max_value, uint::max_value - 10000) |x| {
            m.insert(x, x / 2);
        }

        let mut n = uint::max_value;
        for m.each_reverse |&(k, v)| {
            if n == uint::max_value - 5000 { break }
            assert n > uint::max_value - 5000;

            assert k == n;
            assert *v == n / 2;
            n -= 1;
        }
    }
}
<|endoftext|>