<commit_before>use std::io::{self, Result};

use ByteOrder;

/// Extends `Read` with methods for reading numbers. (For `std::io`.)
///
/// Most of the methods defined here have an unconstrained type parameter that
/// must be explicitly instantiated. Typically, it is instantiated with either
/// the `BigEndian` or `LittleEndian` types defined in this crate.
///
/// # Examples
///
/// Read unsigned 16 bit big-endian integers from a `Read`:
///
/// ```rust
/// use std::io::Cursor;
/// use byteorder::{BigEndian, ReadBytesExt};
///
/// let mut rdr = Cursor::new(vec![2, 5, 3, 0]);
/// assert_eq!(517, rdr.read_u16::<BigEndian>().unwrap());
/// assert_eq!(768, rdr.read_u16::<BigEndian>().unwrap());
/// ```
pub trait ReadBytesExt: io::Read {
    /// Reads an unsigned 8 bit integer from the underlying reader.
    ///
    /// Note that since this reads a single byte, no byte order conversions
    /// are used. It is included for completeness.
    #[inline]
    fn read_u8(&mut self) -> Result<u8> {
        let mut buf = [0; 1];
        try!(self.read_exact(&mut buf));
        Ok(buf[0])
    }

    /// Reads a signed 8 bit integer from the underlying reader.
    ///
    /// Note that since this reads a single byte, no byte order conversions
    /// are used. It is included for completeness.
    #[inline]
    fn read_i8(&mut self) -> Result<i8> {
        let mut buf = [0; 1];
        try!(self.read_exact(&mut buf));
        Ok(buf[0] as i8)
    }

    /// Reads an unsigned 16 bit integer from the underlying reader.
    #[inline]
    fn read_u16<T: ByteOrder>(&mut self) -> Result<u16> {
        let mut buf = [0; 2];
        try!(self.read_exact(&mut buf));
        Ok(T::read_u16(&buf))
    }

    /// Reads a signed 16 bit integer from the underlying reader.
    #[inline]
    fn read_i16<T: ByteOrder>(&mut self) -> Result<i16> {
        let mut buf = [0; 2];
        try!(self.read_exact(&mut buf));
        Ok(T::read_i16(&buf))
    }

    /// Reads an unsigned 32 bit integer from the underlying reader.
    #[inline]
    fn read_u32<T: ByteOrder>(&mut self) -> Result<u32> {
        let mut buf = [0; 4];
        try!(self.read_exact(&mut buf));
        Ok(T::read_u32(&buf))
    }

    /// Reads a signed 32 bit integer from the underlying reader.
    #[inline]
    fn read_i32<T: ByteOrder>(&mut self) -> Result<i32> {
        let mut buf = [0; 4];
        try!(self.read_exact(&mut buf));
        Ok(T::read_i32(&buf))
    }

    /// Reads an unsigned 64 bit integer from the underlying reader.
    #[inline]
    fn read_u64<T: ByteOrder>(&mut self) -> Result<u64> {
        let mut buf = [0; 8];
        try!(self.read_exact(&mut buf));
        Ok(T::read_u64(&buf))
    }

    /// Reads a signed 64 bit integer from the underlying reader.
    #[inline]
    fn read_i64<T: ByteOrder>(&mut self) -> Result<i64> {
        let mut buf = [0; 8];
        try!(self.read_exact(&mut buf));
        Ok(T::read_i64(&buf))
    }

    /// Reads an unsigned n-bytes integer from the underlying reader.
    #[inline]
    fn read_uint<T: ByteOrder>(&mut self, nbytes: usize) -> Result<u64> {
        let mut buf = [0; 8];
        try!(self.read_exact(&mut buf[..nbytes]));
        Ok(T::read_uint(&buf[..nbytes], nbytes))
    }

    /// Reads a signed n-bytes integer from the underlying reader.
    #[inline]
    fn read_int<T: ByteOrder>(&mut self, nbytes: usize) -> Result<i64> {
        let mut buf = [0; 8];
        try!(self.read_exact(&mut buf[..nbytes]));
        Ok(T::read_int(&buf[..nbytes], nbytes))
    }

    /// Reads a IEEE754 single-precision (4 bytes) floating point number from
    /// the underlying reader.
    #[inline]
    fn read_f32<T: ByteOrder>(&mut self) -> Result<f32> {
        let mut buf = [0; 4];
        try!(self.read_exact(&mut buf));
        Ok(T::read_f32(&buf))
    }

    /// Reads a IEEE754 double-precision (8 bytes) floating point number from
    /// the underlying reader.
    #[inline]
    fn read_f64<T: ByteOrder>(&mut self) -> Result<f64> {
        let mut buf = [0; 8];
        try!(self.read_exact(&mut buf));
        Ok(T::read_f64(&buf))
    }
}

/// All types that implement `Read` get methods defined in `ReadBytesExt`
/// for free.
impl<R: io::Read + ?Sized> ReadBytesExt for R {}

fn write_all<W: io::Write + ?Sized>(wtr: &mut W, buf: &[u8]) -> Result<()> {
    wtr.write_all(buf).map_err(From::from)
}

/// Extends `Write` with methods for writing numbers. (For `std::io`.)
///
/// Most of the methods defined here have an unconstrained type parameter that
/// must be explicitly instantiated. Typically, it is instantiated with either
/// the `BigEndian` or `LittleEndian` types defined in this crate.
///
/// # Examples
///
/// Write unsigned 16 bit big-endian integers to a `Write`:
///
/// ```rust
/// use byteorder::{BigEndian, WriteBytesExt};
///
/// let mut wtr = vec![];
/// wtr.write_u16::<BigEndian>(517).unwrap();
/// wtr.write_u16::<BigEndian>(768).unwrap();
/// assert_eq!(wtr, vec![2, 5, 3, 0]);
/// ```
pub trait WriteBytesExt: io::Write {
    /// Writes an unsigned 8 bit integer to the underlying writer.
    ///
    /// Note that since this writes a single byte, no byte order conversions
    /// are used. It is included for completeness.
    #[inline]
    fn write_u8(&mut self, n: u8) -> Result<()> {
        write_all(self, &[n])
    }

    /// Writes a signed 8 bit integer to the underlying writer.
    ///
    /// Note that since this writes a single byte, no byte order conversions
    /// are used. It is included for completeness.
    #[inline]
    fn write_i8(&mut self, n: i8) -> Result<()> {
        write_all(self, &[n as u8])
    }

    /// Writes an unsigned 16 bit integer to the underlying writer.
    #[inline]
    fn write_u16<T: ByteOrder>(&mut self, n: u16) -> Result<()> {
        let mut buf = [0; 2];
        T::write_u16(&mut buf, n);
        write_all(self, &buf)
    }

    /// Writes a signed 16 bit integer to the underlying writer.
    #[inline]
    fn write_i16<T: ByteOrder>(&mut self, n: i16) -> Result<()> {
        let mut buf = [0; 2];
        T::write_i16(&mut buf, n);
        write_all(self, &buf)
    }

    /// Writes an unsigned 32 bit integer to the underlying writer.
    #[inline]
    fn write_u32<T: ByteOrder>(&mut self, n: u32) -> Result<()> {
        let mut buf = [0; 4];
        T::write_u32(&mut buf, n);
        write_all(self, &buf)
    }

    /// Writes a signed 32 bit integer to the underlying writer.
    #[inline]
    fn write_i32<T: ByteOrder>(&mut self, n: i32) -> Result<()> {
        let mut buf = [0; 4];
        T::write_i32(&mut buf, n);
        write_all(self, &buf)
    }

    /// Writes an unsigned 64 bit integer to the underlying writer.
    #[inline]
    fn write_u64<T: ByteOrder>(&mut self, n: u64) -> Result<()> {
        let mut buf = [0; 8];
        T::write_u64(&mut buf, n);
        write_all(self, &buf)
    }

    /// Writes a signed 64 bit integer to the underlying writer.
    #[inline]
    fn write_i64<T: ByteOrder>(&mut self, n: i64) -> Result<()> {
        let mut buf = [0; 8];
        T::write_i64(&mut buf, n);
        write_all(self, &buf)
    }

    /// Writes an unsigned n-bytes integer to the underlying writer.
    ///
    /// If the given integer is not representable in the given number of bytes,
    /// this method panics. If `nbytes > 8`, this method panics.
    #[inline]
    fn write_uint<T: ByteOrder>(
        &mut self,
        n: u64,
        nbytes: usize,
    ) -> Result<()> {
        let mut buf = [0; 8];
        T::write_uint(&mut buf, n, nbytes);
        write_all(self, &buf[0..nbytes])
    }

    /// Writes a signed n-bytes integer to the underlying writer.
    ///
    /// If the given integer is not representable in the given number of bytes,
    /// this method panics. If `nbytes > 8`, this method panics.
    #[inline]
    fn write_int<T: ByteOrder>(
        &mut self,
        n: i64,
        nbytes: usize,
    ) -> Result<()> {
        let mut buf = [0; 8];
        T::write_int(&mut buf, n, nbytes);
        write_all(self, &buf[0..nbytes])
    }

    /// Writes a IEEE754 single-precision (4 bytes) floating point number to
    /// the underlying writer.
    #[inline]
    fn write_f32<T: ByteOrder>(&mut self, n: f32) -> Result<()> {
        let mut buf = [0; 4];
        T::write_f32(&mut buf, n);
        write_all(self, &buf)
    }

    /// Writes a IEEE754 double-precision (8 bytes) floating point number to
    /// the underlying writer.
    #[inline]
    fn write_f64<T: ByteOrder>(&mut self, n: f64) -> Result<()> {
        let mut buf = [0; 8];
        T::write_f64(&mut buf, n);
        write_all(self, &buf)
    }
}

/// All types that implement `Write` get methods defined in `WriteBytesExt`
/// for free.
impl<W: io::Write + ?Sized> WriteBytesExt for W {}
<commit_msg>remove unnecessary write_all implementation<commit_after>use std::io::{self, Result};

use ByteOrder;

/// Extends `Read` with methods for reading numbers. (For `std::io`.)
///
/// Most of the methods defined here have an unconstrained type parameter that
/// must be explicitly instantiated. Typically, it is instantiated with either
/// the `BigEndian` or `LittleEndian` types defined in this crate.
///
/// # Examples
///
/// Read unsigned 16 bit big-endian integers from a `Read`:
///
/// ```rust
/// use std::io::Cursor;
/// use byteorder::{BigEndian, ReadBytesExt};
///
/// let mut rdr = Cursor::new(vec![2, 5, 3, 0]);
/// assert_eq!(517, rdr.read_u16::<BigEndian>().unwrap());
/// assert_eq!(768, rdr.read_u16::<BigEndian>().unwrap());
/// ```
pub trait ReadBytesExt: io::Read {
    /// Reads an unsigned 8 bit integer from the underlying reader.
    ///
    /// Note that since this reads a single byte, no byte order conversions
    /// are used. It is included for completeness.
    #[inline]
    fn read_u8(&mut self) -> Result<u8> {
        let mut buf = [0; 1];
        try!(self.read_exact(&mut buf));
        Ok(buf[0])
    }

    /// Reads a signed 8 bit integer from the underlying reader.
    ///
    /// Note that since this reads a single byte, no byte order conversions
    /// are used. It is included for completeness.
    #[inline]
    fn read_i8(&mut self) -> Result<i8> {
        let mut buf = [0; 1];
        try!(self.read_exact(&mut buf));
        Ok(buf[0] as i8)
    }

    /// Reads an unsigned 16 bit integer from the underlying reader.
    #[inline]
    fn read_u16<T: ByteOrder>(&mut self) -> Result<u16> {
        let mut buf = [0; 2];
        try!(self.read_exact(&mut buf));
        Ok(T::read_u16(&buf))
    }

    /// Reads a signed 16 bit integer from the underlying reader.
    #[inline]
    fn read_i16<T: ByteOrder>(&mut self) -> Result<i16> {
        let mut buf = [0; 2];
        try!(self.read_exact(&mut buf));
        Ok(T::read_i16(&buf))
    }

    /// Reads an unsigned 32 bit integer from the underlying reader.
    #[inline]
    fn read_u32<T: ByteOrder>(&mut self) -> Result<u32> {
        let mut buf = [0; 4];
        try!(self.read_exact(&mut buf));
        Ok(T::read_u32(&buf))
    }

    /// Reads a signed 32 bit integer from the underlying reader.
    #[inline]
    fn read_i32<T: ByteOrder>(&mut self) -> Result<i32> {
        let mut buf = [0; 4];
        try!(self.read_exact(&mut buf));
        Ok(T::read_i32(&buf))
    }

    /// Reads an unsigned 64 bit integer from the underlying reader.
    #[inline]
    fn read_u64<T: ByteOrder>(&mut self) -> Result<u64> {
        let mut buf = [0; 8];
        try!(self.read_exact(&mut buf));
        Ok(T::read_u64(&buf))
    }

    /// Reads a signed 64 bit integer from the underlying reader.
    #[inline]
    fn read_i64<T: ByteOrder>(&mut self) -> Result<i64> {
        let mut buf = [0; 8];
        try!(self.read_exact(&mut buf));
        Ok(T::read_i64(&buf))
    }

    /// Reads an unsigned n-bytes integer from the underlying reader.
    #[inline]
    fn read_uint<T: ByteOrder>(&mut self, nbytes: usize) -> Result<u64> {
        let mut buf = [0; 8];
        try!(self.read_exact(&mut buf[..nbytes]));
        Ok(T::read_uint(&buf[..nbytes], nbytes))
    }

    /// Reads a signed n-bytes integer from the underlying reader.
    #[inline]
    fn read_int<T: ByteOrder>(&mut self, nbytes: usize) -> Result<i64> {
        let mut buf = [0; 8];
        try!(self.read_exact(&mut buf[..nbytes]));
        Ok(T::read_int(&buf[..nbytes], nbytes))
    }

    /// Reads a IEEE754 single-precision (4 bytes) floating point number from
    /// the underlying reader.
    #[inline]
    fn read_f32<T: ByteOrder>(&mut self) -> Result<f32> {
        let mut buf = [0; 4];
        try!(self.read_exact(&mut buf));
        Ok(T::read_f32(&buf))
    }

    /// Reads a IEEE754 double-precision (8 bytes) floating point number from
    /// the underlying reader.
    #[inline]
    fn read_f64<T: ByteOrder>(&mut self) -> Result<f64> {
        let mut buf = [0; 8];
        try!(self.read_exact(&mut buf));
        Ok(T::read_f64(&buf))
    }
}

/// All types that implement `Read` get methods defined in `ReadBytesExt`
/// for free.
impl<R: io::Read + ?Sized> ReadBytesExt for R {}

/// Extends `Write` with methods for writing numbers. (For `std::io`.)
///
/// Most of the methods defined here have an unconstrained type parameter that
/// must be explicitly instantiated. Typically, it is instantiated with either
/// the `BigEndian` or `LittleEndian` types defined in this crate.
///
/// # Examples
///
/// Write unsigned 16 bit big-endian integers to a `Write`:
///
/// ```rust
/// use byteorder::{BigEndian, WriteBytesExt};
///
/// let mut wtr = vec![];
/// wtr.write_u16::<BigEndian>(517).unwrap();
/// wtr.write_u16::<BigEndian>(768).unwrap();
/// assert_eq!(wtr, vec![2, 5, 3, 0]);
/// ```
pub trait WriteBytesExt: io::Write {
    /// Writes an unsigned 8 bit integer to the underlying writer.
    ///
    /// Note that since this writes a single byte, no byte order conversions
    /// are used. It is included for completeness.
    #[inline]
    fn write_u8(&mut self, n: u8) -> Result<()> {
        self.write_all(&[n])
    }

    /// Writes a signed 8 bit integer to the underlying writer.
    ///
    /// Note that since this writes a single byte, no byte order conversions
    /// are used. It is included for completeness.
    #[inline]
    fn write_i8(&mut self, n: i8) -> Result<()> {
        self.write_all(&[n as u8])
    }

    /// Writes an unsigned 16 bit integer to the underlying writer.
    #[inline]
    fn write_u16<T: ByteOrder>(&mut self, n: u16) -> Result<()> {
        let mut buf = [0; 2];
        T::write_u16(&mut buf, n);
        self.write_all(&buf)
    }

    /// Writes a signed 16 bit integer to the underlying writer.
    #[inline]
    fn write_i16<T: ByteOrder>(&mut self, n: i16) -> Result<()> {
        let mut buf = [0; 2];
        T::write_i16(&mut buf, n);
        self.write_all(&buf)
    }

    /// Writes an unsigned 32 bit integer to the underlying writer.
    #[inline]
    fn write_u32<T: ByteOrder>(&mut self, n: u32) -> Result<()> {
        let mut buf = [0; 4];
        T::write_u32(&mut buf, n);
        self.write_all(&buf)
    }

    /// Writes a signed 32 bit integer to the underlying writer.
    #[inline]
    fn write_i32<T: ByteOrder>(&mut self, n: i32) -> Result<()> {
        let mut buf = [0; 4];
        T::write_i32(&mut buf, n);
        self.write_all(&buf)
    }

    /// Writes an unsigned 64 bit integer to the underlying writer.
    #[inline]
    fn write_u64<T: ByteOrder>(&mut self, n: u64) -> Result<()> {
        let mut buf = [0; 8];
        T::write_u64(&mut buf, n);
        self.write_all(&buf)
    }

    /// Writes a signed 64 bit integer to the underlying writer.
    #[inline]
    fn write_i64<T: ByteOrder>(&mut self, n: i64) -> Result<()> {
        let mut buf = [0; 8];
        T::write_i64(&mut buf, n);
        self.write_all(&buf)
    }

    /// Writes an unsigned n-bytes integer to the underlying writer.
    ///
    /// If the given integer is not representable in the given number of bytes,
    /// this method panics. If `nbytes > 8`, this method panics.
    #[inline]
    fn write_uint<T: ByteOrder>(
        &mut self,
        n: u64,
        nbytes: usize,
    ) -> Result<()> {
        let mut buf = [0; 8];
        T::write_uint(&mut buf, n, nbytes);
        self.write_all(&buf[0..nbytes])
    }

    /// Writes a signed n-bytes integer to the underlying writer.
    ///
    /// If the given integer is not representable in the given number of bytes,
    /// this method panics. If `nbytes > 8`, this method panics.
    #[inline]
    fn write_int<T: ByteOrder>(
        &mut self,
        n: i64,
        nbytes: usize,
    ) -> Result<()> {
        let mut buf = [0; 8];
        T::write_int(&mut buf, n, nbytes);
        self.write_all(&buf[0..nbytes])
    }

    /// Writes a IEEE754 single-precision (4 bytes) floating point number to
    /// the underlying writer.
    #[inline]
    fn write_f32<T: ByteOrder>(&mut self, n: f32) -> Result<()> {
        let mut buf = [0; 4];
        T::write_f32(&mut buf, n);
        self.write_all(&buf)
    }

    /// Writes a IEEE754 double-precision (8 bytes) floating point number to
    /// the underlying writer.
    #[inline]
    fn write_f64<T: ByteOrder>(&mut self, n: f64) -> Result<()> {
        let mut buf = [0; 8];
        T::write_f64(&mut buf, n);
        self.write_all(&buf)
    }
}

/// All types that implement `Write` get methods defined in `WriteBytesExt`
/// for free.
impl<W: io::Write + ?Sized> WriteBytesExt for W {}
<|endoftext|>


<commit_before>//! Numeric traits and functions for the built-in numeric types.

pub use core::num::*;
<commit_msg>num: Add trait PrimInt<commit_after>//! Numeric traits and functions for the built-in numeric types.

pub use core::num::*;

/// Primitive operations for built-in integer types
pub trait PrimInt: Sized {
    /// Converts an integer from big endian to the target's endianness
    fn from_be(x: Self) -> Self;

    /// Converts an integer from little endian to the target's endianness
    fn from_le(x: Self) -> Self;

    /// Converts `self` to big endian from the target's endianness
    fn to_be(self) -> Self;

    /// Converts `self` to little endian from the target's endianness
    fn to_le(self) -> Self;
}

macro_rules! prim_int {
    ($($t:ident)*) => ($(
        impl PrimInt for $t {
            #[inline]
            fn from_be(x: Self) -> Self { $t::from_be(x) }
            #[inline]
            fn from_le(x: Self) -> Self { $t::from_le(x) }
            #[inline]
            fn to_be(self) -> Self { self.to_be() }
            #[inline]
            fn to_le(self) -> Self { self.to_le() }
        }
    )*)
}

prim_int!(i8 i16 i32 i64 isize u8 u16 u32 u64 usize);
<|endoftext|>


<commit_before>/// Bit Strings are length/value pairs, so that bit strings with leading
/// zeros aren't conflated.
#[derive(Eq,PartialEq,Hash,Debug,Clone,Copy)]
pub struct BS {
    pub length: i64,
    pub value: i64,
}

pub trait BitString {
    fn pow(i64, i64) -> i64;
    fn flip(i64, i64) -> i64;
    fn is_set(i64, i64) -> bool;
    fn prepend(i64, BS) -> BS;
    fn length(BS) -> i64;

    const MAX_LEN: u32;
}

impl BitString for BS {
    /// `pow(b, n)` yields b^n
    fn pow(b: i64, n: i64) -> i64 {
        match n {
            0 => 1,
            1 => b,
            n => {
                let x = Self::pow(b, n / 2);
                x * x * (if n % 2 == 0 { 1 } else { b })
            }
        }
    }
    /// `flip(i, b)` toggles the `i`th bit of `b`.
    fn flip(i: i64, b: i64) -> i64 {
        let n = Self::pow(2, i);
        if n & b == n {
            return b - Self::pow(2, i);
        } else {
            return b + Self::pow(2, i);
        }
    }
    /// `is_set(i, b)` returns true if the `i`th bit of `b` is set
    fn is_set(i: i64, b: i64) -> bool {
        let n = Self::flip(i, 0);
        (n & b) == n
    }
    /// `prepend(b, bs)` prepends the bit `b` onto the bitstring `bs`.
    /// `b` must be either `0` or `1`.
    fn prepend(b: i64, bs: BS) -> BS {
        match b {
            0 => {
                if !(Self::is_set(bs.length, bs.value)) {
                    BS {
                        length: bs.length + 1,
                        value: bs.value,
                    }
                } else {
                    BS {
                        length: bs.length + 1,
                        value: Self::flip(bs.length, bs.value),
                    }
                }
            }
            1 => {
                if Self::is_set(bs.length, bs.value) {
                    BS {
                        length: bs.length + 1,
                        value: bs.value,
                    }
                } else {
                    BS {
                        length: bs.length + 1,
                        value: Self::flip(bs.length, bs.value),
                    }
                }
            }
            _ => panic!("b has to be a bit (0 or 1)"),
        }
    }
    /// Returns the length of the bitstring `bs`.
    fn length(bs: BS) -> i64 {
        bs.length
    }

    /// The maximum supported length of a bitstring is 30 bits.
    const MAX_LEN: u32 = 30;
}

#[test]
fn test_pow() {
    assert_eq!(BS::pow(0, 0), 1);
    assert_eq!(BS::pow(42, 0), 1);
    assert_eq!(BS::pow(-2, 0), 1);
    assert_eq!(BS::pow(2, 4), 16);
    assert_eq!(BS::pow(-2, 3), -8);
}

#[test]
fn test_flip() {
    assert_eq!(BS::flip(0, 0), 1);
    assert_eq!(BS::flip(2, 0), 4);
    assert_eq!(BS::flip(1, 7), 5);
    assert_eq!(BS::flip(3, 7), 15);
}

#[test]
fn test_is_set() {
    assert_eq!(BS::is_set(4, 0), false);
    assert_eq!(BS::is_set(0, 0), false);
    assert_eq!(BS::is_set(0, 1), true);
    assert_eq!(BS::is_set(1, 2), true);
    assert_eq!(BS::is_set(0, 2), false);
}

#[test]
fn test_prepend() {
    assert_eq!(BS::prepend(0, BS { length: 0, value: 0 }), BS { length: 1, value: 0 });
    assert_eq!(BS::prepend(1, BS { length: 0, value: 0 }), BS { length: 1, value: 1 });
    assert_eq!(BS::prepend(1, BS { length: 1, value: 1 }), BS { length: 2, value: 3 });
    assert_eq!(BS::prepend(0, BS { length: 1, value: 1 }), BS { length: 2, value: 1 });
    assert_eq!(BS::prepend(1, BS { length: 2, value: 1 }), BS { length: 3, value: 5 });
}
<commit_msg>A couple bitstring changes<commit_after>/// Bit Strings are length/value pairs, so that bit strings with leading
/// zeros aren't conflated.
#[derive(Eq,PartialEq,Hash,Debug,Clone,Copy)]
pub struct BS {
    pub length: i64,
    pub value: i64,
}

pub trait BitString {
    fn pow(i64, i64) -> i64;
    fn flip(i64, i64) -> i64;
    fn is_set(i64, i64) -> bool;
    fn prepend(i64, BS) -> BS;
    fn length(BS) -> i64;
    fn shift_left(BS, i64) -> BS;

    const MAX_LEN: i64;
}

impl BitString for BS {
    /// `pow(b, n)` yields b^n
    fn pow(b: i64, n: i64) -> i64 {
        match n {
            0 => 1,
            1 => b,
            n => {
                let x = Self::pow(b, n / 2);
                x * x * (if n % 2 == 0 { 1 } else { b })
            }
        }
    }
    /// `flip(i, b)` toggles the `i`th bit of `b`.
    fn flip(i: i64, b: i64) -> i64 {
        let n = Self::pow(2, i);
        if n & b == n {
            return b - Self::pow(2, i);
        } else {
            return b + Self::pow(2, i);
        }
    }
    /// `is_set(i, b)` returns true if the `i`th bit of `b` is set
    fn is_set(i: i64, b: i64) -> bool {
        let n = Self::flip(i, 0);
        (n & b) == n
    }
    /// `prepend(b, bs)` prepends the bit `b` onto the bitstring `bs`.
    /// `b` must be either `0` or `1`.
    fn prepend(b: i64, bs: BS) -> BS {
        match b {
            0 if !(Self::is_set(bs.length, bs.value)) =>
                BS {
                    length: bs.length + 1,
                    value: bs.value,
                },
            1 if Self::is_set(bs.length, bs.value) =>
                BS {
                    length: bs.length + 1,
                    value: bs.value,
                },
            0 | 1 =>
                BS {
                    length: bs.length + 1,
                    value: Self::flip(bs.length, bs.value),
                },
            _ => panic!("b has to be a bit (0 or 1)"),
        }
    }
    /// Returns the length of the bitstring `bs`.
    fn length(bs: BS) -> i64 {
        bs.length
    }
    /// Performs a logical shift left on the bitstring `bs`.
    fn shift_left(bs: BS, i: i64) -> BS {
        BS {
            length: bs.length,
            value:(bs.value << i) & (2i64.pow(bs.length as u32) - 1),
        }
    }

    /// The maximum supported length of a bitstring is 30 bits.
    const MAX_LEN: i64 = 30;
}

#[test]
fn test_pow() {
    assert_eq!(BS::pow(0, 0), 1);
    assert_eq!(BS::pow(42, 0), 1);
    assert_eq!(BS::pow(-2, 0), 1);
    assert_eq!(BS::pow(2, 4), 16);
    assert_eq!(BS::pow(-2, 3), -8);
}

#[test]
fn test_flip() {
    assert_eq!(BS::flip(0, 0), 1);
    assert_eq!(BS::flip(2, 0), 4);
    assert_eq!(BS::flip(1, 7), 5);
    assert_eq!(BS::flip(3, 7), 15);
}

#[test]
fn test_is_set() {
    assert_eq!(BS::is_set(4, 0), false);
    assert_eq!(BS::is_set(0, 0), false);
    assert_eq!(BS::is_set(0, 1), true);
    assert_eq!(BS::is_set(1, 2), true);
    assert_eq!(BS::is_set(0, 2), false);
}

#[test]
fn test_prepend() {
    assert_eq!(BS::prepend(0, BS { length: 0, value: 0 }), BS { length: 1, value: 0 });
    assert_eq!(BS::prepend(1, BS { length: 0, value: 0 }), BS { length: 1, value: 1 });
    assert_eq!(BS::prepend(1, BS { length: 1, value: 1 }), BS { length: 2, value: 3 });
    assert_eq!(BS::prepend(0, BS { length: 1, value: 1 }), BS { length: 2, value: 1 });
    assert_eq!(BS::prepend(1, BS { length: 2, value: 1 }), BS { length: 3, value: 5 });
}

#[test]
fn test_shift_left() {
    assert_eq!(BS::shift_left(BS { length: 1, value: 0 }, 1), BS { length: 1, value: 0 });
    assert_eq!(BS::shift_left(BS { length: 1, value: 1 }, 1), BS { length: 1, value: 0 });
    assert_eq!(BS::shift_left(BS { length: 2, value: 1 }, 1), BS { length: 2, value: 2 });
    assert_eq!(BS::shift_left(BS { length: 2, value: 3 }, 1), BS { length: 2, value: 2 });
    assert_eq!(BS::shift_left(BS { length: 4, value: 2 }, 2), BS { length: 4, value: 8 });
}
<|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.

//! A module for working with borrowed data.

#![stable(feature = "rust1", since = "1.0.0")]

use core::clone::Clone;
use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
use core::convert::AsRef;
use core::hash::{Hash, Hasher};
use core::marker::Sized;
use core::ops::Deref;
use core::option::Option;

use fmt;
use alloc::{rc, arc};

use self::Cow::*;

/// A trait for borrowing data.
///
/// In general, there may be several ways to "borrow" a piece of data.  The
/// typical ways of borrowing a type `T` are `&T` (a shared borrow) and `&mut T`
/// (a mutable borrow). But types like `Vec<T>` provide additional kinds of
/// borrows: the borrowed slices `&[T]` and `&mut [T]`.
///
/// When writing generic code, it is often desirable to abstract over all ways
/// of borrowing data from a given type. That is the role of the `Borrow`
/// trait: if `T: Borrow<U>`, then `&U` can be borrowed from `&T`.  A given
/// type can be borrowed as multiple different types. In particular, `Vec<T>:
/// Borrow<Vec<T>>` and `Vec<T>: Borrow<[T]>`.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Borrow<Borrowed: ?Sized> {
    /// Immutably borrow from an owned value.
    #[stable(feature = "rust1", since = "1.0.0")]
    fn borrow(&self) -> &Borrowed;
}

/// A trait for mutably borrowing data.
///
/// Similar to `Borrow`, but for mutable borrows.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait BorrowMut<Borrowed: ?Sized> : Borrow<Borrowed> {
    /// Mutably borrow from an owned value.
    #[stable(feature = "rust1", since = "1.0.0")]
    fn borrow_mut(&mut self) -> &mut Borrowed;
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Borrow<T> for T {
    fn borrow(&self) -> &T { self }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> BorrowMut<T> for T {
    fn borrow_mut(&mut self) -> &mut T { self }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: ?Sized> Borrow<T> for &'a T {
    fn borrow(&self) -> &T { &**self }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: ?Sized> Borrow<T> for &'a mut T {
    fn borrow(&self) -> &T { &**self }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: ?Sized> BorrowMut<T> for &'a mut T {
    fn borrow_mut(&mut self) -> &mut T { &mut **self }
}

impl<T> Borrow<T> for rc::Rc<T> {
    fn borrow(&self) -> &T { &**self }
}

impl<T> Borrow<T> for arc::Arc<T> {
    fn borrow(&self) -> &T { &**self }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> Borrow<B> for Cow<'a, B> where B: ToOwned, <B as ToOwned>::Owned: 'a {
    fn borrow(&self) -> &B {
        &**self
    }
}

/// A generalization of Clone to borrowed data.
///
/// Some types make it possible to go from borrowed to owned, usually by
/// implementing the `Clone` trait. But `Clone` works only for going from `&T`
/// to `T`. The `ToOwned` trait generalizes `Clone` to construct owned data
/// from any borrow of a given type.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait ToOwned {
    #[stable(feature = "rust1", since = "1.0.0")]
    type Owned: Borrow<Self>;

    /// Create owned data from borrowed data, usually by copying.
    #[stable(feature = "rust1", since = "1.0.0")]
    fn to_owned(&self) -> Self::Owned;
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ToOwned for T where T: Clone {
    type Owned = T;
    fn to_owned(&self) -> T { self.clone() }
}

/// A clone-on-write smart pointer.
///
/// The type `Cow` is a smart pointer providing clone-on-write functionality: it
/// can enclose and provide immutable access to borrowed data, and clone the
/// data lazily when mutation or ownership is required. The type is designed to
/// work with general borrowed data via the `Borrow` trait.
///
/// `Cow` implements both `Deref`, which means that you can call
/// non-mutating methods directly on the data it encloses. If mutation
/// is desired, `to_mut` will obtain a mutable references to an owned
/// value, cloning if necessary.
///
/// # Examples
///
/// ```
/// use std::borrow::Cow;
///
/// fn abs_all(input: &mut Cow<[i32]>) {
///     for i in 0..input.len() {
///         let v = input[i];
///         if v < 0 {
///             // clones into a vector the first time (if not already owned)
///             input.to_mut()[i] = -v;
///         }
///     }
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub enum Cow<'a, B: ?Sized + 'a> where B: ToOwned {
    /// Borrowed data.
    #[stable(feature = "rust1", since = "1.0.0")]
    Borrowed(&'a B),

    /// Owned data.
    #[stable(feature = "rust1", since = "1.0.0")]
    Owned(<B as ToOwned>::Owned)
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> Clone for Cow<'a, B> where B: ToOwned {
    fn clone(&self) -> Cow<'a, B> {
        match *self {
            Borrowed(b) => Borrowed(b),
            Owned(ref o) => {
                let b: &B = o.borrow();
                Owned(b.to_owned())
            },
        }
    }
}

impl<'a, B: ?Sized> Cow<'a, B> where B: ToOwned {
    /// Acquire a mutable reference to the owned form of the data.
    ///
    /// Copies the data if it is not already owned.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn to_mut(&mut self) -> &mut <B as ToOwned>::Owned {
        match *self {
            Borrowed(borrowed) => {
                *self = Owned(borrowed.to_owned());
                self.to_mut()
            }
            Owned(ref mut owned) => owned
        }
    }

    /// Extract the owned data.
    ///
    /// Copies the data if it is not already owned.
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn into_owned(self) -> <B as ToOwned>::Owned {
        match self {
            Borrowed(borrowed) => borrowed.to_owned(),
            Owned(owned) => owned
        }
    }

    /// Returns true if this `Cow` wraps a borrowed value
    #[deprecated(since = "1.0.0", reason = "match on the enum instead")]
    #[unstable(feature = "std_misc")]
    pub fn is_borrowed(&self) -> bool {
        match *self {
            Borrowed(_) => true,
            _ => false,
        }
    }

    /// Returns true if this `Cow` wraps an owned value
    #[deprecated(since = "1.0.0", reason = "match on the enum instead")]
    #[unstable(feature = "std_misc")]
    pub fn is_owned(&self) -> bool {
        match *self {
            Owned(_) => true,
            _ => false,
        }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> Deref for Cow<'a, B> where B: ToOwned {
    type Target = B;

    fn deref(&self) -> &B {
        match *self {
            Borrowed(borrowed) => borrowed,
            Owned(ref owned) => owned.borrow()
        }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> Eq for Cow<'a, B> where B: Eq + ToOwned {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> Ord for Cow<'a, B> where B: Ord + ToOwned {
    #[inline]
    fn cmp(&self, other: &Cow<'a, B>) -> Ordering {
        Ord::cmp(&**self, &**other)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, 'b, B: ?Sized, C: ?Sized> PartialEq<Cow<'b, C>> for Cow<'a, B> where
    B: PartialEq<C> + ToOwned, C: ToOwned,
{
    #[inline]
    fn eq(&self, other: &Cow<'b, C>) -> bool {
        PartialEq::eq(&**self, &**other)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> PartialOrd for Cow<'a, B> where B: PartialOrd + ToOwned,
{
    #[inline]
    fn partial_cmp(&self, other: &Cow<'a, B>) -> Option<Ordering> {
        PartialOrd::partial_cmp(&**self, &**other)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> fmt::Debug for Cow<'a, B> where
    B: fmt::Debug + ToOwned,
    <B as ToOwned>::Owned: fmt::Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Borrowed(ref b) => fmt::Debug::fmt(b, f),
            Owned(ref o) => fmt::Debug::fmt(o, f),
        }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> fmt::Display for Cow<'a, B> where
    B: fmt::Display + ToOwned,
    <B as ToOwned>::Owned: fmt::Display,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Borrowed(ref b) => fmt::Display::fmt(b, f),
            Owned(ref o) => fmt::Display::fmt(o, f),
        }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> Hash for Cow<'a, B> where B: Hash + ToOwned
{
    #[inline]
    fn hash<H: Hasher>(&self, state: &mut H) {
        Hash::hash(&**self, state)
    }
}

/// Trait for moving into a `Cow`
#[unstable(feature = "into_cow", reason = "may be replaced by `convert::Into`")]
pub trait IntoCow<'a, B: ?Sized> where B: ToOwned {
    /// Moves `self` into `Cow`
    fn into_cow(self) -> Cow<'a, B>;
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a,  B: ?Sized> IntoCow<'a, B> for Cow<'a, B> where B: ToOwned {
    fn into_cow(self) -> Cow<'a, B> {
        self
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: Clone> AsRef<T> for Cow<'a, T> {
    fn as_ref(&self) -> &T {
        self
    }
}
<commit_msg>rollup merge of #23669: steveklabnik/doc_std_borrow<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.

//! A module for working with borrowed data.

#![stable(feature = "rust1", since = "1.0.0")]

use core::clone::Clone;
use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
use core::convert::AsRef;
use core::hash::{Hash, Hasher};
use core::marker::Sized;
use core::ops::Deref;
use core::option::Option;

use fmt;
use alloc::{rc, arc};

use self::Cow::*;

/// A trait for borrowing data.
///
/// In general, there may be several ways to "borrow" a piece of data.  The
/// typical ways of borrowing a type `T` are `&T` (a shared borrow) and `&mut T`
/// (a mutable borrow). But types like `Vec<T>` provide additional kinds of
/// borrows: the borrowed slices `&[T]` and `&mut [T]`.
///
/// When writing generic code, it is often desirable to abstract over all ways
/// of borrowing data from a given type. That is the role of the `Borrow`
/// trait: if `T: Borrow<U>`, then `&U` can be borrowed from `&T`.  A given
/// type can be borrowed as multiple different types. In particular, `Vec<T>:
/// Borrow<Vec<T>>` and `Vec<T>: Borrow<[T]>`.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Borrow<Borrowed: ?Sized> {
    /// Immutably borrow from an owned value.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::borrow::Borrow;
    ///
    /// fn check<T: Borrow<str>>(s: T) {
    ///     assert_eq!("Hello", s.borrow());
    /// }
    ///
    /// let s = "Hello".to_string();
    ///
    /// check(s);
    ///
    /// let s = "Hello";
    ///
    /// check(s);
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    fn borrow(&self) -> &Borrowed;
}

/// A trait for mutably borrowing data.
///
/// Similar to `Borrow`, but for mutable borrows.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait BorrowMut<Borrowed: ?Sized> : Borrow<Borrowed> {
    /// Mutably borrow from an owned value.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::borrow::BorrowMut;
    ///
    /// fn check<T: BorrowMut<[i32]>>(mut v: T) {
    ///     assert_eq!(&mut [1, 2, 3], v.borrow_mut());
    /// }
    ///
    /// let v = vec![1, 2, 3];
    ///
    /// check(v);
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    fn borrow_mut(&mut self) -> &mut Borrowed;
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Borrow<T> for T {
    fn borrow(&self) -> &T { self }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> BorrowMut<T> for T {
    fn borrow_mut(&mut self) -> &mut T { self }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: ?Sized> Borrow<T> for &'a T {
    fn borrow(&self) -> &T { &**self }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: ?Sized> Borrow<T> for &'a mut T {
    fn borrow(&self) -> &T { &**self }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: ?Sized> BorrowMut<T> for &'a mut T {
    fn borrow_mut(&mut self) -> &mut T { &mut **self }
}

impl<T> Borrow<T> for rc::Rc<T> {
    fn borrow(&self) -> &T { &**self }
}

impl<T> Borrow<T> for arc::Arc<T> {
    fn borrow(&self) -> &T { &**self }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> Borrow<B> for Cow<'a, B> where B: ToOwned, <B as ToOwned>::Owned: 'a {
    fn borrow(&self) -> &B {
        &**self
    }
}

/// A generalization of Clone to borrowed data.
///
/// Some types make it possible to go from borrowed to owned, usually by
/// implementing the `Clone` trait. But `Clone` works only for going from `&T`
/// to `T`. The `ToOwned` trait generalizes `Clone` to construct owned data
/// from any borrow of a given type.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait ToOwned {
    #[stable(feature = "rust1", since = "1.0.0")]
    type Owned: Borrow<Self>;

    /// Create owned data from borrowed data, usually by copying.
    #[stable(feature = "rust1", since = "1.0.0")]
    fn to_owned(&self) -> Self::Owned;
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ToOwned for T where T: Clone {
    type Owned = T;
    fn to_owned(&self) -> T { self.clone() }
}

/// A clone-on-write smart pointer.
///
/// The type `Cow` is a smart pointer providing clone-on-write functionality: it
/// can enclose and provide immutable access to borrowed data, and clone the
/// data lazily when mutation or ownership is required. The type is designed to
/// work with general borrowed data via the `Borrow` trait.
///
/// `Cow` implements both `Deref`, which means that you can call
/// non-mutating methods directly on the data it encloses. If mutation
/// is desired, `to_mut` will obtain a mutable references to an owned
/// value, cloning if necessary.
///
/// # Examples
///
/// ```
/// use std::borrow::Cow;
///
/// fn abs_all(input: &mut Cow<[i32]>) {
///     for i in 0..input.len() {
///         let v = input[i];
///         if v < 0 {
///             // clones into a vector the first time (if not already owned)
///             input.to_mut()[i] = -v;
///         }
///     }
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub enum Cow<'a, B: ?Sized + 'a> where B: ToOwned {
    /// Borrowed data.
    #[stable(feature = "rust1", since = "1.0.0")]
    Borrowed(&'a B),

    /// Owned data.
    #[stable(feature = "rust1", since = "1.0.0")]
    Owned(<B as ToOwned>::Owned)
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> Clone for Cow<'a, B> where B: ToOwned {
    fn clone(&self) -> Cow<'a, B> {
        match *self {
            Borrowed(b) => Borrowed(b),
            Owned(ref o) => {
                let b: &B = o.borrow();
                Owned(b.to_owned())
            },
        }
    }
}

impl<'a, B: ?Sized> Cow<'a, B> where B: ToOwned {
    /// Acquire a mutable reference to the owned form of the data.
    ///
    /// Copies the data if it is not already owned.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::borrow::Cow;
    ///
    /// let mut cow: Cow<[_]> = Cow::Owned(vec![1, 2, 3]);
    ///
    /// let hello = cow.to_mut();
    ///
    /// assert_eq!(&[1, 2, 3], hello);
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn to_mut(&mut self) -> &mut <B as ToOwned>::Owned {
        match *self {
            Borrowed(borrowed) => {
                *self = Owned(borrowed.to_owned());
                self.to_mut()
            }
            Owned(ref mut owned) => owned
        }
    }

    /// Extract the owned data.
    ///
    /// Copies the data if it is not already owned.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::borrow::Cow;
    ///
    /// let cow: Cow<[_]> = Cow::Owned(vec![1, 2, 3]);
    ///
    /// let hello = cow.into_owned();
    ///
    /// assert_eq!(vec![1, 2, 3], hello);
    /// ```
    #[stable(feature = "rust1", since = "1.0.0")]
    pub fn into_owned(self) -> <B as ToOwned>::Owned {
        match self {
            Borrowed(borrowed) => borrowed.to_owned(),
            Owned(owned) => owned
        }
    }

    /// Returns true if this `Cow` wraps a borrowed value
    #[deprecated(since = "1.0.0", reason = "match on the enum instead")]
    #[unstable(feature = "std_misc")]
    pub fn is_borrowed(&self) -> bool {
        match *self {
            Borrowed(_) => true,
            _ => false,
        }
    }

    /// Returns true if this `Cow` wraps an owned value
    #[deprecated(since = "1.0.0", reason = "match on the enum instead")]
    #[unstable(feature = "std_misc")]
    pub fn is_owned(&self) -> bool {
        match *self {
            Owned(_) => true,
            _ => false,
        }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> Deref for Cow<'a, B> where B: ToOwned {
    type Target = B;

    fn deref(&self) -> &B {
        match *self {
            Borrowed(borrowed) => borrowed,
            Owned(ref owned) => owned.borrow()
        }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> Eq for Cow<'a, B> where B: Eq + ToOwned {}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> Ord for Cow<'a, B> where B: Ord + ToOwned {
    #[inline]
    fn cmp(&self, other: &Cow<'a, B>) -> Ordering {
        Ord::cmp(&**self, &**other)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, 'b, B: ?Sized, C: ?Sized> PartialEq<Cow<'b, C>> for Cow<'a, B> where
    B: PartialEq<C> + ToOwned, C: ToOwned,
{
    #[inline]
    fn eq(&self, other: &Cow<'b, C>) -> bool {
        PartialEq::eq(&**self, &**other)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> PartialOrd for Cow<'a, B> where B: PartialOrd + ToOwned,
{
    #[inline]
    fn partial_cmp(&self, other: &Cow<'a, B>) -> Option<Ordering> {
        PartialOrd::partial_cmp(&**self, &**other)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> fmt::Debug for Cow<'a, B> where
    B: fmt::Debug + ToOwned,
    <B as ToOwned>::Owned: fmt::Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Borrowed(ref b) => fmt::Debug::fmt(b, f),
            Owned(ref o) => fmt::Debug::fmt(o, f),
        }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> fmt::Display for Cow<'a, B> where
    B: fmt::Display + ToOwned,
    <B as ToOwned>::Owned: fmt::Display,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Borrowed(ref b) => fmt::Display::fmt(b, f),
            Owned(ref o) => fmt::Display::fmt(o, f),
        }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> Hash for Cow<'a, B> where B: Hash + ToOwned
{
    #[inline]
    fn hash<H: Hasher>(&self, state: &mut H) {
        Hash::hash(&**self, state)
    }
}

/// Trait for moving into a `Cow`
#[unstable(feature = "into_cow", reason = "may be replaced by `convert::Into`")]
pub trait IntoCow<'a, B: ?Sized> where B: ToOwned {
    /// Moves `self` into `Cow`
    fn into_cow(self) -> Cow<'a, B>;
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a,  B: ?Sized> IntoCow<'a, B> for Cow<'a, B> where B: ToOwned {
    fn into_cow(self) -> Cow<'a, B> {
        self
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: Clone> AsRef<T> for Cow<'a, T> {
    fn as_ref(&self) -> &T {
        self
    }
}
<|endoftext|>


<commit_before>use std::cell::RefCell;
use std::collections::HashMap;
const PAGE_MASK: u32 = 0b1111_1111_1111_1100_0000_0000; // 16K pages
const ADDR_MASK: u32 = 0b0000_0000_0000_0011_1111_1111; // 1K page size
type Page = [u8; (ADDR_MASK+1) as usize];

pub struct LoggingMem {
	pub log: RefCell<Vec<Operation>>,
	pages: HashMap<u32, Page>,
	initializer: u32,
}

#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub struct AddressSpace(Mode, Segment);

#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
enum Segment {
	Program, Data
}
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
enum Mode {
	User, Supervisor
}

#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Operation {
	None,
	ReadByte(AddressSpace, u32),
	ReadWord(AddressSpace, u32),
	ReadLong(AddressSpace, u32),
	WriteByte(AddressSpace, u32, u32),
	WriteWord(AddressSpace, u32, u32),
	WriteLong(AddressSpace, u32, u32),
}
pub const SUPERVISOR_PROGRAM: AddressSpace = AddressSpace(Mode::Supervisor, Segment::Program);
pub const SUPERVISOR_DATA: AddressSpace = AddressSpace(Mode::Supervisor, Segment::Data);
pub const USER_PROGRAM: AddressSpace = AddressSpace(Mode::User, Segment::Program);
pub const USER_DATA: AddressSpace = AddressSpace(Mode::User, Segment::Data);

trait AddressBus {
	fn read_u8(&self, address_space: AddressSpace, address: u32) -> u32;
	fn read_u16(&self, address_space: AddressSpace, address: u32) -> u32;
	fn read_u32(&self, address_space: AddressSpace, address: u32) -> u32;
	fn write_u8(&mut self, address_space: AddressSpace, address: u32, value: u32);
	fn write_u16(&mut self, address_space: AddressSpace, address: u32, value: u32);
	fn write_u32(&mut self, address_space: AddressSpace, address: u32, value: u32);
}

impl LoggingMem {
	fn new(initializer: u32) -> LoggingMem {
		let mut lmem = LoggingMem { log: RefCell::new(Vec::new()), pages: HashMap::new(), initializer: initializer };
		lmem
	}
	fn loglen(&self) -> usize {
		let log = self.log.borrow();
		log.len()
	}
	fn getlog(&self, index: usize) -> Operation {
		let log = self.log.borrow();
		log[index]
	}
	fn ensure_page(&self, address: u32) -> u32 {
		let page = address & PAGE_MASK;
		if !self.pages.contains_key(&page) {
			self.pages.insert(page, [0u8; (ADDR_MASK + 1) as usize]);
			let mut page = self.pages[&page];
			for v in 0..((ADDR_MASK+1) / 4) {
				page[(4*v+0) as usize] = ((self.initializer >> 24) & 0xFF) as u8;
				page[(4*v+1) as usize] = ((self.initializer >> 16) & 0xFF) as u8;
				page[(4*v+2) as usize] = ((self.initializer >>  8) & 0xFF) as u8;
				page[(4*v+3) as usize] = ((self.initializer >>  0) & 0xFF) as u8;
			}
		}
		page
	}
	fn read_byte(&self, address: u32) -> u32 {
		let index = (address & ADDR_MASK) as usize;
		//self.pages[&self.ensure_page(address)][index] as u32
		0
	}

	fn write_byte(&mut self, address: u32, value: u8) {
		let index = (address & ADDR_MASK) as usize;
		let page = self.ensure_page(address);
		let mut page = self.pages[&page];
		page[index] = value;
	}
}

impl AddressBus for LoggingMem {
	fn read_u8(&self, address_space: AddressSpace, address: u32) -> u32 {
		let mut log = self.log.borrow_mut();
		log.push(Operation::ReadByte(address_space, address));
		self.read_byte(address)
	}

	fn read_u16(&self, address_space: AddressSpace, address: u32) -> u32 {
		let mut log = self.log.borrow_mut();
		log.push(Operation::ReadWord(address_space, address));
		((self.read_byte(address+0) as u16) << 8
		|(self.read_byte(address+1) as u16) << 0
		) as u32
	}

	fn read_u32(&self, address_space: AddressSpace, address: u32) -> u32 {
		let mut log = self.log.borrow_mut();
		log.push(Operation::ReadLong(address_space, address));
		((self.read_byte(address+0) as u32) << 24
		|(self.read_byte(address+1) as u32) << 16
		|(self.read_byte(address+2) as u32) <<  8
		|(self.read_byte(address+3) as u32) <<  0) as u32
	}

	fn write_u8(&mut self, address_space: AddressSpace, address: u32, value: u32) {
		{
			let mut log = self.log.borrow_mut();
			log.push(Operation::WriteByte(address_space, address, value));
		}
		self.write_byte(address, (value & 0xFF) as u8);
	}

	fn write_u16(&mut self, address_space: AddressSpace, address: u32, value: u32) {
		{
			let mut log = self.log.borrow_mut();
			log.push(Operation::WriteWord(address_space, address, value));
		}
		self.write_byte(address+0, ((value >>  8) & 0xFF) as u8);
		self.write_byte(address+1, ((value >>  0) & 0xFF) as u8);
	}

	fn write_u32(&mut self, address_space: AddressSpace, address: u32, value: u32) {
		{
			let mut log = self.log.borrow_mut();
			log.push(Operation::WriteLong(address_space, address, value));
		}
		self.write_byte(address+0, ((value >> 24) & 0xFF) as u8);
		self.write_byte(address+1, ((value >> 16) & 0xFF) as u8);
		self.write_byte(address+2, ((value >>  8) & 0xFF) as u8);
		self.write_byte(address+3, ((value >>  0) & 0xFF) as u8);
	}
}

#[cfg(test)]
mod tests {
	use super::{LoggingMem, AddressBus, Operation, SUPERVISOR_DATA, SUPERVISOR_PROGRAM, USER_DATA, USER_PROGRAM};

	#[test]
	fn read_initialized_memory() {
		let mem = LoggingMem::new(0x01020304);
		for v in 0..256 {
			assert_eq!(0x01, mem.read_u8(SUPERVISOR_DATA, 4*v+0));
			assert_eq!(0x02, mem.read_u8(SUPERVISOR_DATA, 4*v+1));
			assert_eq!(0x03, mem.read_u8(SUPERVISOR_DATA, 4*v+2));
			assert_eq!(0x04, mem.read_u8(SUPERVISOR_DATA, 4*v+3));
		}
		for v in 0..256 {
			assert_eq!(0x0102, mem.read_u16(SUPERVISOR_DATA, 4*v+0));
			assert_eq!(0x0203, mem.read_u16(SUPERVISOR_DATA, 4*v+1));
			assert_eq!(0x0304, mem.read_u16(SUPERVISOR_DATA, 4*v+2));
			if 4*v+3 < 1023 {
				assert_eq!(0x0401, mem.read_u16(SUPERVISOR_DATA, 4*v+3));
			}
		}
		for v in 0..255 {
			assert_eq!(0x01020304, mem.read_u32(SUPERVISOR_DATA, 4*v+0));
			assert_eq!(0x02030401, mem.read_u32(SUPERVISOR_DATA, 4*v+1));
			assert_eq!(0x03040102, mem.read_u32(SUPERVISOR_DATA, 4*v+2));
			assert_eq!(0x04010203, mem.read_u32(SUPERVISOR_DATA, 4*v+3));
		}
		assert_eq!(0x01020304, mem.read_u32(SUPERVISOR_DATA, 4*255));
	}

	#[test]
	fn read_your_u32_writes() {
		let mut mem = LoggingMem::new(0x01020304);
		let pattern = 0xAAAA7777;
		let address = 128;
		assert!(pattern != mem.read_u32(SUPERVISOR_DATA, address));
		mem.write_u32(SUPERVISOR_DATA, address, pattern);
		assert_eq!(pattern, mem.read_u32(SUPERVISOR_DATA, address));
	}

	#[test]
	fn read_your_u16_writes() {
		let mut mem = LoggingMem::new(0x01020304);
		let pattern = 0xAAAA7777;
		let address = 128;
		assert!(pattern != mem.read_u16(SUPERVISOR_DATA, address));
		mem.write_u16(SUPERVISOR_DATA, address, pattern);
		assert_eq!(pattern & 0xFFFF, mem.read_u16(SUPERVISOR_DATA, address));
	}

	#[test]
	fn read_your_u8_writes() {
		let mut mem = LoggingMem::new(0x01020304);
		let pattern = 0xAAAA7777;
		let address = 128;
		assert!(pattern != mem.read_u8(SUPERVISOR_DATA, address));
		mem.write_u8(SUPERVISOR_DATA, address, pattern);
		assert_eq!(pattern & 0xFF, mem.read_u8(SUPERVISOR_DATA, address));
	}

	#[test]
	fn read_u8_is_logged() {
		let mem = LoggingMem::new(0x01020304);
		let address = 128;
		mem.read_u8(SUPERVISOR_DATA, address);
		assert!(mem.loglen() > 0);
		assert_eq!(Operation::ReadByte(SUPERVISOR_DATA, address), mem.getlog(0));
	}

	#[test]
	fn read_u16_is_logged() {
		let mem = LoggingMem::new(0x01020304);
		let address = 128;
		mem.read_u16(SUPERVISOR_PROGRAM, address);
		assert!(mem.loglen() > 0);
		assert_eq!(Operation::ReadWord(SUPERVISOR_PROGRAM, address), mem.getlog(0));
	}

	#[test]
	fn read_u32_is_logged() {
		let mem = LoggingMem::new(0x01020304);
		let address = 128;
		mem.read_u32(USER_DATA, address);
		assert!(mem.loglen() > 0);
		assert_eq!(Operation::ReadLong(USER_DATA, address), mem.getlog(0));
	}

	#[test]
	fn write_u8_is_logged() {
		let mut mem = LoggingMem::new(0x01020304);
		let address = 128;
		let pattern = 0xAAAA7777;
		mem.write_u8(SUPERVISOR_DATA, address, pattern);
		assert!(mem.loglen() > 0);
		assert_eq!(Operation::WriteByte(SUPERVISOR_DATA, address, pattern), mem.getlog(0));
	}

	#[test]
	fn write_u16_is_logged() {
		let mut mem = LoggingMem::new(0x01020304);
		let address = 128;
		let pattern = 0xAAAA7777;
		mem.write_u16(SUPERVISOR_PROGRAM, address, pattern);
		assert!(mem.loglen() > 0);
		assert_eq!(Operation::WriteWord(SUPERVISOR_PROGRAM, address, pattern), mem.getlog(0));
	}

	#[test]
	fn write_u32_is_logged() {
		let mut mem = LoggingMem::new(0x01020304);
		let address = 128;
		let pattern = 0xAAAA7777;
		mem.write_u32(USER_DATA, address, pattern);
		assert!(mem.loglen() > 0);
		assert_eq!(Operation::WriteLong(USER_DATA, address, pattern), mem.getlog(0));
	}

	#[test]
	fn shared_address_space() {
		let mut mem = LoggingMem::new(0x01020304);
		let pattern = 0xAAAA7777;
		let address = 128;
		assert!(pattern != mem.read_u32(SUPERVISOR_DATA, address));
		assert!(pattern != mem.read_u32(SUPERVISOR_PROGRAM, address));
		assert!(pattern != mem.read_u32(USER_DATA, address));
		assert!(pattern != mem.read_u32(USER_PROGRAM, address));
		mem.write_u32(SUPERVISOR_DATA, address, pattern);

		assert_eq!(pattern, mem.read_u32(SUPERVISOR_DATA, address));
		assert_eq!(pattern, mem.read_u32(SUPERVISOR_PROGRAM, address));
		assert_eq!(pattern, mem.read_u32(USER_DATA, address));
		assert_eq!(pattern, mem.read_u32(USER_PROGRAM, address));
	}
}<commit_msg>Memory is now a RefCell to a HashMap of pages<commit_after>use std::cell::RefCell;
use std::collections::HashMap;
// The m68k had a 24 bit external address bus with
// (2^24 bytes = ) 16 MB addressable space
const PAGE_SIZE: u32 = 1024; // 1K page size
const ADDR_MASK: u32 = PAGE_SIZE - 1; // 1K page size
const PAGE_MASK: u32 = 0xFFFFFF ^ ADDR_MASK; // 16K pages

type Page = Vec<u8>;

pub struct LoggingMem {
	pub log: RefCell<Vec<Operation>>,
	pages: RefCell<HashMap<u32, Page>>,
	initializer: u32,
}

#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub struct AddressSpace(Mode, Segment);

#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
enum Segment {
	Program, Data
}
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
enum Mode {
	User, Supervisor
}

#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Operation {
	None,
	ReadByte(AddressSpace, u32),
	ReadWord(AddressSpace, u32),
	ReadLong(AddressSpace, u32),
	WriteByte(AddressSpace, u32, u32),
	WriteWord(AddressSpace, u32, u32),
	WriteLong(AddressSpace, u32, u32),
}
pub const SUPERVISOR_PROGRAM: AddressSpace = AddressSpace(Mode::Supervisor, Segment::Program);
pub const SUPERVISOR_DATA: AddressSpace = AddressSpace(Mode::Supervisor, Segment::Data);
pub const USER_PROGRAM: AddressSpace = AddressSpace(Mode::User, Segment::Program);
pub const USER_DATA: AddressSpace = AddressSpace(Mode::User, Segment::Data);

trait AddressBus {
	fn read_u8(&self, address_space: AddressSpace, address: u32) -> u32;
	fn read_u16(&self, address_space: AddressSpace, address: u32) -> u32;
	fn read_u32(&self, address_space: AddressSpace, address: u32) -> u32;
	fn write_u8(&mut self, address_space: AddressSpace, address: u32, value: u32);
	fn write_u16(&mut self, address_space: AddressSpace, address: u32, value: u32);
	fn write_u32(&mut self, address_space: AddressSpace, address: u32, value: u32);
}

impl LoggingMem {
	fn new(initializer: u32) -> LoggingMem {
		let lmem = LoggingMem { log: RefCell::new(Vec::new()), pages: RefCell::new(HashMap::new()), initializer: initializer };
		lmem
	}
	fn loglen(&self) -> usize {
		let log = self.log.borrow();
		log.len()
	}
	fn getlog(&self, index: usize) -> Operation {
		let log = self.log.borrow();
		log[index]
	}
	fn ensure_page(&self, address: u32) -> u32 {
		let page = address & PAGE_MASK;
		let mut pages = self.pages.borrow_mut();
		if !pages.contains_key(&page) {
			pages.insert(page, Vec::with_capacity(PAGE_SIZE as usize));
			if let Some(mut page) = pages.get_mut(&page) {
				for v in 0..((ADDR_MASK+1) / 4) {
					page.push(((self.initializer >> 24) & 0xFF) as u8);
					page.push(((self.initializer >> 16) & 0xFF) as u8);
					page.push(((self.initializer >>  8) & 0xFF) as u8);
					page.push(((self.initializer >>  0) & 0xFF) as u8);
				}
			}
		}
		page
	}
	fn read_byte(&self, address: u32) -> u32 {
		let page = self.ensure_page(address);
		let index = (address & ADDR_MASK) as usize;
		self.pages.borrow()[&page][index] as u32
	}

	fn write_byte(&mut self, address: u32, value: u8) {
		let index = (address & ADDR_MASK) as usize;
		let page = self.ensure_page(address);
		{
			let mut pages = self.pages.borrow_mut();
			if let Some(mut page) = pages.get_mut(&page) {
				page[index] = value;
			}
		}
	}
}

impl AddressBus for LoggingMem {
	fn read_u8(&self, address_space: AddressSpace, address: u32) -> u32 {
		let mut log = self.log.borrow_mut();
		log.push(Operation::ReadByte(address_space, address));
		self.read_byte(address)
	}

	fn read_u16(&self, address_space: AddressSpace, address: u32) -> u32 {
		let mut log = self.log.borrow_mut();
		log.push(Operation::ReadWord(address_space, address));
		((self.read_byte(address+0) as u16) << 8
		|(self.read_byte(address+1) as u16) << 0
		) as u32
	}

	fn read_u32(&self, address_space: AddressSpace, address: u32) -> u32 {
		let mut log = self.log.borrow_mut();
		log.push(Operation::ReadLong(address_space, address));
		((self.read_byte(address+0) as u32) << 24
		|(self.read_byte(address+1) as u32) << 16
		|(self.read_byte(address+2) as u32) <<  8
		|(self.read_byte(address+3) as u32) <<  0) as u32
	}

	fn write_u8(&mut self, address_space: AddressSpace, address: u32, value: u32) {
		{
			let mut log = self.log.borrow_mut();
			log.push(Operation::WriteByte(address_space, address, value));
		}
		self.write_byte(address, (value & 0xFF) as u8);
	}

	fn write_u16(&mut self, address_space: AddressSpace, address: u32, value: u32) {
		{
			let mut log = self.log.borrow_mut();
			log.push(Operation::WriteWord(address_space, address, value));
		}
		self.write_byte(address+0, ((value >>  8) & 0xFF) as u8);
		self.write_byte(address+1, ((value >>  0) & 0xFF) as u8);
	}

	fn write_u32(&mut self, address_space: AddressSpace, address: u32, value: u32) {
		{
			let mut log = self.log.borrow_mut();
			log.push(Operation::WriteLong(address_space, address, value));
		}
		self.write_byte(address+0, ((value >> 24) & 0xFF) as u8);
		self.write_byte(address+1, ((value >> 16) & 0xFF) as u8);
		self.write_byte(address+2, ((value >>  8) & 0xFF) as u8);
		self.write_byte(address+3, ((value >>  0) & 0xFF) as u8);
	}
}

#[cfg(test)]
mod tests {
	use super::{LoggingMem, AddressBus, Operation, SUPERVISOR_DATA, SUPERVISOR_PROGRAM, USER_DATA, USER_PROGRAM};

	#[test]
	fn read_initialized_memory() {
		let mem = LoggingMem::new(0x01020304);
		for v in 0..256 {
			assert_eq!(0x01, mem.read_u8(SUPERVISOR_DATA, 4*v+0));
			assert_eq!(0x02, mem.read_u8(SUPERVISOR_DATA, 4*v+1));
			assert_eq!(0x03, mem.read_u8(SUPERVISOR_DATA, 4*v+2));
			assert_eq!(0x04, mem.read_u8(SUPERVISOR_DATA, 4*v+3));
		}
		for v in 0..256 {
			assert_eq!(0x0102, mem.read_u16(SUPERVISOR_DATA, 4*v+0));
			assert_eq!(0x0203, mem.read_u16(SUPERVISOR_DATA, 4*v+1));
			assert_eq!(0x0304, mem.read_u16(SUPERVISOR_DATA, 4*v+2));
			if 4*v+3 < 1023 {
				assert_eq!(0x0401, mem.read_u16(SUPERVISOR_DATA, 4*v+3));
			}
		}
		for v in 0..255 {
			assert_eq!(0x01020304, mem.read_u32(SUPERVISOR_DATA, 4*v+0));
			assert_eq!(0x02030401, mem.read_u32(SUPERVISOR_DATA, 4*v+1));
			assert_eq!(0x03040102, mem.read_u32(SUPERVISOR_DATA, 4*v+2));
			assert_eq!(0x04010203, mem.read_u32(SUPERVISOR_DATA, 4*v+3));
		}
		assert_eq!(0x01020304, mem.read_u32(SUPERVISOR_DATA, 4*255));
	}

	#[test]
	fn read_your_u32_writes() {
		let mut mem = LoggingMem::new(0x01020304);
		let pattern = 0xAAAA7777;
		let address = 128;
		assert!(pattern != mem.read_u32(SUPERVISOR_DATA, address));
		mem.write_u32(SUPERVISOR_DATA, address, pattern);
		assert_eq!(pattern, mem.read_u32(SUPERVISOR_DATA, address));
	}

	#[test]
	fn read_your_u16_writes() {
		let mut mem = LoggingMem::new(0x01020304);
		let pattern = 0xAAAA7777;
		let address = 128;
		assert!(pattern != mem.read_u16(SUPERVISOR_DATA, address));
		mem.write_u16(SUPERVISOR_DATA, address, pattern);
		assert_eq!(pattern & 0xFFFF, mem.read_u16(SUPERVISOR_DATA, address));
	}

	#[test]
	fn read_your_u8_writes() {
		let mut mem = LoggingMem::new(0x01020304);
		let pattern = 0xAAAA7777;
		let address = 128;
		assert!(pattern != mem.read_u8(SUPERVISOR_DATA, address));
		mem.write_u8(SUPERVISOR_DATA, address, pattern);
		assert_eq!(pattern & 0xFF, mem.read_u8(SUPERVISOR_DATA, address));
	}

	#[test]
	fn read_u8_is_logged() {
		let mem = LoggingMem::new(0x01020304);
		let address = 128;
		mem.read_u8(SUPERVISOR_DATA, address);
		assert!(mem.loglen() > 0);
		assert_eq!(Operation::ReadByte(SUPERVISOR_DATA, address), mem.getlog(0));
	}

	#[test]
	fn read_u16_is_logged() {
		let mem = LoggingMem::new(0x01020304);
		let address = 128;
		mem.read_u16(SUPERVISOR_PROGRAM, address);
		assert!(mem.loglen() > 0);
		assert_eq!(Operation::ReadWord(SUPERVISOR_PROGRAM, address), mem.getlog(0));
	}

	#[test]
	fn read_u32_is_logged() {
		let mem = LoggingMem::new(0x01020304);
		let address = 128;
		mem.read_u32(USER_DATA, address);
		assert!(mem.loglen() > 0);
		assert_eq!(Operation::ReadLong(USER_DATA, address), mem.getlog(0));
	}

	#[test]
	fn write_u8_is_logged() {
		let mut mem = LoggingMem::new(0x01020304);
		let address = 128;
		let pattern = 0xAAAA7777;
		mem.write_u8(SUPERVISOR_DATA, address, pattern);
		assert!(mem.loglen() > 0);
		assert_eq!(Operation::WriteByte(SUPERVISOR_DATA, address, pattern), mem.getlog(0));
	}

	#[test]
	fn write_u16_is_logged() {
		let mut mem = LoggingMem::new(0x01020304);
		let address = 128;
		let pattern = 0xAAAA7777;
		mem.write_u16(SUPERVISOR_PROGRAM, address, pattern);
		assert!(mem.loglen() > 0);
		assert_eq!(Operation::WriteWord(SUPERVISOR_PROGRAM, address, pattern), mem.getlog(0));
	}

	#[test]
	fn write_u32_is_logged() {
		let mut mem = LoggingMem::new(0x01020304);
		let address = 128;
		let pattern = 0xAAAA7777;
		mem.write_u32(USER_DATA, address, pattern);
		assert!(mem.loglen() > 0);
		assert_eq!(Operation::WriteLong(USER_DATA, address, pattern), mem.getlog(0));
	}

	#[test]
	fn shared_address_space() {
		let mut mem = LoggingMem::new(0x01020304);
		let pattern = 0xAAAA7777;
		let address = 128;
		assert!(pattern != mem.read_u32(SUPERVISOR_DATA, address));
		assert!(pattern != mem.read_u32(SUPERVISOR_PROGRAM, address));
		assert!(pattern != mem.read_u32(USER_DATA, address));
		assert!(pattern != mem.read_u32(USER_PROGRAM, address));
		mem.write_u32(SUPERVISOR_DATA, address, pattern);

		assert_eq!(pattern, mem.read_u32(SUPERVISOR_DATA, address));
		assert_eq!(pattern, mem.read_u32(SUPERVISOR_PROGRAM, address));
		assert_eq!(pattern, mem.read_u32(USER_DATA, address));
		assert_eq!(pattern, mem.read_u32(USER_PROGRAM, address));
	}
}<|endoftext|>


<commit_before>//! Callback methods for rustwlc
use rustwlc::handle::{WlcOutput, WlcView};
use rustwlc::types::*;
use rustwlc::input::{pointer, keyboard};

use compositor;
use super::keys;
use super::lua;
use super::keys::KeyPress;
use super::layout::tree;
use super::layout::container::ContainerType;

/// If the event is handled by way-cooler
const EVENT_HANDLED: bool = true;

/// If the event should be passed through to clients
const EVENT_PASS_THROUGH: bool = false;

// wlc callbacks

pub extern fn output_created(output: WlcOutput) -> bool {
    trace!("output_created: {:?}: {}", output, output.get_name());
    {
        if let Ok(mut tree) = tree::try_lock_tree() {
            tree.add_output(output.clone());
            tree.switch_to_workspace(&"1");
            true
        } else {
            false
        }
    }
}

pub extern fn output_destroyed(output: WlcOutput) {
    trace!("output_destroyed: {:?}", output);
}

pub extern fn output_focus(output: WlcOutput, focused: bool) {
    trace!("output_focus: {:?} focus={}", output, focused);
}

pub extern fn output_resolution(output: WlcOutput,
                            old_size_ptr: &Size, new_size_ptr: &Size) {
    trace!("output_resolution: {:?} from  {:?} to {:?}",
           output, *old_size_ptr, *new_size_ptr);
    // Update the resolution of the output and it's children
    output.set_resolution(new_size_ptr.clone());
    if let Ok(mut tree) = tree::try_lock_tree() {
        tree.layout_active_of(ContainerType::Output);
    }
}
/*
pub extern fn output_render_pre(output: WlcOutput) {
    //println!("output_render_pre");
}

pub extern fn output_render_post(output: WlcOutput) {
    //println!("output_render_post");
}
*/
pub extern fn view_created(view: WlcView) -> bool {
    trace!("view_created: {:?}: \"{}\"", view, view.get_title());
    let output = view.get_output();
    if let Ok(mut tree) = tree::try_lock_tree() {
        let v_type = view.get_type();
        if v_type == ViewType::empty() {
            tree.add_view(view.clone());
        }
        tree.normalize_view(view.clone());
        tree.layout_active_of(ContainerType::Container);
        tree.set_active_container(view.clone());
        drop(tree);
        view.set_mask(output.get_mask());
        true
    } else {
        false
    }
}

pub extern fn view_destroyed(view: WlcView) {
    trace!("view_destroyed: {:?}", view);
    if let Ok(mut tree) = tree::try_lock_tree() {
        tree.remove_view(&view);
        tree.layout_active_of(ContainerType::Workspace);
    } else {
        warn!("Could not delete view {:?}", view);
    }
}

pub extern fn view_focus(current: WlcView, focused: bool) {
    trace!("view_focus: {:?} {}", current, focused);
    current.set_state(VIEW_ACTIVATED, focused);
    // set the focus view in the tree
    {
        // If tree is already grabbed,
        // it should have the active container all set
        if let Ok(mut tree) = tree::try_lock_tree() {
            tree.set_active_container(current.clone());
        }
    }
}

pub extern fn view_move_to_output(current: WlcView,
                                  o1: WlcOutput, o2: WlcOutput) {
    trace!("view_move_to_output: {:?}, {:?}, {:?}", current, o1, o2);
}

pub extern fn view_request_geometry(view: WlcView, geometry: &Geometry) {
    trace!("view_request_geometry: {:?} wants {:?}", view, geometry);
    warn!("Denying request");
}

pub extern fn view_request_state(view: WlcView, state: ViewState, handled: bool) {
    trace!("view_request_state: {}, {:?}, handled: {}",
    view.get_title(), state, handled);
    view.set_state(state, handled);
}

pub extern fn view_request_move(view: WlcView, dest: &Point) {
    // Called by views when they have a dang resize mouse thing, we should only
    // let it happen in view floating mode
    compositor::start_interactive_move(&view, dest);
    trace!("view_request_move: to {}", *dest);
}

pub extern fn view_request_resize(view: WlcView,
                              edge: ResizeEdge, location: &Point) {
    compositor::start_interactive_resize(&view, edge, location);
    trace!("view_request_resize: edge {:?}, to {}",
             edge, location);
}

pub extern fn keyboard_key(_view: WlcView, _time: u32, mods: &KeyboardModifiers,
                       key: u32, state: KeyState) -> bool {
    if state == KeyState::Pressed {
        // TODO this function will throw an error in Rustwlc right now
        // let mut keys = keyboard::get_current_keys().into_iter()
        //      .map(|&k| Keysym::from(k)).collect();
        let sym = keyboard::get_keysym_for_key(key, &KeyMod::empty());
        let keys = vec![sym];

        let press = KeyPress::new(mods.mods, keys);
        if let Some(action) = keys::get(&press) {
            debug!("[key] Found an action for {:?}", press);
            action();
            return EVENT_HANDLED;
        }
    }

    return EVENT_PASS_THROUGH;
}

pub extern fn pointer_button(view: WlcView, _time: u32,
                         mods: &KeyboardModifiers, button: u32,
                             state: ButtonState, point: &Point) -> bool {
    compositor::on_pointer_button(view, _time, mods, button, state, point)
}

pub extern fn pointer_scroll(_view: WlcView, _time: u32,
                         _mods_ptr: &KeyboardModifiers, axis: ScrollAxis,
                         heights: [f64; 2]) -> bool {
    trace!("pointer_scroll: {:?} {:?}", axis,
           heights.iter().map(|f| f.clone().round()).collect::<Vec<f64>>());
    false
}

pub extern fn pointer_motion(_view: WlcView, _time: u32, point: &Point) -> bool {
    pointer::set_position(point);
    compositor::on_pointer_motion(_view, _time, point)
}

/*
pub extern fn touch(view: WlcView, time: u32, mods_ptr: &KeyboardModifiers,
               touch: TouchType, key: i32, point_ptr: &Point) -> bool {
    false
}
*/

pub extern fn compositor_ready() {
    info!("Preparing compositor!");
    info!("Initializing Lua...");
    lua::init();
}

pub extern fn compositor_terminating() {
    info!("Compositor terminating!");
    lua::send(lua::LuaQuery::Terminate).ok();
}

pub fn init() {
    use rustwlc::callback;

    callback::output_created(output_created);
    callback::output_destroyed(output_destroyed);
    callback::output_focus(output_focus);
    callback::output_resolution(output_resolution);
    callback::view_created(view_created);
    callback::view_destroyed(view_destroyed);
    callback::view_focus(view_focus);
    callback::view_move_to_output(view_move_to_output);
    callback::view_request_geometry(view_request_geometry);
    callback::view_request_state(view_request_state);
    callback::view_request_move(view_request_move);
    callback::view_request_resize(view_request_resize);
    callback::keyboard_key(keyboard_key);
    callback::pointer_button(pointer_button);
    callback::pointer_scroll(pointer_scroll);
    callback::pointer_motion(pointer_motion);
    callback::compositor_ready(compositor_ready);
    callback::compositor_terminate(compositor_terminating);
    trace!("Registered wlc callbacks");
}
<commit_msg>Cleaned up view_created<commit_after>//! Callback methods for rustwlc
use rustwlc::handle::{WlcOutput, WlcView};
use rustwlc::types::*;
use rustwlc::input::{pointer, keyboard};

use compositor;
use super::keys;
use super::lua;
use super::keys::KeyPress;
use super::layout::tree;
use super::layout::container::ContainerType;

/// If the event is handled by way-cooler
const EVENT_HANDLED: bool = true;

/// If the event should be passed through to clients
const EVENT_PASS_THROUGH: bool = false;

// wlc callbacks

pub extern fn output_created(output: WlcOutput) -> bool {
    trace!("output_created: {:?}: {}", output, output.get_name());
    {
        if let Ok(mut tree) = tree::try_lock_tree() {
            tree.add_output(output.clone());
            tree.switch_to_workspace(&"1");
            true
        } else {
            false
        }
    }
}

pub extern fn output_destroyed(output: WlcOutput) {
    trace!("output_destroyed: {:?}", output);
}

pub extern fn output_focus(output: WlcOutput, focused: bool) {
    trace!("output_focus: {:?} focus={}", output, focused);
}

pub extern fn output_resolution(output: WlcOutput,
                            old_size_ptr: &Size, new_size_ptr: &Size) {
    trace!("output_resolution: {:?} from  {:?} to {:?}",
           output, *old_size_ptr, *new_size_ptr);
    // Update the resolution of the output and it's children
    output.set_resolution(new_size_ptr.clone());
    if let Ok(mut tree) = tree::try_lock_tree() {
        tree.layout_active_of(ContainerType::Output);
    }
}
/*
pub extern fn output_render_pre(output: WlcOutput) {
    //println!("output_render_pre");
}

pub extern fn output_render_post(output: WlcOutput) {
    //println!("output_render_post");
}
*/
pub extern fn view_created(view: WlcView) -> bool {
    trace!("view_created: {:?}: \"{}\"", view, view.get_title());
    let output = view.get_output();
    if let Ok(mut tree) = tree::try_lock_tree() {
        let v_type = view.get_type();
        if v_type != ViewType::empty() {
            return true
        }
        tree.add_view(view.clone());
        tree.normalize_view(view.clone());
        tree.layout_active_of(ContainerType::Container);
        tree.set_active_container(view.clone());
        view.set_mask(output.get_mask());
        true
    } else {
        false
    }
}

pub extern fn view_destroyed(view: WlcView) {
    trace!("view_destroyed: {:?}", view);
    if let Ok(mut tree) = tree::try_lock_tree() {
        tree.remove_view(&view);
        tree.layout_active_of(ContainerType::Workspace);
    } else {
        warn!("Could not delete view {:?}", view);
    }
}

pub extern fn view_focus(current: WlcView, focused: bool) {
    trace!("view_focus: {:?} {}", current, focused);
    current.set_state(VIEW_ACTIVATED, focused);
    // set the focus view in the tree
    {
        // If tree is already grabbed,
        // it should have the active container all set
        if let Ok(mut tree) = tree::try_lock_tree() {
            tree.set_active_container(current.clone());
        }
    }
}

pub extern fn view_move_to_output(current: WlcView,
                                  o1: WlcOutput, o2: WlcOutput) {
    trace!("view_move_to_output: {:?}, {:?}, {:?}", current, o1, o2);
}

pub extern fn view_request_geometry(view: WlcView, geometry: &Geometry) {
    trace!("view_request_geometry: {:?} wants {:?}", view, geometry);
    warn!("Denying request");
}

pub extern fn view_request_state(view: WlcView, state: ViewState, handled: bool) {
    trace!("view_request_state: {}, {:?}, handled: {}",
    view.get_title(), state, handled);
    view.set_state(state, handled);
}

pub extern fn view_request_move(view: WlcView, dest: &Point) {
    // Called by views when they have a dang resize mouse thing, we should only
    // let it happen in view floating mode
    compositor::start_interactive_move(&view, dest);
    trace!("view_request_move: to {}", *dest);
}

pub extern fn view_request_resize(view: WlcView,
                              edge: ResizeEdge, location: &Point) {
    compositor::start_interactive_resize(&view, edge, location);
    trace!("view_request_resize: edge {:?}, to {}",
             edge, location);
}

pub extern fn keyboard_key(_view: WlcView, _time: u32, mods: &KeyboardModifiers,
                       key: u32, state: KeyState) -> bool {
    if state == KeyState::Pressed {
        // TODO this function will throw an error in Rustwlc right now
        // let mut keys = keyboard::get_current_keys().into_iter()
        //      .map(|&k| Keysym::from(k)).collect();
        let sym = keyboard::get_keysym_for_key(key, &KeyMod::empty());
        let keys = vec![sym];

        let press = KeyPress::new(mods.mods, keys);
        if let Some(action) = keys::get(&press) {
            debug!("[key] Found an action for {:?}", press);
            action();
            return EVENT_HANDLED;
        }
    }

    return EVENT_PASS_THROUGH;
}

pub extern fn pointer_button(view: WlcView, _time: u32,
                         mods: &KeyboardModifiers, button: u32,
                             state: ButtonState, point: &Point) -> bool {
    compositor::on_pointer_button(view, _time, mods, button, state, point)
}

pub extern fn pointer_scroll(_view: WlcView, _time: u32,
                         _mods_ptr: &KeyboardModifiers, axis: ScrollAxis,
                         heights: [f64; 2]) -> bool {
    trace!("pointer_scroll: {:?} {:?}", axis,
           heights.iter().map(|f| f.clone().round()).collect::<Vec<f64>>());
    false
}

pub extern fn pointer_motion(_view: WlcView, _time: u32, point: &Point) -> bool {
    pointer::set_position(point);
    compositor::on_pointer_motion(_view, _time, point)
}

/*
pub extern fn touch(view: WlcView, time: u32, mods_ptr: &KeyboardModifiers,
               touch: TouchType, key: i32, point_ptr: &Point) -> bool {
    false
}
*/

pub extern fn compositor_ready() {
    info!("Preparing compositor!");
    info!("Initializing Lua...");
    lua::init();
}

pub extern fn compositor_terminating() {
    info!("Compositor terminating!");
    lua::send(lua::LuaQuery::Terminate).ok();
}

pub fn init() {
    use rustwlc::callback;

    callback::output_created(output_created);
    callback::output_destroyed(output_destroyed);
    callback::output_focus(output_focus);
    callback::output_resolution(output_resolution);
    callback::view_created(view_created);
    callback::view_destroyed(view_destroyed);
    callback::view_focus(view_focus);
    callback::view_move_to_output(view_move_to_output);
    callback::view_request_geometry(view_request_geometry);
    callback::view_request_state(view_request_state);
    callback::view_request_move(view_request_move);
    callback::view_request_resize(view_request_resize);
    callback::keyboard_key(keyboard_key);
    callback::pointer_button(pointer_button);
    callback::pointer_scroll(pointer_scroll);
    callback::pointer_motion(pointer_motion);
    callback::compositor_ready(compositor_ready);
    callback::compositor_terminate(compositor_terminating);
    trace!("Registered wlc callbacks");
}
<|endoftext|>


<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.

// NB: transitionary, de-mode-ing.
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];

#[cfg(stage0)]
use T = inst::T;
#[cfg(stage1)]
#[cfg(stage2)]
use T = self::inst::T;

use cmp::{Eq, Ord};
use from_str::FromStr;

pub const bits : uint = inst::bits;
pub const bytes : uint = (inst::bits / 8);

pub const min_value: T = 0 as T;
pub const max_value: T = 0 as T - 1 as T;

pub pure fn min(x: T, y: T) -> T { if x < y { x } else { y } }
pub pure fn max(x: T, y: T) -> T { if x > y { x } else { y } }

pub pure fn add(x: T, y: T) -> T { x + y }
pub pure fn sub(x: T, y: T) -> T { x - y }
pub pure fn mul(x: T, y: T) -> T { x * y }
pub pure fn div(x: T, y: T) -> T { x / y }
pub pure fn rem(x: T, y: T) -> T { x % y }

pub pure fn lt(x: T, y: T) -> bool { x < y }
pub pure fn le(x: T, y: T) -> bool { x <= y }
pub pure fn eq(x: T, y: T) -> bool { x == y }
pub pure fn ne(x: T, y: T) -> bool { x != y }
pub pure fn ge(x: T, y: T) -> bool { x >= y }
pub pure fn gt(x: T, y: T) -> bool { x > y }

pub pure fn is_positive(x: T) -> bool { x > 0 as T }
pub pure fn is_negative(x: T) -> bool { x < 0 as T }
pub pure fn is_nonpositive(x: T) -> bool { x <= 0 as T }
pub pure fn is_nonnegative(x: T) -> bool { x >= 0 as T }

#[inline(always)]
/// Iterate over the range [`lo`..`hi`)
pub pure fn range(lo: T, hi: T, it: fn(T) -> bool) {
    let mut i = lo;
    while i < hi {
        if !it(i) { break }
        i += 1 as T;
    }
}

/// Computes the bitwise complement
pub pure fn compl(i: T) -> T {
    max_value ^ i
}

#[cfg(notest)]
impl T : Ord {
    pure fn lt(&self, other: &T) -> bool { (*self) < (*other) }
    pure fn le(&self, other: &T) -> bool { (*self) <= (*other) }
    pure fn ge(&self, other: &T) -> bool { (*self) >= (*other) }
    pure fn gt(&self, other: &T) -> bool { (*self) > (*other) }
}

#[cfg(notest)]
impl T : Eq {
    pure fn eq(&self, other: &T) -> bool { return (*self) == (*other); }
    pure fn ne(&self, other: &T) -> bool { return (*self) != (*other); }
}

impl T: num::Num {
    pure fn add(&self, other: &T)    -> T { return *self + *other; }
    pure fn sub(&self, other: &T)    -> T { return *self - *other; }
    pure fn mul(&self, other: &T)    -> T { return *self * *other; }
    pure fn div(&self, other: &T)    -> T { return *self / *other; }
    pure fn modulo(&self, other: &T) -> T { return *self % *other; }
    pure fn neg(&self)              -> T { return -*self;        }

    pure fn to_int(&self)         -> int { return *self as int; }
    static pure fn from_int(n: int) -> T   { return n as T;      }
}

impl T: iter::Times {
    #[inline(always)]
    #[doc = "A convenience form for basic iteration. Given a variable `x` \
        of any numeric type, the expression `for x.times { /* anything */ }` \
        will execute the given function exactly x times. If we assume that \
        `x` is an int, this is functionally equivalent to \
        `for int::range(0, x) |_i| { /* anything */ }`."]
    pure fn times(it: fn() -> bool) {
        let mut i = self;
        while i > 0 {
            if !it() { break }
            i -= 1;
        }
    }
}

/**
 * Parse a buffer of bytes
 *
 * # Arguments
 *
 * * buf - A byte buffer
 * * radix - The base of the number
 *
 * # Failure
 *
 * `buf` must not be empty
 */
pub pure fn parse_bytes(buf: &[const u8], radix: uint) -> Option<T> {
    if vec::len(buf) == 0u { return None; }
    let mut i = vec::len(buf) - 1u;
    let mut power = 1u as T;
    let mut n = 0u as T;
    loop {
        match char::to_digit(buf[i] as char, radix) {
          Some(d) => n += d as T * power,
          None => return None
        }
        power *= radix as T;
        if i == 0u { return Some(n); }
        i -= 1u;
    };
}

/// Parse a string to an int
pub pure fn from_str(s: &str) -> Option<T>
{
    parse_bytes(str::to_bytes(s), 10u)
}

impl T : FromStr {
    static pure fn from_str(s: &str) -> Option<T> { from_str(s) }
}

/// Parse a string as an unsigned integer.
pub fn from_str_radix(buf: &str, radix: u64) -> Option<u64> {
    if str::len(buf) == 0u { return None; }
    let mut i = str::len(buf) - 1u;
    let mut power = 1u64, n = 0u64;
    loop {
        match char::to_digit(buf[i] as char, radix as uint) {
          Some(d) => n += d as u64 * power,
          None => return None
        }
        power *= radix;
        if i == 0u { return Some(n); }
        i -= 1u;
    };
}

/**
 * Convert to a string in a given base
 *
 * # Failure
 *
 * Fails if `radix` < 2 or `radix` > 16
 */
pub pure fn to_str(num: T, radix: uint) -> ~str {
    do to_str_bytes(false, num, radix) |slice| {
        do vec::as_imm_buf(slice) |p, len| {
            unsafe { str::raw::from_buf_len(p, len) }
        }
    }
}

/// Low-level helper routine for string conversion.
pub pure fn to_str_bytes<U>(neg: bool, num: T, radix: uint,
                   f: fn(v: &[u8]) -> U) -> U {

    #[inline(always)]
    fn digit(n: T) -> u8 {
        if n <= 9u as T {
            n as u8 + '0' as u8
        } else if n <= 15u as T {
            (n - 10 as T) as u8 + 'a' as u8
        } else {
            fail;
        }
    }

    assert (1u < radix && radix <= 16u);

    // Enough room to hold any number in any radix.
    // Worst case: 64-bit number, binary-radix, with
    // a leading negative sign = 65 bytes.
    let buf : [mut u8 * 65] = [mut 0u8, ..65];

    // FIXME (#2649): post-snapshot, you can do this without the raw
    // pointers and unsafe bits, and the codegen will prove it's all
    // in-bounds, no extra cost.

    unsafe {
        do vec::as_imm_buf(buf) |p, len| {
            let mp = p as *mut u8;
            let mut i = len;
            let mut n = num;
            let radix = radix as T;
            loop {
                i -= 1u;
                assert 0u < i && i < len;
                *ptr::mut_offset(mp, i) = digit(n % radix);
                n /= radix;
                if n == 0 as T { break; }
            }

            assert 0u < i && i < len;

            if neg {
                i -= 1u;
                *ptr::mut_offset(mp, i) = '-' as u8;
            }

            vec::raw::buf_as_slice(ptr::offset(p, i), len - i, f)
        }
    }
}

/// Convert to a string
pub pure fn str(i: T) -> ~str { return to_str(i, 10u); }

#[test]
pub fn test_to_str() {
    assert to_str(0 as T, 10u) == ~"0";
    assert to_str(1 as T, 10u) == ~"1";
    assert to_str(2 as T, 10u) == ~"2";
    assert to_str(11 as T, 10u) == ~"11";
    assert to_str(11 as T, 16u) == ~"b";
    assert to_str(255 as T, 16u) == ~"ff";
    assert to_str(0xff as T, 10u) == ~"255";
}

#[test]
pub fn test_from_str() {
    assert from_str(~"0") == Some(0u as T);
    assert from_str(~"3") == Some(3u as T);
    assert from_str(~"10") == Some(10u as T);
    assert from_str(~"123456789") == Some(123456789u as T);
    assert from_str(~"00100") == Some(100u as T);

    assert from_str(~"").is_none();
    assert from_str(~" ").is_none();
    assert from_str(~"x").is_none();
}

#[test]
pub fn test_parse_bytes() {
    use str::to_bytes;
    assert parse_bytes(to_bytes(~"123"), 10u) == Some(123u as T);
    assert parse_bytes(to_bytes(~"1001"), 2u) == Some(9u as T);
    assert parse_bytes(to_bytes(~"123"), 8u) == Some(83u as T);
    assert parse_bytes(to_bytes(~"123"), 16u) == Some(291u as T);
    assert parse_bytes(to_bytes(~"ffff"), 16u) == Some(65535u as T);
    assert parse_bytes(to_bytes(~"z"), 36u) == Some(35u as T);

    assert parse_bytes(to_bytes(~"Z"), 10u).is_none();
    assert parse_bytes(to_bytes(~"_"), 2u).is_none();
}

#[test]
#[should_fail]
#[ignore(cfg(windows))]
pub fn to_str_radix1() {
    uint::to_str(100u, 1u);
}

#[test]
#[should_fail]
#[ignore(cfg(windows))]
pub fn to_str_radix17() {
    uint::to_str(100u, 17u);
}

#[test]
pub fn test_times() {
    use iter::Times;
    let ten = 10 as T;
    let mut accum = 0;
    for ten.times { accum += 1; }
    assert (accum == 10);
}
<commit_msg>rewrite uint::to_str_bytes to avoid raw pointers<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.

// NB: transitionary, de-mode-ing.
#[forbid(deprecated_mode)];
#[forbid(deprecated_pattern)];

#[cfg(stage0)]
use T = inst::T;
#[cfg(stage1)]
#[cfg(stage2)]
use T = self::inst::T;

use cmp::{Eq, Ord};
use from_str::FromStr;

pub const bits : uint = inst::bits;
pub const bytes : uint = (inst::bits / 8);

pub const min_value: T = 0 as T;
pub const max_value: T = 0 as T - 1 as T;

pub pure fn min(x: T, y: T) -> T { if x < y { x } else { y } }
pub pure fn max(x: T, y: T) -> T { if x > y { x } else { y } }

pub pure fn add(x: T, y: T) -> T { x + y }
pub pure fn sub(x: T, y: T) -> T { x - y }
pub pure fn mul(x: T, y: T) -> T { x * y }
pub pure fn div(x: T, y: T) -> T { x / y }
pub pure fn rem(x: T, y: T) -> T { x % y }

pub pure fn lt(x: T, y: T) -> bool { x < y }
pub pure fn le(x: T, y: T) -> bool { x <= y }
pub pure fn eq(x: T, y: T) -> bool { x == y }
pub pure fn ne(x: T, y: T) -> bool { x != y }
pub pure fn ge(x: T, y: T) -> bool { x >= y }
pub pure fn gt(x: T, y: T) -> bool { x > y }

pub pure fn is_positive(x: T) -> bool { x > 0 as T }
pub pure fn is_negative(x: T) -> bool { x < 0 as T }
pub pure fn is_nonpositive(x: T) -> bool { x <= 0 as T }
pub pure fn is_nonnegative(x: T) -> bool { x >= 0 as T }

#[inline(always)]
/// Iterate over the range [`lo`..`hi`)
pub pure fn range(lo: T, hi: T, it: fn(T) -> bool) {
    let mut i = lo;
    while i < hi {
        if !it(i) { break }
        i += 1 as T;
    }
}

/// Computes the bitwise complement
pub pure fn compl(i: T) -> T {
    max_value ^ i
}

#[cfg(notest)]
impl T : Ord {
    pure fn lt(&self, other: &T) -> bool { (*self) < (*other) }
    pure fn le(&self, other: &T) -> bool { (*self) <= (*other) }
    pure fn ge(&self, other: &T) -> bool { (*self) >= (*other) }
    pure fn gt(&self, other: &T) -> bool { (*self) > (*other) }
}

#[cfg(notest)]
impl T : Eq {
    pure fn eq(&self, other: &T) -> bool { return (*self) == (*other); }
    pure fn ne(&self, other: &T) -> bool { return (*self) != (*other); }
}

impl T: num::Num {
    pure fn add(&self, other: &T)    -> T { return *self + *other; }
    pure fn sub(&self, other: &T)    -> T { return *self - *other; }
    pure fn mul(&self, other: &T)    -> T { return *self * *other; }
    pure fn div(&self, other: &T)    -> T { return *self / *other; }
    pure fn modulo(&self, other: &T) -> T { return *self % *other; }
    pure fn neg(&self)              -> T { return -*self;        }

    pure fn to_int(&self)         -> int { return *self as int; }
    static pure fn from_int(n: int) -> T   { return n as T;      }
}

impl T: iter::Times {
    #[inline(always)]
    #[doc = "A convenience form for basic iteration. Given a variable `x` \
        of any numeric type, the expression `for x.times { /* anything */ }` \
        will execute the given function exactly x times. If we assume that \
        `x` is an int, this is functionally equivalent to \
        `for int::range(0, x) |_i| { /* anything */ }`."]
    pure fn times(it: fn() -> bool) {
        let mut i = self;
        while i > 0 {
            if !it() { break }
            i -= 1;
        }
    }
}

/**
 * Parse a buffer of bytes
 *
 * # Arguments
 *
 * * buf - A byte buffer
 * * radix - The base of the number
 *
 * # Failure
 *
 * `buf` must not be empty
 */
pub pure fn parse_bytes(buf: &[const u8], radix: uint) -> Option<T> {
    if vec::len(buf) == 0u { return None; }
    let mut i = vec::len(buf) - 1u;
    let mut power = 1u as T;
    let mut n = 0u as T;
    loop {
        match char::to_digit(buf[i] as char, radix) {
          Some(d) => n += d as T * power,
          None => return None
        }
        power *= radix as T;
        if i == 0u { return Some(n); }
        i -= 1u;
    };
}

/// Parse a string to an int
pub pure fn from_str(s: &str) -> Option<T>
{
    parse_bytes(str::to_bytes(s), 10u)
}

impl T : FromStr {
    static pure fn from_str(s: &str) -> Option<T> { from_str(s) }
}

/// Parse a string as an unsigned integer.
pub fn from_str_radix(buf: &str, radix: u64) -> Option<u64> {
    if str::len(buf) == 0u { return None; }
    let mut i = str::len(buf) - 1u;
    let mut power = 1u64, n = 0u64;
    loop {
        match char::to_digit(buf[i] as char, radix as uint) {
          Some(d) => n += d as u64 * power,
          None => return None
        }
        power *= radix;
        if i == 0u { return Some(n); }
        i -= 1u;
    };
}

/**
 * Convert to a string in a given base
 *
 * # Failure
 *
 * Fails if `radix` < 2 or `radix` > 16
 */
pub pure fn to_str(num: T, radix: uint) -> ~str {
    do to_str_bytes(false, num, radix) |slice| {
        do vec::as_imm_buf(slice) |p, len| {
            unsafe { str::raw::from_buf_len(p, len) }
        }
    }
}

/// Low-level helper routine for string conversion.
pub pure fn to_str_bytes<U>(neg: bool, num: T, radix: uint,
                   f: fn(v: &[u8]) -> U) -> U {

    #[inline(always)]
    pure fn digit(n: T) -> u8 {
        if n <= 9u as T {
            n as u8 + '0' as u8
        } else if n <= 15u as T {
            (n - 10 as T) as u8 + 'a' as u8
        } else {
            fail;
        }
    }

    assert (1u < radix && radix <= 16u);

    // Enough room to hold any number in any radix.
    // Worst case: 64-bit number, binary-radix, with
    // a leading negative sign = 65 bytes.
    let buf : [mut u8 * 65] = [mut 0u8, ..65];
    let len = buf.len();

    let mut i = len;
    let mut n = num;
    let radix = radix as T;
    loop {
        i -= 1u;
        assert 0u < i && i < len;
        buf[i] = digit(n % radix);
        n /= radix;
        if n == 0 as T { break; }
    }

    assert 0u < i && i < len;

    if neg {
        i -= 1u;
        buf[i] = '-' as u8;
    }

    f(vec::view(buf, i, len))
}

/// Convert to a string
pub pure fn str(i: T) -> ~str { return to_str(i, 10u); }

#[test]
pub fn test_to_str() {
    assert to_str(0 as T, 10u) == ~"0";
    assert to_str(1 as T, 10u) == ~"1";
    assert to_str(2 as T, 10u) == ~"2";
    assert to_str(11 as T, 10u) == ~"11";
    assert to_str(11 as T, 16u) == ~"b";
    assert to_str(255 as T, 16u) == ~"ff";
    assert to_str(0xff as T, 10u) == ~"255";
}

#[test]
pub fn test_from_str() {
    assert from_str(~"0") == Some(0u as T);
    assert from_str(~"3") == Some(3u as T);
    assert from_str(~"10") == Some(10u as T);
    assert from_str(~"123456789") == Some(123456789u as T);
    assert from_str(~"00100") == Some(100u as T);

    assert from_str(~"").is_none();
    assert from_str(~" ").is_none();
    assert from_str(~"x").is_none();
}

#[test]
pub fn test_parse_bytes() {
    use str::to_bytes;
    assert parse_bytes(to_bytes(~"123"), 10u) == Some(123u as T);
    assert parse_bytes(to_bytes(~"1001"), 2u) == Some(9u as T);
    assert parse_bytes(to_bytes(~"123"), 8u) == Some(83u as T);
    assert parse_bytes(to_bytes(~"123"), 16u) == Some(291u as T);
    assert parse_bytes(to_bytes(~"ffff"), 16u) == Some(65535u as T);
    assert parse_bytes(to_bytes(~"z"), 36u) == Some(35u as T);

    assert parse_bytes(to_bytes(~"Z"), 10u).is_none();
    assert parse_bytes(to_bytes(~"_"), 2u).is_none();
}

#[test]
#[should_fail]
#[ignore(cfg(windows))]
pub fn to_str_radix1() {
    uint::to_str(100u, 1u);
}

#[test]
#[should_fail]
#[ignore(cfg(windows))]
pub fn to_str_radix17() {
    uint::to_str(100u, 17u);
}

#[test]
pub fn test_times() {
    use iter::Times;
    let ten = 10 as T;
    let mut accum = 0;
    for ten.times { accum += 1; }
    assert (accum == 10);
}
<|endoftext|>


<commit_before>use std::cmp::{PartialOrd, PartialEq, Ordering};
use std::fmt;

#[derive(Eq, Ord)]
pub struct Rev<T: Ord>(pub T);

impl<T: Ord> PartialEq<Rev<T>> for Rev<T> {
    #[inline(always)]
	fn eq(&self, other: &Rev<T>) -> bool {
		other.0.eq(&self.0)
	}
}

impl<T: Ord> PartialOrd<Rev<T>> for Rev<T> {
    #[inline(always)]
	fn partial_cmp(&self, other: &Rev<T>) -> Option<Ordering> {
		other.0.partial_cmp(&self.0)
	}
}

impl<T: Ord + fmt::Debug> fmt::Debug for Rev<T> {
	fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
		self.0.fmt(f)
	}
}

impl<T: Ord + fmt::Display> fmt::Display for Rev<T> {
	fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
		self.0.fmt(f)
	}
}
<commit_msg>add testes for Rev wrapper<commit_after>use std::cmp::{PartialOrd, PartialEq, Ordering};
use std::fmt;

#[derive(Eq, Ord)]
pub struct Rev<T: Ord>(pub T);

impl<T: Ord> PartialEq<Rev<T>> for Rev<T> {
    #[inline(always)]
	fn eq(&self, other: &Rev<T>) -> bool {
		other.0.eq(&self.0)
	}
}

impl<T: Ord> PartialOrd<Rev<T>> for Rev<T> {
    #[inline(always)]
	fn partial_cmp(&self, other: &Rev<T>) -> Option<Ordering> {
		other.0.partial_cmp(&self.0)
	}
}

impl<T: Ord + fmt::Debug> fmt::Debug for Rev<T> {
	fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
		self.0.fmt(f)
	}
}

impl<T: Ord + fmt::Display> fmt::Display for Rev<T> {
	fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
		self.0.fmt(f)
	}
}

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

	#[test]
	fn test_eq() {
	    assert!(Rev(1u32) == Rev(1u32));
	    assert!(Rev(1u32) != Rev(0u32));
	}

	#[test]
	fn test_rev_cmp() {
	    assert!(Rev(1u32) < Rev(0u32));
	    assert!(Rev(1u32) > Rev(2u32));
	}
}
<|endoftext|>