1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
// Copyright 2019 statiolake <statiolake@gmail.com> // // 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. //! Defines whitespace-splitted token stream wrapping actual stream like stdin. //! //! The main is trait `Source`. This is implemented to the following two type of source: //! //! 1. Read entire source at once. (`once::OnceSource`) //! 1. Read source line by line. (`line::LineSource`) //! //! `OnceSource` is very fast, while `LineSource` is handy for local debugging. `OnceSource` must //! read entire input before any other work and you must put EOF (Ctrl-D on Unix or Ctrl-Z on //! Windows) after input. LineSource reads source one by one. Simply press enter to input. //! //! There is another source named `auto::AutoSource`. `AutoSource` is `OnceSource` in release //! build, is `LineSource` in debug build. If you use debug build in local testing, `LineSource`, //! convenience version is used. In judge server it is compiled in release mode, so `OnceSource`, //! faster version is used. This is usually no problem in judging (except interactive problem?). //! //! You can specify the source to be used in `input!` as follows: //! //! ``` //! # extern crate proconio; //! use proconio::source::auto::AutoSource; //! use proconio::input; //! //! let source = AutoSource::from("32 54 -23"); //! input! { //! from source, //! n: u8, //! m: u32, //! l: i32, //! } //! //! println!("{} {} {}", n, m, l); //! assert_eq!(n, 32); //! assert_eq!(m, 54); //! assert_eq!(l, -23); //! ``` //! //! In above example, `OnceSource<BufReader<&[u8]>>` and `LineSource<BufReader<&[u8]>>` implements //! `From<&str>`, so you can create the source from a string literal. You can create an instance //! directly from the value of type implementing `BufRead` by using `OnceSource::new()` and //! `LineSource::new()`. //! //! If you use `input!` macro with no source specified then it uses `AutoSource` with stdin. So, //! locally `LineSource` are used, in the server `OnceSource` are used. `OnceSource` and //! `LineSource` behaves samely in point of the read result, but, unintentionally, it may differ in //! a bare possibility. If it should differ, you can manually specify `LineSource` as `source` of //! `input!`. use std::io::BufRead; pub mod line; pub mod once; pub mod auto { //! Defines `AutoSource`. //! //! It is `LineSource` for debug build, `OnceSource` for release build. #[cfg(debug_assertions)] pub use super::line::LineSource as AutoSource; #[cfg(not(debug_assertions))] pub use super::once::OnceSource as AutoSource; } /// The main trait. Types implementing this trait can be used for source of `input!` macro. pub trait Source<R: BufRead> { /// Gets a whitespace-splitted next token. fn next_token(&mut self) -> Option<&str>; /// Check if tokens are empty fn is_empty(&mut self) -> bool; /// Force gets a whitespace-splitted next token. fn next_token_unwrap(&mut self) -> &str { self.next_token().expect(concat!( "failed to get the next token; ", "maybe reader reached an end of input. ", "ensure that arguments for `input!` macro is correctly ", "specified to match the problem input." )) } } // &mut S where S: Source is also source. impl<R: BufRead, S: Source<R>> Source<R> for &'_ mut S { fn next_token(&mut self) -> Option<&str> { (*self).next_token() } fn is_empty(&mut self) -> bool { (*self).is_empty() } } /// A trait representing which type can be read from `Source`. /// /// If you want to read your own type using `input!`, you can implement this trait for your type. /// Alternatively, you can add `#[derive_readable]` if you put `use /// proconio_derive::derive_readable` in your source. It automatically implements `Readable` if /// all members of your type are `Readable`. pub trait Readable { type Output; fn read<R: BufRead, S: Source<R>>(source: &mut S) -> Self::Output; }