<commit_before>use super::interconnect::Interconnect;
use super::memory::END_RESERVED;
use super::rand;
use super::timer::Timer;

const INSTRUCTION_SIZE: u16 = 2;
const STACK_SIZE: usize = 16;

pub struct Cpu {
    v: [u8; 16],
    pc: u16,
    i: u16,
    stack: [u16; STACK_SIZE],
    stack_index: usize,

    delay_timer: Timer,
    sound_timer: Timer,
}

impl Cpu {
    pub fn new() -> Cpu {
        Cpu{
            v: [0; 16],
            pc: END_RESERVED as u16,
            i: 0,
            stack: [0;16],
            stack_index: 0,

            delay_timer: Timer::new(),
            sound_timer: Timer::new(),
        }
    }

    pub fn step(&mut self, interconnect: &mut Interconnect) {
        let instr = interconnect.mem.read_word(self.pc);

        let opcode = (instr >> 12) as u8;
        let nnn = instr & 0xfff;
        let x = ((instr >> 8) & 0xf) as usize;
        let y = ((instr >> 4) & 0xf) as usize;
        let n = (instr & 0xf) as usize;
        let kk = (instr & 0xff) as u8;
        self.pc += INSTRUCTION_SIZE;

        match opcode {
            0x0 => {
                match kk {
                    0xe0 => {
                        // 00E0 - CLS
                        interconnect.graphics.clear();
                    }
                    0xee => {
                        // 00EE - RET
                        let ret = self.pop();
                        self.pc = ret;
                    }
                    _ => {
                        // 0nnn - SYS addr
                        // This instruction is only used on the old computers on which Chip-8 was
                        // originally implemented. It is ignored by modern interpreters.
                    }
                }
            }
            0x1 => {
                // 1nnn - JP addr
                self.pc = nnn;
            }
            0x2 => {
                // 2nnn - CALL addr
                let pc = self.pc;
                self.push(pc);
                self.pc = nnn;
            }
            0x3 => {
                // 3xkk - SE Vx, byte
                if self.v[x] == kk {
                    self.pc += INSTRUCTION_SIZE;
                }
            }
            0x4 => {
                // 4xkk - SNE Vx, byte
                if self.v[x] != kk {
                    self.pc += INSTRUCTION_SIZE;
                }
            }
            0x5 => {
                // 5xy0 - SE Vx, Vy
                if self.v[x] == self.v[y] {
                    self.pc += INSTRUCTION_SIZE;
                }
            }
            0x6 => {
                // 6xkk - LD Vx, byte
                self.v[x as usize] = kk;
            }
            0x7 => {
                // 7xkk - ADD Vx, byte
                self.v[x] = self.v[x].wrapping_add(kk as u8);
            }
            0x8 => {
                match n {
                    0x0 => {
                        // 8xy0 - LD Vx, Vy
                        self.v[x] = self.v[y];
                    }
                    0x1 => {
                        // 8xy1 - OR Vx, Vy
                        self.v[x] |= self.v[y];
                    }
                    0x2 => {
                        // 8xy2 - AND Vx, Vy
                        self.v[x] &= self.v[y];
                    }
                    0x3 => {
                        // 8xy3 - XOR Vx, Vy
                        self.v[x] ^= self.v[y];
                    }
                    0x4 => {
                        // 8xy4 - ADD Vx, Vy
                        let ret = (self.v[x] as u16) + (self.v[y] as u16);
                        if ret > 255 {
                            self.v[0xf] = 1;
                        } else {
                            self.v[0xf] = 0;
                        }
                        self.v[x] = ret as u8;
                    }
                    0x5 => {
                        // 8xy5 - SUB Vx, Vy
                        if self.v[x] > self.v[y] {
                            self.v[0xf] = 1;
                        } else {
                            self.v[0xf] = 0;
                        }
                        self.v[x] = self.v[x].wrapping_sub(self.v[y]);
                    }
                    0x6 => {
                        // 8xy6 - SHR Vx {, Vy}
                        self.v[0xf] = self.v[x] & 0x1;
                        self.v[x] >>= 1;
                    }
                    0x7 => {
                        // 8xy7 - SUBN Vx, Vy
                        if self.v[y] > self.v[x] {
                            self.v[0xf] = 1;
                        } else {
                            self.v[0xf] = 0;
                        }
                        self.v[x] = self.v[y].wrapping_sub(self.v[x]);
                    }
                    0xE => {
                        self.v[0xf] = self.v[x] >> 7;
                        self.v[x] <<= 1;
                    }
                    _ => panic!("Unrecognized 8 variant {:x}({:x})", instr, n),
                }
            }
            0x9 => {
                // 9xy0 - SNE Vx, Vy
                if self.v[x] != self.v[y] {
                    self.pc += INSTRUCTION_SIZE;
                }
            }
            0xa => {
                // Annn - LD I, addr
                self.i = nnn;
            }
            0xb => {
                // Bnnn - JP V0, addr
                self.pc = (self.v[0] as u16) + nnn;
            }
            0xc => {
                // Cxkk - RND Vx, byte
                self.v[x] = rand::random::<u8>() & kk;
            }
            0xd => {
                // Dxyn - DRW Vx, Vy, nibble
                let mut sprite = vec![0 as u8; n as usize];
                let vx = self.v[x] as usize;
                let vy = self.v[y] as usize;

                for (i, sprite) in sprite.iter_mut().enumerate() {
                    *sprite = interconnect.mem.read_byte(self.i + i as u16);
                }

                self.v[0xf] = interconnect.graphics.draw(vx, vy, sprite);
            }
            0xe => {
                match kk {
                    0x9e => {
                        // Ex9E - SKP Vx
                        if interconnect.input.key_pressed(self.v[x]) {
                            self.pc += INSTRUCTION_SIZE;
                        }
                    }
                    0xa1 => {
                        // ExA1 - SKNP Vx
                        if !interconnect.input.key_pressed(self.v[x]) {
                            self.pc += INSTRUCTION_SIZE;
                        }
                    }
                    _ => panic!("Unrecognized e variant {:x}({:x})", instr, kk),
                }
            }
            0xf => {
                match kk {
                    0x07 => {
                        // Fx07 - LD Vx, DT
                        self.v[x] = self.delay_timer.get();
                    }
                    0x0a => {
                        // Fx0A - LD Vx, K
                        match interconnect.input.any_key_pressed() {
                            Some(index) => self.v[x] = index,
                            None => self.pc -= INSTRUCTION_SIZE,
                        }
                    }
                    0x15 => {
                        // Fx15 - LD DT, Vx
                        let val = self.v[x];
                        self.delay_timer.set(val);
                    }
                    0x18 => {
                        // Fx18 - LD ST, Vx
                        self.sound_timer.set(self.v[x]);
                    }
                    0x1E => {
                        // Fx1E - ADD I, Vx
                        self.i += self.v[x] as u16;
                    }
                    0x29 => {
                        // Fx29 - LD F, Vx
                        let val = self.v[x];
                        self.i = interconnect.mem.get_digit_sprite(val);
                    }
                    0x33 => {
                        // Fx33 - LD B, Vx
                        let val = self.v[x];
                        interconnect.mem.write_byte(self.i, val / 100);
                        interconnect.mem.write_byte(self.i + 1, (val % 100) / 10);
                        interconnect.mem.write_byte(self.i + 2, val % 10);
                    }
                    0x55 => {
                        // Fx55 - LD [I], Vx
                        for i in 0..(x + 1) {
                            interconnect.mem.write_byte(self.i + i as u16, self.v[i]);
                        }
                    }
                    0x65 => {
                        // Fx65 - LD Vx, [I]
                        for i in 0..(x+1) {
                            self.v[i] = interconnect.mem.read_byte(self.i + i as u16);
                        }
                    }
                    _ => panic!("Unrecognized f variant {:x}({:x})", instr, kk),
                }
            }

            _ => panic!("Unrecognized instruction 0x{:x} ({:x})", instr, opcode),
        }

        self.handle_timers();
    }

    fn handle_timers(&mut self) {
        self.delay_timer.update();
        self.sound_timer.update();
    }

    fn pop(&mut self) -> u16 {
        if self.stack_index == 0 {
            panic!("pop from empty stack");
        }
        self.stack_index -= 1;
        self.stack[self.stack_index]
    }

    fn push(&mut self, val: u16) {
        if self.stack_index == STACK_SIZE {
            panic!("push to full stack");
        }
        self.stack[self.stack_index] = val;
        self.stack_index += 1;
    }
}
<commit_msg>Pass the SCTEST rom<commit_after>use std::cmp;
use super::interconnect::Interconnect;
use super::memory::{END_RESERVED, RAM_BYTES};
use super::rand;
use super::timer::Timer;

const INSTRUCTION_SIZE: u16 = 2;
const STACK_SIZE: usize = 16;

pub struct Cpu {
    v: [u8; 16],
    pc: u16,
    i: u16,
    schip_rpl_flags: [u8; 8],
    stack: [u16; STACK_SIZE],
    stack_index: usize,

    delay_timer: Timer,
    sound_timer: Timer,
}

impl Cpu {
    pub fn new() -> Cpu {
        Cpu{
            v: [0; 16],
            pc: END_RESERVED as u16,
            i: 0,
            schip_rpl_flags: [0; 8],
            stack: [0;16],
            stack_index: 0,

            delay_timer: Timer::new(),
            sound_timer: Timer::new(),
        }
    }

    pub fn step(&mut self, interconnect: &mut Interconnect) {
        let instr = interconnect.mem.read_word(self.pc);

        let opcode = (instr >> 12) as u8;
        let nnn = instr & 0xfff;
        let x = ((instr >> 8) & 0xf) as usize;
        let y = ((instr >> 4) & 0xf) as usize;
        let n = (instr & 0xf) as usize;
        let kk = (instr & 0xff) as u8;
        self.pc += INSTRUCTION_SIZE;

        match opcode {
            0x0 => {
                match kk {
                    0xe0 => {
                        // 00E0 - CLS
                        interconnect.graphics.clear();
                    }
                    0xee => {
                        // 00EE - RET
                        let ret = self.pop();
                        self.pc = ret;
                    }
                    _ => {
                        // 0nnn - SYS addr
                        // This instruction is only used on the old computers on which Chip-8 was
                        // originally implemented. It is ignored by modern interpreters.
                    }
                }
            }
            0x1 => {
                // 1nnn - JP addr
                self.pc = nnn;
            }
            0x2 => {
                // 2nnn - CALL addr
                let pc = self.pc;
                self.push(pc);
                self.pc = nnn;
            }
            0x3 => {
                // 3xkk - SE Vx, byte
                if self.v[x] == kk {
                    self.pc += INSTRUCTION_SIZE;
                }
            }
            0x4 => {
                // 4xkk - SNE Vx, byte
                if self.v[x] != kk {
                    self.pc += INSTRUCTION_SIZE;
                }
            }
            0x5 => {
                // 5xy0 - SE Vx, Vy
                if self.v[x] == self.v[y] {
                    self.pc += INSTRUCTION_SIZE;
                }
            }
            0x6 => {
                // 6xkk - LD Vx, byte
                self.v[x as usize] = kk;
            }
            0x7 => {
                // 7xkk - ADD Vx, byte
                self.v[x] = self.v[x].wrapping_add(kk as u8);
            }
            0x8 => {
                match n {
                    0x0 => {
                        // 8xy0 - LD Vx, Vy
                        self.v[x] = self.v[y];
                    }
                    0x1 => {
                        // 8xy1 - OR Vx, Vy
                        self.v[x] |= self.v[y];
                    }
                    0x2 => {
                        // 8xy2 - AND Vx, Vy
                        self.v[x] &= self.v[y];
                    }
                    0x3 => {
                        // 8xy3 - XOR Vx, Vy
                        self.v[x] ^= self.v[y];
                    }
                    0x4 => {
                        // 8xy4 - ADD Vx, Vy
                        let ret = (self.v[x] as u16) + (self.v[y] as u16);
                        if ret > 255 {
                            self.v[0xf] = 1;
                        } else {
                            self.v[0xf] = 0;
                        }
                        self.v[x] = ret as u8;
                    }
                    0x5 => {
                        // 8xy5 - SUB Vx, Vy
                        if self.v[x] >= self.v[y] {
                            self.v[0xf] = 1;
                        } else {
                            self.v[0xf] = 0;
                        }
                        self.v[x] = self.v[x].wrapping_sub(self.v[y]);
                    }
                    0x6 => {
                        // 8xy6 - SHR Vx {, Vy}
                        self.v[0xf] = self.v[x] & 0x1;
                        self.v[x] >>= 1;
                    }
                    0x7 => {
                        // 8xy7 - SUBN Vx, Vy
                        if self.v[y] >= self.v[x] {
                            self.v[0xf] = 1;
                        } else {
                            self.v[0xf] = 0;
                        }
                        self.v[x] = self.v[y].wrapping_sub(self.v[x]);
                    }
                    0xE => {
                        self.v[0xf] = self.v[x] >> 7;
                        self.v[x] <<= 1;
                    }
                    _ => panic!("Unrecognized 8 variant {:x}({:x})", instr, n),
                }
            }
            0x9 => {
                // 9xy0 - SNE Vx, Vy
                if self.v[x] != self.v[y] {
                    self.pc += INSTRUCTION_SIZE;
                }
            }
            0xa => {
                // Annn - LD I, addr
                self.i = nnn;
            }
            0xb => {
                // Bnnn - JP V0, addr
                self.pc = (self.v[0] as u16) + nnn;
            }
            0xc => {
                // Cxkk - RND Vx, byte
                self.v[x] = rand::random::<u8>() & kk;
            }
            0xd => {
                // Dxyn - DRW Vx, Vy, nibble
                let mut sprite = vec![0 as u8; n as usize];
                let vx = self.v[x] as usize;
                let vy = self.v[y] as usize;

                for (i, sprite) in sprite.iter_mut().enumerate() {
                    *sprite = interconnect.mem.read_byte(self.i + i as u16);
                }

                self.v[0xf] = interconnect.graphics.draw(vx, vy, sprite);
            }
            0xe => {
                match kk {
                    0x9e => {
                        // Ex9E - SKP Vx
                        if interconnect.input.key_pressed(self.v[x]) {
                            self.pc += INSTRUCTION_SIZE;
                        }
                    }
                    0xa1 => {
                        // ExA1 - SKNP Vx
                        if !interconnect.input.key_pressed(self.v[x]) {
                            self.pc += INSTRUCTION_SIZE;
                        }
                    }
                    _ => panic!("Unrecognized e variant {:x}({:x})", instr, kk),
                }
            }
            0xf => {
                match kk {
                    0x07 => {
                        // Fx07 - LD Vx, DT
                        self.v[x] = self.delay_timer.get();
                    }
                    0x0a => {
                        // Fx0A - LD Vx, K
                        match interconnect.input.any_key_pressed() {
                            Some(index) => self.v[x] = index,
                            None => self.pc -= INSTRUCTION_SIZE,
                        }
                    }
                    0x15 => {
                        // Fx15 - LD DT, Vx
                        let val = self.v[x];
                        self.delay_timer.set(val);
                    }
                    0x18 => {
                        // Fx18 - LD ST, Vx
                        self.sound_timer.set(self.v[x]);
                    }
                    0x1E => {
                        // Fx1E - ADD I, Vx
                        self.i += self.v[x] as u16;
                        if self.i >= RAM_BYTES as u16 {
                            self.v[0xf] = 1;
                        } else {
                            self.v[0xf] = 0;
                        }
                    }
                    0x29 => {
                        // Fx29 - LD F, Vx
                        let val = self.v[x];
                        self.i = interconnect.mem.get_digit_sprite(val);
                    }
                    0x33 => {
                        // Fx33 - LD B, Vx
                        let val = self.v[x];
                        interconnect.mem.write_byte(self.i, val / 100);
                        interconnect.mem.write_byte(self.i + 1, (val % 100) / 10);
                        interconnect.mem.write_byte(self.i + 2, val % 10);
                    }
                    0x55 => {
                        // Fx55 - LD [I], Vx
                        for i in 0..(x + 1) {
                            interconnect.mem.write_byte(self.i + i as u16, self.v[i]);
                        }
                    }
                    0x65 => {
                        // Fx65 - LD Vx, [I]
                        for i in 0..(x+1) {
                            self.v[i] = interconnect.mem.read_byte(self.i + i as u16);
                        }
                    }
                    0x75 => {
                        // Fx75 - LD R Vx
                        for i in 0..cmp::min(x+1, 8) {
                            self.schip_rpl_flags[i] = self.v[i];
                        }
                    }
                    0x85 => {
                        // Fx75 - LD Vx R
                        for i in 0..cmp::min(x+1, 8) {
                            self.v[i] = self.schip_rpl_flags[i];
                        }
                    }
                    _ => panic!("Unrecognized f variant {:x}({:x})", instr, kk),
                }
            }

            _ => panic!("Unrecognized instruction 0x{:x} ({:x})", instr, opcode),
        }

        self.handle_timers();
    }

    fn handle_timers(&mut self) {
        self.delay_timer.update();
        self.sound_timer.update();
    }

    fn pop(&mut self) -> u16 {
        if self.stack_index == 0 {
            panic!("pop from empty stack");
        }
        self.stack_index -= 1;
        self.stack[self.stack_index]
    }

    fn push(&mut self, val: u16) {
        if self.stack_index == STACK_SIZE {
            panic!("push to full stack");
        }
        self.stack[self.stack_index] = val;
        self.stack_index += 1;
    }
}
<|endoftext|>


<commit_before>use std::fmt::{Display, Formatter, Error};
use memory::Memory;

const FL_CARRY: u8 = 1 << 0;
const FL_STATUS: u8 = 1 << 1;
const FL_INTERRUPT_DISABLE: u8 = 1 << 2;
const FL_BRK: u8 = 1 << 4;
const FL_OVERFLOW: u8 = 1 << 6;
const FL_SIGN: u8 = 1 << 7;

// Graciously taken from https://github.com/pcwalton/sprocketnes
static CYCLE_TABLE: [u8; 256] = [
  /*0x00*/ 7,6,2,8,3,3,5,5,3,2,2,2,4,4,6,6,
  /*0x10*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,
  /*0x20*/ 6,6,2,8,3,3,5,5,4,2,2,2,4,4,6,6,
  /*0x30*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,
  /*0x40*/ 6,6,2,8,3,3,5,5,3,2,2,2,3,4,6,6,
  /*0x50*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,
  /*0x60*/ 6,6,2,8,3,3,5,5,4,2,2,2,5,4,6,6,
  /*0x70*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,
  /*0x80*/ 2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,
  /*0x90*/ 2,6,2,6,4,4,4,4,2,5,2,5,5,5,5,5,
  /*0xA0*/ 2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,
  /*0xB0*/ 2,5,2,5,4,4,4,4,2,4,2,4,4,4,4,4,
  /*0xC0*/ 2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,
  /*0xD0*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,
  /*0xE0*/ 2,6,3,8,3,3,5,5,2,2,2,2,4,4,6,6,
  /*0xF0*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,
];

pub struct Cpu6502 {
  registers: Registers,
  memory: Memory
}

pub struct Registers {
  pc: u16, // Program Counter
  sp: u8, // Stack Pointer
  acc: u8, // Accumulator
  irx: u8, // Index Register X
  iry: u8, // Index Register Y
  stat: u8 // Processor Status Flags
}

pub enum AddressingMode {
  Immediate,
  ZeroPage,
  ZeroPageX,
  Absolute,
  AboluteX,
  AbsoluteY,
  IndirectX,
  IndirectY
}

impl Registers {
  fn new() -> Registers {
    Registers {
      pc: 0,
      sp: 0,
      acc: 0,
      irx: 0,
      iry: 0,
      stat: 0b00010000
    }
  }

  fn get_flag(&self, mask: u8) -> bool {
    self.stat & mask != 0
  }

  fn set_flag(&mut self, mask: u8, val: bool) {
    if val {
      self.stat |= mask;
    } else {
      self.stat &= !mask;
    }
  }
}

impl Cpu6502 {
 pub fn new() -> Cpu6502 {
    Cpu6502 {
      registers: Registers::new(),
      memory: Memory::new()
    }
  }

  pub fn adc(&mut self, arg: u8, mode: AddressingMode) {
    match mode {
      AddressingMode::Immediate => {
        // Cheaply determine carry flag by casting the values to the native
        // word size and checking if the result carries over to the 9th bit.
        let res = if self.registers.get_flag(FL_CARRY) { 1 } else { 0 }
            + self.registers.acc as usize + arg as usize;

        self.registers.set_flag(FL_CARRY, res & 0x100 != 0);

        let res = res as u8;
        let acc = self.registers.acc;

        // Set the overflow flag when both operands have the same sign bit AND
        // the sign bit of the result differs from the two.
        //
        // This is a clever way of determining whether or not the result overflows
        // 8-bits and works with both signed and unsigned values.
        self.registers.set_flag(FL_OVERFLOW, (acc ^ arg) & 0x80 == 0
            && (acc ^ res) & 0x80 == 0x80);

        // TODO: Set remaining flags
      },
      _ => {
        panic!("not implemented");
      }
    }
  }
}

impl Display for Cpu6502 {
  fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> {
    write!(formatter, "{}|{}|{}|{}|{}|{}",
        self.registers.pc, self.registers.sp, self.registers.acc,
        self.registers.irx, self.registers.iry, self.registers.stat)
  }
}
<commit_msg>Remove formatting trait impl<commit_after>use memory::Memory;

const FL_CARRY: u8 = 1 << 0;
const FL_STATUS: u8 = 1 << 1;
const FL_INTERRUPT_DISABLE: u8 = 1 << 2;
const FL_BRK: u8 = 1 << 4;
const FL_OVERFLOW: u8 = 1 << 6;
const FL_SIGN: u8 = 1 << 7;

// Graciously taken from https://github.com/pcwalton/sprocketnes
static CYCLE_TABLE: [u8; 256] = [
  /*0x00*/ 7,6,2,8,3,3,5,5,3,2,2,2,4,4,6,6,
  /*0x10*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,
  /*0x20*/ 6,6,2,8,3,3,5,5,4,2,2,2,4,4,6,6,
  /*0x30*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,
  /*0x40*/ 6,6,2,8,3,3,5,5,3,2,2,2,3,4,6,6,
  /*0x50*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,
  /*0x60*/ 6,6,2,8,3,3,5,5,4,2,2,2,5,4,6,6,
  /*0x70*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,
  /*0x80*/ 2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,
  /*0x90*/ 2,6,2,6,4,4,4,4,2,5,2,5,5,5,5,5,
  /*0xA0*/ 2,6,2,6,3,3,3,3,2,2,2,2,4,4,4,4,
  /*0xB0*/ 2,5,2,5,4,4,4,4,2,4,2,4,4,4,4,4,
  /*0xC0*/ 2,6,2,8,3,3,5,5,2,2,2,2,4,4,6,6,
  /*0xD0*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,
  /*0xE0*/ 2,6,3,8,3,3,5,5,2,2,2,2,4,4,6,6,
  /*0xF0*/ 2,5,2,8,4,4,6,6,2,4,2,7,4,4,7,7,
];

pub struct Cpu6502 {
  registers: Registers,
  memory: Memory
}

pub struct Registers {
  pc: u16, // Program Counter
  sp: u8, // Stack Pointer
  acc: u8, // Accumulator
  irx: u8, // Index Register X
  iry: u8, // Index Register Y
  stat: u8 // Processor Status Flags
}

pub enum AddressingMode {
  Immediate,
  ZeroPage,
  ZeroPageX,
  Absolute,
  AboluteX,
  AbsoluteY,
  IndirectX,
  IndirectY
}

impl Registers {
  fn new() -> Registers {
    Registers {
      pc: 0,
      sp: 0,
      acc: 0,
      irx: 0,
      iry: 0,
      stat: 0b00010000
    }
  }

  fn get_flag(&self, mask: u8) -> bool {
    self.stat & mask != 0
  }

  fn set_flag(&mut self, mask: u8, val: bool) {
    if val {
      self.stat |= mask;
    } else {
      self.stat &= !mask;
    }
  }
}

impl Cpu6502 {
 pub fn new() -> Cpu6502 {
    Cpu6502 {
      registers: Registers::new(),
      memory: Memory::new()
    }
  }

  pub fn adc(&mut self, arg: u8, mode: AddressingMode) {
    match mode {
      AddressingMode::Immediate => {
        // Cheaply determine carry flag by casting the values to the native
        // word size and checking if the result carries over to the 9th bit.
        let res = if self.registers.get_flag(FL_CARRY) { 1 } else { 0 }
            + self.registers.acc as usize + arg as usize;

        self.registers.set_flag(FL_CARRY, res & 0x100 != 0);

        let res = res as u8;
        let acc = self.registers.acc;

        // Set the overflow flag when both operands have the same sign bit AND
        // the sign bit of the result differs from the two.
        //
        // This is a clever way of determining whether or not the result overflows
        // 8-bits and works with both signed and unsigned values.
        self.registers.set_flag(FL_OVERFLOW, (acc ^ arg) & 0x80 == 0
            && (acc ^ res) & 0x80 == 0x80);

        // TODO: Set remaining flags
      },
      _ => {
        panic!("not implemented");
      }
    }
  }
}
<|endoftext|>


<commit_before>#![feature(test)]

extern crate test;
extern crate itertools;

use test::{black_box};
use itertools::Stride;
use itertools::Itertools;

#[cfg(feature = "unstable")]
use itertools::{ZipTrusted};

use itertools::ZipSlices;

use std::iter::repeat;
use std::cmp;

#[bench]
fn slice_iter(b: &mut test::Bencher)
{
    let xs: Vec<_> = repeat(1i32).take(20).collect();
    b.iter(|| for elt in xs.iter() {
        test::black_box(elt);
    })
}

#[bench]
fn slice_iter_rev(b: &mut test::Bencher)
{
    let xs: Vec<_> = repeat(1i32).take(20).collect();
    b.iter(|| for elt in xs.iter().rev() {
        test::black_box(elt);
    })
}

#[bench]
fn stride_iter(b: &mut test::Bencher)
{
    let xs: Vec<_> = repeat(1i32).take(20).collect();
    b.iter(|| for elt in Stride::from_slice(&xs, 1) {
        test::black_box(elt);
    })
}

#[bench]
fn stride_iter_rev(b: &mut test::Bencher)
{
    let xs: Vec<_> = repeat(1i32).take(20).collect();
    b.iter(|| for elt in Stride::from_slice(&xs, 1).rev() {
        test::black_box(elt);
    })
}

#[bench]
fn zip_default_zip(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let xs = black_box(xs);
    let ys = black_box(ys);

    b.iter(|| {
        for (&x, &y) in xs.iter().zip(&ys) {
            test::black_box(x);
            test::black_box(y);
        }
    })
}

#[bench]
fn zip_default_zip3(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let zs = vec![0; 766];
    let xs = black_box(xs);
    let ys = black_box(ys);
    let zs = black_box(zs);

    b.iter(|| {
        for ((&x, &y), &z) in xs.iter().zip(&ys).zip(&zs) {
            test::black_box(x);
            test::black_box(y);
            test::black_box(z);
        }
    })
}

/*
#[bench]
fn zip_slices_ziptuple(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];

    b.iter(|| {
        let xs = black_box(&xs);
        let ys = black_box(&ys);
        for (&x, &y) in Zip::new((xs, ys)) {
            test::black_box(x);
            test::black_box(y);
        }
    })
}
*/

#[bench]
fn zip_slices(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let xs = black_box(xs);
    let ys = black_box(ys);

    b.iter(|| {
        for (&x, &y) in ZipSlices::new(&xs, &ys) {
            test::black_box(x);
            test::black_box(y);
        }
    })
}

#[bench]
fn zip_slices_mut(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let xs = black_box(xs);
    let mut ys = black_box(ys);

    b.iter(|| {
        for (&x, &mut y) in ZipSlices::from_slices(&xs[..], &mut ys[..]) {
            test::black_box(x);
            test::black_box(y);
        }
    })
}

#[cfg(feature = "unstable")]
#[bench]
fn ziptrusted(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let xs = black_box(xs);
    let ys = black_box(ys);

    b.iter(|| {
        for (&x, &y) in ZipTrusted::new((xs.iter(), ys.iter())) {
            test::black_box(x);
            test::black_box(y);
        }
    })
}

#[cfg(feature = "unstable")]
#[bench]
fn ziptrusted3(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let zs = vec![0; 766];
    let xs = black_box(xs);
    let ys = black_box(ys);
    let zs = black_box(zs);

    b.iter(|| {
        for (&x, &y, &z) in ZipTrusted::new((xs.iter(), ys.iter(), zs.iter())) {
            test::black_box(x);
            test::black_box(y);
            test::black_box(z);
        }
    })
}

#[bench]
fn zip_checked_counted_loop(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let xs = black_box(xs);
    let ys = black_box(ys);

    b.iter(|| {
        let xs = &xs[..];
        let ys = &ys[..];
        let len = cmp::min(xs.len(), ys.len());

        for i in 0..len {
            let x = xs[i];
            let y = ys[i];
            test::black_box(x);
            test::black_box(y);
        }
    })
}

#[bench]
fn zip_unchecked_counted_loop(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let xs = black_box(xs);
    let ys = black_box(ys);

    b.iter(|| {
        let len = cmp::min(xs.len(), ys.len());
        for i in 0..len {
            unsafe {
            let x = *xs.get_unchecked(i);
            let y = *ys.get_unchecked(i);
            test::black_box(x);
            test::black_box(y);
            }
        }
    })
}

#[bench]
fn zip_unchecked_counted_loop3(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let zs = vec![0; 766];
    let xs = black_box(xs);
    let ys = black_box(ys);
    let zs = black_box(zs);

    b.iter(|| {
        let len = cmp::min(xs.len(), cmp::min(ys.len(), zs.len()));
        for i in 0..len {
            unsafe {
            let x = *xs.get_unchecked(i);
            let y = *ys.get_unchecked(i);
            let z = *zs.get_unchecked(i);
            test::black_box(x);
            test::black_box(y);
            test::black_box(z);
            }
        }
    })
}

#[bench]
fn group_by_lazy_1(b: &mut test::Bencher) {
    let mut data = vec![0; 1024];
    for (index, elt) in data.iter_mut().enumerate() {
        *elt = index / 10;
    }

    let data = test::black_box(data);

    b.iter(|| {
        for (_key, group) in &data.iter().group_by_lazy(|elt| **elt) {
            for elt in group {
                test::black_box(elt);
            }
        }
    })
}

#[bench]
fn group_by_lazy_2(b: &mut test::Bencher) {
    let mut data = vec![0; 1024];
    for (index, elt) in data.iter_mut().enumerate() {
        *elt = index / 2;
    }

    let data = test::black_box(data);

    b.iter(|| {
        for (_key, group) in &data.iter().group_by_lazy(|elt| **elt) {
            for elt in group {
                test::black_box(elt);
            }
        }
    })
}

#[bench]
fn equal(b: &mut test::Bencher) {
    let data = vec![7; 1024];
    let l = data.len();
    b.iter(|| {
        let a = test::black_box(&data[1..]);
        let b = test::black_box(&data[..l - 1]);
        itertools::equal(a, b)
    })
}
<commit_msg>bench: Fix counted checked loop<commit_after>#![feature(test)]

extern crate test;
extern crate itertools;

use test::{black_box};
use itertools::Stride;
use itertools::Itertools;

#[cfg(feature = "unstable")]
use itertools::{ZipTrusted};

use itertools::ZipSlices;

use std::iter::repeat;
use std::cmp;

#[bench]
fn slice_iter(b: &mut test::Bencher)
{
    let xs: Vec<_> = repeat(1i32).take(20).collect();
    b.iter(|| for elt in xs.iter() {
        test::black_box(elt);
    })
}

#[bench]
fn slice_iter_rev(b: &mut test::Bencher)
{
    let xs: Vec<_> = repeat(1i32).take(20).collect();
    b.iter(|| for elt in xs.iter().rev() {
        test::black_box(elt);
    })
}

#[bench]
fn stride_iter(b: &mut test::Bencher)
{
    let xs: Vec<_> = repeat(1i32).take(20).collect();
    b.iter(|| for elt in Stride::from_slice(&xs, 1) {
        test::black_box(elt);
    })
}

#[bench]
fn stride_iter_rev(b: &mut test::Bencher)
{
    let xs: Vec<_> = repeat(1i32).take(20).collect();
    b.iter(|| for elt in Stride::from_slice(&xs, 1).rev() {
        test::black_box(elt);
    })
}

#[bench]
fn zip_default_zip(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let xs = black_box(xs);
    let ys = black_box(ys);

    b.iter(|| {
        for (&x, &y) in xs.iter().zip(&ys) {
            test::black_box(x);
            test::black_box(y);
        }
    })
}

#[bench]
fn zip_default_zip3(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let zs = vec![0; 766];
    let xs = black_box(xs);
    let ys = black_box(ys);
    let zs = black_box(zs);

    b.iter(|| {
        for ((&x, &y), &z) in xs.iter().zip(&ys).zip(&zs) {
            test::black_box(x);
            test::black_box(y);
            test::black_box(z);
        }
    })
}

/*
#[bench]
fn zip_slices_ziptuple(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];

    b.iter(|| {
        let xs = black_box(&xs);
        let ys = black_box(&ys);
        for (&x, &y) in Zip::new((xs, ys)) {
            test::black_box(x);
            test::black_box(y);
        }
    })
}
*/

#[bench]
fn zip_slices(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let xs = black_box(xs);
    let ys = black_box(ys);

    b.iter(|| {
        for (&x, &y) in ZipSlices::new(&xs, &ys) {
            test::black_box(x);
            test::black_box(y);
        }
    })
}

#[bench]
fn zip_slices_mut(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let xs = black_box(xs);
    let mut ys = black_box(ys);

    b.iter(|| {
        for (&x, &mut y) in ZipSlices::from_slices(&xs[..], &mut ys[..]) {
            test::black_box(x);
            test::black_box(y);
        }
    })
}

#[cfg(feature = "unstable")]
#[bench]
fn ziptrusted(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let xs = black_box(xs);
    let ys = black_box(ys);

    b.iter(|| {
        for (&x, &y) in ZipTrusted::new((xs.iter(), ys.iter())) {
            test::black_box(x);
            test::black_box(y);
        }
    })
}

#[cfg(feature = "unstable")]
#[bench]
fn ziptrusted3(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let zs = vec![0; 766];
    let xs = black_box(xs);
    let ys = black_box(ys);
    let zs = black_box(zs);

    b.iter(|| {
        for (&x, &y, &z) in ZipTrusted::new((xs.iter(), ys.iter(), zs.iter())) {
            test::black_box(x);
            test::black_box(y);
            test::black_box(z);
        }
    })
}

#[bench]
fn zip_checked_counted_loop(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let xs = black_box(xs);
    let ys = black_box(ys);

    b.iter(|| {
        // Must slice to equal lengths, and then bounds checks are eliminated!
        let len = cmp::min(xs.len(), ys.len());
        let xs = &xs[..len];
        let ys = &ys[..len];

        for i in 0..len {
            let x = xs[i];
            let y = ys[i];
            test::black_box(x);
            test::black_box(y);
        }
    })
}

#[bench]
fn zip_unchecked_counted_loop(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let xs = black_box(xs);
    let ys = black_box(ys);

    b.iter(|| {
        let len = cmp::min(xs.len(), ys.len());
        for i in 0..len {
            unsafe {
            let x = *xs.get_unchecked(i);
            let y = *ys.get_unchecked(i);
            test::black_box(x);
            test::black_box(y);
            }
        }
    })
}

#[bench]
fn zip_unchecked_counted_loop3(b: &mut test::Bencher)
{
    let xs = vec![0; 1024];
    let ys = vec![0; 768];
    let zs = vec![0; 766];
    let xs = black_box(xs);
    let ys = black_box(ys);
    let zs = black_box(zs);

    b.iter(|| {
        let len = cmp::min(xs.len(), cmp::min(ys.len(), zs.len()));
        for i in 0..len {
            unsafe {
            let x = *xs.get_unchecked(i);
            let y = *ys.get_unchecked(i);
            let z = *zs.get_unchecked(i);
            test::black_box(x);
            test::black_box(y);
            test::black_box(z);
            }
        }
    })
}

#[bench]
fn group_by_lazy_1(b: &mut test::Bencher) {
    let mut data = vec![0; 1024];
    for (index, elt) in data.iter_mut().enumerate() {
        *elt = index / 10;
    }

    let data = test::black_box(data);

    b.iter(|| {
        for (_key, group) in &data.iter().group_by_lazy(|elt| **elt) {
            for elt in group {
                test::black_box(elt);
            }
        }
    })
}

#[bench]
fn group_by_lazy_2(b: &mut test::Bencher) {
    let mut data = vec![0; 1024];
    for (index, elt) in data.iter_mut().enumerate() {
        *elt = index / 2;
    }

    let data = test::black_box(data);

    b.iter(|| {
        for (_key, group) in &data.iter().group_by_lazy(|elt| **elt) {
            for elt in group {
                test::black_box(elt);
            }
        }
    })
}

#[bench]
fn equal(b: &mut test::Bencher) {
    let data = vec![7; 1024];
    let l = data.len();
    b.iter(|| {
        let a = test::black_box(&data[1..]);
        let b = test::black_box(&data[..l - 1]);
        itertools::equal(a, b)
    })
}
<|endoftext|>


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

//! # The Rust Standard Library
//!
//! The Rust Standard Library provides the essential runtime
//! functionality for building portable Rust software.
//! It is linked to all Rust crates by default.
//!
//! ## Intrinsic types and operations
//!
//! The [`ptr`](ptr/index.html) and [`mem`](mem/index.html)
//! modules deal with unsafe pointers and memory manipulation.
//! [`kinds`](kinds/index.html) defines the special built-in traits,
//! and [`raw`](raw/index.html) the runtime representation of Rust types.
//! These are some of the lowest-level building blocks in Rust.
//!
//! ## Math on primitive types and math traits
//!
//! Although basic operations on primitive types are implemented
//! directly by the compiler, the standard library additionally
//! defines many common operations through traits defined in
//! mod [`num`](num/index.html).
//!
//! ## Pervasive types
//!
//! The [`option`](option/index.html) and [`result`](result/index.html)
//! modules define optional and error-handling types, `Option` and `Result`.
//! [`iter`](iter/index.html) defines Rust's iterator protocol
//! along with a wide variety of iterators.
//! [`Cell` and `RefCell`](cell/index.html) are for creating types that
//! manage their own mutability.
//!
//! ## Vectors, slices and strings
//!
//! The common container type, `Vec`, a growable vector backed by an
//! array, lives in the [`vec`](vec/index.html) module. References to
//! arrays, `&[T]`, more commonly called "slices", are built-in types
//! for which the [`slice`](slice/index.html) module defines many
//! methods.
//!
//! `&str`, a UTF-8 string, is a built-in type, and the standard library
//! defines methods for it on a variety of traits in the
//! [`str`](str/index.html) module. Rust strings are immutable;
//! use the `String` type defined in [`string`](string/index.html)
//! for a mutable string builder.
//!
//! For converting to strings use the [`format!`](fmt/index.html)
//! macro, and for converting from strings use the
//! [`FromStr`](str/trait.FromStr.html) trait.
//!
//! ## Platform abstractions
//!
//! Besides basic data types, the standard library is largely concerned
//! with abstracting over differences in common platforms, most notably
//! Windows and Unix derivatives. The [`os`](os/index.html) module
//! provides a number of basic functions for interacting with the
//! operating environment, including program arguments, environment
//! variables, and directory navigation. The [`path`](path/index.html)
//! module encapsulates the platform-specific rules for dealing
//! with file paths.
//!
//! `std` also includes modules for interoperating with the
//! C language: [`c_str`](c_str/index.html) and
//! [`c_vec`](c_vec/index.html).
//!
//! ## Concurrency, I/O, and the runtime
//!
//! The [`task`](task/index.html) module contains Rust's threading abstractions,
//! while [`comm`](comm/index.html) contains the channel types for message
//! passing. [`sync`](sync/index.html) contains further, primitive, shared
//! memory types, including [`atomic`](sync/atomic/index.html).
//!
//! Common types of I/O, including files, TCP, UDP, pipes, Unix domain sockets,
//! timers, and process spawning, are defined in the [`io`](io/index.html) module.
//!
//! Rust's I/O and concurrency depends on a small runtime interface
//! that lives, along with its support code, in mod [`rt`](rt/index.html).
//! While a notable part of the standard library's architecture, this
//! module is not intended for public use.
//!
//! ## The Rust prelude and macros
//!
//! Finally, the [`prelude`](prelude/index.html) defines a
//! common set of traits, types, and functions that are made available
//! to all code by default. [`macros`](macros/index.html) contains
//! all the standard macros, such as `assert!`, `panic!`, `println!`,
//! and `format!`, also available to all Rust code.

#![crate_name = "std"]
#![unstable]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://doc.rust-lang.org/nightly/",
       html_playground_url = "http://play.rust-lang.org/")]

#![allow(unknown_features)]
#![feature(macro_rules, globs, linkage)]
#![feature(default_type_params, phase, lang_items, unsafe_destructor)]
#![feature(import_shadowing, slicing_syntax)]

// Don't link to std. We are std.
#![no_std]

#![deny(missing_docs)]

#![reexport_test_harness_main = "test_main"]

#[cfg(test)] #[phase(plugin, link)] extern crate log;

extern crate alloc;
extern crate unicode;
extern crate core;
extern crate "collections" as core_collections;
extern crate "rand" as core_rand;
extern crate libc;
extern crate rustrt;

// Make std testable by not duplicating lang items. See #2912
#[cfg(test)] extern crate "std" as realstd;
#[cfg(test)] pub use realstd::kinds;
#[cfg(test)] pub use realstd::ops;
#[cfg(test)] pub use realstd::cmp;
#[cfg(test)] pub use realstd::boxed;

// NB: These reexports are in the order they should be listed in rustdoc

pub use core::any;
pub use core::bool;
pub use core::borrow;
pub use core::cell;
pub use core::clone;
#[cfg(not(test))] pub use core::cmp;
pub use core::default;
pub use core::finally;
pub use core::intrinsics;
pub use core::iter;
#[cfg(not(test))] pub use core::kinds;
pub use core::mem;
#[cfg(not(test))] pub use core::ops;
pub use core::ptr;
pub use core::raw;
pub use core::simd;
pub use core::tuple;
// FIXME #15320: primitive documentation needs top-level modules, this
// should be `std::tuple::unit`.
pub use core::unit;
pub use core::result;
pub use core::option;

pub use alloc::boxed;
pub use alloc::rc;

pub use core_collections::slice;
pub use core_collections::str;
pub use core_collections::string;
pub use core_collections::vec;

pub use rustrt::c_str;

pub use unicode::char;

/* Exported macros */

pub mod macros;
pub mod bitflags;

mod rtdeps;

/* The Prelude. */

pub mod prelude;

/* Primitive types */

#[path = "num/float_macros.rs"] mod float_macros;
#[path = "num/int_macros.rs"]   mod int_macros;
#[path = "num/uint_macros.rs"]  mod uint_macros;

#[path = "num/int.rs"]  pub mod int;
#[path = "num/i8.rs"]   pub mod i8;
#[path = "num/i16.rs"]  pub mod i16;
#[path = "num/i32.rs"]  pub mod i32;
#[path = "num/i64.rs"]  pub mod i64;

#[path = "num/uint.rs"] pub mod uint;
#[path = "num/u8.rs"]   pub mod u8;
#[path = "num/u16.rs"]  pub mod u16;
#[path = "num/u32.rs"]  pub mod u32;
#[path = "num/u64.rs"]  pub mod u64;

#[path = "num/f32.rs"]   pub mod f32;
#[path = "num/f64.rs"]   pub mod f64;

pub mod ascii;

/* Common traits */

pub mod error;
pub mod num;

/* Runtime and platform support */

pub mod thread_local;
pub mod c_vec;
pub mod dynamic_lib;
pub mod fmt;
pub mod io;
pub mod os;
pub mod path;
pub mod rand;
pub mod time;

/* Common data structures */

pub mod collections;
pub mod hash;

/* Tasks and communication */

pub mod task;
pub mod sync;
pub mod comm;

#[cfg(unix)]
#[path = "sys/unix/mod.rs"] mod sys;
#[cfg(windows)]
#[path = "sys/windows/mod.rs"] mod sys;

#[path = "sys/common/mod.rs"] mod sys_common;

pub mod rt;
mod failure;

// A curious inner-module that's not exported that contains the binding
// 'std' so that macro-expanded references to std::error and such
// can be resolved within libstd.
#[doc(hidden)]
mod std {
    // mods used for deriving
    pub use clone;
    pub use cmp;
    pub use hash;

    pub use comm; // used for select!()
    pub use error; // used for try!()
    pub use fmt; // used for any formatting strings
    pub use io; // used for println!()
    pub use option; // used for bitflags!{}
    pub use rt; // used for panic!()
    pub use vec; // used for vec![]
    pub use cell; // used for tls!
    pub use thread_local; // used for thread_local!
    pub use kinds; // used for tls!

    // The test runner calls ::std::os::args() but really wants realstd
    #[cfg(test)] pub use realstd::os as os;
    // The test runner requires std::slice::Vector, so re-export std::slice just for it.
    //
    // It is also used in vec![]
    pub use slice;

    pub use boxed; // used for vec![]

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

//! # The Rust Standard Library
//!
//! The Rust Standard Library provides the essential runtime
//! functionality for building portable Rust software.
//! It is linked to all Rust crates by default.
//!
//! ## Intrinsic types and operations
//!
//! The [`ptr`](ptr/index.html) and [`mem`](mem/index.html)
//! modules deal with unsafe pointers and memory manipulation.
//! [`kinds`](kinds/index.html) defines the special built-in traits,
//! and [`raw`](raw/index.html) the runtime representation of Rust types.
//! These are some of the lowest-level building blocks in Rust.
//!
//! ## Math on primitive types and math traits
//!
//! Although basic operations on primitive types are implemented
//! directly by the compiler, the standard library additionally
//! defines many common operations through traits defined in
//! mod [`num`](num/index.html).
//!
//! ## Pervasive types
//!
//! The [`option`](option/index.html) and [`result`](result/index.html)
//! modules define optional and error-handling types, `Option` and `Result`.
//! [`iter`](iter/index.html) defines Rust's iterator protocol
//! along with a wide variety of iterators.
//! [`Cell` and `RefCell`](cell/index.html) are for creating types that
//! manage their own mutability.
//!
//! ## Vectors, slices and strings
//!
//! The common container type, `Vec`, a growable vector backed by an
//! array, lives in the [`vec`](vec/index.html) module. References to
//! arrays, `&[T]`, more commonly called "slices", are built-in types
//! for which the [`slice`](slice/index.html) module defines many
//! methods.
//!
//! `&str`, a UTF-8 string, is a built-in type, and the standard library
//! defines methods for it on a variety of traits in the
//! [`str`](str/index.html) module. Rust strings are immutable;
//! use the `String` type defined in [`string`](string/index.html)
//! for a mutable string builder.
//!
//! For converting to strings use the [`format!`](fmt/index.html)
//! macro, and for converting from strings use the
//! [`FromStr`](str/trait.FromStr.html) trait.
//!
//! ## Platform abstractions
//!
//! Besides basic data types, the standard library is largely concerned
//! with abstracting over differences in common platforms, most notably
//! Windows and Unix derivatives. The [`os`](os/index.html) module
//! provides a number of basic functions for interacting with the
//! operating environment, including program arguments, environment
//! variables, and directory navigation. The [`path`](path/index.html)
//! module encapsulates the platform-specific rules for dealing
//! with file paths.
//!
//! `std` also includes modules for interoperating with the
//! C language: [`c_str`](c_str/index.html) and
//! [`c_vec`](c_vec/index.html).
//!
//! ## Concurrency, I/O, and the runtime
//!
//! The [`task`](task/index.html) module contains Rust's threading abstractions,
//! while [`comm`](comm/index.html) contains the channel types for message
//! passing. [`sync`](sync/index.html) contains further, primitive, shared
//! memory types, including [`atomic`](sync/atomic/index.html).
//!
//! Common types of I/O, including files, TCP, UDP, pipes, Unix domain sockets,
//! timers, and process spawning, are defined in the [`io`](io/index.html) module.
//!
//! Rust's I/O and concurrency depends on a small runtime interface
//! that lives, along with its support code, in mod [`rt`](rt/index.html).
//! While a notable part of the standard library's architecture, this
//! module is not intended for public use.
//!
//! ## The Rust prelude and macros
//!
//! Finally, the [`prelude`](prelude/index.html) defines a
//! common set of traits, types, and functions that are made available
//! to all code by default. [`macros`](macros/index.html) contains
//! all the standard macros, such as `assert!`, `panic!`, `println!`,
//! and `format!`, also available to all Rust code.

#![crate_name = "std"]
#![unstable]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://doc.rust-lang.org/nightly/",
       html_playground_url = "http://play.rust-lang.org/")]

#![allow(unknown_features)]
#![feature(macro_rules, globs, linkage)]
#![feature(default_type_params, phase, lang_items, unsafe_destructor)]
#![feature(import_shadowing, slicing_syntax)]
#![feature(unboxed_closures)]

// Don't link to std. We are std.
#![no_std]

#![deny(missing_docs)]

#![reexport_test_harness_main = "test_main"]

#[cfg(test)] #[phase(plugin, link)] extern crate log;

extern crate alloc;
extern crate unicode;
extern crate core;
extern crate "collections" as core_collections;
extern crate "rand" as core_rand;
extern crate libc;
extern crate rustrt;

// Make std testable by not duplicating lang items. See #2912
#[cfg(test)] extern crate "std" as realstd;
#[cfg(test)] pub use realstd::kinds;
#[cfg(test)] pub use realstd::ops;
#[cfg(test)] pub use realstd::cmp;
#[cfg(test)] pub use realstd::boxed;

// NB: These reexports are in the order they should be listed in rustdoc

pub use core::any;
pub use core::bool;
pub use core::borrow;
pub use core::cell;
pub use core::clone;
#[cfg(not(test))] pub use core::cmp;
pub use core::default;
pub use core::finally;
pub use core::intrinsics;
pub use core::iter;
#[cfg(not(test))] pub use core::kinds;
pub use core::mem;
#[cfg(not(test))] pub use core::ops;
pub use core::ptr;
pub use core::raw;
pub use core::simd;
pub use core::tuple;
// FIXME #15320: primitive documentation needs top-level modules, this
// should be `std::tuple::unit`.
pub use core::unit;
pub use core::result;
pub use core::option;

pub use alloc::boxed;
pub use alloc::rc;

pub use core_collections::slice;
pub use core_collections::str;
pub use core_collections::string;
pub use core_collections::vec;

pub use rustrt::c_str;

pub use unicode::char;

/* Exported macros */

pub mod macros;
pub mod bitflags;

mod rtdeps;

/* The Prelude. */

pub mod prelude;

/* Primitive types */

#[path = "num/float_macros.rs"] mod float_macros;
#[path = "num/int_macros.rs"]   mod int_macros;
#[path = "num/uint_macros.rs"]  mod uint_macros;

#[path = "num/int.rs"]  pub mod int;
#[path = "num/i8.rs"]   pub mod i8;
#[path = "num/i16.rs"]  pub mod i16;
#[path = "num/i32.rs"]  pub mod i32;
#[path = "num/i64.rs"]  pub mod i64;

#[path = "num/uint.rs"] pub mod uint;
#[path = "num/u8.rs"]   pub mod u8;
#[path = "num/u16.rs"]  pub mod u16;
#[path = "num/u32.rs"]  pub mod u32;
#[path = "num/u64.rs"]  pub mod u64;

#[path = "num/f32.rs"]   pub mod f32;
#[path = "num/f64.rs"]   pub mod f64;

pub mod ascii;

/* Common traits */

pub mod error;
pub mod num;

/* Runtime and platform support */

pub mod thread_local;
pub mod c_vec;
pub mod dynamic_lib;
pub mod fmt;
pub mod io;
pub mod os;
pub mod path;
pub mod rand;
pub mod time;

/* Common data structures */

pub mod collections;
pub mod hash;

/* Tasks and communication */

pub mod task;
pub mod sync;
pub mod comm;

#[cfg(unix)]
#[path = "sys/unix/mod.rs"] mod sys;
#[cfg(windows)]
#[path = "sys/windows/mod.rs"] mod sys;

#[path = "sys/common/mod.rs"] mod sys_common;

pub mod rt;
mod failure;

// A curious inner-module that's not exported that contains the binding
// 'std' so that macro-expanded references to std::error and such
// can be resolved within libstd.
#[doc(hidden)]
mod std {
    // mods used for deriving
    pub use clone;
    pub use cmp;
    pub use hash;

    pub use comm; // used for select!()
    pub use error; // used for try!()
    pub use fmt; // used for any formatting strings
    pub use io; // used for println!()
    pub use option; // used for bitflags!{}
    pub use rt; // used for panic!()
    pub use vec; // used for vec![]
    pub use cell; // used for tls!
    pub use thread_local; // used for thread_local!
    pub use kinds; // used for tls!

    // The test runner calls ::std::os::args() but really wants realstd
    #[cfg(test)] pub use realstd::os as os;
    // The test runner requires std::slice::Vector, so re-export std::slice just for it.
    //
    // It is also used in vec![]
    pub use slice;

    pub use boxed; // used for vec![]

}
<|endoftext|>


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

//! # The Rust Standard Library
//!
//! The Rust Standard Library provides the essential runtime
//! functionality for building portable Rust software.
//! It is linked to all Rust crates by default.
//!
//! ## Intrinsic types and operations
//!
//! The [`ptr`](ptr/index.html) and [`mem`](mem/index.html)
//! modules deal with unsafe pointers and memory manipulation.
//! [`marker`](marker/index.html) defines the special built-in traits,
//! and [`raw`](raw/index.html) the runtime representation of Rust types.
//! These are some of the lowest-level building blocks in Rust.
//!
//! ## Math on primitive types and math traits
//!
//! Although basic operations on primitive types are implemented
//! directly by the compiler, the standard library additionally
//! defines many common operations through traits defined in
//! mod [`num`](num/index.html).
//!
//! ## Pervasive types
//!
//! The [`option`](option/index.html) and [`result`](result/index.html)
//! modules define optional and error-handling types, `Option` and `Result`.
//! [`iter`](iter/index.html) defines Rust's iterator protocol
//! along with a wide variety of iterators.
//! [`Cell` and `RefCell`](cell/index.html) are for creating types that
//! manage their own mutability.
//!
//! ## Vectors, slices and strings
//!
//! The common container type, `Vec`, a growable vector backed by an
//! array, lives in the [`vec`](vec/index.html) module. References to
//! arrays, `&[T]`, more commonly called "slices", are built-in types
//! for which the [`slice`](slice/index.html) module defines many
//! methods.
//!
//! `&str`, a UTF-8 string, is a built-in type, and the standard library
//! defines methods for it on a variety of traits in the
//! [`str`](str/index.html) module. Rust strings are immutable;
//! use the `String` type defined in [`string`](string/index.html)
//! for a mutable string builder.
//!
//! For converting to strings use the [`format!`](fmt/index.html)
//! macro, and for converting from strings use the
//! [`FromStr`](str/trait.FromStr.html) trait.
//!
//! ## Platform abstractions
//!
//! Besides basic data types, the standard library is largely concerned
//! with abstracting over differences in common platforms, most notably
//! Windows and Unix derivatives. The [`os`](os/index.html) module
//! provides a number of basic functions for interacting with the
//! operating environment, including program arguments, environment
//! variables, and directory navigation. The [`path`](path/index.html)
//! module encapsulates the platform-specific rules for dealing
//! with file paths.
//!
//! `std` also includes modules for interoperating with the
//! C language: [`c_str`](c_str/index.html) and
//! [`c_vec`](c_vec/index.html).
//!
//! ## Concurrency, I/O, and the runtime
//!
//! The [`thread`](thread/index.html) module contains Rust's threading abstractions.
//! [`sync`](sync/index.html) contains further, primitive, shared memory types,
//! including [`atomic`](sync/atomic/index.html), and [`mpsc`](sync/mpmc/index.html),
//! which contains the channel types for message passing.
//!
//! Common types of I/O, including files, TCP, UDP, pipes, Unix domain sockets,
//! timers, and process spawning, are defined in the
//! [`old_io`](old_io/index.html) module.
//!
//! Rust's I/O and concurrency depends on a small runtime interface
//! that lives, along with its support code, in mod [`rt`](rt/index.html).
//! While a notable part of the standard library's architecture, this
//! module is not intended for public use.
//!
//! ## The Rust prelude and macros
//!
//! Finally, the [`prelude`](prelude/index.html) defines a
//! common set of traits, types, and functions that are made available
//! to all code by default. [`macros`](macros/index.html) contains
//! all the standard macros, such as `assert!`, `panic!`, `println!`,
//! and `format!`, also available to all Rust code.
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "std"]
#![stable(feature = "rust1", since = "1.0.0")]
#![staged_api]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://doc.rust-lang.org/nightly/",
       html_playground_url = "http://play.rust-lang.org/")]

#![feature(alloc)]
#![feature(box_syntax)]
#![feature(collections)]
#![feature(core)]
#![feature(hash)]
#![feature(lang_items)]
#![feature(libc)]
#![feature(linkage, thread_local, asm)]
#![feature(old_impl_check)]
#![feature(optin_builtin_traits)]
#![feature(rand)]
#![feature(staged_api)]
#![feature(unboxed_closures)]
#![feature(unicode)]
#![feature(unsafe_destructor)]
#![feature(unsafe_no_drop_flag)]
#![feature(macro_reexport)]
#![feature(hash)]
#![feature(int_uint)]
#![feature(unique)]
#![feature(allow_internal_unstable)]
#![feature(str_char)]
#![cfg_attr(test, feature(test, rustc_private))]

// Don't link to std. We are std.
#![feature(no_std)]
#![no_std]

#![deny(missing_docs)]

#[cfg(test)] extern crate test;
#[cfg(test)] #[macro_use] extern crate log;

#[macro_use]
#[macro_reexport(assert, assert_eq, debug_assert, debug_assert_eq,
    unreachable, unimplemented, write, writeln)]
extern crate core;

#[macro_use]
#[macro_reexport(vec, format)]
extern crate "collections" as core_collections;

#[allow(deprecated)] extern crate "rand" as core_rand;
extern crate alloc;
extern crate unicode;
extern crate libc;

#[macro_use] #[no_link] extern crate rustc_bitflags;

// Make std testable by not duplicating lang items. See #2912
#[cfg(test)] extern crate "std" as realstd;
#[cfg(test)] pub use realstd::marker;
#[cfg(test)] pub use realstd::ops;
#[cfg(test)] pub use realstd::cmp;
#[cfg(test)] pub use realstd::boxed;

// NB: These reexports are in the order they should be listed in rustdoc

pub use core::any;
pub use core::cell;
pub use core::clone;
#[cfg(not(test))] pub use core::cmp;
pub use core::default;
#[allow(deprecated)]
pub use core::finally;
pub use core::hash;
pub use core::intrinsics;
pub use core::iter;
#[cfg(not(test))] pub use core::marker;
pub use core::mem;
#[cfg(not(test))] pub use core::ops;
pub use core::ptr;
pub use core::raw;
pub use core::simd;
pub use core::result;
pub use core::option;
pub use core::error;

#[cfg(not(test))] pub use alloc::boxed;
pub use alloc::rc;

pub use core_collections::borrow;
pub use core_collections::fmt;
pub use core_collections::slice;
pub use core_collections::str;
pub use core_collections::string;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core_collections::vec;

pub use unicode::char;

/* Exported macros */

#[macro_use]
mod macros;

mod rtdeps;

/* The Prelude. */

pub mod prelude;

/* Primitive types */

#[path = "num/float_macros.rs"]
#[macro_use]
mod float_macros;

#[path = "num/int_macros.rs"]
#[macro_use]
mod int_macros;

#[path = "num/uint_macros.rs"]
#[macro_use]
mod uint_macros;

#[path = "num/isize.rs"]  pub mod isize;
#[path = "num/i8.rs"]   pub mod i8;
#[path = "num/i16.rs"]  pub mod i16;
#[path = "num/i32.rs"]  pub mod i32;
#[path = "num/i64.rs"]  pub mod i64;

#[path = "num/usize.rs"] pub mod usize;
#[path = "num/u8.rs"]   pub mod u8;
#[path = "num/u16.rs"]  pub mod u16;
#[path = "num/u32.rs"]  pub mod u32;
#[path = "num/u64.rs"]  pub mod u64;

#[path = "num/f32.rs"]   pub mod f32;
#[path = "num/f64.rs"]   pub mod f64;

pub mod ascii;
pub mod thunk;

/* Common traits */

pub mod num;

/* Runtime and platform support */

#[macro_use]
pub mod thread_local;

pub mod dynamic_lib;
pub mod ffi;
pub mod old_io;
pub mod io;
pub mod fs;
pub mod net;
pub mod os;
pub mod env;
pub mod path;
pub mod old_path;
pub mod process;
pub mod rand;
pub mod time;

/* Common data structures */

pub mod collections;

/* Threads and communication */

pub mod thread;
pub mod sync;

#[macro_use]
#[path = "sys/common/mod.rs"] mod sys_common;

#[cfg(unix)]
#[path = "sys/unix/mod.rs"] mod sys;
#[cfg(windows)]
#[path = "sys/windows/mod.rs"] mod sys;

pub mod rt;
mod panicking;

// Documentation for primitive types

mod bool;
mod unit;
mod tuple;

// A curious inner-module that's not exported that contains the binding
// 'std' so that macro-expanded references to std::error and such
// can be resolved within libstd.
#[doc(hidden)]
mod std {
    pub use sync; // used for select!()
    pub use error; // used for try!()
    pub use fmt; // used for any formatting strings
    #[allow(deprecated)]
    pub use old_io; // used for println!()
    pub use option; // used for bitflags!{}
    pub use rt; // used for panic!()
    pub use vec; // used for vec![]
    pub use cell; // used for tls!
    pub use thread_local; // used for thread_local!
    pub use marker;  // used for tls!
    pub use ops; // used for bitflags!

    // The test runner calls ::std::env::args() but really wants realstd
    #[cfg(test)] pub use realstd::env as env;
    // The test runner requires std::slice::Vector, so re-export std::slice just for it.
    //
    // It is also used in vec![]
    pub use slice;

    pub use boxed; // used for vec![]
}
<commit_msg>Rollup merge of #23641 - steveklabnik:gh23632, r=alexcrichton<commit_after>// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! # The Rust Standard Library
//!
//! The Rust Standard Library provides the essential runtime
//! functionality for building portable Rust software.
//! It is linked to all Rust crates by default.
//!
//! ## Intrinsic types and operations
//!
//! The [`ptr`](ptr/index.html) and [`mem`](mem/index.html)
//! modules deal with unsafe pointers and memory manipulation.
//! [`marker`](marker/index.html) defines the special built-in traits,
//! and [`raw`](raw/index.html) the runtime representation of Rust types.
//! These are some of the lowest-level building blocks in Rust.
//!
//! ## Math on primitive types and math traits
//!
//! Although basic operations on primitive types are implemented
//! directly by the compiler, the standard library additionally
//! defines many common operations through traits defined in
//! mod [`num`](num/index.html).
//!
//! ## Pervasive types
//!
//! The [`option`](option/index.html) and [`result`](result/index.html)
//! modules define optional and error-handling types, `Option` and `Result`.
//! [`iter`](iter/index.html) defines Rust's iterator protocol
//! along with a wide variety of iterators.
//! [`Cell` and `RefCell`](cell/index.html) are for creating types that
//! manage their own mutability.
//!
//! ## Vectors, slices and strings
//!
//! The common container type, `Vec`, a growable vector backed by an array,
//! lives in the [`vec`](vec/index.html) module. Contiguous, unsized regions
//! of memory, `[T]`, commonly called "slices", and their borrowed versions,
//! `&[T]`, commonly called "borrowed slices", are built-in types for which the
//! for which the [`slice`](slice/index.html) module defines many methods.
//!
//! `&str`, a UTF-8 string, is a built-in type, and the standard library
//! defines methods for it on a variety of traits in the
//! [`str`](str/index.html) module. Rust strings are immutable;
//! use the `String` type defined in [`string`](string/index.html)
//! for a mutable string builder.
//!
//! For converting to strings use the [`format!`](fmt/index.html)
//! macro, and for converting from strings use the
//! [`FromStr`](str/trait.FromStr.html) trait.
//!
//! ## Platform abstractions
//!
//! Besides basic data types, the standard library is largely concerned
//! with abstracting over differences in common platforms, most notably
//! Windows and Unix derivatives. The [`os`](os/index.html) module
//! provides a number of basic functions for interacting with the
//! operating environment, including program arguments, environment
//! variables, and directory navigation. The [`path`](path/index.html)
//! module encapsulates the platform-specific rules for dealing
//! with file paths.
//!
//! `std` also includes modules for interoperating with the
//! C language: [`c_str`](c_str/index.html) and
//! [`c_vec`](c_vec/index.html).
//!
//! ## Concurrency, I/O, and the runtime
//!
//! The [`thread`](thread/index.html) module contains Rust's threading abstractions.
//! [`sync`](sync/index.html) contains further, primitive, shared memory types,
//! including [`atomic`](sync/atomic/index.html), and [`mpsc`](sync/mpmc/index.html),
//! which contains the channel types for message passing.
//!
//! Common types of I/O, including files, TCP, UDP, pipes, Unix domain sockets,
//! timers, and process spawning, are defined in the
//! [`old_io`](old_io/index.html) module.
//!
//! Rust's I/O and concurrency depends on a small runtime interface
//! that lives, along with its support code, in mod [`rt`](rt/index.html).
//! While a notable part of the standard library's architecture, this
//! module is not intended for public use.
//!
//! ## The Rust prelude and macros
//!
//! Finally, the [`prelude`](prelude/index.html) defines a
//! common set of traits, types, and functions that are made available
//! to all code by default. [`macros`](macros/index.html) contains
//! all the standard macros, such as `assert!`, `panic!`, `println!`,
//! and `format!`, also available to all Rust code.
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "std"]
#![stable(feature = "rust1", since = "1.0.0")]
#![staged_api]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "http://www.rust-lang.org/favicon.ico",
       html_root_url = "http://doc.rust-lang.org/nightly/",
       html_playground_url = "http://play.rust-lang.org/")]

#![feature(alloc)]
#![feature(box_syntax)]
#![feature(collections)]
#![feature(core)]
#![feature(hash)]
#![feature(lang_items)]
#![feature(libc)]
#![feature(linkage, thread_local, asm)]
#![feature(old_impl_check)]
#![feature(optin_builtin_traits)]
#![feature(rand)]
#![feature(staged_api)]
#![feature(unboxed_closures)]
#![feature(unicode)]
#![feature(unsafe_destructor)]
#![feature(unsafe_no_drop_flag)]
#![feature(macro_reexport)]
#![feature(hash)]
#![feature(int_uint)]
#![feature(unique)]
#![feature(allow_internal_unstable)]
#![feature(str_char)]
#![cfg_attr(test, feature(test, rustc_private))]

// Don't link to std. We are std.
#![feature(no_std)]
#![no_std]

#![deny(missing_docs)]

#[cfg(test)] extern crate test;
#[cfg(test)] #[macro_use] extern crate log;

#[macro_use]
#[macro_reexport(assert, assert_eq, debug_assert, debug_assert_eq,
    unreachable, unimplemented, write, writeln)]
extern crate core;

#[macro_use]
#[macro_reexport(vec, format)]
extern crate "collections" as core_collections;

#[allow(deprecated)] extern crate "rand" as core_rand;
extern crate alloc;
extern crate unicode;
extern crate libc;

#[macro_use] #[no_link] extern crate rustc_bitflags;

// Make std testable by not duplicating lang items. See #2912
#[cfg(test)] extern crate "std" as realstd;
#[cfg(test)] pub use realstd::marker;
#[cfg(test)] pub use realstd::ops;
#[cfg(test)] pub use realstd::cmp;
#[cfg(test)] pub use realstd::boxed;

// NB: These reexports are in the order they should be listed in rustdoc

pub use core::any;
pub use core::cell;
pub use core::clone;
#[cfg(not(test))] pub use core::cmp;
pub use core::default;
#[allow(deprecated)]
pub use core::finally;
pub use core::hash;
pub use core::intrinsics;
pub use core::iter;
#[cfg(not(test))] pub use core::marker;
pub use core::mem;
#[cfg(not(test))] pub use core::ops;
pub use core::ptr;
pub use core::raw;
pub use core::simd;
pub use core::result;
pub use core::option;
pub use core::error;

#[cfg(not(test))] pub use alloc::boxed;
pub use alloc::rc;

pub use core_collections::borrow;
pub use core_collections::fmt;
pub use core_collections::slice;
pub use core_collections::str;
pub use core_collections::string;
#[stable(feature = "rust1", since = "1.0.0")]
pub use core_collections::vec;

pub use unicode::char;

/* Exported macros */

#[macro_use]
mod macros;

mod rtdeps;

/* The Prelude. */

pub mod prelude;

/* Primitive types */

#[path = "num/float_macros.rs"]
#[macro_use]
mod float_macros;

#[path = "num/int_macros.rs"]
#[macro_use]
mod int_macros;

#[path = "num/uint_macros.rs"]
#[macro_use]
mod uint_macros;

#[path = "num/isize.rs"]  pub mod isize;
#[path = "num/i8.rs"]   pub mod i8;
#[path = "num/i16.rs"]  pub mod i16;
#[path = "num/i32.rs"]  pub mod i32;
#[path = "num/i64.rs"]  pub mod i64;

#[path = "num/usize.rs"] pub mod usize;
#[path = "num/u8.rs"]   pub mod u8;
#[path = "num/u16.rs"]  pub mod u16;
#[path = "num/u32.rs"]  pub mod u32;
#[path = "num/u64.rs"]  pub mod u64;

#[path = "num/f32.rs"]   pub mod f32;
#[path = "num/f64.rs"]   pub mod f64;

pub mod ascii;
pub mod thunk;

/* Common traits */

pub mod num;

/* Runtime and platform support */

#[macro_use]
pub mod thread_local;

pub mod dynamic_lib;
pub mod ffi;
pub mod old_io;
pub mod io;
pub mod fs;
pub mod net;
pub mod os;
pub mod env;
pub mod path;
pub mod old_path;
pub mod process;
pub mod rand;
pub mod time;

/* Common data structures */

pub mod collections;

/* Threads and communication */

pub mod thread;
pub mod sync;

#[macro_use]
#[path = "sys/common/mod.rs"] mod sys_common;

#[cfg(unix)]
#[path = "sys/unix/mod.rs"] mod sys;
#[cfg(windows)]
#[path = "sys/windows/mod.rs"] mod sys;

pub mod rt;
mod panicking;

// Documentation for primitive types

mod bool;
mod unit;
mod tuple;

// A curious inner-module that's not exported that contains the binding
// 'std' so that macro-expanded references to std::error and such
// can be resolved within libstd.
#[doc(hidden)]
mod std {
    pub use sync; // used for select!()
    pub use error; // used for try!()
    pub use fmt; // used for any formatting strings
    #[allow(deprecated)]
    pub use old_io; // used for println!()
    pub use option; // used for bitflags!{}
    pub use rt; // used for panic!()
    pub use vec; // used for vec![]
    pub use cell; // used for tls!
    pub use thread_local; // used for thread_local!
    pub use marker;  // used for tls!
    pub use ops; // used for bitflags!

    // The test runner calls ::std::env::args() but really wants realstd
    #[cfg(test)] pub use realstd::env as env;
    // The test runner requires std::slice::Vector, so re-export std::slice just for it.
    //
    // It is also used in vec![]
    pub use slice;

    pub use boxed; // used for vec![]
}
<|endoftext|>


<commit_before>use std::old_io::{IoResult, EndOfFile, IoError};
use bytes;

pub struct LineReader<'a, R> {
    block: Vec<u8>,

    inner: R,
    buf: Vec<u8>,
    pos: usize,
    cap: usize,
}

static DEFAULT_BUF_SIZE: usize = 64 * 1024;

impl<'a, R: Reader> LineReader<'a, R> {

    pub fn with_capacity(cap: usize, inner: R) -> LineReader<'a, R> {
        let mut buf = Vec::with_capacity(cap);
        unsafe { buf.set_len(cap); }
        LineReader {
            block: Vec::new(),

            inner: inner,
            buf: buf,
            pos: 0,
            cap: 0,
        }
    }

    pub fn new(inner: R) -> LineReader<'a, R> {
        LineReader::with_capacity(DEFAULT_BUF_SIZE, inner)
    }

    // private
    fn fill_buf(&'a mut self) -> IoResult<()> {
        if self.pos == self.cap {
            self.cap = try!(self.inner.read(&mut self.buf[]));
            self.pos = 0;
        }
        Ok(())
    }

    fn read_until(&'a mut self, byte: u8) -> IoResult<&'a [u8]> {
        // ~ clear our previously delivered block - if any
        unsafe { self.block.set_len(0); }

        loop {
            // ensure we have data to process
            match self.fill_buf() {
                Ok(_) => {},
                Err(e@IoError{kind: EndOfFile, ..}) => {
                    return if self.block.is_empty() {
                        Err(e)
                    } else {
                        Ok(&self.block[])
                    };
                }
                Err(e) => return Err(e),
            };

            // note: we're dealing here with buf, pos, cap directly
            // to avoid the mutability checker from getting in our way
            let b = &self.buf[self.pos .. self.cap];
            match bytes::index(b, byte) {
                Some(mut i) => {
                    i += 1;
                    let b = if self.block.is_empty() {
                        &self.buf[self.pos .. self.pos+i]
                    } else {
                        self.block.push_all(&b[..i]);
                        &self.block[]
                    };
                    self.pos += i;
                    return Ok(b);
                }
                None => {
                    self.block.push_all(b);
                    self.pos += b.len();
                    // continue looping
                }
            }
        }
    }

    #[inline]
    pub fn read_line(&'a mut self) -> IoResult<&'a [u8]> {
        self.read_until(b'\n')
    }

}

#[macro_export]
macro_rules! read_lines {
    ($inp:ident in $expr:expr, $b:block) => {
        { let ref mut r = &mut $expr;
          loop {
              let $inp = r.read_line();
              match $inp {
                  Err(::std::old_io::IoError{kind: ::std::old_io::EndOfFile, ..}) => {
                      break
                  }
                  _ => { $b }
              };
          };
        }
    }
}

pub fn count_lines<'a, R: Reader> (mut r: LineReader<'a, R>)
    -> IoResult<usize>
{
    let mut lines = 0us;
    read_lines!(line in r, {
        match line {
            Err(e) => return Err(e),
            Ok(_) => lines += 1,
        }
    });
    Ok(lines)
}
<commit_msg>Avoid useless lifetype parameter<commit_after>use std::old_io::{IoResult, EndOfFile, IoError};
use bytes;

pub struct LineReader<R> {
    block: Vec<u8>,

    inner: R,
    buf: Vec<u8>,
    pos: usize,
    cap: usize,
}

static DEFAULT_BUF_SIZE: usize = 64 * 1024;

impl<R: Reader> LineReader<R> {

    pub fn with_capacity(cap: usize, inner: R) -> LineReader<R> {
        let mut buf = Vec::with_capacity(cap);
        unsafe { buf.set_len(cap); }
        LineReader {
            block: Vec::new(),

            inner: inner,
            buf: buf,
            pos: 0,
            cap: 0,
        }
    }

    pub fn new(inner: R) -> LineReader<R> {
        LineReader::with_capacity(DEFAULT_BUF_SIZE, inner)
    }

    // private
    fn fill_buf<'a>(&'a mut self) -> IoResult<()> {
        if self.pos == self.cap {
            self.cap = try!(self.inner.read(&mut self.buf[]));
            self.pos = 0;
        }
        Ok(())
    }

    fn read_until<'a>(&'a mut self, byte: u8) -> IoResult<&'a [u8]> {
        // ~ clear our previously delivered block - if any
        unsafe { self.block.set_len(0); }

        loop {
            // ensure we have data to process
            match self.fill_buf() {
                Ok(_) => {},
                Err(e@IoError{kind: EndOfFile, ..}) => {
                    return if self.block.is_empty() {
                        Err(e)
                    } else {
                        Ok(&self.block[])
                    };
                }
                Err(e) => return Err(e),
            };

            // note: we're dealing here with buf, pos, cap directly
            // to avoid the mutability checker from getting in our way
            let b = &self.buf[self.pos .. self.cap];
            match bytes::index(b, byte) {
                Some(mut i) => {
                    i += 1;
                    let b = if self.block.is_empty() {
                        &self.buf[self.pos .. self.pos+i]
                    } else {
                        self.block.push_all(&b[..i]);
                        &self.block[]
                    };
                    self.pos += i;
                    return Ok(b);
                }
                None => {
                    self.block.push_all(b);
                    self.pos += b.len();
                    // continue looping
                }
            }
        }
    }

    #[inline]
    pub fn read_line<'a>(&'a mut self) -> IoResult<&'a [u8]> {
        self.read_until(b'\n')
    }

}

#[macro_export]
macro_rules! read_lines {
    ($inp:ident in $expr:expr, $b:block) => {
        { let ref mut r = &mut $expr;
          loop {
              let $inp = r.read_line();
              match $inp {
                  Err(::std::old_io::IoError{kind: ::std::old_io::EndOfFile, ..}) => {
                      break
                  }
                  _ => { $b }
              };
          };
        }
    }
}

pub fn count_lines<R: Reader> (mut r: LineReader<R>)
    -> IoResult<usize>
{
    let mut lines = 0us;
    read_lines!(line in r, {
        match line {
            Err(e) => return Err(e),
            Ok(_) => lines += 1,
        }
    });
    Ok(lines)
}
<|endoftext|>


<commit_before>extern crate libc;
use std::str;
use std::ffi;
use self::libc::{size_t, c_char, time_t, uint32_t};

#[repr(C)]
struct memcached_st;

#[repr(C)]
struct memcached_return_t;

#[link(name = "memcached")]
extern {
    fn memcached(string: *const c_char, string_length: size_t) -> *const memcached_st;
    fn memcached_last_error_message(client: *const memcached_st) -> *const c_char;
    fn memcached_set(client: *const memcached_st, key: *const c_char, key_length: size_t, value: *const c_char, value_length: size_t, expire: time_t, flag: uint32_t);
}

#[test]
fn test_memcaced() {
    unsafe {
        let s = "--SERVER=localhost";
        let string = ffi::CString::new(s).unwrap();
        let client = memcached(string.as_ptr(), 18);
        println!("{:?}", client);
        assert!(!client.is_null());
    }
}

#[test]
fn test_memcached_last_error_message() {
    unsafe {
        let string = ffi::CString::new("foo").unwrap();
        let client = memcached(string.as_ptr(), 3);
        let error = memcached_last_error_message(client);
        let slice = ffi::CStr::from_ptr(error);
        println!("string returned: {}", str::from_utf8(slice.to_bytes()).unwrap());
        assert!(!error.is_null());
    }
}

#[test]
fn test_memcached_set() {
    unsafe{
        let s = "--SERVER=localhost";
        let string = ffi::CString::new(s).unwrap();
        let client = memcached(string.as_ptr(), 18);
        assert!(!client.is_null());

        let key = ffi::CString::new("foo").unwrap().as_ptr();
        let key_length = 3;
        let value = ffi::CString::new("bar").unwrap().as_ptr();
        let value_length = 3;
        let r = memcached_set(client, key, key_length, value, value_length, 0, 0);
        println!("{:?}", r);

        let error = memcached_last_error_message(client);
        let slice = ffi::CStr::from_ptr(error);
        println!("string returned: {}", str::from_utf8(slice.to_bytes()).unwrap());
    }
}
<commit_msg>add memcached_flush<commit_after>extern crate libc;
use std::str;
use std::ffi;
use self::libc::{size_t, c_char, time_t, uint32_t};

#[repr(C)]
struct memcached_st;

#[repr(C)]
#[derive(Debug)]
enum memcached_return_t {
    MEMCACHED_SUCCESS,
    MEMCACHED_FAILURE,
    MEMCACHED_HOST_LOOKUP_FAILURE, // getaddrinfo() and getnameinfo() only
    MEMCACHED_CONNECTION_FAILURE,
    MEMCACHED_CONNECTION_BIND_FAILURE,  // DEPRECATED, see MEMCACHED_HOST_LOOKUP_FAILURE
    MEMCACHED_WRITE_FAILURE,
    MEMCACHED_READ_FAILURE,
    MEMCACHED_UNKNOWN_READ_FAILURE,
    MEMCACHED_PROTOCOL_ERROR,
    MEMCACHED_CLIENT_ERROR,
    MEMCACHED_SERVER_ERROR, // Server returns "SERVER_ERROR"
    MEMCACHED_ERROR, // Server returns "ERROR"
    MEMCACHED_DATA_EXISTS,
    MEMCACHED_DATA_DOES_NOT_EXIST,
    MEMCACHED_NOTSTORED,
    MEMCACHED_STORED,
    MEMCACHED_NOTFOUND,
    MEMCACHED_MEMORY_ALLOCATION_FAILURE,
    MEMCACHED_PARTIAL_READ,
    MEMCACHED_SOME_ERRORS,
    MEMCACHED_NO_SERVERS,
    MEMCACHED_END,
    MEMCACHED_DELETED,
    MEMCACHED_VALUE,
    MEMCACHED_STAT,
    MEMCACHED_ITEM,
    MEMCACHED_ERRNO,
    MEMCACHED_FAIL_UNIX_SOCKET, // DEPRECATED
    MEMCACHED_NOT_SUPPORTED,
    MEMCACHED_NO_KEY_PROVIDED, /* Deprecated. Use MEMCACHED_BAD_KEY_PROVIDED! */
    MEMCACHED_FETCH_NOTFINISHED,
    MEMCACHED_TIMEOUT,
    MEMCACHED_BUFFERED,
    MEMCACHED_BAD_KEY_PROVIDED,
    MEMCACHED_INVALID_HOST_PROTOCOL,
    MEMCACHED_SERVER_MARKED_DEAD,
    MEMCACHED_UNKNOWN_STAT_KEY,
    MEMCACHED_E2BIG,
    MEMCACHED_INVALID_ARGUMENTS,
    MEMCACHED_KEY_TOO_BIG,
    MEMCACHED_AUTH_PROBLEM,
    MEMCACHED_AUTH_FAILURE,
    MEMCACHED_AUTH_CONTINUE,
    MEMCACHED_PARSE_ERROR,
    MEMCACHED_PARSE_USER_ERROR,
    MEMCACHED_DEPRECATED,
    MEMCACHED_IN_PROGRESS,
    MEMCACHED_SERVER_TEMPORARILY_DISABLED,
    MEMCACHED_SERVER_MEMORY_ALLOCATION_FAILURE,
    MEMCACHED_MAXIMUM_RETURN, /* Always add new error code before */
    // MEMCACHED_CONNECTION_SOCKET_CREATE_FAILURE= MEMCACHED_ERROR
}

#[link(name = "memcached")]
extern {
    fn memcached(string: *const c_char, string_length: size_t) -> *const memcached_st;
    fn memcached_last_error_message(client: *const memcached_st) -> *const c_char;
    fn memcached_strerror(client: *const memcached_st, rc: memcached_return_t) -> *const c_char;
    fn memcached_set(client: *const memcached_st, key: *const c_char, key_length: size_t, value: *const c_char, value_length: size_t, expiration: time_t, flag: uint32_t) -> memcached_return_t;
    fn memcached_flush(client: *const memcached_st, expiration: time_t) -> memcached_return_t;

}

#[test]
fn test_memcaced() {
    unsafe {
        let s = "--SERVER=localhost";
        let string = ffi::CString::new(s).unwrap();
        let client = memcached(string.as_ptr(), 18);
        println!("{:?}", client);
        assert!(!client.is_null());
    }
}

#[test]
fn test_memcached_last_error_message() {
    unsafe {
        let string = ffi::CString::new("foo").unwrap();
        let client = memcached(string.as_ptr(), 3);
        let error = memcached_last_error_message(client);
        let slice = ffi::CStr::from_ptr(error);
        println!("string returned: {}", str::from_utf8(slice.to_bytes()).unwrap());
        assert!(!error.is_null());
    }
}

#[test]
fn test_memcached_set() {
    unsafe{
        let s = "--SERVER=localhost";
        let string = ffi::CString::new(s).unwrap();
        let client = memcached(string.as_ptr(), 18);
        assert!(!client.is_null());

        let key = ffi::CString::new("foo").unwrap().as_ptr();
        let key_length = 3;
        let value = ffi::CString::new("bar").unwrap().as_ptr();
        let value_length = 3;
        let r = memcached_set(client, key, key_length, value, value_length, 0, 0);

        match r {
            memcached_return_t::MEMCACHED_SUCCESS => {}
            _ => assert!(false)
        }
    }
}

#[test]
fn test_memcached_flush() {
    unsafe{
        let s = "--SERVER=localhost";
        let string = ffi::CString::new(s).unwrap();
        let client = memcached(string.as_ptr(), 18);
        assert!(!client.is_null());

        let r = memcached_flush(client, 0);
        match r {
            memcached_return_t::MEMCACHED_SUCCESS => {}
            _ => assert!(false)
        }
    }
}
<|endoftext|>