1use std::{
2 any::type_name,
3 fmt::Debug,
4 io::{BufRead, BufReader, Stdin},
5 marker::PhantomData,
6 str::FromStr,
7 sync::{Mutex, OnceLock},
8};
9
10pub static STDIN_SOURCE: OnceLock<Mutex<AutoSource<BufReader<Stdin>>>> =
11 OnceLock::new();
12
13pub trait Source<R: BufRead> {
14 fn next_token(&mut self) -> Option<String>;
15 fn next_token_unwrap(&mut self) -> String { self.next_token().unwrap() }
16}
17
18impl<R: BufRead, S: Source<R>> Source<R> for &'_ mut S {
19 fn next_token(&mut self) -> Option<String> { (*self).next_token() }
20}
21
22pub type AutoSource<R> = OnceSource<R>;
23
24pub struct OnceSource<R: BufRead> {
25 tokens: std::vec::IntoIter<String>,
26 _phantom: PhantomData<R>,
27}
28
29impl<R: BufRead> OnceSource<R> {
30 pub fn new(mut source: R) -> Self {
31 let mut context = "".to_owned();
32 source.read_to_string(&mut context).unwrap();
33 let tokens: Vec<_> =
34 context.split_whitespace().map(|s| s.to_owned()).collect();
35 Self {
36 tokens: tokens.into_iter(),
37 _phantom: PhantomData,
38 }
39 }
40}
41
42impl<R: BufRead> Source<R> for OnceSource<R> {
43 fn next_token(&mut self) -> Option<String> { self.tokens.next() }
44}
45
46impl<'a> From<&'a str> for OnceSource<BufReader<&'a [u8]>> {
47 fn from(s: &'a str) -> Self {
48 OnceSource::new(BufReader::new(s.as_bytes()))
49 }
50}
51
52pub trait Readable {
53 type Output;
54 fn read<R: BufRead, S: Source<R>>(source: &mut S) -> Self::Output;
55}
56
57impl<T: FromStr> Readable for T
58where
59 T::Err: Debug,
60{
61 type Output = T;
62 fn read<R: BufRead, S: Source<R>>(source: &mut S) -> T {
63 let token = source.next_token_unwrap();
64 match token.parse() {
65 Ok(v) => v,
66 Err(e) => panic!(
67 "`{input}` `{ty}` `{err:?}`",
68 input = token,
69 ty = type_name::<T>(),
70 err = e
71 ),
72 }
73 }
74}
75
76#[macro_export]
77macro_rules! scan {
78 (@from [$source:expr] @rest) => {};
80
81 (@from [$source:expr] @rest mut $($rest:tt)*) => {
83 $crate::scan! {
84 @from [$source]
85 @mut [mut]
86 @rest $($rest)*
87 }
88 };
89 (@from [$source:expr] @rest $($rest:tt)*) => {
90 $crate::scan! {
91 @from [$source]
92 @mut []
93 @rest $($rest)*
94 }
95 };
96
97 (@from [$source:expr] @mut [$($mut:tt)?] @rest $var:tt: $($rest:tt)*) => {
99 $crate::scan! {
100 @from [$source]
101 @mut [$($mut)?]
102 @var $var
103 @kind []
104 @rest $($rest)*
105 }
106 };
107
108 (@from [$source:expr] @mut [$($mut:tt)?] @var $var:tt @kind [$($kind:tt)*] @rest) => {
110 let $($mut)? $var = $crate::read_value!(@source [$source] @kind [$($kind)*] @hint [$var]);
111 };
112 (@from [$source:expr] @mut [$($mut:tt)?] @var $var:tt @kind [$($kind:tt)*] @rest, $($rest:tt)*) => {
113 $crate::scan!(@from [$source] @mut [$($mut)?] @var $var @kind [$($kind)*] @rest);
114 $crate::scan!(@from [$source] @rest $($rest)*);
115 };
116 (@from [$source:expr] @mut [$($mut:tt)?] @var $var:tt @kind [$($kind:tt)*] @rest $tt:tt $($rest:tt)*) => {
117 $crate::scan!(@from [$source] @mut [$($mut)?] @var $var @kind [$($kind)* $tt] @rest $($rest)*);
118 };
119
120 (from $source:expr, $($rest:tt)*) => {
121 #[allow(unused_variables, unused_mut)]
122 let mut s = $source;
123 $crate::scan! {
124 @from [&mut s]
125 @rest $($rest)*
126 }
127 };
128 ($($rest:tt)*) => {
129 let mut locked_stdin = $crate::STDIN_SOURCE.get_or_init(|| {
130 ::std::sync::Mutex::new($crate::AutoSource::new(::std::io::BufReader::new(::std::io::stdin())))
131 }).lock().unwrap();
132 $crate::scan! {
133 @from [&mut *locked_stdin]
134 @rest $($rest)*
135 }
136 drop(locked_stdin);
137 };
138}
139
140#[macro_export]
141macro_rules! read_value {
142 (@source [$source:expr] @kind [[$($kind:tt)*]] @hint [$var:tt]) => {
144 $crate::read_value!(@vec @source [$source] @kind [] @hint [$var] @rest $($kind)*)
145 };
146 (@vec @source [$source:expr] @kind [$($kind:tt)*] @hint [$var:tt] @rest) => {{
147 let len = <usize as $crate::Readable>::read($source);
148 $crate::read_value!(@source [$source] @kind [[$($kind)*; len]] @hint [$var])
149 }};
150 (@vec @source [$source:expr] @kind [$($kind:tt)*] @hint[$var:tt] @rest ; const $($rest:tt)*) => {
151 $crate::read_value!(@array @source [$source] @kind [$($kind)*] @hint [$var] @len [$($rest)*])
152 };
153 (@vec @source [$source:expr] @kind [$($kind:tt)*] @hint[$var:tt] @rest ; const $($rest:tt)*) => {
154 $crate::read_value!(@array @source [$source] @kind [$($kind)*] @hint[$var] @len [$($rest)*])
155 };
156 (@vec @source [$source:expr] @kind [$($kind:tt)*] @hint[$var:tt] @rest ; _) => {
157 $crate::read_value!(@array @source [$source] @kind [$($kind)*] @hint [$var] @len [_])
158 };
159 (@vec @source [$source:expr] @kind [$($kind:tt)*] @hint[$var:tt] @rest ; $($rest:tt)*) => {
160 $crate::read_value!(@vec @source [$source] @kind [$($kind)*] @hint [$var] @len [$($rest)*])
161 };
162 (@vec @source [$source:expr] @kind [$($kind:tt)*] @hint[$var:tt] @rest $tt:tt $($rest:tt)*) => {
163 $crate::read_value!(@vec @source [$source] @kind [$($kind)* $tt] @hint [$var] @rest $($rest)*)
164 };
165 (@vec @source [$source:expr] @kind [$($kind:tt)*] @hint[$var:tt] @len [$($len:tt)*]) => {{
166 let len = $($len)*;
167 (0..len)
168 .map(|_| $crate::read_value!(@source [$source] @kind [$($kind)*] @hint [$var]))
169 .collect::<Vec<_>>()
170 }};
171 (@array @source [$source:expr] @kind [$($kind:tt)*] @hint[$var:tt] @len [_]) => {{
172 const LEN: usize = {
173 const fn zero_array<const N: usize>() -> [(); N] { [(); N] }
174 let $var = zero_array();
175 let a = $var;
176 a.len()
177 };
178 let mut tmp = [Default::default(); LEN];
179 for i in 0..LEN {
180 tmp[i] = $crate::read_value!(@source [$source] @kind [$($kind)*] @hint [$var])
181 }
182 tmp
183 }};
184 (@array @source [$source:expr] @kind [$($kind:tt)*] @hint[$var:tt] @len [$($len:tt)*]) => {{
185 const LEN: usize = $($len)*;
186 let mut tmp = [Default::default(); LEN];
187 for i in 0..LEN {
188 tmp[i] = $crate::read_value!(@source [$source] @kind [$($kind)*] @hint [$var])
189 }
190 tmp
191 }};
192
193 (@source [$source:expr] @kind [($($kinds:tt)*)] @hint [$var:tt]) => {
195 $crate::read_value!(@tuple @source [$source] @kinds [] @current [] @hint [$var] @rest $($kinds)*)
196 };
197 (@tuple @source [$source:expr] @kinds [$([$($kind:tt)*])*] @current [] @hint [$var:tt] @rest) => {
198 (
199 $($crate::read_value!(@source [$source] @kind [$($kind)*] @hint [$var]),)*
200 )
201 };
202 (@tuple @source [$source:expr] @kinds [$($kinds:tt)*] @current [$($curr:tt)*] @hint [$var:tt] @rest) => {
203 $crate::read_value!(@tuple @source [$source] @kinds [$($kinds)* [$($curr)*]] @current [] @hint [$var] @rest)
204 };
205 (@tuple @source [$source:expr] @kinds [$($kinds:tt)*] @current [$($curr:tt)*] @hint [$var:tt] @rest, $($rest:tt)*) => {
206 $crate::read_value!(@tuple @source [$source] @kinds [$($kinds)* [$($curr)*]] @current [] @hint [$var] @rest $($rest)*)
207 };
208 (@tuple @source [$source:expr] @kinds [$($kinds:tt)*] @current [$($curr:tt)*] @hint [$var:tt] @rest $tt:tt $($rest:tt)*) => {
209 $crate::read_value!(@tuple @source [$source] @kinds [$($kinds)*] @current [$($curr)* $tt] @hint [$var] @rest $($rest)*)
210 };
211
212 (@source [$source:expr] @kind [] @hint [$var:tt]) => {
214 compile_error!("Reached unreachable statement while parsing macro input.")
215 };
216
217 (@source [$source:expr] @kind [$kind:ty] @hint [$var:tt]) => {
219 <$kind as $crate::Readable>::read($source)
220 };
221}
222
223#[test]
224fn sanity_check() {
225 let src = AutoSource::from("1 2 3 4");
227 scan! {
228 from src,
229 int: u32,
230 frac: f64,
231 ch: char,
232 string: String,
233 }
234 assert_eq!((int, frac, ch, string), (1, 2.0, '3', "4".to_owned()));
235
236 let src = AutoSource::from("2 1 2 3 1 2 3 1 2 3 1 2 3");
238 scan! {
239 from src,
240 n: usize,
241 vec_n: [u32; n],
242 vec: [u32],
243 array: [u32; const 3],
244 [un, pac, ked]: [u32; _],
245 }
246 assert_eq!((vec_n, vec, array), (vec![1, 2], vec![1, 2, 3], [1, 2, 3]));
247 assert_eq!([un, pac, ked], [1, 2, 3]);
248
249 let src = AutoSource::from("1 2 3 4 5 6 7 8");
251 scan! {
252 from src,
253 a: (i32, i32, (i32, i32), i32),
254 (b, c): (i32, i32,),
255 (d,): (i32,),
256 }
257 assert_eq!((a, b, c, d), ((1, 2, (3, 4), 5), 6, 7, 8));
258}