<commit_before>//! The Scene system is basically for transitioning between
//! *completely* different states that have entirely different game
//! loops and but which all share a state.  It operates as a stack, with new
//! scenes getting pushed to the stack (while the old ones stay in
//! memory unchanged).  Apparently this is basically a push-down automata.
//!
//! Also there's no reason you can't have a Scene contain its own
//! Scene subsystem to do its own indirection.  With a different state
//! type, as well!  What fun!  Though whether you want to go that deep
//! down the rabbit-hole is up to you.  I haven't found it necessary
//! yet.
//!
//! This is basically identical in concept to the Amethyst engine's scene
//! system, the only difference is the details of how the pieces are put
//! together.

use ggez;

use input;

pub enum SceneSwitch<C, Ev> {
    None,
    Push(Box<Scene<C, Ev>>),
    Replace(Box<Scene<C, Ev>>),
    Pop,
}

pub trait Scene<C, Ev> {
    fn update(&mut self, gameworld: &mut C) -> SceneSwitch<C, Ev>;
    fn draw(&mut self, gameworld: &mut C, ctx: &mut ggez::Context) -> ggez::GameResult<()>;
    fn input(&mut self, gameworld: &mut C, event: Ev, started: bool);
    /// Only used for human-readable convenience (or not at all, tbh)
    fn name(&self) -> &str;
    /// Whether or not to draw the next lowest scene on the stack as well;
    /// this is useful for GUI stuff that only partially covers the screen.
    fn draw_previous(&self) -> bool {
        false
    }
}

impl<C, Ev> SceneSwitch<C, Ev> {
    /// Convenient shortcut function for boxing scenes.
    ///
    /// Slightly nicer than writing
    /// `SceneSwitch::Replace(Box::new(x))` all the damn time.
    fn replace(scene: Box<Scene<C, Ev>>) -> Self {
        SceneSwitch::Replace(scene)
    }

    /// Same as `replace()` but returns SceneSwitch::Push
    fn push(scene: Box<Scene<C, Ev>>) -> Self {
        SceneSwitch::Push(scene)
    }
}

pub struct SceneStack<C, Ev> {
    pub world: C,
    scenes: Vec<Box<Scene<C, Ev>>>,
}

impl<C, Ev> SceneStack<C, Ev> {
    pub fn new<F>(ctx: &mut ggez::Context, creator: F) -> Self
        where F: Fn(&mut ggez::Context) -> C
    {
        let c = creator(ctx);
        Self {
            world: c,
            scenes: Vec::new(),
        }
    }

    pub fn push(&mut self, scene: Box<Scene<C, Ev>>) {
        self.scenes.push(scene)
    }

    pub fn pop(&mut self) -> Box<Scene<C, Ev>> {
        self.scenes
            .pop()
            .expect("ERROR: Popped an empty scene stack.")
    }

    pub fn current(&self) -> &Scene<C, Ev> {
        &**self.scenes
            .last()
            .expect("ERROR: Tried to get current scene of an empty scene stack.")
    }

    pub fn switch(&mut self, next_scene: SceneSwitch<C, Ev>) -> Option<Box<Scene<C, Ev>>> {
        // let operation = self.current_mut().next();
        match next_scene {
            SceneSwitch::None => None,
            SceneSwitch::Pop => {
                let s = self.pop();
                let current_name = self.current().name();
                Some(s)
            }
            SceneSwitch::Push(s) => {
                self.push(s);
                None
            }
            SceneSwitch::Replace(s) => {
                let old_scene = self.pop();
                self.push(s);
                Some(old_scene)

            }
        }
    }

    // These functions must be on the SceneStack because otherwise
    // if you try to get the current scene and the world to call
    // update() on the current scene it causes a double-borrow.  :/
    pub fn update(&mut self) {
        let next_scene = {
            let current_scene = &mut **self.scenes
                .last_mut()
                .expect("Tried to update empty scene stack");
            current_scene.update(&mut self.world)
        };
        self.switch(next_scene);
    }

    // We walk down the scene stack until we find a scene where we aren't
    // supposed to draw the previous one, then draw them from the bottom up.
    //
    // This allows for layering GUI's and such.
    fn draw_scenes(scenes: &mut [Box<Scene<C, Ev>>], world: &mut C, ctx: &mut ggez::Context) {
        if scenes.len() > 0 {
            if let Some((current, rest)) = scenes.split_last_mut() {
                if current.draw_previous() {
                    SceneStack::draw_scenes(rest, world, ctx);
                }
                current.draw(world, ctx)
                    .expect("I would hope drawing a scene never fails!");

            }
        }
    }

    pub fn draw(&mut self, ctx: &mut ggez::Context) {
        SceneStack::draw_scenes(&mut self.scenes, &mut self.world, ctx)
    }

    pub fn input(&mut self, event: Ev, started: bool) {
        let current_scene = &mut **self.scenes
            .last_mut()
            .expect("Tried to do input for empty scene stack");
        current_scene.input(&mut self.world, event, started);
    }
}

<commit_msg>Noodling about with sceneswitch objects<commit_after>//! The Scene system is basically for transitioning between
//! *completely* different states that have entirely different game
//! loops and but which all share a state.  It operates as a stack, with new
//! scenes getting pushed to the stack (while the old ones stay in
//! memory unchanged).  Apparently this is basically a push-down automata.
//!
//! Also there's no reason you can't have a Scene contain its own
//! Scene subsystem to do its own indirection.  With a different state
//! type, as well!  What fun!  Though whether you want to go that deep
//! down the rabbit-hole is up to you.  I haven't found it necessary
//! yet.
//!
//! This is basically identical in concept to the Amethyst engine's scene
//! system, the only difference is the details of how the pieces are put
//! together.

use ggez;

use input;

pub enum SceneSwitch<C, Ev> {
    None,
    Push(Box<Scene<C, Ev>>),
    Replace(Box<Scene<C, Ev>>),
    Pop,
}

pub trait Scene<C, Ev> {
    fn update(&mut self, gameworld: &mut C) -> SceneSwitch<C, Ev>;
    fn draw(&mut self, gameworld: &mut C, ctx: &mut ggez::Context) -> ggez::GameResult<()>;
    fn input(&mut self, gameworld: &mut C, event: Ev, started: bool);
    /// Only used for human-readable convenience (or not at all, tbh)
    fn name(&self) -> &str;
    /// Whether or not to draw the next lowest scene on the stack as well;
    /// this is useful for GUI stuff that only partially covers the screen.
    fn draw_previous(&self) -> bool {
        false
    }
}

impl<C, Ev> SceneSwitch<C, Ev> {
    /// Convenient shortcut function for boxing scenes.
    ///
    /// Slightly nicer than writing
    /// `SceneSwitch::Replace(Box::new(x))` all the damn time.
    pub fn replace<S>(scene: S) -> Self
        where S: Scene<C, Ev> + 'static {
        SceneSwitch::Replace(Box::new(scene))
    }

    /// Same as `replace()` but returns SceneSwitch::Push
    pub fn push<S>(scene: S) -> Self
        where S: Scene<C, Ev> + 'static {
        SceneSwitch::Push(Box::new(scene))
    }

}

pub struct SceneStack<C, Ev> {
    pub world: C,
    scenes: Vec<Box<Scene<C, Ev>>>,
}

impl<C, Ev> SceneStack<C, Ev> {
    pub fn new<F>(ctx: &mut ggez::Context, creator: F) -> Self
        where F: Fn(&mut ggez::Context) -> C
    {
        let c = creator(ctx);
        Self {
            world: c,
            scenes: Vec::new(),
        }
    }

    pub fn push(&mut self, scene: Box<Scene<C, Ev>>) {
        self.scenes.push(scene)
    }

    pub fn pop(&mut self) -> Box<Scene<C, Ev>> {
        self.scenes
            .pop()
            .expect("ERROR: Popped an empty scene stack.")
    }

    pub fn current(&self) -> &Scene<C, Ev> {
        &**self.scenes
            .last()
            .expect("ERROR: Tried to get current scene of an empty scene stack.")
    }

    pub fn switch(&mut self, next_scene: SceneSwitch<C, Ev>) -> Option<Box<Scene<C, Ev>>> {
        // let operation = self.current_mut().next();
        match next_scene {
            SceneSwitch::None => None,
            SceneSwitch::Pop => {
                let s = self.pop();
                let current_name = self.current().name();
                Some(s)
            }
            SceneSwitch::Push(s) => {
                self.push(s);
                None
            }
            SceneSwitch::Replace(s) => {
                let old_scene = self.pop();
                self.push(s);
                Some(old_scene)

            }
        }
    }

    // These functions must be on the SceneStack because otherwise
    // if you try to get the current scene and the world to call
    // update() on the current scene it causes a double-borrow.  :/
    pub fn update(&mut self) {
        let next_scene = {
            let current_scene = &mut **self.scenes
                .last_mut()
                .expect("Tried to update empty scene stack");
            current_scene.update(&mut self.world)
        };
        self.switch(next_scene);
    }

    // We walk down the scene stack until we find a scene where we aren't
    // supposed to draw the previous one, then draw them from the bottom up.
    //
    // This allows for layering GUI's and such.
    fn draw_scenes(scenes: &mut [Box<Scene<C, Ev>>], world: &mut C, ctx: &mut ggez::Context) {
        if scenes.len() > 0 {
            if let Some((current, rest)) = scenes.split_last_mut() {
                if current.draw_previous() {
                    SceneStack::draw_scenes(rest, world, ctx);
                }
                current.draw(world, ctx)
                    .expect("I would hope drawing a scene never fails!");

            }
        }
    }

    pub fn draw(&mut self, ctx: &mut ggez::Context) {
        SceneStack::draw_scenes(&mut self.scenes, &mut self.world, ctx)
    }

    pub fn input(&mut self, event: Ev, started: bool) {
        let current_scene = &mut **self.scenes
            .last_mut()
            .expect("Tried to do input for empty scene stack");
        current_scene.input(&mut self.world, event, started);
    }
}

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

    struct Thing {
        scenes: Vec<SceneStack<u32, u32>>,
    }

    #[test]
    fn test1() {
        let x = Thing { scenes: vec![] };
    }
}
<|endoftext|>


<commit_before>use parser::Node;

type Check = Result<(), CheckErrorKind>;

#[derive(Debug, Clone, PartialEq)]
pub enum CheckErrorKind {
  NotInLoop,
  MissingIf,
}

#[derive(Debug, Clone, PartialEq)]
pub struct SemChecker {
  in_loop: bool,
  has_if: bool,
}

impl SemChecker {
  pub fn new() -> SemChecker {
    SemChecker {
      in_loop: false,
      has_if: false,
    }
  }

  pub fn check(&mut self, node: &mut Node) -> Check {
    println!("checking: {:?}", node);
    match *node {
      Node::Stmt(ref mut bx) => {
        self.check(bx)?;
      }

      Node::Block(ref mut ls) | Node::Catch(ref mut ls) => for mut n in ls {
        self.check(&mut n)?;
      },

      Node::Loop { body: ref mut ls } => {
        self.in_loop = true;
        for mut n in ls {
          self.check(&mut n)?;
        }
        self.in_loop = false;
      }

      Node::Break | Node::Continue => {
        if !self.in_loop {
          return Err(CheckErrorKind::NotInLoop);
        }
      }

      _ => {}
    }

    Ok(())
  }
}
<commit_msg>semck: Add For/While checks<commit_after>use parser::Node;

type Check = Result<(), CheckErrorKind>;

#[derive(Debug, Clone, PartialEq)]
pub enum CheckErrorKind {
  NotInLoop,
  MissingIf,
}

#[derive(Debug, Clone, PartialEq)]
pub struct SemChecker {
  in_loop: bool,
  has_if: bool,
}

impl SemChecker {
  pub fn new() -> SemChecker {
    SemChecker {
      in_loop: false,
      has_if: false,
    }
  }

  pub fn check(&mut self, node: &mut Node) -> Check {
    println!("checking: {:?}", node);
    match *node {
      Node::Stmt(ref mut bx) => {
        self.check(bx)?;
      }

      Node::Block(ref mut ls) | Node::Catch(ref mut ls) => for mut n in ls {
        self.check(&mut n)?;
      },

      Node::Loop { ref mut body } => {
        self.in_loop = true;
        for mut n in body {
          self.check(&mut n)?;
        }
        self.in_loop = false;
      }

      Node::While {
        ref mut body,
        ref expr,
      } => {
        self.in_loop = true;
        for mut n in body {
          self.check(&mut n)?;
        }
        self.in_loop = false;
      }

      Node::For {
        ref mut body,
        ref decl,
        ref expr,
      } => {
        self.in_loop = true;
        for mut n in body {
          self.check(&mut n)?;
        }
        self.in_loop = false;
      }

      Node::Break | Node::Continue => {
        if !self.in_loop {
          return Err(CheckErrorKind::NotInLoop);
        }
      }

      // TODO add if-else if-else checks
      // TODO add assn checks
      _ => {}
    }

    Ok(())
  }
}
<|endoftext|>


<commit_before>/// Code based on <https://github.com/defuz/sublimate/blob/master/src/core/settings.rs>
/// released under the MIT license by @defuz
use plist::Error as PlistError;
use std::io::{Read, Seek};

pub use serde_json::Value as Settings;
pub use serde_json::Value::Array as SettingsArray;
pub use serde_json::Value::Object as SettingsObject;

pub trait FromSettings: Sized {
    fn from_settings(settings: Settings) -> Self;
}

pub trait ParseSettings: Sized {
    type Error;
    fn parse_settings(settings: Settings) -> Result<Self, Self::Error>;
}

/// An error parsing a settings file
#[derive(Debug)]
pub enum SettingsError {
    /// Incorrect Plist syntax
    Plist(PlistError),
}

impl From<PlistError> for SettingsError {
    fn from(error: PlistError) -> SettingsError {
        SettingsError::Plist(error)
    }
}

pub fn read_plist<R: Read + Seek>(reader: R) -> Result<Settings, SettingsError> {
    let settings = plist::from_reader(reader)?;
    Ok(settings)
}
<commit_msg>Remove trait FromSettings which has never been used for anything<commit_after>/// Code based on <https://github.com/defuz/sublimate/blob/master/src/core/settings.rs>
/// released under the MIT license by @defuz
use plist::Error as PlistError;
use std::io::{Read, Seek};

pub use serde_json::Value as Settings;
pub use serde_json::Value::Array as SettingsArray;
pub use serde_json::Value::Object as SettingsObject;

pub trait ParseSettings: Sized {
    type Error;
    fn parse_settings(settings: Settings) -> Result<Self, Self::Error>;
}

/// An error parsing a settings file
#[derive(Debug)]
pub enum SettingsError {
    /// Incorrect Plist syntax
    Plist(PlistError),
}

impl From<PlistError> for SettingsError {
    fn from(error: PlistError) -> SettingsError {
        SettingsError::Plist(error)
    }
}

pub fn read_plist<R: Read + Seek>(reader: R) -> Result<Settings, SettingsError> {
    let settings = plist::from_reader(reader)?;
    Ok(settings)
}
<|endoftext|>


<commit_before>use std::collections::HashMap;

use chrono::{DateTime, UTC, Timelike};
use byteorder::{WriteBytesExt, BigEndian};

use token::Token;

#[derive(Debug)]
pub enum FieldValue {
    String(String),
    Integer(i64),
    Boolean(bool),
    DateTime(DateTime<UTC>),
}

impl FieldValue {
    pub fn to_bytes(&self) -> Vec<u8> {
        match *self {
            FieldValue::String(ref string) => {
                let mut bytes = Vec::with_capacity(string.len());

                for byte in string.as_bytes() {
                    bytes.push(*byte);
                }

                bytes
            }
            FieldValue::Integer(value) => {
                let mut bytes = Vec::with_capacity(8);
                bytes.write_i64::<BigEndian>(value).unwrap();
                bytes
            }
            FieldValue::Boolean(value) => {
                if value {
                    vec![b't']
                } else {
                    vec![b'f']
                }
            }
            FieldValue::DateTime(value) => {
                let mut bytes = Vec::with_capacity(0);
                let timestamp = value.timestamp();
                let micros = value.nanosecond() / 1000;
                let timestamp_with_micros = timestamp * 1000000 + micros as i64;
                bytes.write_i64::<BigEndian>(timestamp_with_micros).unwrap();
                bytes
            }
        }
    }
}

#[derive(Debug)]
pub struct Document {
    pub key: String,
    pub indexed_fields: HashMap<String, Vec<Token>>,
    pub stored_fields: HashMap<String, FieldValue>,
}
<commit_msg>Implement FieldValue.as_json()<commit_after>use std::collections::HashMap;

use rustc_serialize::json::Json;
use chrono::{DateTime, UTC, Timelike};
use byteorder::{WriteBytesExt, BigEndian};

use token::Token;

#[derive(Debug)]
pub enum FieldValue {
    String(String),
    Integer(i64),
    Boolean(bool),
    DateTime(DateTime<UTC>),
}

impl FieldValue {
    pub fn to_bytes(&self) -> Vec<u8> {
        match *self {
            FieldValue::String(ref string) => {
                let mut bytes = Vec::with_capacity(string.len());

                for byte in string.as_bytes() {
                    bytes.push(*byte);
                }

                bytes
            }
            FieldValue::Integer(value) => {
                let mut bytes = Vec::with_capacity(8);
                bytes.write_i64::<BigEndian>(value).unwrap();
                bytes
            }
            FieldValue::Boolean(value) => {
                if value {
                    vec![b't']
                } else {
                    vec![b'f']
                }
            }
            FieldValue::DateTime(value) => {
                let mut bytes = Vec::with_capacity(0);
                let timestamp = value.timestamp();
                let micros = value.nanosecond() / 1000;
                let timestamp_with_micros = timestamp * 1000000 + micros as i64;
                bytes.write_i64::<BigEndian>(timestamp_with_micros).unwrap();
                bytes
            }
        }
    }

    pub fn as_json(&self) -> Json {
        match *self {
            FieldValue::String(ref string) => Json::String(string.clone()),
            FieldValue::Boolean(value) => Json::Boolean(value),
            FieldValue::Integer(value) => Json::I64(value),
            FieldValue::DateTime(value) => Json::String(value.to_rfc3339()),
        }
    }
}

#[derive(Debug)]
pub struct Document {
    pub key: String,
    pub indexed_fields: HashMap<String, Vec<Token>>,
    pub stored_fields: HashMap<String, FieldValue>,
}
<|endoftext|>


<commit_before>use support::{ResultTest,Tap,shell_writes};
use hamcrest::{assert_that};
use std::io::{MemWriter, BufWriter, IoResult};
use std::str::from_utf8_lossy;
use cargo::core::shell::{Shell,ShellConfig};
use term::{Terminal,TerminfoTerminal,color};

fn setup() {
}

fn writer(buf: &mut [u8]) -> Box<Writer> {
    box BufWriter::new(buf) as Box<Writer>
}

test!(non_tty {
    let config = ShellConfig { color: true, verbose: true, tty: false };
    let mut buf: Vec<u8> = Vec::from_elem(9, 0 as u8);

    Shell::create(writer(buf.as_mut_slice()), config).tap(|shell| {
        shell.say("Hey Alex", color::RED).assert();
        assert_that(buf.as_slice(), shell_writes("Hey Alex\n"));
    });
})

test!(color_explicitly_disabled {
    let config = ShellConfig { color: false, verbose: true, tty: true };
    let mut buf: Vec<u8> = Vec::from_elem(9, 0 as u8);

    Shell::create(writer(buf.as_mut_slice()), config).tap(|shell| {
        shell.say("Hey Alex", color::RED).assert();
        assert_that(buf.as_slice(), shell_writes("Hey Alex\n"));
    });
})

test!(colored_shell {
    let config = ShellConfig { color: true, verbose: true, tty: true };
    let mut buf: Vec<u8> = Vec::from_elem(100, 0 as u8);

    Shell::create(writer(buf.as_mut_slice()), config).tap(|shell| {
        shell.say("Hey Alex", color::RED).assert();
        let buf = buf.as_slice().slice_to(buf.iter().position(|a| *a == 0).unwrap());
        assert_that(buf, shell_writes(colored_output("Hey Alex\n",
                                                     color::RED).assert()));
    });
})

fn colored_output<S: Str>(string: S, color: color::Color) -> IoResult<String> {
    let mut term: TerminfoTerminal<MemWriter> =
        Terminal::new(MemWriter::new()).assert();
    try!(term.reset());
    try!(term.fg(color));
    try!(term.write_str(string.as_slice()));
    try!(term.reset());
    try!(term.flush());
    Ok(from_utf8_lossy(term.get_ref().get_ref()).to_str())
}
<commit_msg>Disable terminal tests on windows<commit_after>#![cfg(not(windows))] // getting the actual colored output is a little different
                      // on windows, so it's tough to get a reference copy of all
                      // the color

use support::{ResultTest,Tap,shell_writes};
use hamcrest::{assert_that};
use std::io::{MemWriter, BufWriter, IoResult};
use std::str::from_utf8_lossy;
use cargo::core::shell::{Shell,ShellConfig};
use term::{Terminal,TerminfoTerminal,color};

fn setup() {
}

fn writer(buf: &mut [u8]) -> Box<Writer> {
    box BufWriter::new(buf) as Box<Writer>
}

test!(non_tty {
    let config = ShellConfig { color: true, verbose: true, tty: false };
    let mut buf: Vec<u8> = Vec::from_elem(9, 0 as u8);

    Shell::create(writer(buf.as_mut_slice()), config).tap(|shell| {
        shell.say("Hey Alex", color::RED).assert();
        assert_that(buf.as_slice(), shell_writes("Hey Alex\n"));
    });
})

test!(color_explicitly_disabled {
    let config = ShellConfig { color: false, verbose: true, tty: true };
    let mut buf: Vec<u8> = Vec::from_elem(9, 0 as u8);

    Shell::create(writer(buf.as_mut_slice()), config).tap(|shell| {
        shell.say("Hey Alex", color::RED).assert();
        assert_that(buf.as_slice(), shell_writes("Hey Alex\n"));
    });
})

test!(colored_shell {
    let config = ShellConfig { color: true, verbose: true, tty: true };
    let mut buf: Vec<u8> = Vec::from_elem(100, 0 as u8);

    Shell::create(writer(buf.as_mut_slice()), config).tap(|shell| {
        shell.say("Hey Alex", color::RED).assert();
        let buf = buf.as_slice().slice_to(buf.iter().position(|a| *a == 0).unwrap());
        assert_that(buf, shell_writes(colored_output("Hey Alex\n",
                                                     color::RED).assert()));
    });
})

fn colored_output<S: Str>(string: S, color: color::Color) -> IoResult<String> {
    let mut term: TerminfoTerminal<MemWriter> =
        Terminal::new(MemWriter::new()).assert();
    try!(term.reset());
    try!(term.fg(color));
    try!(term.write_str(string.as_slice()));
    try!(term.reset());
    try!(term.flush());
    Ok(from_utf8_lossy(term.get_ref().get_ref()).to_str())
}
<|endoftext|>


<commit_before>use std::io::{Read, Write};

use result::{BfResult, Error};

/// The default number of 8-bit memory cells, as used by
/// [`State::new`](struct.State.html#method.new).
pub const DEFAULT_CAPACITY: usize = 30_000;

/// The BF machine state.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct State {
    memory: Box<[u8]>,
    pointer: usize,
}

/// The result of saving the pointer position, which allows restoring it without
/// a bounds check.
///
/// Using a saved pointer from one machine on another will result in a panic if
/// the pointer results in an out-of-bounds memory access.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct SavedPointer(usize);

impl State {
    /// Creates a new BF machine state with capacity
    /// [`DEFAULT_CAPACITY`].
    pub fn new() -> Self {
        Self::with_capacity(DEFAULT_CAPACITY)
    }

    /// Creates a new BF machine state.
    pub fn with_capacity(capacity: usize) -> Self {
        State {
            memory: vec![0; capacity].into_boxed_slice(),
            pointer: 0,
        }
    }

    /// Decrements the pointer.
    ///
    /// # Errors
    ///
    /// Panics if pointer would go below 0.
    #[inline]
    pub fn left(&mut self, count: usize) -> BfResult<()> {
        if self.pointer < count {
            Err(Error::PointerUnderflow)
        } else {
            self.pointer -= count;
            Ok(())
        }
    }

    /// Increments the pointer.
    ///
    /// # Errors
    ///
    /// Panics if pointer would go past the end of the memory.
    #[inline]
    pub fn right(&mut self, count: usize) -> BfResult<()> {
        if self.pointer + count >= self.memory.len() {
            Err(Error::PointerOverflow)
        } else {
            self.pointer += count;
            Ok(())
        }
    }

    /// Increments the byte at the pointer.
    ///
    /// Wraps around modulo 256.
    #[inline]
    pub fn up(&mut self, count: u8) {
        let old = self.load();
        self.store(old.wrapping_add(count));
    }

    /// Decrements the byte at the pointer.
    ///
    /// Wraps around modulo 256.
    #[inline]
    pub fn down(&mut self, count: u8) {
        let old = self.load();
        self.store(old.wrapping_sub(count));
    }

    /// Gets the value of the point at the pointer.
    #[inline]
    pub fn load(&self) -> u8 {
        self.memory[self.pointer]
    }

    /// Sets the value of the byte at the pointer.
    #[inline]
    pub fn store(&mut self, value: u8) {
        self.memory[self.pointer] = value;
    }

    /// Gets the current value of the pointer.
    #[inline]
    pub fn save_ptr(&self) -> SavedPointer {
        SavedPointer(self.pointer)
    }

    /// Restores a previously saved value of the pointer.
    ///
    /// # Errors
    ///
    /// Does not panic if the pointer is out of bounds, but the next memory
    /// access will panic.
    #[inline]
    pub fn restore_ptr(&mut self, old: SavedPointer) {
        self.pointer = old.0;
    }

    /// Reads from a `Read` into the byte at the pointer.
    #[inline]
    pub fn read<R: Read>(&mut self, input: &mut R) {
        let mut byte = [0];
        let _ = input.read_exact(&mut byte);
        self.store(byte[0]);
    }

    /// Writes to a `Write` from the byte at the pointer.
    #[inline]
    pub fn write<W: Write>(&self, output: &mut W) {
        let _ = output.write_all(&[self.load()]);
    }
}

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

    #[test]
    fn right_moves_right() {
        let mut actual = make(&[0, 0, 0], 0);
        let expected = make(&[0, 0, 0], 1);

        actual.right(1).unwrap();

        assert_eq!(actual, expected);
    }

    #[test]
    fn right_then_left_restores() {
        let mut actual = make(&[0, 0, 0], 0);
        let expected = make(&[0, 0, 0], 0);

        actual.right(1).unwrap();
        actual.left(1).unwrap();

        assert_eq!(actual, expected);
    }

    #[test]
    fn up_goes_to_1() {
        let mut actual = make(&[0, 0, 0], 0);
        actual.up(1);
        assert_eq!(actual, make(&[1, 0, 0], 0))
    }

    #[test]
    fn down_goes_to_255() {
        let mut actual = make(&[0, 0, 0], 0);
        actual.down(1);
        assert_eq!(actual, make(&[255, 0, 0], 0))
    }

    #[test]
    fn load_reads() {
        assert_eq!(make(&[0, 0, 0], 0).load(), 0);
        assert_eq!(make(&[1, 0, 0], 0).load(), 1);
        assert_eq!(make(&[1, 2, 0], 1).load(), 2);
    }

    #[test]
    fn store_writes() {
        let mut actual = make(&[0, 0, 0], 0);
        actual.store(5);
        assert_eq!(actual, make(&[5, 0, 0], 0));
        actual.right(1).unwrap();
        actual.store(8);
        assert_eq!(actual, make(&[5, 8, 0], 1));
    }

    #[test]
    fn longer_sequence_of_actions() {
        let mut actual = make(&[0, 0, 0], 0);
        actual.up(1);
        assert_eq!(actual, make(&[1, 0, 0], 0));
        actual.up(1);
        assert_eq!(actual, make(&[2, 0, 0], 0));
        actual.right(1).unwrap();
        assert_eq!(actual, make(&[2, 0, 0], 1));
        actual.down(1);
        assert_eq!(actual, make(&[2, 255, 0], 1));
        actual.down(1);
        assert_eq!(actual, make(&[2, 254, 0], 1));
        actual.right(1).unwrap();
        assert_eq!(actual, make(&[2, 254, 0], 2));
        actual.store(77);
        assert_eq!(actual, make(&[2, 254, 77], 2));
    }

    #[test]
    fn right_to_right_edge_is_okay() {
        let mut actual = make(&[0, 0, 0], 0);
        actual.right(1).unwrap();
        actual.right(1).unwrap();
        assert_eq!(actual, make(&[0, 0, 0], 2));
    }

    #[test]
    #[should_panic]
    fn right_past_edge_is_error() {
        let mut actual = make(&[0, 0, 0], 0);
        actual.right(1).unwrap();
        actual.right(1).unwrap();
        actual.right(1).unwrap();
    }

    #[test]
    #[should_panic]
    fn move_left_is_error() {
        let mut machine = make(&[0, 0, 0], 0);
        machine.left(1).unwrap();
    }

    fn make(memory: &[u8], pointer: usize) -> State {
        State {
            memory: memory.to_vec().into_boxed_slice(),
            pointer: pointer,
        }
    }
}
<commit_msg>Fixed error description for State::left and State::right.<commit_after>use std::io::{Read, Write};

use result::{BfResult, Error};

/// The default number of 8-bit memory cells, as used by
/// [`State::new`](struct.State.html#method.new).
pub const DEFAULT_CAPACITY: usize = 30_000;

/// The BF machine state.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct State {
    memory: Box<[u8]>,
    pointer: usize,
}

/// The result of saving the pointer position, which allows restoring it without
/// a bounds check.
///
/// Using a saved pointer from one machine on another will result in a panic if
/// the pointer results in an out-of-bounds memory access.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct SavedPointer(usize);

impl State {
    /// Creates a new BF machine state with capacity
    /// [`DEFAULT_CAPACITY`].
    pub fn new() -> Self {
        Self::with_capacity(DEFAULT_CAPACITY)
    }

    /// Creates a new BF machine state.
    pub fn with_capacity(capacity: usize) -> Self {
        State {
            memory: vec![0; capacity].into_boxed_slice(),
            pointer: 0,
        }
    }

    /// Decrements the pointer.
    ///
    /// # Errors
    ///
    /// Return `Err` if pointer would go below 0.
    #[inline]
    pub fn left(&mut self, count: usize) -> BfResult<()> {
        if self.pointer >= count {
            self.pointer -= count;
            Ok(())
        } else {
            Err(Error::PointerUnderflow)
        }
    }

    /// Increments the pointer.
    ///
    /// # Errors
    ///
    /// Return `Err` if pointer would go past the end of the memory.
    #[inline]
    pub fn right(&mut self, count: usize) -> BfResult<()> {
        if self.pointer + count < self.memory.len() {
            self.pointer += count;
            Ok(())
        } else {
            Err(Error::PointerOverflow)
        }
    }

    /// Increments the byte at the pointer.
    ///
    /// Wraps around modulo 256.
    #[inline]
    pub fn up(&mut self, count: u8) {
        let old = self.load();
        self.store(old.wrapping_add(count));
    }

    /// Decrements the byte at the pointer.
    ///
    /// Wraps around modulo 256.
    #[inline]
    pub fn down(&mut self, count: u8) {
        let old = self.load();
        self.store(old.wrapping_sub(count));
    }

    /// Gets the value of the point at the pointer.
    #[inline]
    pub fn load(&self) -> u8 {
        self.memory[self.pointer]
    }

    /// Sets the value of the byte at the pointer.
    #[inline]
    pub fn store(&mut self, value: u8) {
        self.memory[self.pointer] = value;
    }

    /// Gets the current value of the pointer.
    #[inline]
    pub fn save_ptr(&self) -> SavedPointer {
        SavedPointer(self.pointer)
    }

    /// Restores a previously saved value of the pointer.
    ///
    /// # Errors
    ///
    /// Does not panic if the pointer is out of bounds, but the next memory
    /// access will panic.
    #[inline]
    pub fn restore_ptr(&mut self, old: SavedPointer) {
        self.pointer = old.0;
    }

    /// Reads from a `Read` into the byte at the pointer.
    #[inline]
    pub fn read<R: Read>(&mut self, input: &mut R) {
        let mut byte = [0];
        let _ = input.read_exact(&mut byte);
        self.store(byte[0]);
    }

    /// Writes to a `Write` from the byte at the pointer.
    #[inline]
    pub fn write<W: Write>(&self, output: &mut W) {
        let _ = output.write_all(&[self.load()]);
    }
}

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

    #[test]
    fn right_moves_right() {
        let mut actual = make(&[0, 0, 0], 0);
        let expected = make(&[0, 0, 0], 1);

        actual.right(1).unwrap();

        assert_eq!(actual, expected);
    }

    #[test]
    fn right_then_left_restores() {
        let mut actual = make(&[0, 0, 0], 0);
        let expected = make(&[0, 0, 0], 0);

        actual.right(1).unwrap();
        actual.left(1).unwrap();

        assert_eq!(actual, expected);
    }

    #[test]
    fn up_goes_to_1() {
        let mut actual = make(&[0, 0, 0], 0);
        actual.up(1);
        assert_eq!(actual, make(&[1, 0, 0], 0))
    }

    #[test]
    fn down_goes_to_255() {
        let mut actual = make(&[0, 0, 0], 0);
        actual.down(1);
        assert_eq!(actual, make(&[255, 0, 0], 0))
    }

    #[test]
    fn load_reads() {
        assert_eq!(make(&[0, 0, 0], 0).load(), 0);
        assert_eq!(make(&[1, 0, 0], 0).load(), 1);
        assert_eq!(make(&[1, 2, 0], 1).load(), 2);
    }

    #[test]
    fn store_writes() {
        let mut actual = make(&[0, 0, 0], 0);
        actual.store(5);
        assert_eq!(actual, make(&[5, 0, 0], 0));
        actual.right(1).unwrap();
        actual.store(8);
        assert_eq!(actual, make(&[5, 8, 0], 1));
    }

    #[test]
    fn longer_sequence_of_actions() {
        let mut actual = make(&[0, 0, 0], 0);
        actual.up(1);
        assert_eq!(actual, make(&[1, 0, 0], 0));
        actual.up(1);
        assert_eq!(actual, make(&[2, 0, 0], 0));
        actual.right(1).unwrap();
        assert_eq!(actual, make(&[2, 0, 0], 1));
        actual.down(1);
        assert_eq!(actual, make(&[2, 255, 0], 1));
        actual.down(1);
        assert_eq!(actual, make(&[2, 254, 0], 1));
        actual.right(1).unwrap();
        assert_eq!(actual, make(&[2, 254, 0], 2));
        actual.store(77);
        assert_eq!(actual, make(&[2, 254, 77], 2));
    }

    #[test]
    fn right_to_right_edge_is_okay() {
        let mut actual = make(&[0, 0, 0], 0);
        actual.right(1).unwrap();
        actual.right(1).unwrap();
        assert_eq!(actual, make(&[0, 0, 0], 2));
    }

    #[test]
    #[should_panic]
    fn right_past_edge_is_error() {
        let mut actual = make(&[0, 0, 0], 0);
        actual.right(1).unwrap();
        actual.right(1).unwrap();
        actual.right(1).unwrap();
    }

    #[test]
    #[should_panic]
    fn move_left_is_error() {
        let mut machine = make(&[0, 0, 0], 0);
        machine.left(1).unwrap();
    }

    fn make(memory: &[u8], pointer: usize) -> State {
        State {
            memory: memory.to_vec().into_boxed_slice(),
            pointer: pointer,
        }
    }
}
<|endoftext|>


<commit_before>use std::{ u16, u32 };
use std::num::Int;

use store::Store::{ Array, Bitmap };

pub enum Store {
    Array(Vec<u16>),
    Bitmap([u32; 2048]),
}

impl Store {
    pub fn insert(&mut self, index: u16) -> bool {
        match self {
            &Array(ref mut vec) => {
                vec.binary_search_by(|elem| elem.cmp(&index))
                    .map_err(|loc| vec.insert(loc, index))
                    .is_err()
            },
            &Bitmap(ref mut bits) => {
                let (key, bit) = bitmap_location(index);
                if bits[key] & (1 << bit) == 0 {
                    bits[key] |= 1 << bit;
                    true
                } else {
                    false
                }
            },
        }
    }

    pub fn remove(&mut self, index: u16) -> bool {
        match self {
            &Array(ref mut vec) => {
                vec.binary_search_by(|elem| elem.cmp(&index))
                    .map(|loc| vec.remove(loc))
                    .is_ok()
            },
            &Bitmap(ref mut bits) => {
                let (key, bit) = bitmap_location(index);
                if bits[key] & (1 << bit) != 0 {
                    bits[key] &= !(1 << bit);
                    true
                } else {
                    false
                }
            },
        }
    }

    pub fn contains(&self, index: u16) -> bool {
        match self {
            &Array(ref vec) => {
                vec.binary_search_by(|elem| elem.cmp(&index)).is_ok()
            },
            &Bitmap(ref bits) => {
                let (key, bit) = bitmap_location(index);
                bits[key] & (1 << bit) != 0
            },
        }
    }

    pub fn is_disjoint(&self, other: &Self) -> bool {
        match (self, other) {
            (&Array(ref vec1), &Array(ref vec2)) => {
                let (mut i1, mut i2) = (vec1.iter(), vec2.iter());
                let (mut value1, mut value2) = (i1.next(), i2.next());
                loop {
                    match (value1, value2) {
                        (None, _) | (_, None) => return true,
                        (v1, v2) if v1 == v2 => return false,
                        (v1, v2) if v1 < v2 => value1 = i1.next(),
                        (v1, v2) if v1 > v2 => value2 = i2.next(),
                        (_, _) => panic!(),
                    }
                }
            },
            (&Bitmap(ref bits1), &Bitmap(ref bits2)) => {
                for (index1, index2) in bits1.iter().zip(bits2.iter()) {
                    if *index1 & *index2 != 0 {
                        return false;
                    }
                }
                return true;
            },
            (&Array(ref vec), store @ &Bitmap(..)) | (store @ &Bitmap(..), &Array(ref vec)) => {
                for &index in vec.iter() {
                    if store.contains(index) {
                        return false;
                    }
                }
                return true;
            },
        }
    }

    pub fn is_subset(&self, other: &Self) -> bool {
        match (self, other) {
            (&Array(ref vec1), &Array(ref vec2)) => {
                let (mut i1, mut i2) = (vec1.iter(), vec2.iter());
                let (mut value1, mut value2) = (i1.next(), i2.next());
                loop {
                    match (value1, value2) {
                        (None, _) => return true,
                        (_, None) => return false,
                        (v1, v2) if v1 == v2 => {
                            value1 = i1.next();
                            value2 = i2.next();
                        },
                        (v1, v2) if v1 < v2 => return false,
                        (v1, v2) if v1 > v2 => value2 = i2.next(),
                        (_, _) => panic!(),
                    }
                }
            },
            (&Bitmap(ref bits1), &Bitmap(ref bits2)) => {
                for (index1, index2) in bits1.iter().zip(bits2.iter()) {
                    if *index1 & *index2 != *index1 {
                        return false;
                    }
                }
                return true;
            },
            (&Array(ref vec), store @ &Bitmap(..)) => {
                for &index in vec.iter() {
                    if !store.contains(index) {
                        return false;
                    }
                }
                return true;
            },
            (&Bitmap(..), &Array(..)) => false,
        }
    }

    pub fn to_array(&self) -> Self {
        match self {
            &Array(..) => panic!("Cannot convert array to array"),
            &Bitmap(ref bits) => {
                let mut vec = Vec::new();
                for (key, val) in bits.iter().map(|v| *v).enumerate() {
                    if val == 0 {
                        continue
                    }
                    for bit in 0..(u32::BITS) {
                        if (val & (1 << bit)) != 0 {
                            vec.push((key * u32::BITS + bit) as u16);
                        }
                    }
                }
                Array(vec)
            },
        }
    }

    pub fn to_bitmap(&self) -> Self {
        match self {
            &Array(ref vec) => {
                let mut bits = [0; 2048];
                for index in vec.iter() {
                    let (key, bit) = bitmap_location(*index);
                    bits[key] |= 1 << bit;
                }
                Bitmap(bits)
            },
            &Bitmap(..) => panic!("Cannot convert bitmap to bitmap"),
        }
    }

    pub fn union_with(&mut self, other: &Self) {
        match (self, other) {
            (ref mut this, &Array(ref vec)) => {
                for &index in vec.iter() {
                    this.insert(index);
                }
            },
            (&Bitmap(ref mut bits1), &Bitmap(ref bits2)) => {
                for (index1, &index2) in bits1.iter_mut().zip(bits2.iter()) {
                    *index1 |= index2;
                }
            },
            (this @ &Array(..), &Bitmap(..)) => {
                *this = this.to_bitmap();
                this.union_with(other);
            },
        }
    }

    pub fn intersect_with(&mut self, other: &Self) {
        match (self, other) {
            (&Array(ref mut vec1), &Array(ref vec2)) => {
                let mut i1 = 0u;
                let mut iter2 = vec2.iter();
                let mut current2 = iter2.next();
                while i1 < vec1.len() {
                    match (vec1[i1], current2) {
                        (_, None) => { vec1.remove(i1); },
                        (ref val1, Some(val2)) if val1 < val2 => { vec1.remove(i1); },
                        (ref val1, Some(val2)) if val1 > val2 => { current2 = iter2.next(); },
                        (ref val1, Some(val2)) if val1 == val2 => {
                            i1 += 1;
                            current2 = iter2.next();
                        },
                        _ => panic!("Should not be possible to get here"),
                    }
                }
            },
            (&Bitmap(ref mut bits1), &Bitmap(ref bits2)) => {
                for (index1, index2) in bits1.iter_mut().zip(bits2.iter()) {
                    *index1 &= *index2;
                }
            },
            (&Array(ref mut vec), store @ &Bitmap(..)) => {
                let mut i = 0;
                while i < vec.len() {
                    if store.contains(vec[i]) {
                        i += 1;
                    } else {
                        vec.remove(i);
                    }
                }
            },
            (this @ &Bitmap(..), &Array(..)) => {
                *this = this.to_array();
                this.intersect_with(other);
            },
        }
    }

    pub fn difference_with(&mut self, other: &Self) {
        match (self, other) {
            (ref mut this @ _, &Array(ref vec2)) => {
                for index in vec2.iter() {
                    this.remove(*index);
                }
            },
            (&Bitmap(ref mut bits1), &Bitmap(ref bits2)) => {
                for (index1, index2) in bits1.iter_mut().zip(bits2.iter()) {
                    *index1 &= !*index2;
                }
            },
            (&Array(ref mut vec), store @ &Bitmap(..)) => {
                for i in range(0, vec.len()).rev() {
                    if store.contains(vec[i]) {
                        vec.remove(i);
                    }
                }
            },
        }
    }

    pub fn symmetric_difference_with(&mut self, other: &Self) {
        match (self, other) {
            (ref mut this, &Array(ref vec2)) => {
                for index in vec2.iter() {
                    if this.contains(*index) {
                        this.remove(*index);
                    } else {
                        this.insert(*index);
                    }
                }
            },
            (&Bitmap(ref mut bits1), &Bitmap(ref bits2)) => {
                for (index1, index2) in bits1.iter_mut().zip(bits2.iter()) {
                    *index1 ^= *index2;
                }
            },
            (this @ &Array(..), &Bitmap(..)) => {
                *this = this.to_bitmap();
                this.symmetric_difference_with(other);
            },
        }
    }

    pub fn len(&self) -> u16 {
        match self {
            &Array(ref vec) => vec.len() as u16,
            &Bitmap(ref bits) => {
                let mut len = 0;
                for bit in bits.iter() {
                    len += bit.count_ones()
                }
                len as u16
            },
        }
    }

    pub fn min(&self) -> u16 {
        match self {
            &Array(ref vec) => vec[0],
            &Bitmap(ref bits) => {
                for (index, bit) in bits.iter().enumerate() {
                    if *bit != 0 {
                        return (index * u32::BITS + bit.leading_zeros()) as u16;
                    }
                }
                return u16::MIN;
            },
        }
    }

    pub fn max(&self) -> u16 {
        match self {
            &Array(ref vec) => vec[vec.len() - 1],
            &Bitmap(ref bits) => {
                for (index, bit) in bits.iter().enumerate().rev() {
                    if *bit != 0 {
                        return ((index + 1) * u32::BITS - bit.trailing_zeros()) as u16;
                    }
                }
                return u16::MAX;
            },
        }
    }
}

impl PartialEq for Store {
    fn eq(&self, other: &Store) -> bool {
        match (self, other) {
            (&Array(ref vec1), &Array(ref vec2)) => {
                vec1 == vec2
            },
            (&Bitmap(ref bits1), &Bitmap(ref bits2)) => {
                bits1.iter().zip(bits2.iter()).map(|(i1, i2)| i1 == i2).fold(true, |acc, n| acc & n)
            },
            _ => false,
        }
    }
}

impl Clone for Store {
    fn clone(&self) -> Self {
        match self {
            &Array(ref vec) => Array(vec.clone()),
            &Bitmap(ref bits) => {
                let mut new_bits = [0u32; 2048];
                for (i1, &i2) in new_bits.iter_mut().zip(bits.iter()) {
                    *i1 = i2;
                }
                Bitmap(new_bits)
            },
        }
    }
}

#[inline]
fn bitmap_location(index: u16) -> (uint, uint) {
    ((index / (u32::BITS as u16)) as uint, (index % (u32::BITS as u16)) as uint)
}
<commit_msg>Replace binary_search_by with binary_search in store<commit_after>use std::{ u16, u32 };
use std::num::Int;

use store::Store::{ Array, Bitmap };

pub enum Store {
    Array(Vec<u16>),
    Bitmap([u32; 2048]),
}

impl Store {
    pub fn insert(&mut self, index: u16) -> bool {
        match self {
            &Array(ref mut vec) => {
                vec.binary_search(&index)
                    .map_err(|loc| vec.insert(loc, index))
                    .is_err()
            },
            &Bitmap(ref mut bits) => {
                let (key, bit) = bitmap_location(index);
                if bits[key] & (1 << bit) == 0 {
                    bits[key] |= 1 << bit;
                    true
                } else {
                    false
                }
            },
        }
    }

    pub fn remove(&mut self, index: u16) -> bool {
        match self {
            &Array(ref mut vec) => {
                vec.binary_search(&index)
                    .map(|loc| vec.remove(loc))
                    .is_ok()
            },
            &Bitmap(ref mut bits) => {
                let (key, bit) = bitmap_location(index);
                if bits[key] & (1 << bit) != 0 {
                    bits[key] &= !(1 << bit);
                    true
                } else {
                    false
                }
            },
        }
    }

    pub fn contains(&self, index: u16) -> bool {
        match self {
            &Array(ref vec) => {
                vec.binary_search(&index).is_ok()
            },
            &Bitmap(ref bits) => {
                let (key, bit) = bitmap_location(index);
                bits[key] & (1 << bit) != 0
            },
        }
    }

    pub fn is_disjoint(&self, other: &Self) -> bool {
        match (self, other) {
            (&Array(ref vec1), &Array(ref vec2)) => {
                let (mut i1, mut i2) = (vec1.iter(), vec2.iter());
                let (mut value1, mut value2) = (i1.next(), i2.next());
                loop {
                    match (value1, value2) {
                        (None, _) | (_, None) => return true,
                        (v1, v2) if v1 == v2 => return false,
                        (v1, v2) if v1 < v2 => value1 = i1.next(),
                        (v1, v2) if v1 > v2 => value2 = i2.next(),
                        (_, _) => panic!(),
                    }
                }
            },
            (&Bitmap(ref bits1), &Bitmap(ref bits2)) => {
                for (index1, index2) in bits1.iter().zip(bits2.iter()) {
                    if *index1 & *index2 != 0 {
                        return false;
                    }
                }
                return true;
            },
            (&Array(ref vec), store @ &Bitmap(..)) | (store @ &Bitmap(..), &Array(ref vec)) => {
                for &index in vec.iter() {
                    if store.contains(index) {
                        return false;
                    }
                }
                return true;
            },
        }
    }

    pub fn is_subset(&self, other: &Self) -> bool {
        match (self, other) {
            (&Array(ref vec1), &Array(ref vec2)) => {
                let (mut i1, mut i2) = (vec1.iter(), vec2.iter());
                let (mut value1, mut value2) = (i1.next(), i2.next());
                loop {
                    match (value1, value2) {
                        (None, _) => return true,
                        (_, None) => return false,
                        (v1, v2) if v1 == v2 => {
                            value1 = i1.next();
                            value2 = i2.next();
                        },
                        (v1, v2) if v1 < v2 => return false,
                        (v1, v2) if v1 > v2 => value2 = i2.next(),
                        (_, _) => panic!(),
                    }
                }
            },
            (&Bitmap(ref bits1), &Bitmap(ref bits2)) => {
                for (index1, index2) in bits1.iter().zip(bits2.iter()) {
                    if *index1 & *index2 != *index1 {
                        return false;
                    }
                }
                return true;
            },
            (&Array(ref vec), store @ &Bitmap(..)) => {
                for &index in vec.iter() {
                    if !store.contains(index) {
                        return false;
                    }
                }
                return true;
            },
            (&Bitmap(..), &Array(..)) => false,
        }
    }

    pub fn to_array(&self) -> Self {
        match self {
            &Array(..) => panic!("Cannot convert array to array"),
            &Bitmap(ref bits) => {
                let mut vec = Vec::new();
                for (key, val) in bits.iter().map(|v| *v).enumerate() {
                    if val == 0 {
                        continue
                    }
                    for bit in 0..(u32::BITS) {
                        if (val & (1 << bit)) != 0 {
                            vec.push((key * u32::BITS + bit) as u16);
                        }
                    }
                }
                Array(vec)
            },
        }
    }

    pub fn to_bitmap(&self) -> Self {
        match self {
            &Array(ref vec) => {
                let mut bits = [0; 2048];
                for index in vec.iter() {
                    let (key, bit) = bitmap_location(*index);
                    bits[key] |= 1 << bit;
                }
                Bitmap(bits)
            },
            &Bitmap(..) => panic!("Cannot convert bitmap to bitmap"),
        }
    }

    pub fn union_with(&mut self, other: &Self) {
        match (self, other) {
            (ref mut this, &Array(ref vec)) => {
                for &index in vec.iter() {
                    this.insert(index);
                }
            },
            (&Bitmap(ref mut bits1), &Bitmap(ref bits2)) => {
                for (index1, &index2) in bits1.iter_mut().zip(bits2.iter()) {
                    *index1 |= index2;
                }
            },
            (this @ &Array(..), &Bitmap(..)) => {
                *this = this.to_bitmap();
                this.union_with(other);
            },
        }
    }

    pub fn intersect_with(&mut self, other: &Self) {
        match (self, other) {
            (&Array(ref mut vec1), &Array(ref vec2)) => {
                let mut i1 = 0u;
                let mut iter2 = vec2.iter();
                let mut current2 = iter2.next();
                while i1 < vec1.len() {
                    match (vec1[i1], current2) {
                        (_, None) => { vec1.remove(i1); },
                        (ref val1, Some(val2)) if val1 < val2 => { vec1.remove(i1); },
                        (ref val1, Some(val2)) if val1 > val2 => { current2 = iter2.next(); },
                        (ref val1, Some(val2)) if val1 == val2 => {
                            i1 += 1;
                            current2 = iter2.next();
                        },
                        _ => panic!("Should not be possible to get here"),
                    }
                }
            },
            (&Bitmap(ref mut bits1), &Bitmap(ref bits2)) => {
                for (index1, index2) in bits1.iter_mut().zip(bits2.iter()) {
                    *index1 &= *index2;
                }
            },
            (&Array(ref mut vec), store @ &Bitmap(..)) => {
                let mut i = 0;
                while i < vec.len() {
                    if store.contains(vec[i]) {
                        i += 1;
                    } else {
                        vec.remove(i);
                    }
                }
            },
            (this @ &Bitmap(..), &Array(..)) => {
                *this = this.to_array();
                this.intersect_with(other);
            },
        }
    }

    pub fn difference_with(&mut self, other: &Self) {
        match (self, other) {
            (ref mut this @ _, &Array(ref vec2)) => {
                for index in vec2.iter() {
                    this.remove(*index);
                }
            },
            (&Bitmap(ref mut bits1), &Bitmap(ref bits2)) => {
                for (index1, index2) in bits1.iter_mut().zip(bits2.iter()) {
                    *index1 &= !*index2;
                }
            },
            (&Array(ref mut vec), store @ &Bitmap(..)) => {
                for i in range(0, vec.len()).rev() {
                    if store.contains(vec[i]) {
                        vec.remove(i);
                    }
                }
            },
        }
    }

    pub fn symmetric_difference_with(&mut self, other: &Self) {
        match (self, other) {
            (ref mut this, &Array(ref vec2)) => {
                for index in vec2.iter() {
                    if this.contains(*index) {
                        this.remove(*index);
                    } else {
                        this.insert(*index);
                    }
                }
            },
            (&Bitmap(ref mut bits1), &Bitmap(ref bits2)) => {
                for (index1, index2) in bits1.iter_mut().zip(bits2.iter()) {
                    *index1 ^= *index2;
                }
            },
            (this @ &Array(..), &Bitmap(..)) => {
                *this = this.to_bitmap();
                this.symmetric_difference_with(other);
            },
        }
    }

    pub fn len(&self) -> u16 {
        match self {
            &Array(ref vec) => vec.len() as u16,
            &Bitmap(ref bits) => {
                let mut len = 0;
                for bit in bits.iter() {
                    len += bit.count_ones()
                }
                len as u16
            },
        }
    }

    pub fn min(&self) -> u16 {
        match self {
            &Array(ref vec) => vec[0],
            &Bitmap(ref bits) => {
                for (index, bit) in bits.iter().enumerate() {
                    if *bit != 0 {
                        return (index * u32::BITS + bit.leading_zeros()) as u16;
                    }
                }
                return u16::MIN;
            },
        }
    }

    pub fn max(&self) -> u16 {
        match self {
            &Array(ref vec) => vec[vec.len() - 1],
            &Bitmap(ref bits) => {
                for (index, bit) in bits.iter().enumerate().rev() {
                    if *bit != 0 {
                        return ((index + 1) * u32::BITS - bit.trailing_zeros()) as u16;
                    }
                }
                return u16::MAX;
            },
        }
    }
}

impl PartialEq for Store {
    fn eq(&self, other: &Store) -> bool {
        match (self, other) {
            (&Array(ref vec1), &Array(ref vec2)) => {
                vec1 == vec2
            },
            (&Bitmap(ref bits1), &Bitmap(ref bits2)) => {
                bits1.iter().zip(bits2.iter()).map(|(i1, i2)| i1 == i2).fold(true, |acc, n| acc & n)
            },
            _ => false,
        }
    }
}

impl Clone for Store {
    fn clone(&self) -> Self {
        match self {
            &Array(ref vec) => Array(vec.clone()),
            &Bitmap(ref bits) => {
                let mut new_bits = [0u32; 2048];
                for (i1, &i2) in new_bits.iter_mut().zip(bits.iter()) {
                    *i1 = i2;
                }
                Bitmap(new_bits)
            },
        }
    }
}

#[inline]
fn bitmap_location(index: u16) -> (uint, uint) {
    ((index / (u32::BITS as u16)) as uint, (index % (u32::BITS as u16)) as uint)
}
<|endoftext|>


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

//! An owned, growable string that enforces that its contents are valid UTF-8.

use core::prelude::*;

use core::default::Default;
use core::fmt;
use core::mem;
use core::ptr;
use core::raw::Slice;

use {Collection, Mutable};
use hash;
use str;
use str::{CharRange, StrAllocating};
use vec::Vec;

/// A growable string stored as a UTF-8 encoded buffer.
#[deriving(Clone, PartialEq, PartialOrd, Eq, Ord)]
pub struct String {
    vec: Vec<u8>,
}

impl String {
    /// Creates a new string buffer initialized with the empty string.
    #[inline]
    pub fn new() -> String {
        String {
            vec: Vec::new(),
        }
    }

    /// Creates a new string buffer with the given capacity.
    #[inline]
    pub fn with_capacity(capacity: uint) -> String {
        String {
            vec: Vec::with_capacity(capacity),
        }
    }

    /// Creates a new string buffer from length, capacity, and a pointer.
    #[inline]
    pub unsafe fn from_raw_parts(length: uint, capacity: uint, ptr: *mut u8) -> String {
        String {
            vec: Vec::from_raw_parts(length, capacity, ptr),
        }
    }

    /// Creates a new string buffer from the given string.
    #[inline]
    pub fn from_str(string: &str) -> String {
        String {
            vec: Vec::from_slice(string.as_bytes())
        }
    }

    #[allow(missing_doc)]
    #[deprecated = "obsoleted by the removal of ~str"]
    #[inline]
    pub fn from_owned_str(string: String) -> String {
        string
    }

    /// Returns the vector as a string buffer, if possible, taking care not to
    /// copy it.
    ///
    /// Returns `Err` with the original vector if the vector contains invalid
    /// UTF-8.
    #[inline]
    pub fn from_utf8(vec: Vec<u8>) -> Result<String, Vec<u8>> {
        if str::is_utf8(vec.as_slice()) {
            Ok(String { vec: vec })
        } else {
            Err(vec)
        }
    }

    /// Return the underlying byte buffer, encoded as UTF-8.
    #[inline]
    pub fn into_bytes(self) -> Vec<u8> {
        self.vec
    }

    /// Pushes the given string onto this buffer; then, returns `self` so that it can be used
    /// again.
    #[inline]
    pub fn append(mut self, second: &str) -> String {
        self.push_str(second);
        self
    }

    /// Creates a string buffer by repeating a character `length` times.
    #[inline]
    pub fn from_char(length: uint, ch: char) -> String {
        if length == 0 {
            return String::new()
        }

        let mut buf = String::new();
        buf.push_char(ch);
        let size = buf.len() * length;
        buf.reserve(size);
        for _ in range(1, length) {
            buf.push_char(ch)
        }
        buf
    }

    /// Pushes the given string onto this string buffer.
    #[inline]
    pub fn push_str(&mut self, string: &str) {
        self.vec.push_all(string.as_bytes())
    }

    /// Push `ch` onto the given string `count` times.
    #[inline]
    pub fn grow(&mut self, count: uint, ch: char) {
        for _ in range(0, count) {
            self.push_char(ch)
        }
    }

    /// Returns the number of bytes that this string buffer can hold without reallocating.
    #[inline]
    pub fn byte_capacity(&self) -> uint {
        self.vec.capacity()
    }

    /// Reserves capacity for at least `extra` additional bytes in this string buffer.
    #[inline]
    pub fn reserve_additional(&mut self, extra: uint) {
        self.vec.reserve_additional(extra)
    }

    /// Reserves capacity for at least `capacity` bytes in this string buffer.
    #[inline]
    pub fn reserve(&mut self, capacity: uint) {
        self.vec.reserve(capacity)
    }

    /// Reserves capacity for exactly `capacity` bytes in this string buffer.
    #[inline]
    pub fn reserve_exact(&mut self, capacity: uint) {
        self.vec.reserve_exact(capacity)
    }

    /// Shrinks the capacity of this string buffer to match its length.
    #[inline]
    pub fn shrink_to_fit(&mut self) {
        self.vec.shrink_to_fit()
    }

    /// Adds the given character to the end of the string.
    #[inline]
    pub fn push_char(&mut self, ch: char) {
        let cur_len = self.len();
        // This may use up to 4 bytes.
        self.vec.reserve_additional(4);

        unsafe {
            // Attempt to not use an intermediate buffer by just pushing bytes
            // directly onto this string.
            let slice = Slice {
                data: self.vec.as_ptr().offset(cur_len as int),
                len: 4,
            };
            let used = ch.encode_utf8(mem::transmute(slice));
            self.vec.set_len(cur_len + used);
        }
    }

    /// Pushes the given bytes onto this string buffer. This is unsafe because it does not check
    /// to ensure that the resulting string will be valid UTF-8.
    #[inline]
    pub unsafe fn push_bytes(&mut self, bytes: &[u8]) {
        self.vec.push_all(bytes)
    }

    /// Works with the underlying buffer as a byte slice.
    #[inline]
    pub fn as_bytes<'a>(&'a self) -> &'a [u8] {
        self.vec.as_slice()
    }

    /// Works with the underlying buffer as a mutable byte slice. Unsafe
    /// because this can be used to violate the UTF-8 property.
    #[inline]
    pub unsafe fn as_mut_bytes<'a>(&'a mut self) -> &'a mut [u8] {
        self.vec.as_mut_slice()
    }

    /// Shorten a string to the specified length (which must be <= the current length)
    #[inline]
    pub fn truncate(&mut self, len: uint) {
        assert!(self.as_slice().is_char_boundary(len));
        self.vec.truncate(len)
    }

    /// Appends a byte to this string buffer. The caller must preserve the valid UTF-8 property.
    #[inline]
    pub unsafe fn push_byte(&mut self, byte: u8) {
        self.push_bytes([byte])
    }

    /// Removes the last byte from the string buffer and returns it. Returns `None` if this string
    /// buffer is empty.
    ///
    /// The caller must preserve the valid UTF-8 property.
    #[inline]
    pub unsafe fn pop_byte(&mut self) -> Option<u8> {
        let len = self.len();
        if len == 0 {
            return None
        }

        let byte = self.as_bytes()[len - 1];
        self.vec.set_len(len - 1);
        Some(byte)
    }

    /// Removes the last character from the string buffer and returns it. Returns `None` if this
    /// string buffer is empty.
    #[inline]
    pub fn pop_char(&mut self) -> Option<char> {
        let len = self.len();
        if len == 0 {
            return None
        }

        let CharRange {ch, next} = self.as_slice().char_range_at_reverse(len);
        unsafe {
            self.vec.set_len(next);
        }
        Some(ch)
    }

    /// Removes the first byte from the string buffer and returns it. Returns `None` if this string
    /// buffer is empty.
    ///
    /// The caller must preserve the valid UTF-8 property.
    pub unsafe fn shift_byte(&mut self) -> Option<u8> {
        self.vec.shift()
    }

    /// Removes the first character from the string buffer and returns it. Returns `None` if this
    /// string buffer is empty.
    ///
    /// # Warning
    ///
    /// This is a O(n) operation as it requires copying every element in the buffer.
    pub fn shift_char (&mut self) -> Option<char> {
        let len = self.len();
        if len == 0 {
            return None
        }

        let CharRange {ch, next} = self.as_slice().char_range_at(0);
        let new_len = len - next;
        unsafe {
            ptr::copy_memory(self.vec.as_mut_ptr(), self.vec.as_ptr().offset(next as int), new_len);
            self.vec.set_len(new_len);
        }
        Some(ch)
    }

    /// Views the string buffer as a mutable sequence of bytes.
    ///
    /// Callers must preserve the valid UTF-8 property.
    pub unsafe fn as_mut_vec<'a>(&'a mut self) -> &'a mut Vec<u8> {
        &mut self.vec
    }
}

impl Collection for String {
    #[inline]
    fn len(&self) -> uint {
        self.vec.len()
    }
}

impl Mutable for String {
    #[inline]
    fn clear(&mut self) {
        self.vec.clear()
    }
}

impl FromIterator<char> for String {
    fn from_iter<I:Iterator<char>>(iterator: I) -> String {
        let mut buf = String::new();
        buf.extend(iterator);
        buf
    }
}

impl Extendable<char> for String {
    fn extend<I:Iterator<char>>(&mut self, mut iterator: I) {
        for ch in iterator {
            self.push_char(ch)
        }
    }
}

impl Str for String {
    #[inline]
    fn as_slice<'a>(&'a self) -> &'a str {
        unsafe {
            mem::transmute(self.vec.as_slice())
        }
    }
}

impl StrAllocating for String {
    #[inline]
    fn into_string(self) -> String {
        self
    }
}

impl Default for String {
    fn default() -> String {
        String::new()
    }
}

impl fmt::Show for String {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.as_slice().fmt(f)
    }
}

impl<H: hash::Writer> hash::Hash<H> for String {
    #[inline]
    fn hash(&self, hasher: &mut H) {
        self.as_slice().hash(hasher)
    }
}

impl<'a, S: Str> Equiv<S> for String {
    #[inline]
    fn equiv(&self, other: &S) -> bool {
        self.as_slice() == other.as_slice()
    }
}

impl<S: Str> Add<S, String> for String {
    fn add(&self, other: &S) -> String {
        let mut s = self.to_string();
        s.push_str(other.as_slice());
        return s;
    }
}

#[cfg(test)]
mod tests {
    use std::prelude::*;
    use test::Bencher;

    use Mutable;
    use str::{Str, StrSlice};
    use super::String;

    #[bench]
    fn bench_with_capacity(b: &mut Bencher) {
        b.iter(|| {
            String::with_capacity(100)
        });
    }

    #[bench]
    fn bench_push_str(b: &mut Bencher) {
        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
        b.iter(|| {
            let mut r = String::new();
            r.push_str(s);
        });
    }

    #[test]
    fn test_push_bytes() {
        let mut s = String::from_str("ABC");
        unsafe {
            s.push_bytes([ 'D' as u8 ]);
        }
        assert_eq!(s.as_slice(), "ABCD");
    }

    #[test]
    fn test_push_str() {
        let mut s = String::new();
        s.push_str("");
        assert_eq!(s.as_slice().slice_from(0), "");
        s.push_str("abc");
        assert_eq!(s.as_slice().slice_from(0), "abc");
        s.push_str("ประเทศไทย中华Việt Nam");
        assert_eq!(s.as_slice().slice_from(0), "abcประเทศไทย中华Việt Nam");
    }

    #[test]
    fn test_push_char() {
        let mut data = String::from_str("ประเทศไทย中");
        data.push_char('华');
        data.push_char('b'); // 1 byte
        data.push_char('¢'); // 2 byte
        data.push_char('€'); // 3 byte
        data.push_char('𤭢'); // 4 byte
        assert_eq!(data.as_slice(), "ประเทศไทย中华b¢€𤭢");
    }

    #[test]
    fn test_pop_char() {
        let mut data = String::from_str("ประเทศไทย中华b¢€𤭢");
        assert_eq!(data.pop_char().unwrap(), '𤭢'); // 4 bytes
        assert_eq!(data.pop_char().unwrap(), '€'); // 3 bytes
        assert_eq!(data.pop_char().unwrap(), '¢'); // 2 bytes
        assert_eq!(data.pop_char().unwrap(), 'b'); // 1 bytes
        assert_eq!(data.pop_char().unwrap(), '华');
        assert_eq!(data.as_slice(), "ประเทศไทย中");
    }

    #[test]
    fn test_shift_char() {
        let mut data = String::from_str("𤭢€¢b华ประเทศไทย中");
        assert_eq!(data.shift_char().unwrap(), '𤭢'); // 4 bytes
        assert_eq!(data.shift_char().unwrap(), '€'); // 3 bytes
        assert_eq!(data.shift_char().unwrap(), '¢'); // 2 bytes
        assert_eq!(data.shift_char().unwrap(), 'b'); // 1 bytes
        assert_eq!(data.shift_char().unwrap(), '华');
        assert_eq!(data.as_slice(), "ประเทศไทย中");
    }

    #[test]
    fn test_str_truncate() {
        let mut s = String::from_str("12345");
        s.truncate(5);
        assert_eq!(s.as_slice(), "12345");
        s.truncate(3);
        assert_eq!(s.as_slice(), "123");
        s.truncate(0);
        assert_eq!(s.as_slice(), "");

        let mut s = String::from_str("12345");
        let p = s.as_slice().as_ptr();
        s.truncate(3);
        s.push_str("6");
        let p_ = s.as_slice().as_ptr();
        assert_eq!(p_, p);
    }

    #[test]
    #[should_fail]
    fn test_str_truncate_invalid_len() {
        let mut s = String::from_str("12345");
        s.truncate(6);
    }

    #[test]
    #[should_fail]
    fn test_str_truncate_split_codepoint() {
        let mut s = String::from_str("\u00FC"); // ü
        s.truncate(1);
    }

    #[test]
    fn test_str_clear() {
        let mut s = String::from_str("12345");
        s.clear();
        assert_eq!(s.len(), 0);
        assert_eq!(s.as_slice(), "");
    }

    #[test]
    fn test_str_add() {
        let a = String::from_str("12345");
        let b = a + "2";
        let b = b + String::from_str("2");
        assert_eq!(b.len(), 7);
        assert_eq!(b.as_slice(), "1234522");
    }
}
<commit_msg>Optimize String::push_byte()<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! An owned, growable string that enforces that its contents are valid UTF-8.

use core::prelude::*;

use core::default::Default;
use core::fmt;
use core::mem;
use core::ptr;
use core::raw::Slice;

use {Collection, Mutable};
use hash;
use str;
use str::{CharRange, StrAllocating};
use vec::Vec;

/// A growable string stored as a UTF-8 encoded buffer.
#[deriving(Clone, PartialEq, PartialOrd, Eq, Ord)]
pub struct String {
    vec: Vec<u8>,
}

impl String {
    /// Creates a new string buffer initialized with the empty string.
    #[inline]
    pub fn new() -> String {
        String {
            vec: Vec::new(),
        }
    }

    /// Creates a new string buffer with the given capacity.
    #[inline]
    pub fn with_capacity(capacity: uint) -> String {
        String {
            vec: Vec::with_capacity(capacity),
        }
    }

    /// Creates a new string buffer from length, capacity, and a pointer.
    #[inline]
    pub unsafe fn from_raw_parts(length: uint, capacity: uint, ptr: *mut u8) -> String {
        String {
            vec: Vec::from_raw_parts(length, capacity, ptr),
        }
    }

    /// Creates a new string buffer from the given string.
    #[inline]
    pub fn from_str(string: &str) -> String {
        String {
            vec: Vec::from_slice(string.as_bytes())
        }
    }

    #[allow(missing_doc)]
    #[deprecated = "obsoleted by the removal of ~str"]
    #[inline]
    pub fn from_owned_str(string: String) -> String {
        string
    }

    /// Returns the vector as a string buffer, if possible, taking care not to
    /// copy it.
    ///
    /// Returns `Err` with the original vector if the vector contains invalid
    /// UTF-8.
    #[inline]
    pub fn from_utf8(vec: Vec<u8>) -> Result<String, Vec<u8>> {
        if str::is_utf8(vec.as_slice()) {
            Ok(String { vec: vec })
        } else {
            Err(vec)
        }
    }

    /// Return the underlying byte buffer, encoded as UTF-8.
    #[inline]
    pub fn into_bytes(self) -> Vec<u8> {
        self.vec
    }

    /// Pushes the given string onto this buffer; then, returns `self` so that it can be used
    /// again.
    #[inline]
    pub fn append(mut self, second: &str) -> String {
        self.push_str(second);
        self
    }

    /// Creates a string buffer by repeating a character `length` times.
    #[inline]
    pub fn from_char(length: uint, ch: char) -> String {
        if length == 0 {
            return String::new()
        }

        let mut buf = String::new();
        buf.push_char(ch);
        let size = buf.len() * length;
        buf.reserve(size);
        for _ in range(1, length) {
            buf.push_char(ch)
        }
        buf
    }

    /// Pushes the given string onto this string buffer.
    #[inline]
    pub fn push_str(&mut self, string: &str) {
        self.vec.push_all(string.as_bytes())
    }

    /// Push `ch` onto the given string `count` times.
    #[inline]
    pub fn grow(&mut self, count: uint, ch: char) {
        for _ in range(0, count) {
            self.push_char(ch)
        }
    }

    /// Returns the number of bytes that this string buffer can hold without reallocating.
    #[inline]
    pub fn byte_capacity(&self) -> uint {
        self.vec.capacity()
    }

    /// Reserves capacity for at least `extra` additional bytes in this string buffer.
    #[inline]
    pub fn reserve_additional(&mut self, extra: uint) {
        self.vec.reserve_additional(extra)
    }

    /// Reserves capacity for at least `capacity` bytes in this string buffer.
    #[inline]
    pub fn reserve(&mut self, capacity: uint) {
        self.vec.reserve(capacity)
    }

    /// Reserves capacity for exactly `capacity` bytes in this string buffer.
    #[inline]
    pub fn reserve_exact(&mut self, capacity: uint) {
        self.vec.reserve_exact(capacity)
    }

    /// Shrinks the capacity of this string buffer to match its length.
    #[inline]
    pub fn shrink_to_fit(&mut self) {
        self.vec.shrink_to_fit()
    }

    /// Adds the given character to the end of the string.
    #[inline]
    pub fn push_char(&mut self, ch: char) {
        let cur_len = self.len();
        // This may use up to 4 bytes.
        self.vec.reserve_additional(4);

        unsafe {
            // Attempt to not use an intermediate buffer by just pushing bytes
            // directly onto this string.
            let slice = Slice {
                data: self.vec.as_ptr().offset(cur_len as int),
                len: 4,
            };
            let used = ch.encode_utf8(mem::transmute(slice));
            self.vec.set_len(cur_len + used);
        }
    }

    /// Pushes the given bytes onto this string buffer. This is unsafe because it does not check
    /// to ensure that the resulting string will be valid UTF-8.
    #[inline]
    pub unsafe fn push_bytes(&mut self, bytes: &[u8]) {
        self.vec.push_all(bytes)
    }

    /// Works with the underlying buffer as a byte slice.
    #[inline]
    pub fn as_bytes<'a>(&'a self) -> &'a [u8] {
        self.vec.as_slice()
    }

    /// Works with the underlying buffer as a mutable byte slice. Unsafe
    /// because this can be used to violate the UTF-8 property.
    #[inline]
    pub unsafe fn as_mut_bytes<'a>(&'a mut self) -> &'a mut [u8] {
        self.vec.as_mut_slice()
    }

    /// Shorten a string to the specified length (which must be <= the current length)
    #[inline]
    pub fn truncate(&mut self, len: uint) {
        assert!(self.as_slice().is_char_boundary(len));
        self.vec.truncate(len)
    }

    /// Appends a byte to this string buffer. The caller must preserve the valid UTF-8 property.
    #[inline]
    pub unsafe fn push_byte(&mut self, byte: u8) {
        self.vec.push(byte)
    }

    /// Removes the last byte from the string buffer and returns it. Returns `None` if this string
    /// buffer is empty.
    ///
    /// The caller must preserve the valid UTF-8 property.
    #[inline]
    pub unsafe fn pop_byte(&mut self) -> Option<u8> {
        let len = self.len();
        if len == 0 {
            return None
        }

        let byte = self.as_bytes()[len - 1];
        self.vec.set_len(len - 1);
        Some(byte)
    }

    /// Removes the last character from the string buffer and returns it. Returns `None` if this
    /// string buffer is empty.
    #[inline]
    pub fn pop_char(&mut self) -> Option<char> {
        let len = self.len();
        if len == 0 {
            return None
        }

        let CharRange {ch, next} = self.as_slice().char_range_at_reverse(len);
        unsafe {
            self.vec.set_len(next);
        }
        Some(ch)
    }

    /// Removes the first byte from the string buffer and returns it. Returns `None` if this string
    /// buffer is empty.
    ///
    /// The caller must preserve the valid UTF-8 property.
    pub unsafe fn shift_byte(&mut self) -> Option<u8> {
        self.vec.shift()
    }

    /// Removes the first character from the string buffer and returns it. Returns `None` if this
    /// string buffer is empty.
    ///
    /// # Warning
    ///
    /// This is a O(n) operation as it requires copying every element in the buffer.
    pub fn shift_char (&mut self) -> Option<char> {
        let len = self.len();
        if len == 0 {
            return None
        }

        let CharRange {ch, next} = self.as_slice().char_range_at(0);
        let new_len = len - next;
        unsafe {
            ptr::copy_memory(self.vec.as_mut_ptr(), self.vec.as_ptr().offset(next as int), new_len);
            self.vec.set_len(new_len);
        }
        Some(ch)
    }

    /// Views the string buffer as a mutable sequence of bytes.
    ///
    /// Callers must preserve the valid UTF-8 property.
    pub unsafe fn as_mut_vec<'a>(&'a mut self) -> &'a mut Vec<u8> {
        &mut self.vec
    }
}

impl Collection for String {
    #[inline]
    fn len(&self) -> uint {
        self.vec.len()
    }
}

impl Mutable for String {
    #[inline]
    fn clear(&mut self) {
        self.vec.clear()
    }
}

impl FromIterator<char> for String {
    fn from_iter<I:Iterator<char>>(iterator: I) -> String {
        let mut buf = String::new();
        buf.extend(iterator);
        buf
    }
}

impl Extendable<char> for String {
    fn extend<I:Iterator<char>>(&mut self, mut iterator: I) {
        for ch in iterator {
            self.push_char(ch)
        }
    }
}

impl Str for String {
    #[inline]
    fn as_slice<'a>(&'a self) -> &'a str {
        unsafe {
            mem::transmute(self.vec.as_slice())
        }
    }
}

impl StrAllocating for String {
    #[inline]
    fn into_string(self) -> String {
        self
    }
}

impl Default for String {
    fn default() -> String {
        String::new()
    }
}

impl fmt::Show for String {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.as_slice().fmt(f)
    }
}

impl<H: hash::Writer> hash::Hash<H> for String {
    #[inline]
    fn hash(&self, hasher: &mut H) {
        self.as_slice().hash(hasher)
    }
}

impl<'a, S: Str> Equiv<S> for String {
    #[inline]
    fn equiv(&self, other: &S) -> bool {
        self.as_slice() == other.as_slice()
    }
}

impl<S: Str> Add<S, String> for String {
    fn add(&self, other: &S) -> String {
        let mut s = self.to_string();
        s.push_str(other.as_slice());
        return s;
    }
}

#[cfg(test)]
mod tests {
    use std::prelude::*;
    use test::Bencher;

    use Mutable;
    use str::{Str, StrSlice};
    use super::String;

    #[bench]
    fn bench_with_capacity(b: &mut Bencher) {
        b.iter(|| {
            String::with_capacity(100)
        });
    }

    #[bench]
    fn bench_push_str(b: &mut Bencher) {
        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
        b.iter(|| {
            let mut r = String::new();
            r.push_str(s);
        });
    }

    #[test]
    fn test_push_bytes() {
        let mut s = String::from_str("ABC");
        unsafe {
            s.push_bytes([ 'D' as u8 ]);
        }
        assert_eq!(s.as_slice(), "ABCD");
    }

    #[test]
    fn test_push_str() {
        let mut s = String::new();
        s.push_str("");
        assert_eq!(s.as_slice().slice_from(0), "");
        s.push_str("abc");
        assert_eq!(s.as_slice().slice_from(0), "abc");
        s.push_str("ประเทศไทย中华Việt Nam");
        assert_eq!(s.as_slice().slice_from(0), "abcประเทศไทย中华Việt Nam");
    }

    #[test]
    fn test_push_char() {
        let mut data = String::from_str("ประเทศไทย中");
        data.push_char('华');
        data.push_char('b'); // 1 byte
        data.push_char('¢'); // 2 byte
        data.push_char('€'); // 3 byte
        data.push_char('𤭢'); // 4 byte
        assert_eq!(data.as_slice(), "ประเทศไทย中华b¢€𤭢");
    }

    #[test]
    fn test_pop_char() {
        let mut data = String::from_str("ประเทศไทย中华b¢€𤭢");
        assert_eq!(data.pop_char().unwrap(), '𤭢'); // 4 bytes
        assert_eq!(data.pop_char().unwrap(), '€'); // 3 bytes
        assert_eq!(data.pop_char().unwrap(), '¢'); // 2 bytes
        assert_eq!(data.pop_char().unwrap(), 'b'); // 1 bytes
        assert_eq!(data.pop_char().unwrap(), '华');
        assert_eq!(data.as_slice(), "ประเทศไทย中");
    }

    #[test]
    fn test_shift_char() {
        let mut data = String::from_str("𤭢€¢b华ประเทศไทย中");
        assert_eq!(data.shift_char().unwrap(), '𤭢'); // 4 bytes
        assert_eq!(data.shift_char().unwrap(), '€'); // 3 bytes
        assert_eq!(data.shift_char().unwrap(), '¢'); // 2 bytes
        assert_eq!(data.shift_char().unwrap(), 'b'); // 1 bytes
        assert_eq!(data.shift_char().unwrap(), '华');
        assert_eq!(data.as_slice(), "ประเทศไทย中");
    }

    #[test]
    fn test_str_truncate() {
        let mut s = String::from_str("12345");
        s.truncate(5);
        assert_eq!(s.as_slice(), "12345");
        s.truncate(3);
        assert_eq!(s.as_slice(), "123");
        s.truncate(0);
        assert_eq!(s.as_slice(), "");

        let mut s = String::from_str("12345");
        let p = s.as_slice().as_ptr();
        s.truncate(3);
        s.push_str("6");
        let p_ = s.as_slice().as_ptr();
        assert_eq!(p_, p);
    }

    #[test]
    #[should_fail]
    fn test_str_truncate_invalid_len() {
        let mut s = String::from_str("12345");
        s.truncate(6);
    }

    #[test]
    #[should_fail]
    fn test_str_truncate_split_codepoint() {
        let mut s = String::from_str("\u00FC"); // ü
        s.truncate(1);
    }

    #[test]
    fn test_str_clear() {
        let mut s = String::from_str("12345");
        s.clear();
        assert_eq!(s.len(), 0);
        assert_eq!(s.as_slice(), "");
    }

    #[test]
    fn test_str_add() {
        let a = String::from_str("12345");
        let b = a + "2";
        let b = b + String::from_str("2");
        assert_eq!(b.len(), 7);
        assert_eq!(b.as_slice(), "1234522");
    }
}
<|endoftext|>


<commit_before>use core::num::{NonZeroU32, NonZeroI32};
use core::option::Option;
use core::option::Option::{Some, None};
use std::mem::size_of;

#[test]
fn test_create_nonzero_instance() {
    let _a = unsafe {
        NonZeroU32::new_unchecked(21)
    };
}

#[test]
fn test_size_nonzero_in_option() {
    assert_eq!(size_of::<NonZeroU32>(), size_of::<Option<NonZeroU32>>());
    assert_eq!(size_of::<NonZeroI32>(), size_of::<Option<NonZeroI32>>());
}

#[test]
fn test_match_on_nonzero_option() {
    let a = Some(unsafe {
        NonZeroU32::new_unchecked(42)
    });
    match a {
        Some(val) => assert_eq!(val.get(), 42),
        None => panic!("unexpected None while matching on Some(NonZeroU32(_))")
    }

    match unsafe { Some(NonZeroU32::new_unchecked(43)) } {
        Some(val) => assert_eq!(val.get(), 43),
        None => panic!("unexpected None while matching on Some(NonZeroU32(_))")
    }
}

#[test]
fn test_match_option_empty_vec() {
    let a: Option<Vec<isize>> = Some(vec![]);
    match a {
        None => panic!("unexpected None while matching on Some(vec![])"),
        _ => {}
    }
}

#[test]
fn test_match_option_vec() {
    let a = Some(vec![1, 2, 3, 4]);
    match a {
        Some(v) => assert_eq!(v, [1, 2, 3, 4]),
        None => panic!("unexpected None while matching on Some(vec![1, 2, 3, 4])")
    }
}

#[test]
fn test_match_option_rc() {
    use std::rc::Rc;

    let five = Rc::new(5);
    match Some(five) {
        Some(r) => assert_eq!(*r, 5),
        None => panic!("unexpected None while matching on Some(Rc::new(5))")
    }
}

#[test]
fn test_match_option_arc() {
    use std::sync::Arc;

    let five = Arc::new(5);
    match Some(five) {
        Some(a) => assert_eq!(*a, 5),
        None => panic!("unexpected None while matching on Some(Arc::new(5))")
    }
}

#[test]
fn test_match_option_empty_string() {
    let a = Some(String::new());
    match a {
        None => panic!("unexpected None while matching on Some(String::new())"),
        _ => {}
    }
}

#[test]
fn test_match_option_string() {
    let five = "Five".to_string();
    match Some(five) {
        Some(s) => assert_eq!(s, "Five"),
        None => panic!("unexpected None while matching on Some(String { ... })")
    }
}

mod atom {
    use core::num::NonZeroU32;

    #[derive(PartialEq, Eq)]
    pub struct Atom {
        index: NonZeroU32, // private
    }
    pub const FOO_ATOM: Atom = Atom { index: unsafe { NonZeroU32::new_unchecked(7) } };
}

macro_rules! atom {
    ("foo") => { atom::FOO_ATOM }
}

#[test]
fn test_match_nonzero_const_pattern() {
    match atom!("foo") {
        // Using as a pattern is supported by the compiler:
        atom!("foo") => {}
        _ => panic!("Expected the const item as a pattern to match.")
    }
}

#[test]
fn test_from_nonzero() {
    let nz = NonZeroU32::new(1).unwrap();
    let num: u32 = nz.into();
    assert_eq!(num, 1u32);
}

#[test]
fn test_from_signed_nonzero() {
    let nz = NonZeroI32::new(1).unwrap();
    let num: i32 = nz.into();
    assert_eq!(num, 1i32);
}

#[test]
fn test_from_str() {
    assert_eq!("123".parse::<NonZeroU8>(), Ok(NonZeroU8::new(123).unwrap()));
    assert_eq!(
        "0".parse::<NonZeroU8>(),
        Err(ParseIntError {
            kind: IntErrorKind::Zero
        })
    );
    assert_eq!(
        "-1".parse::<NonZeroU8>(),
        Err(ParseIntError {
            kind: IntErrorKind::Underflow
        })
    );
    assert_eq!(
        "129".parse::<NonZeroU8>(),
        Err(ParseIntError {
            kind: IntErrorKind::Overflow
        })
    );
}
<commit_msg>fixed nonzero tests<commit_after>use core::num::{IntErrorKind, NonZeroU8, NonZeroU32, NonZeroI32, ParseIntError};
use core::option::Option::{self, Some, None};
use std::mem::size_of;

#[test]
fn test_create_nonzero_instance() {
    let _a = unsafe {
        NonZeroU32::new_unchecked(21)
    };
}

#[test]
fn test_size_nonzero_in_option() {
    assert_eq!(size_of::<NonZeroU32>(), size_of::<Option<NonZeroU32>>());
    assert_eq!(size_of::<NonZeroI32>(), size_of::<Option<NonZeroI32>>());
}

#[test]
fn test_match_on_nonzero_option() {
    let a = Some(unsafe {
        NonZeroU32::new_unchecked(42)
    });
    match a {
        Some(val) => assert_eq!(val.get(), 42),
        None => panic!("unexpected None while matching on Some(NonZeroU32(_))")
    }

    match unsafe { Some(NonZeroU32::new_unchecked(43)) } {
        Some(val) => assert_eq!(val.get(), 43),
        None => panic!("unexpected None while matching on Some(NonZeroU32(_))")
    }
}

#[test]
fn test_match_option_empty_vec() {
    let a: Option<Vec<isize>> = Some(vec![]);
    match a {
        None => panic!("unexpected None while matching on Some(vec![])"),
        _ => {}
    }
}

#[test]
fn test_match_option_vec() {
    let a = Some(vec![1, 2, 3, 4]);
    match a {
        Some(v) => assert_eq!(v, [1, 2, 3, 4]),
        None => panic!("unexpected None while matching on Some(vec![1, 2, 3, 4])")
    }
}

#[test]
fn test_match_option_rc() {
    use std::rc::Rc;

    let five = Rc::new(5);
    match Some(five) {
        Some(r) => assert_eq!(*r, 5),
        None => panic!("unexpected None while matching on Some(Rc::new(5))")
    }
}

#[test]
fn test_match_option_arc() {
    use std::sync::Arc;

    let five = Arc::new(5);
    match Some(five) {
        Some(a) => assert_eq!(*a, 5),
        None => panic!("unexpected None while matching on Some(Arc::new(5))")
    }
}

#[test]
fn test_match_option_empty_string() {
    let a = Some(String::new());
    match a {
        None => panic!("unexpected None while matching on Some(String::new())"),
        _ => {}
    }
}

#[test]
fn test_match_option_string() {
    let five = "Five".to_string();
    match Some(five) {
        Some(s) => assert_eq!(s, "Five"),
        None => panic!("unexpected None while matching on Some(String { ... })")
    }
}

mod atom {
    use core::num::NonZeroU32;

    #[derive(PartialEq, Eq)]
    pub struct Atom {
        index: NonZeroU32, // private
    }
    pub const FOO_ATOM: Atom = Atom { index: unsafe { NonZeroU32::new_unchecked(7) } };
}

macro_rules! atom {
    ("foo") => { atom::FOO_ATOM }
}

#[test]
fn test_match_nonzero_const_pattern() {
    match atom!("foo") {
        // Using as a pattern is supported by the compiler:
        atom!("foo") => {}
        _ => panic!("Expected the const item as a pattern to match.")
    }
}

#[test]
fn test_from_nonzero() {
    let nz = NonZeroU32::new(1).unwrap();
    let num: u32 = nz.into();
    assert_eq!(num, 1u32);
}

#[test]
fn test_from_signed_nonzero() {
    let nz = NonZeroI32::new(1).unwrap();
    let num: i32 = nz.into();
    assert_eq!(num, 1i32);
}

#[test]
fn test_from_str() {
    assert_eq!("123".parse::<NonZeroU8>(), Ok(NonZeroU8::new(123).unwrap()));
    assert_eq!(
        "0".parse::<NonZeroU8>(),
        Err(ParseIntError {
            kind: IntErrorKind::Zero
        })
    );
    assert_eq!(
        "-1".parse::<NonZeroU8>(),
        Err(ParseIntError {
            kind: IntErrorKind::Underflow
        })
    );
    assert_eq!(
        "257".parse::<NonZeroU8>(),
        Err(ParseIntError {
            kind: IntErrorKind::Overflow
        })
    );
}
<|endoftext|>