これで効率爆上がり！C/C++の競プロ用テンプレートをmain関数の下に追いやる必殺技

# はじめに

皆さんは競技プログラミングで「テンプレート」は使っていますか？
`rep` や `chmin` 、 `modpow` など、よく使う処理を事前に用意したもののことです。
この記事では、C/C++で使える「テンプレート」[^template]の記述方法について紹介します。

[^template]: C++のクラステンプレートや関数テンプレートの「テンプレート」ではないです。

# C/C++のテンプレートは邪魔！

テンプレートはとても便利です。コンテスト時に書くコードが少なくなり、解答スピードが速くなります。
実装方法を忘れてコンテスト中に調べ直す、なんてこともなくなります。

しかし、便利さを追い求めて様々な関数やクラスの追加を重ねるうちに、テンプレートが**膨大な行数**になってしまいがちです。
また、C/C++ではどうしても**使うより先に宣言**が必要です。すると、 main 関数はテンプレートの下に書かなくてはならず、いちばん下の main 関数にたどり着くまでの**スクロールでイライラしてしまいます**。
さらに、参考にしようとあなたの提出コードを読もうとした人が、いつまでも続くテンプレートを見て読むのを諦めてしまうかもしれません。

ヘッダファイルに分割しようにも、[AtCoder](https://atcoder.jp/)などの競技プログラミングサイトではフォルダでまとめて提出するといったことができません。
なので、**すべて1つのファイルに**書く必要があります。

ん？　ヘッダファイル？　1つのファイルに書く？　…………！

# 必殺！「自身をインクルード」

私、ひらめいちゃいました。
提出ファイルに**ソースファイル兼ヘッダファイル**になってもらって、**提出ファイルに提出ファイルをインクルード**すればいいのです！

「ちょっと何言ってるかわからない。」

まあ、一度見てみてください。

## 必殺技の使い方

必殺技を使うには、下のように書きます。
テンプレートの部分は、自分用に書き換えて使ってください。

```c++
#ifndef INCLUDED_MAIN
#define INCLUDED_MAIN

#include __FILE__  // このファイル自体をインクルード

int main()
{
    // 解答コード
}

#else  // INCLUDED_MAIN

// ↓テンプレート↓

#include <iostream>
#include <vector>
using namespace std;
using ll = long long;
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define all(x) begin(x), end(x)
template <class T>
bool chmax(T &a, const T &b) {
    if (a < b) a = b; return a < b;
}
template <class T>
bool chmin(T &a, const T &b) {
    if (b < a) a = b; return b < a;
}

// ↑テンプレート↑

#endif  // INCLUDED_MAIN
```

**main 関数がテンプレートより上に来ています！**
これでテンプレートをどれだけ増やしても、ファイルやリンクを開くと**すぐに main 関数**が読めます！

## 必殺技の解説

ポイントは**プリプロセッサによる条件分岐**です。インクルードガードと同じような方法を使っています。

```c++
#ifndef INCLUDED_MAIN

// ①

#else

// ②

#endif
```

最初の行の `#ifndef` の条件分岐で、 `INCLUDED_MAIN` マクロが定義されていないときは①のコードだけ読まれ、すでに定義されているときは②のコードだけ読まれます。

```c++
#define INCLUDED_MAIN
                   // INCLUDED_MAIN が定義されているので
#include __FILE__  // ←ここでは②だけ読まれる
```

そして、①の部分の最初に `INCLUDED_MAIN` を定義してから、**自身をインクルード**します。 `__FILE__` は自身のファイル名[^__file__]の文字列リテラルに展開される組み込みマクロです。
すると、先ほど解説した条件分岐で②の部分だけ読まれます。

[^__file__]: 絶対パスの場合もあります。

ということは、①の部分はソースファイル、②の部分はヘッダファイルとして扱えます。
したがって、**①の部分に main 関数を、②の部分にテンプレート**を書けばいいのです。

これで**テンプレートが main 関数の下にあってもコンパイルが通ります！**

# もっと main 関数を上に！

ここまでは **main 関数の上にテンプレートをインクルード**してきましたが、**テンプレートの下に main 関数をインクルード**しても、展開後のコードは変わりません。

なので、次のようにも書くことができ、これなら**2行目から main 関数**を書き始めることができます！

```c++
#ifdef INCLUDED_MAIN

int main()
{
    // 解答コード
}

#else

// テンプレート

#define INCLUDED_MAIN
#include __FILE__

#endif
```

# Codeforces で使う方法

Codeforces では、提出したコードに `#include __FILE__` もしくはそれに相当するような文字列が含まれていると、 Judgement failed となってジャッジされません。

しかし、 `__FILE__` マクロを使うかわりに、**直接ファイル名をコードに書く**ことで、 Codeforces でも使うことができます！

Codeforces のジャッジ時のファイル名は、 Clang なら p71.cpp 、それ以外なら program.cpp なので、 `FILENAME` マクロをそれにあうように定義して `#include FILENAME` と書くと、 `#include __FILE__` と同じように展開されます。
また、ローカルでのファイル名を自由に決められるように、ジャッジ環境で定義されている `ONLINE_JUDGE` マクロが定義されていないときは、 `FILENAME` を `__FILE__` と定義します。

```c++
#ifdef INCLUDED_MAIN

int main()
{
    // 解答コード
}

#else

// テンプレート

#ifdef ONLINE_JUDGE
# ifdef __clang__
#  define FILENAME "p71.cpp"
# else
#  define FILENAME "program.cpp"
# endif
#else
# define FILENAME __FILE__
#endif

#define INCLUDED_MAIN
#include FILENAME

#endif
```
※ マクロを使わず `#include "program.cpp"` のように書くと、 Judgement failed になります。
※ このコードは、ジャッジ時のファイル名に依存するため、今後使えなくなる可能性があります。

# \_\_INCLUDE\_LEVEL\_\_ を使う方法 

@fujitanozomu さんにコメントで `__INCLUDE_LEVEL__` について教えていただきました。
これはGCCやClangなどで使用できるマクロで、**インクルードの深さ**を表す整数に展開されます。
直接読まれるときは `0` 、インクルードされたときは `1` 、インクルードされたファイルにインクルードされたときは `2` といった感じです。

これは、自身をインクルードしたときでも使えます。
`__INCLUDE_LEVEL__` は、**はじめて読まれるときは `0` 、インクルードされて再度読まれるときは `1`** に展開されます。
このことを利用して、 `__INCLUDE_LEVEL__` が使用できる環境では、**よりスマートに必殺技が使えます**。

```c++
#if !__INCLUDE_LEVEL__

#include __FILE__
int main()
{
    // 解答コード
}

#else

// テンプレート

#endif
```

`INCLUDED_MAIN` といった条件分岐用のマクロを定義する必要がなくなるので、シンプルで読みやすくなります。

# おわりに

これで問題を解く効率が少しはよくなると思います。[^bakuagari]
C/C++使いの方はぜひご活用ください。

[^bakuagari]: タイトルの「爆上がり」は言い過ぎだと思います。