diff --git a/basm-std/src/platform/io/reader.rs b/basm-std/src/platform/io/reader.rs index 1c660052..0c7f4755 100644 --- a/basm-std/src/platform/io/reader.rs +++ b/basm-std/src/platform/io/reader.rs @@ -21,8 +21,10 @@ pub trait ReaderTrait: Sized { fn u128(&mut self) -> u128; fn usize(&mut self) -> usize; fn f64(&mut self) -> f64; + fn byte(&mut self) -> u8; fn word(&mut self) -> String; fn line(&mut self) -> String; + fn skip_whitespace(&mut self) -> usize; fn next(&mut self) -> T { T::read(self) } @@ -174,23 +176,7 @@ impl Reader { } consumed } - // We do not use avx2 for this function since most of the time - // we only skip a few whitespaces. - pub fn skip_whitespace(&mut self) -> usize { - let mut len = 0; - 'outer: loop { - while self.off < self.len { - if unsafe { self.buf[self.off].assume_init() } > b' ' { - break 'outer len; - } - self.off += 1; - len += 1; - } - if self.try_refill(1) == 0 { - break len; - } - } - } + pub fn skip_until_whitespace(&mut self) -> usize { let mut len = 0; 'outer: loop { @@ -246,15 +232,6 @@ impl Reader { } } - pub fn ascii(&mut self) -> u8 { - self.try_refill(1); - let mut out = 0u8; - if self.off < self.len { - out = unsafe { self.buf[self.off].assume_init() }; - self.off += 1; - } - out - } pub fn word_buf(&mut self, buf: &mut [u8]) -> usize { self.skip_whitespace(); let mut len = 0; @@ -501,6 +478,32 @@ impl ReaderTrait for Reader { if let Ok(ans) = out { ans } else { f64::NAN } } } + fn byte(&mut self) -> u8 { + self.try_refill(1); + let mut out = 0u8; + if self.off < self.len { + out = unsafe { self.buf[self.off].assume_init() }; + self.off += 1; + } + out + } + // We do not use avx2 for this function since most of the time + // we only skip a few whitespaces. + fn skip_whitespace(&mut self) -> usize { + let mut len = 0; + 'outer: loop { + while self.off < self.len { + if unsafe { self.buf[self.off].assume_init() } > b' ' { + break 'outer len; + } + self.off += 1; + len += 1; + } + if self.try_refill(1) == 0 { + break len; + } + } + } } /* diff --git a/basm-std/src/platform/io/reader_traits.rs b/basm-std/src/platform/io/reader_traits.rs index 83ccd378..8c0aa0a9 100644 --- a/basm-std/src/platform/io/reader_traits.rs +++ b/basm-std/src/platform/io/reader_traits.rs @@ -1,5 +1,6 @@ use super::{Readable, ReaderTrait}; use alloc::string::String; +use core::ops::Deref; macro_rules! impl_primitive { ($($ty:ident)*) => { @@ -30,6 +31,31 @@ impl Readable for Line { } } +impl Deref for Line { + type Target = String; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +pub struct Nonwhite(pub u8); + +impl Readable for Nonwhite { + fn read(reader: &mut impl ReaderTrait) -> Self { + reader.skip_whitespace(); + Self(reader.byte()) + } +} + +impl Deref for Nonwhite { + type Target = u8; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + impl Readable for [T; N] { fn read(reader: &mut impl ReaderTrait) -> Self { core::array::from_fn(|_| T::read(reader)) diff --git a/tests/boj_14939.rs b/tests/boj_14939.rs index 4ccf6a9b..57f8f405 100644 --- a/tests/boj_14939.rs +++ b/tests/boj_14939.rs @@ -7,7 +7,7 @@ pub fn main() { for i in 0..n { for j in 0..n { reader.skip_whitespace(); - let c = reader.ascii(); + let c = reader.byte(); if c == b'O' { board[i] |= 1u32 << j; }