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;
}