IOライブラリの設計
競プロ用の入出力ライブラリ(Rust)を作る
要件
長年抱えてる葛藤が、貼る用のライブラリをゴテゴテに作りこむか、簡潔にとどめたほうが綺麗かという
— しの (@shino_skycrew) October 5, 2020
妥協ラインとして、ライブラリは多少長くしてもよい代わりにすべて main 等の下に追いやります。
- マクロは使わずに、
proconioのinput!くらい使いやすいものにしたい - おおよそ 100 ms 単位で最速になってほしい
外部クレートには依存しません。(使えるものなら proconio を使う…)
完成
使用例
#27339 – Library-Checker(Point Add Range Sum)
下のコードをなんとかかんとかで pack? bundle? したもの。
|
|
とても快適です、ありがとう
純粋に IO の速度を測るなら、Many A + B を使うべきでしょう。
設計
- 初期化時に入力をすべて受け取って
Box::leakする- ライフタイムであ"~ってなった時、とりあえずこうすると楽になる
- 出力は
std::io::BufWriter(この 2 つだけでtie/syncを切ったcin/coutやscanf/printfより既に速い) scanが返せる型をScanトレイトで表現し、多相にする- ネストしたタプルや配列も空気を読んでやってくれる
- 整数は
str::pareseの代わりに自力で読む
printが受け取れる値をPrint(以下略)- ネストしたタプルも
char? 知らない子ですね
いまいちな点
- 入力を丸ごと
leakしている- 高々 $10^5$ 程度のオーダーということで…
*mut strを持っておいて最後にBox::from_rawすれば drop されるが、IOは入力の一部を&'static [u8]として返すのでまずい
- 入力と出力は分離するべきじゃないの?
- 実際互いに完全に独立しているが、別オブジェクトだとめんどくさいだけ
Scan::scanやPrint::printが&mut IOを受け取る必要はないのでは?f: &mut F where F: FnMut() -> &[u8]とかいちいち書くのも面倒
- インタラクティブは?
src/io_interactive.rsを作りました。適宜 1 行ずつ読み取るという違いだけの、コピペです(悲しい)- とはいえ一度に使うのは片方だけだし、いいかな…
IO::scanに、どういうときに型引数を明示的に渡さないといけないのかよくわからない- とりあえず怒られてから直す