#![allow(dead_code)]
use std::io::{self, Read};
use std::fs::File;
macro_rules! assert_has_more {
($self:ident) => { assert!($self.has_more(), "InputReader: Reached end of input!"); }
}
pub struct InputReader {
reader: Box<dyn Read>,
buf: Vec<u8>,
bytes_read: usize,
current_index: usize,
str_buf: String,
}
impl InputReader {
pub fn new() -> Self {
Self::from_reader(Box::new( io::stdin() ))
}
pub fn from_file(path: &str) -> Self {
let file = Box::new( File::open(path).unwrap() );
Self::from_reader(file)
}
pub fn from_reader(reader: Box<dyn Read>) -> Self {
InputReader {
reader,
buf: vec![0; 1 << 16],
bytes_read: 0,
current_index: 0,
str_buf: String::with_capacity(1 << 8),
}
}
}
impl InputReader {
pub fn has_more(&mut self) -> bool {
self.ensure_buffer();
self.bytes_read > 0
}
pub fn next_word(&mut self) -> &str {
self.consume_until(|c| c.is_ascii_graphic());
self.str_buf.clear();
while self.peek().is_ascii_graphic() {
self.str_buf.push(self.peek());
self.consume();
if !self.has_more() { break; }
}
&self.str_buf
}
pub fn next_line(&mut self) -> &str {
assert_has_more!(self);
self.str_buf.clear();
while self.peek() != '\n' {
self.str_buf.push(self.peek());
self.consume();
if !self.has_more() { break; }
}
self.consume(); &self.str_buf
}
pub fn next_usize(&mut self) -> usize {
self.consume_until(|c| c.is_ascii_digit());
let mut num = 0;
while self.peek().is_ascii_digit() {
let digit = self.peek() as usize - '0' as usize;
num = num * 10 + digit;
self.consume();
if !self.has_more() { break; }
}
num
}
pub fn next_i64(&mut self) -> i64 {
let sign = self.consume_until_signed_num();
self.next_usize() as i64 * sign
}
pub fn next_f64(&mut self) -> f64 {
let sign = self.consume_until_signed_num() as f64;
let num: f64 = self.next_word().parse().unwrap();
num * sign
}
pub fn next_u8(&mut self) -> u8 { self.next_usize() as u8 }
pub fn next_u16(&mut self) -> u16 { self.next_usize() as u16 }
pub fn next_u32(&mut self) -> u32 { self.next_usize() as u32 }
pub fn next_u64(&mut self) -> u64 { self.next_usize() as u64 }
pub fn next_i8(&mut self) -> i8 { self.next_i64() as i8 }
pub fn next_i16(&mut self) -> i16 { self.next_i64() as i16 }
pub fn next_i32(&mut self) -> i32 { self.next_i64() as i32 }
pub fn next_f32(&mut self) -> f32 { self.next_f64() as f32 }
pub fn set_buf_size(&mut self, buf_size: usize) {
assert!(buf_size >= self.bytes_read, "InputReader: Data loss while shrinking buffer!");
self.buf.resize(buf_size, 0);
}
}
impl InputReader {
#[inline(always)]
fn peek(&self) -> char { self.buf[self.current_index] as char }
#[inline(always)]
fn consume(&mut self) { self.current_index += 1; }
fn ensure_buffer(&mut self) {
if self.current_index < self.bytes_read {
return;
}
self.bytes_read = self.reader.read(&mut self.buf[..]).unwrap();
self.current_index = 0;
}
fn consume_until<F: Fn(char) -> bool>(&mut self, test: F) {
while !test(self.peek()) {
self.consume();
assert_has_more!(self);
}
}
fn consume_until_signed_num(&mut self) -> i64 {
let mut sign = 1;
loop {
self.consume_until(|c| c.is_ascii_digit() || c == '-');
if self.peek() != '-' { break; }
self.consume();
assert_has_more!(self);
if self.peek().is_ascii_digit() {
sign = -1;
break;
}
}
sign
}
}