use lazy_static::lazy_static;
use std::cell::{RefCell, RefMut};
use std::io::{stdin, Read};
use std::str::FromStr;
use std::sync::Mutex;
use std::fs::File;
const DEFAULT_BUF_SIZE: usize = 8_000;
struct Stream {
source: Box<dyn Read + Send>,
buf: Vec<u8>,
ptr: usize,
limit: usize,
error: bool, }
impl Stream {
fn new(source: Box<dyn Read + Send>, buf_size: usize) -> Self {
let vc = vec![0; buf_size];
Stream {
source,
buf: vc,
ptr: 0,
limit: 0,
error: false,
}
}
fn refill(&mut self) {
let res = self.source.read(&mut self.buf);
self.ptr = 0;
match res {
Ok(0) => {
self.error = true;
}
Ok(n) => {
self.limit = n;
self.error = false;
}
Err(_e) => {
self.error = true;
}
}
}
fn pop_byte(&mut self) -> Option<u8> {
if self.ptr >= self.limit {
self.refill();
}
if self.error {
None
} else {
self.ptr += 1;
Some(self.buf[self.ptr - 1])
}
}
fn pop_char(&mut self) -> Option<char> {
let c1: u32 = self.pop_byte()? as u32;
let res: u32;
if c1 & 0xC0 == 0x80{
return None;
}
if (c1 & 0x80) == 0 {
res = c1;
return std::char::from_u32(res);
}
if (c1 & 0xE0) == 0xC0 {
let c2 = self.pop_byte()? as u32;
res = ((c1 & 0x1F) << 6) | (c2 & 0x3F << 0);
return std::char::from_u32(res);
}
else if (c1 & 0xF0) == 0xE0 {
let c2 = self.pop_byte()? as u32;
let c3 = self.pop_byte()? as u32;
res = ((c1 & 0x0F) << 12) | (c2 & 0x3F << 6) | (c3 & 0x3F << 0);
return std::char::from_u32(res);
}
else if (c1 & 0xF8) == 0xF0 {
let c2 = self.pop_byte()? as u32;
let c3 = self.pop_byte()? as u32;
let c4 = self.pop_byte()? as u32;
res = (c1 & 0x07 << 18) | (c2 & 0x3F << 12) | (c3 & 0x3F << 6) | (c4 & 0x3F << 0);
return std::char::from_u32(res);
}
None
}
fn read<T: FromStr>(&mut self) -> Option<T> {
let mut buf = String::new();
loop {
match self.pop_char() {
None => break, Some(c) => {
if c.is_whitespace() {
if !buf.is_empty() {
break;
}
} else {
buf.push(c);
}
}
}
}
if buf.is_empty() {
return None;
}
T::from_str(&buf).ok()
}
fn read_line(&mut self) -> Option<String> {
let mut buf = String::new();
loop {
match self.pop_char() {
None => break, Some('\n') => break,
Some(c) => buf.push(c),
}
}
if self.error && buf.is_empty() {
None
} else {
Some(buf)
}
}
fn skip_line(&mut self) {
loop {
match self.pop_char() {
None => break,
Some('\n') => break,
_ => (),
}
}
}
fn valid(&self) -> bool {
!self.error
}
}
pub struct RCin;
impl RCin {
pub fn read<T: FromStr>(&self) -> Option<T> {
let guard = GLOB_STREAM.lock().unwrap();
let mut rc: RefMut<Stream> = (*guard).borrow_mut();
rc.read()
}
pub fn read_line(&self) -> Option<String> {
let guard = GLOB_STREAM.lock().unwrap();
let mut rc: RefMut<Stream> = (*guard).borrow_mut();
rc.read_line()
}
pub fn skip_line(&self) {
let guard = GLOB_STREAM.lock().unwrap();
let mut rc: RefMut<Stream> = (*guard).borrow_mut();
rc.skip_line()
}
pub fn read_char(&self) -> Option<char>{
let guard = GLOB_STREAM.lock().unwrap();
let mut rc: RefMut<Stream> = (*guard).borrow_mut();
rc.pop_char()
}
}
impl<T> std::ops::Shr<&mut T> for rin
where
T: FromStr,
{
type Output = bool;
fn shr(self, rhs: &mut T) -> Self::Output {
if let Some(value) = self.read() {
*rhs = value;
true
} else {
false
}
}
}
lazy_static! {
#[derive(Copy, Clone)]
pub static ref rin: RCin = RCin{};
static ref GLOB_STREAM: Mutex<RefCell<Stream>> =
Mutex::new(RefCell::new(Stream::new(Box::new(stdin()),DEFAULT_BUF_SIZE)));
}
pub struct RInStream {
source: Stream,
}
impl RInStream {
pub fn from_file(f: File) -> Self {
Self::from_source(Box::new(f))
}
pub fn from_source(src: Box<dyn Read + Send>) -> Self {
Self::new(src, DEFAULT_BUF_SIZE)
}
pub fn new(src: Box<dyn Read + Send>, cap: usize) -> Self {
RInStream {
source: Stream::new(src, cap),
}
}
pub fn read_char(&mut self) -> Option<char>{
self.source.pop_char()
}
pub fn read<T: FromStr>(&mut self) -> Option<T> {
self.source.read()
}
pub fn read_line(&mut self) -> Option<String> {
self.source.read_line()
}
pub fn skip_line(&mut self) {
self.source.skip_line()
}
pub fn valid(&self) -> bool {
self.source.valid()
}
}