適当にヘッダを生成するツール

つくりました。

なにができるの?

毎回毎回

#include<iostream>
#include<vector>
...

とか書くのめんどくさいですよね?

雛形ファイル作ってもいいですが、多めに書いておくと最終的なソースが汚くなる気がします。

そこで、自動的にそういうのを生成しちゃえ、というツールです。C/C++専用です
例えば、

int main(){
  std::vector<int> v;
  v.push_back(0); v.push_back(5); v.push_back(3);
  sort(v.begin(), v.end());
  FOR(it, v) std::cout << *it << std::endl;
}

とかがある時にこのツールを使うと、自動的に

#include <iostream>
#include <algorithm>
#include <vector>
#define FOR(i,c) for(__typeof((c).begin()) i=(c).begin(); i!=(c).end(); i++)

int main(){
  std::vector<int> v;
  v.push_back(0); v.push_back(5); v.push_back(3);
  sort(v.begin(), v.end());
  FOR(it, v) std::cout << *it << std::endl;
}

となります(後述のように設定次第ですが…)。

まあぶっちゃけると、SRM用です。雛形ファイルだと使ってないコードが多すぎて怒られうわなにをする

競技プログラミングで素早く解きたいけど、汚いコードは嫌だ!」という人向けのツールを想定して作りました。

インストール

ダウンロードはこちらから
https://github.com/mazun/Generate-header-for-C-C--

gen_headerだけ取ってくれば大丈夫です。

他に

が必要なので、入っていなければ入れてください。
(GNU GLOBAL および g++ はデータベースを作るときにだけ必要なので、すでにデータベースがある場合は不必要です。)

Linuxcygwin なら ./gen_header のような形で使えますが、windows の場合は python gen_header のようにしないと使えないと思います(windowspython入れてないので未確認)。windowsの方は以下適宜そのように読み替えてください。

使い方

普段の使いやすさを重視したので、ソースが置いてある所に gen_header を置いてください。

設定編

自分でも設定方法がちょっとめんどくさい気もしますが、設定は1回すれば終わりなのでまあいいかという感じ。

とりあえずデータベースを作成します、というかこれが全て。

通常のヘッダ編

$ ./gen_header --generate_database -a iostream vector

という感じで使うヘッダを全部入れてください。
複数回に分けて登録しても大丈夫です。-a がそのためのオプションです。一からつくり直す場合には -a を消してください。

インライン展開してほしいモノ編

次のようなファイルを用意します。

#define FOR(i,c) for(__typeof((c).begin()) i=(c).begin(); i!=(c).end(); i++)

これを FOR.h とすると、

$ ./gen_header --generate_inline_database -a FOR.h

でデータベースに追加できます。
好きなだけ用意して追加しちゃってください。
もちろん関数やtypedefも大丈夫です。

注意点としては、ファイル単位でインライン展開するので、複数のファイルに分けて用意しなければいけません。

これで設定編は終了です。
なお、このデータベースは gen_header_database というファイルにできるので、これさえ持ち運べば別環境でも動きます(大体大丈夫だと思うけど、コンパイラのバージョンとか変わると微妙かも)。

実際に使ってみる編

test.cpp に使うときには、

$ ./gen_header test.cpp

とするだけです。いじょ!
(注意: test.cppが書き換わります。多分ないと思うけど何らかのエラーでtest.cppが消えたりしたらごめんなさい。)
なお、複数回動作させても大丈夫なように作っているので、gen_header してから g++ にかけるみたいなのをいっぺんにやるスクリプトなりエイリアスなりつくっとくと便利かもしれない。

既知の不具合およびキモイ動作

  • 関数の引数の型とかは見てません。つまり引数の型で使うヘッダファイルを変えるみたいなことはできません。
  • namespace も同様です。
  • なるべく少ないヘッダファイルで完結するように頑張ってます。また、同じ効果が得られそうなときは辞書順に選びます。したがって(少なくとも私の環境では) queue と vector を登録している場合に、vector を使うと queue が include されます。おそらく queue の中で vector を使っているのでしょう。この場合でもコンパイルは通るので特に問題はないです。
  • iostreamにstringやsstreamがあると勘違いしてしまうようです(要修正)

おわりに

ということで、こんなツールつくったよ報告でした。
私は多分今後、競技プログラミングするときには使うと思います。