diff --git a/AGENTS.md b/AGENTS.md index 74dd2d2..f28d535 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -7,166 +7,8 @@ Markdown では、改行のために行末を意図的に 2 個の空白にす ## レビューについて ライブラリを構成するヘッダファイル、verify ソースコード、ドキュメントと、リポジトリ内のスクリプト、設定ファイル、ドキュメントなどの両方をレビューすること。 -特に、以下の点を必ず確認すること。 -なお、以下の説明において、「ライブラリのドキュメント」は [docs/](docs/) または [.competitive-verifier/docs/](.competitive-verifier/docs/) 配下のドキュメントを指し、「リポジトリのドキュメント」はその他のドキュメント(特に [README.md](README.md), [CONTRIBUTING.md](CONTRIBUTING.md), [AGENTS.md](AGENTS.md))を指すこととする。 +レビューでは [STYLE_GUIDE.md](STYLE_GUIDE.md) に記載されている観点を全て確認すること。 -### 共通 -- 変更するファイルの末尾に改行がある。 -- 句読点が基本的に `、` と `。` である(`,` と `.` などでない)。 - - ただし、`Library Checker (Yosupo Judge), yukicoder, AOJ` のように英数字どうしを並べる際のカンマまで全角に修正させる必要はない(どちらでもよい)。 -- 複数の語句を並べる際の区切り記号が `、` または `, ` であり、上の規約にも従っている(`・` や ` / `、`/` などでない)。 -- マークダウンの箇条書きのインデントがスペース 2 文字である。 -- マークダウンの番号なし箇条書きが `- ` である(`* ` や ` - ` などでない)。 -- マークダウンの番号付き箇条書きが常に `1. ` である(`2. ` 以降は使わない)。 -- ソースコード中のコメントやドキュメントなどの文章は日本語で書かれており、次の項で示すファイルを除いて文体が常体で統一されている(`です`、`ます` などの敬体が混ざっていない)。 - - [pyproject.toml](pyproject.toml) の `[project]` 内の `description` および [.editorconfig](.editorconfig), [.gitattributes](.gitattributes), [.gitignore](.gitignore) 内のコメントは除く(英語で記述する)。 - - 参考文献も除く(人名も含めて、英語で記述する)。 - - また、日本語で同じ内容が記述されている場合は、英語などの他の言語が併記されていてもよい。 -- リポジトリの [README.md](README.md) や [CONTRIBUTING.md](CONTRIBUTING.md)、GitHub Pages 上のドキュメントのトップページ([.competitive-verifier/docs/index.md](.competitive-verifier/docs/index.md) を基に生成される)の文章は日本語で書かれており、文体が敬体で統一されている(以下の例外を除いて、`だ`、`である` などの常体が混ざっていない)。 - - ただし、箇条書き内の文章は常体でも敬体でもよいとする(少なくとも深さが最も小さい部分の文章は常体を推奨するが、厳密に片方に決める運用はしないものとする)。 -- プログラム、スクリプトやコンパイラが出力するエラーメッセージは英語で書かれている。 -- 「ならば」の代わりに「なら」を使用していない。 -- ハイフン、エンダッシュ、エムダッシュの使い分けがされている。 - - 人名どうしの連結や期間などでは、ハイフンやエムダッシュではなくエンダッシュを使用している。 - - 文章中で追加の情報を後ろから挿入する用法などでは、ハイフンやエンダッシュではなくエムダッシュを使用している。 - - ただし、もし正しい使い分けがされていない固有名詞がある場合は、その固有名詞の表記を優先する。 - - また、[LICENSE](LICENSE) 中の記述も例外とする。 -- 文章中の引用符は `‘ ’` と `“ ”` とする(`' '` と `" "` などでない)。 - - ただし、C++ の文字リテラルや文字列リテラルを表す場合の引用符は `' '` と `" "` でよい。 - - また、もし正しい使い分けがされていない固有名詞がある場合は、その固有名詞の表記を優先する。 - - また、[LICENSE](LICENSE) 中の記述も例外とする。 -- 文章中のアポストロフィーは `’` とする(`'` などでない)。 - - ただし、`Luzhiled's Library` や `Nyaan's Library` のような固有名詞は例外とする。 - - また、[LICENSE](LICENSE) 中の記述も例外とする。 -- indexing は `0-based indexing`, `1-based indexing` のように `k-based indexing` の形で記述する(`k-indexed` などでない)。 -- かぎかっこは「引用を表す囲み」もしくは「囲みがないと入れ子になって読みにくいような部分のための囲み」にのみ使われている(強調などに濫用されていない)。 -- 数式中に現れる文字(一般的な数学関数や数学定数を除く)は、その数式よりも前に説明を書いている。 - - ただし、Jekyll Front Matter の `title` 中の数式は例外とする。 - -### パス、ファイル名 -- C++ のソースコードを配置するディレクトリ名およびファイル名の単語の区切りがハイフンである(アンダースコアなどでない)。 -- Python のソースコードを配置するディレクトリ名およびファイル名の単語の区切りがアンダースコアである(ハイフンなどでない)。 -- ルート直下に全てのヘッダファイルを入れるディレクトリを置いていない。 -- ドキュメントは [docs/](docs/) 内に存在し、対応するヘッダファイルのルート直下から見た階層と同じ階層に置く。 -- verify ソースコードは [verify/](verify/) 内に存在する。 - - それぞれの verify ソースコードのファイル名の先頭は `yosupo`, `yukicoder`, `aoj`, `standalone` のどれかである。 - - 先頭が `standalone` 以外であれば、その後ろに問題の ID などが続いている。 - - 先頭が `standalone` であれば、その後ろに verify 対象が続いている(フルパスではなく、basename から拡張子を除いたものでよい)。 - - verify ソースコードの拡張子は `.test.cpp` である。 - -### C++ ソースコード(共通) -- テンプレート引数によってプリミティブな整数型以外の型が与えられる可能性がある型(ただし、イテレータが与えられることが想定される型を除く)の値では、インクリメントを `+= 1`、デクリメントを `-= 1` で行っている(インクリメント演算子 `++`、デクリメント演算子 `--` を用いていない)。 -- テンプレート引数によって主にイテレータが与えられることが想定される型については、前置インクリメント演算子および後置インクリメント演算子を使用し、イテレータでない型が与えられないようにメタ関数や `static_assert` などを使用している。 -- テンプレート引数によってプリミティブな整数型以外の型が与えられる可能性がある型の値では、ビット演算で行う必要がない演算にビット演算を用いていない。 - - たとえば、「偶奇判定に `& 1` ではなく `% 2` を用いているか」「2 倍の計算に `<< 1`, `<<= 1` ではなく `* 2`, `*= 2` を用いているか」「2 で割った商の計算に `>> 1`, `>>= 1` ではなく `/ 2`, `/= 2` を用いているか」などをチェックすること。 -- clang-format 20 を用いて、[.clang-format](.clang-format) で指定したオプションによりフォーマットされている。 -- 1 行目が空行でない。 -- ブロックの末尾の `}` のみからなる行の 1 つ前の行が空行でない。 -- URL を記述する場合、URL が行末になるように記述している。 - - URL が行末でない場合、competitive-verifier がその後の文字列まで URL の一部であるとしてドキュメントを生成してしまうため。 -- テンプレート宣言中の型名の明示で `class` キーワードが使用されている(`template ` のように `typename` キーワードが使用されていない)。 -- このライブラリの他のファイルの include よりも先に、標準ライブラリを include している。 -- `static_assert` のエラーメッセージを省略していない。 - -### ヘッダファイル -- ヘッダファイルの include guard はファイルの先頭にあり、ドキュメンテーションコメントなどより前に書いてある。 - - include guard の名前はそのファイルの相対パスを英大文字またはアンダースコアのみで表したものになっている。 - - `#pragma once` を使用していない。 -- そのファイルで使う標準ヘッダは明示的に列挙されている。 - - `bits/stdc++.h` は使っていない。 - - 未使用 include がない。 -- GCC 拡張および、`__gnu_pbds`, `#pragma GCC optimize`, `typeof`, VLA などを使っていない。 -- g++ および clang++ の C++20(`-std=c++20`)でコンパイルできる。 - - コンパイラ依存の実装になっていない。 -- 前提を満たさない入力に対する救済処理を過度に入れていない。 - - 必要な前提は `assert` などで確認している。 - - 前提を満たす入力に対する性能を著しく落とすような救済処理がない。 -- 公開 API の名前は VSCode 等による補完を使用しやすい名前になっている。 - - 用途から思い出しにくい名前や、短すぎる名前になっていない。 -- 構造体またはクラスの場合、基本的にメンバが `public` になっている。 - - あるメンバ関数が内部的に再帰を行うために引数を増やした関数などは `private` でもよい。 -- ヘッダファイルの先頭のコメントには、何をするものであるか、主な事前条件、計算量などが簡潔に書かれている。 - - 冗長な一般論や導入文になっていない。 -- include guard、先頭のコメント、標準ライブラリについての include 文、このライブラリの他のファイルについての include 文、実装の先頭のそれぞれの間には、空行が 1 行ずつ入っている。 -- 実装の末尾と `#endif` の間には、空行が 1 行入っている。 - -### verify ソースコード -- verify ソースコードの先頭には `// competitive-verifier: ...` がある。 - - AtCoder の問題を使っていない。 - - Library Checker (Yosupo Judge), yukicoder, AOJ のいずれかの問題を使用するか、または `STANDALONE` としている。 - - いずれかのジャッジの問題を使用する場合は `// competitive-verifier: PROBLEM ...` としており、`...` の部分に問題の URL を記述している。 - - `STANDALONE` の場合は `// competitive-verifier: STANDALONE` としている。 -- verify 問題が小数誤差許容問題である場合、verify ソースコードの 2 行目に `// competitive-verifier: ERROR ...` がある(`...` には許容誤差を小数で指定する)。 -- オンラインジャッジ上の問題を使う verify ソースコードと、STANDALONE で行う自己検証を 1 つのファイルにまとめていない。 - - オンラインジャッジ上の問題を使う verify ソースコードは、その問題を解くために必要な処理だけで構成されている。 - - ライブラリ API の網羅テスト、愚直解との比較、小さい入力の全探索テストなどは `// competitive-verifier: STANDALONE` の verify ソースコードに分離している。 - - ライブラリの用途や計算量に対して不自然な問題を、オンラインジャッジ上の verify 問題として無理に選んでいない。 -- AOJ の URL は `https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=...` の形式である(`http://...` などでない)。 -- 先頭の competitive-verifier 向けのコメント、標準ライブラリについての include 文、このライブラリの他のファイルについての include 文、実装の先頭のそれぞれの間には、空行が 1 行ずつ入っている。 -- 標準出力では `std::endl` を使用せず、`'\n'` を出力して改行している。 -- `main` 関数の引数は明示的に `void` と記述せず、空になっている。 -- 標準入出力を行う場合、`main` 関数の最初の 2 行は順に `std::ios::sync_with_stdio(false);` と `std::cin.tie(nullptr);` となっており、その次に空行が 1 行入っている。 -- `main` 関数内の全ての `return 0;` の前の行には、空行が 1 行入っている。 -- `main` 関数の最後の行にも `return 0;` が記述されている。 - -### ドキュメント(共通) -- TeX 数式の囲みが `$ $` である(`\( \)` などでない)。 -- TeX 数式の前後は、空白または改行である(たとえ前後が句読点であっても、`$` との間に空白を入れている)。 -- TeX 数式での絶対値記号による囲みが `\lvert \rvert` である(`| |` などでない)。 -- TeX 数式の等号付き不等号や否定記号は `e` で終わるコマンド(`\ge`, `\le`, `\ne`)で記述されている(`\geq`, `\leq`, `\neq` などでない)。 -- 複数のインライン数式が連続して並ぶ場合、1 つの TeX 数式として記述されている(数式の外の `,` や `、` などで区切られた複数の TeX 数式になっていない)。 - -### ライブラリのドキュメント -- ライブラリのドキュメントは箇条書きを中心とした簡潔な記述である。 -- 先頭に Jekyll Front Matter がある。 - - `documentation_of` が対応するヘッダファイルを指している。 - - `title` は人間にとって分かりやすいタイトルになっている(TeX 数式を使用してもよい)。 -- 「前提: 」や「備考: 」などにおけるコロンは、半角コロンと半角スペースである(「前提:」「前提:」「前提 : 」などでない)。 -- 自動で挿入される、対応するヘッダファイルの include 指令のテキストを必要なく記述していない。 - - 使用例のソースコードなどの、include 指令が実際に必要である例は除く。 -- `## 概要`、`## 使い方`、`## 計算量` の見出しがこの順に存在する。 -- `## 使い方` の節では、公開 API ごとの使い方の説明がある。 - - 返り値、区間や引数の意味、変更する引数やメンバ変数などが簡潔に書いてある。 - - 必要な前提や境界の扱いが書いてある。 - - ソースコードによる例だけで説明を済ませていない。 -- `## 計算量` の節で、計算量の種類を略して「時間」または「空間」と表記する場合、`時間 $O(n)$` のように計算量よりも前に書く(`$O(n)$ 時間` などでない)。 -- `## 計算量` の節に記載されている、big-O 記法などのランダウの記法による計算量オーダーは、ランダウの記法の数学的な定義に従った厳密な値であり、ランダウの記法を用いることが自然なものである。 - - 関数 $f$ を用いて計算量オーダーを $O(f)$ と記述する場合、 $f$ は正しい上界である(悪い例は、入力サイズ $n$ についての漸近計算量オーダーが実際は $\Theta(n\log n)$ であるのにもかかわらず、 $O(n)$ と記述するなどである)。 - - 関数 $f$ を用いて計算量オーダーを $\Theta(f)$ と記述する場合、計算量オーダーは実際に $f$ で上からも下からも抑えられる(悪い例は、入力サイズ $n$ についての漸近計算量オーダーが実際は $O(n)$ であるのにもかかわらず、 $\Theta(n \log n)$ と記述するなどである)。 - - 関数 $f$ を用いて計算量オーダーを $\Omega(f)$ と記述する場合、 $f$ は正しい下界である。 - - ランダウの記法を用いる場合、非負整数 $N$ に対する $(\log N)^{-1}$ のように値が小さい場合に未定義になる式を用いていても修正する必要はない。特に、多変数のランダウの記法であっても、一部の変数のみを無限大に飛ばして他の変数を小さい値に固定した場合を考慮して過度に複雑な式にする必要はない。 - - big-O 記法を用いて厳密に記述するのが難しい計算量であれば、適宜 $\tilde{O}$ や $\mathrm{poly}$ などを用いている。 - - このライブラリで特殊化した特定の定数に比例する場合は、ランダウの記法以外を用いてその旨を説明している(悪い例は、 $O(128)$ などである)。 -- `## 計算量` の節で、平均計算量や期待計算量などの最悪計算量と償却計算量以外の計算量を述べる場合は、その旨を説明している。 -- 数式として書くべきである制約などの記述は、バッククォートによる囲みなどではなく TeX 数式として書いてある。 - - 1 文字の値(数学定数などローマン体で表記されるべき値を除く)はイタリック体である(`\mathrm{ }` などを使用していない)。 - - 引数などの、通常の数式に現れないような 2 文字以上の文字列で表される値を数式中で使用する場合は、先に別の文字でおいている。 - - おいた文字は、イタリック体の 1 文字もしくはイタリック体の 1 文字に上付きまたは下付きの数や文字列が付いたものである。 - - 上付きまたは下付きの文字列が英字 1 文字(数学定数などローマン体で表記されるべき値を除く)であれば、イタリック体になっている(`\mathrm{ }` などを使用していない)。 - - 上付きまたは下付きの文字列が、ローマン体で表記されるべき値または 2 文字以上の文字列であれば、`\mathrm{ }` を使用している。 -- ライブラリのドキュメント中の C++ ソースコードの例は「```C++」から「```」までによって囲まれている(特に、先頭は「```」や「```c++」「```cpp」などでない)。 - -### リポジトリのドキュメント -- リポジトリ内のファイルやディレクトリのパスは、先頭に `./` を付けずにリポジトリのルートからの相対パスで記述している。 -- リポジトリ内のファイルやディレクトリのパスを、バッククォートで囲んでいない。 -- リポジトリ内のディレクトリのパスは、末尾に `/` を付けて記述している。 -- リポジトリ内のファイルやディレクトリのパスを、`[path/to/file](path/to/file)` の形でリンクにしている。 -- リポジトリ内のファイルやディレクトリのパスが `[ ]` で囲まれている場合、`( )` で囲まれたパスも全く同じパスが記述されている(先頭の `./` の有無や末尾の `/` の有無の違いもない)。 - - `[CC0-1.0 license](LICENSE)` のように、パスでない文字列がリポジトリ内の特定のファイルやディレクトリのパスにリンクされていてもよい。 - -### 依存関係 -- [NotLeonian/competitive-verifier](https://github.com/NotLeonian/competitive-verifier) は [pyproject.toml](pyproject.toml) の `[tool.uv.sources].competitive-verifier` は、`rev` による 40 文字の commit SHA または `tag` によるタグのどちらかによって固定されている(`branch` などの更新されうる参照ではない)。 -- [.github/workflows/verify.yml](.github/workflows/verify.yml) に [NotLeonian/competitive-verifier](https://github.com/NotLeonian/competitive-verifier) の commit SHA やタグを直接書いていない。 - -### 設定ファイルなど -- [.gitignore](.gitignore) では、各行が `# ` から始まるコメントで下に続く ignore の内容を説明している。 -- [.gitignore](.gitignore) では、各行が `## ` から始まるコメントで下に続く記述の由来を説明している。 - - もし下に続く記述が他のリポジトリのファイルに由来しないこのリポジトリ独自の記述であれば、その旨を説明している。 - - もし下に続く記述が [github/gitignore](https://github.com/github/gitignore) 等の他のリポジトリのファイルに由来する場合は、対象とするプログラミング言語および元となったファイルの permalink を順に記述している。 - - もし permalink 先の記述に変更を加えている場合は、変更内容も詳細に各行が `## ` から始まるコメントで説明している。 - ---- - -### 逆にレビューしないでよいこと +### レビューしないでよいこと - [pyproject.toml](pyproject.toml) で固定されている [NotLeonian/competitive-verifier](https://github.com/NotLeonian/competitive-verifier) 内に、このリポジトリで必要なファイルが存在するかどうかの確認。 - 権限が足りないなどで正しく確認できない可能性が高い。 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5c98e13..18a48cc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,18 +1,19 @@ # CONTRIBUTING.md -NicheLibrary への貢献をご検討していただきありがとうございます。 -このライブラリは、既存の有名な競技プログラミング用ライブラリで要件を満たせないものを補うためのライブラリです。 +NicheLibrary への貢献をご検討していただきありがとうございます。 + +このライブラリは、既存の有名な競技プログラミング用ライブラリで要件を満たせないものを補うためのライブラリです。 このライブラリだけで汎用的な問題を解けるようなライブラリにすることは想定していません。 個人で管理しているため、方針と合わない変更、保守コストに見合わない変更、検証が難しい変更は採用しないことがあります。 -このドキュメントは貢献者向けの概要です。 -レビュー時の細かな観点は [AGENTS.md](AGENTS.md) にも記載しています。 +このドキュメントは貢献者向けの概要です。 +コーディング規約は [STYLE_GUIDE.md](STYLE_GUIDE.md) に記載しています。 ## 言語と文体 - ソースコード中のコメント、[docs/](docs/) および [.competitive-verifier/docs/](.competitive-verifier/docs/) 配下のドキュメントでは、原則として日本語の常体を使用してください。 - [README.md](README.md), [CONTRIBUTING.md](CONTRIBUTING.md), GitHub Pages 上のトップページなどのリポジトリについてのドキュメントでは、原則として日本語の敬体を使用してください。 - Issue および Pull Request の description は、日本語以外でも構いません。 -- Markdown の記法、句読点、ファイルパスの書き方などの細かな規約は、[AGENTS.md](AGENTS.md) に従ってください。 +- Markdown の記法、句読点、ファイルパスの書き方などの細かな規約は、[STYLE_GUIDE.md](STYLE_GUIDE.md) に従ってください。 ## 受け付ける Issue, Pull Request ### 不具合の報告、修正 @@ -60,7 +61,7 @@ C++ の実装では、少なくとも次の点を満たしてください。 - ヘッダファイルでは include guard を使用し、`#pragma once` を使用しない。 - 公開 API の名前、前提条件、計算量、例外的な挙動が既存の実装と同程度に分かるようにする。 -より細かなレビュー観点は [AGENTS.md](AGENTS.md) を確認してください。 +より細かなコーディング規約は [STYLE_GUIDE.md](STYLE_GUIDE.md) を確認してください。 ## verify とドキュメント 新規の実装を追加する場合は、対応する verify ソースコードを [verify/](verify/) に追加してください。 @@ -69,7 +70,7 @@ C++ の実装では、少なくとも次の点を満たしてください。 ライブラリとして公開するヘッダファイルには、原則として対応するドキュメントを [docs/](docs/) に追加または更新してください。 ドキュメントは、対応するヘッダファイルのルート直下から見た階層と同じ階層に置いてください。 -より細かなレビュー観点は [AGENTS.md](AGENTS.md) を確認してください。 +より細かなコーディング規約は [STYLE_GUIDE.md](STYLE_GUIDE.md) を確認してください。 ## フォーマットとローカルでの確認 C++ のソースコードは、[.clang-format](.clang-format) に従い clang-format 20 でフォーマットしてください。 @@ -86,12 +87,12 @@ yukicoder の問題を verify する場合は、`YUKICODER_TOKEN` を環境変 ローカル verify の詳細は [README.md](README.md) を参照してください。 ## リポジトリの運用に関わるファイルの変更 -[AGENTS.md](AGENTS.md), [README.md](README.md), [CONTRIBUTING.md](CONTRIBUTING.md), [.github/workflows/verify.yml](.github/workflows/verify.yml), [.github/scripts/](.github/scripts/), [.competitive-verifier/config.toml](.competitive-verifier/config.toml), [pyproject.toml](pyproject.toml), [uv.lock](uv.lock), [.clang-format](.clang-format) などは、レビュー、CI、verify、ドキュメント生成、依存関係の前提に影響します。 +[AGENTS.md](AGENTS.md), [STYLE_GUIDE.md](STYLE_GUIDE.md), [README.md](README.md), [CONTRIBUTING.md](CONTRIBUTING.md), [.github/workflows/verify.yml](.github/workflows/verify.yml), [.github/scripts/](.github/scripts/), [.competitive-verifier/config.toml](.competitive-verifier/config.toml), [pyproject.toml](pyproject.toml), [uv.lock](uv.lock), [.clang-format](.clang-format) などは、レビュー、CI、verify、ドキュメント生成、依存関係の前提に影響します。 これらを変更する Pull Request では、変更理由、影響範囲、ローカルで確認した内容を description に書いてください。 運用方針そのものを変える変更は、通常のヘッダ追加や不具合修正よりも慎重に扱います。 -AI 支援ツールや自動修正ツールを使用する場合も、出力をそのまま提出せず、[AGENTS.md](AGENTS.md) のレビュー観点に照らして内容を確認してください。 +AI 支援ツールや自動修正ツールを使用する場合も、出力をそのまま提出せず、[STYLE_GUIDE.md](STYLE_GUIDE.md) のコーディング規約に照らして内容を確認してください。 ## Pull Request 作成前の確認 diff --git a/STYLE_GUIDE.md b/STYLE_GUIDE.md new file mode 100644 index 0000000..d38a868 --- /dev/null +++ b/STYLE_GUIDE.md @@ -0,0 +1,159 @@ +# コーディング規約 +このドキュメントは、NicheLibrary のヘッダファイル、verify ソースコード、ドキュメント、スクリプト、設定ファイルなどに適用するコーディング規約である。 + +以下の説明において、「ライブラリのドキュメント」は [docs/](docs/) または [.competitive-verifier/docs/](.competitive-verifier/docs/) 配下のドキュメントを指し、「リポジトリのドキュメント」はその他のドキュメント(特に [README.md](README.md)、[CONTRIBUTING.md](CONTRIBUTING.md)、[AGENTS.md](AGENTS.md)、[STYLE_GUIDE.md](STYLE_GUIDE.md))を指す。 + +## 共通 +- 全てのテキストファイルの末尾には改行を入れる。 +- 句読点は基本的に `、` と `。` とする(`,` と `.` などでない)。 + - ただし、`Library Checker (Yosupo Judge), yukicoder, AOJ` のように英数字どうしを並べる際のカンマまで避ける必要はない(どちらでもよい)。 +- 複数の語句を並べる際の区切り記号は `、` または `, ` とし、上の規約にも従う(`・` や ` / `、`/` などでない)。 +- マークダウンの箇条書きのインデントはスペース 2 文字とする。 +- マークダウンの番号なし箇条書きは `- ` とする(`* ` や ` - ` などでない)。 +- マークダウンの番号付き箇条書きは常に `1. ` とする(`2. ` 以降は使用しない)。 +- ソースコード中のコメントやドキュメントなどの文章は日本語で記述し、次の項で示すファイルを除いて文体を常体で統一する(`です`、`ます` などの敬体を使用しない)。 + - [pyproject.toml](pyproject.toml) の `[project]` 内の `description` および [.editorconfig](.editorconfig), [.gitattributes](.gitattributes), [.gitignore](.gitignore) 内のコメントは英語で記述する。 + - 参考文献を記述する場合は、人名も含めて英語で記述する。 + - また、日本語で同じ内容が記述されている場合は、英語などの他の言語が併記されていてもよい。 +- リポジトリの [README.md](README.md) や [CONTRIBUTING.md](CONTRIBUTING.md)、GitHub Pages 上のドキュメントのトップページ([.competitive-verifier/docs/index.md](.competitive-verifier/docs/index.md) を基に生成される)の文章は日本語で記述し、文体を敬体で統一する(以下の例外を除いて、`だ`、`である` などの常体を使用しない)。 + - ただし、箇条書き内の文章は常体でも敬体でもよいとする(少なくとも深さが最も小さい部分の文章は常体を推奨するが、厳密に片方に決める運用はしないものとする)。 +- プログラム、スクリプトやコンパイラが出力するエラーメッセージは英語で記述する。 +- 「ならば」の代わりに「なら」を使用しない。 +- ハイフン、エンダッシュ、エムダッシュを使い分ける。 + - 人名どうしの連結や期間の開始と終了を結ぶ記号などでは、ハイフンやエムダッシュではなくエンダッシュを使用する。 + - 文章中で追加の情報を後ろから挿入する用法などでは、ハイフンやエンダッシュではなくエムダッシュを使用する。 + - ただし、もし正しい使い分けがされていない固有名詞がある場合は、その固有名詞の表記を優先する。 + - また、[LICENSE](LICENSE) 中の記述も例外とする。 +- 文章中の引用符は `‘ ’` と `“ ”` とする(`' '` と `" "` などでない)。 + - ただし、C++ の文字リテラルや文字列リテラルを表す場合の引用符は `' '` と `" "` でよい。 + - また、もし正しい使い分けがされていない固有名詞がある場合は、その固有名詞の表記を優先する。 + - また、[LICENSE](LICENSE) 中の記述も例外とする。 +- 文章中のアポストロフィーは `’` とする(`'` などでない)。 + - ただし、`Luzhiled's Library` や `Nyaan's Library` のような固有名詞は例外とする。 + - また、[LICENSE](LICENSE) 中の記述も例外とする。 +- indexing は `0-based indexing`, `1-based indexing` のように `k-based indexing` の形で記述する(`k-indexed` などでない)。 +- かぎかっこは「引用を表す囲み」もしくは「囲みがないと入れ子になって読みにくいような部分のための囲み」にのみ使い、強調などに濫用しない。 +- 数式中に現れる文字(一般的な数学関数や数学定数を除く)は、その数式よりも前に説明を書く。 + - ただし、Jekyll Front Matter の `title` 中の数式は例外とする。 + +## パス、ファイル名 +- C++ のソースコードを配置するディレクトリ名およびファイル名の単語の区切りはハイフンとする(アンダースコアなどでない)。 +- Python のソースコードを配置するディレクトリ名およびファイル名の単語の区切りはアンダースコアとする(ハイフンなどでない)。 +- ルート直下に全てのヘッダファイルを入れるディレクトリを置かない。 +- ドキュメントは [docs/](docs/) 内に置き、対応するヘッダファイルのルート直下から見た階層と同じ階層に置く。 +- verify ソースコードは [verify/](verify/) 内に置く。 + - それぞれの verify ソースコードのファイル名の先頭は `yosupo`, `yukicoder`, `aoj`, `standalone` のいずれかにする。 + - 先頭が `standalone` 以外であれば、その後ろは問題の ID などとする。 + - 先頭が `standalone` であれば、その後ろは verify を行うヘッダファイルの名前とする(フルパスではなく、basename から拡張子を除いたものでよい)。 + - verify ソースコードの拡張子は `.test.cpp` とする。 + +## C++ ソースコード(共通) +- テンプレート引数によってプリミティブな整数型以外の型が与えられる可能性がある型(ただし、イテレータが与えられることが想定される型を除く)の値では、インクリメントを `+= 1`、デクリメントを `-= 1` で行う(インクリメント演算子 `++`、デクリメント演算子 `--` を用いない)。 +- テンプレート引数によって主にイテレータが与えられることが想定される型については、前置インクリメント演算子および後置インクリメント演算子を使用し、イテレータでない型が与えられないようにメタ関数や `static_assert` などを使用する。 +- テンプレート引数によってプリミティブな整数型以外の型が与えられる可能性がある型の値では、ビット演算で行う必要がない演算にビット演算を用いない。 + - たとえば、偶奇判定には `& 1` ではなく `% 2` を用い、2 倍の計算には `<< 1`, `<<= 1` ではなく `* 2`, `*= 2` を用い、2 で割った商の計算には `>> 1`, `>>= 1` ではなく `/ 2`, `/= 2` を用いる。 +- clang-format 20 を用いて、[.clang-format](.clang-format) で指定したオプションによりフォーマットする。 +- 1 行目を空行にしない。 +- ブロックの末尾の `}` のみからなる行の 1 つ前の行を空行にしない。 +- URL を記述する場合、URL が行末になるように記述する。 + - URL が行末でない場合、competitive-verifier がその後の文字列まで URL の一部であるとしてドキュメントを生成してしまうため。 +- テンプレート宣言中の型名の明示では `class` キーワードを使用する(`template ` のように `typename` キーワードを使用しない)。 +- このライブラリの他のファイルの include よりも先に、標準ライブラリを include する。 +- `static_assert` のエラーメッセージを省略しない。 + +## ヘッダファイル +- ヘッダファイルの include guard はファイルの先頭に置き、ドキュメンテーションコメントなどより前に書く。 + - include guard の名前はそのファイルの相対パスを英大文字またはアンダースコアのみで表したものにする。 + - `#pragma once` を使用しない。 +- そのファイルで使う標準ヘッダを明示的に列挙する。 + - `bits/stdc++.h` を使用しない。 + - 未使用のヘッダを include しない。 +- GCC 拡張および、`__gnu_pbds`, `#pragma GCC optimize`, `typeof`, VLA などを使用しない。 +- g++ および clang++ の C++20(`-std=c++20`)でコンパイルできるようにする。 + - コンパイラ依存の実装にしない。 +- 前提を満たさない入力に対する救済処理を過度に入れない。 + - 必要な前提は `assert` などで確認する。 + - 前提を満たす入力に対する性能を著しく落とすような救済処理を入れない。 +- 公開 API の名前は VS Code 等による補完を使用しやすい名前にする。 + - 用途から思い出しにくい名前や、短すぎる名前にしない。 +- 構造体またはクラスの場合、基本的にメンバを `public` にする。 + - あるメンバ関数が内部的に再帰を行うために引数を増やした関数などは `private` でもよい。 +- ヘッダファイルの先頭のコメントには、何をするものであるか、主な事前条件、計算量などを簡潔に書く。 + - 冗長な一般論や導入文にしない。 +- include guard、先頭のコメント、標準ライブラリについての include 文、このライブラリの他のファイルについての include 文、実装の先頭のそれぞれの間には、空行を 1 行ずつ入れる。 +- 実装の末尾と `#endif` の間には、空行を 1 行入れる。 + +## verify ソースコード +- verify ソースコードの先頭には `// competitive-verifier: ...` を記述する。 + - Library Checker (Yosupo Judge), yukicoder, AOJ のいずれかの問題を使用するか、または `STANDALONE` とする。 + - いずれかのジャッジの問題を使用する場合は `// competitive-verifier: PROBLEM ...` とし、`...` の部分に問題の URL を記述する。 + - `STANDALONE` の場合は `// competitive-verifier: STANDALONE` とする。 + - verify に AtCoder の問題を使用しない。 +- verify 問題が小数誤差許容問題である場合、verify ソースコードの 2 行目に `// competitive-verifier: ERROR ...` を記述する(`...` には許容誤差を小数で指定する)。 +- オンラインジャッジ上の問題を使う verify ソースコードと、STANDALONE で行う自己検証を 1 つのファイルにまとめない。 + - オンラインジャッジ上の問題を使う verify ソースコードは、その問題を解くために必要な処理だけで構成する。 + - ライブラリ API の網羅テスト、愚直解との比較、小さい入力の全探索テストなどは `// competitive-verifier: STANDALONE` の verify ソースコードに分離する。 + - ライブラリの用途や計算量に対して不自然な問題を、オンラインジャッジ上の verify 問題として無理に選ばない。 +- AOJ の URL は `https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=...` の形式とする(`http://...` などでない)。 +- 先頭の competitive-verifier 向けのコメント、標準ライブラリについての include 文、このライブラリの他のファイルについての include 文、実装の先頭のそれぞれの間には、空行を 1 行ずつ入れる。 +- 標準出力では `std::endl` を使用せず、`'\n'` を出力して改行する。 +- `main` 関数の引数は明示的に `void` と記述せず、空にする。 +- 標準入出力を行う場合、`main` 関数の最初の 2 行は順に `std::ios::sync_with_stdio(false);` と `std::cin.tie(nullptr);` とし、その次に空行を 1 行入れる。 +- `main` 関数内の全ての `return 0;` の前の行には、空行を 1 行入れる。 +- `main` 関数の最後の行にも `return 0;` を記述する。 + +## ドキュメント(共通) +- TeX 数式の囲みは `$ $` とする(`\( \)` などでない)。 +- TeX 数式の前後は、必ず空白または改行とする(たとえ前後が句読点や括弧であっても、`$` との間に空白を入れる)。 +- TeX 数式での絶対値記号による囲みは `\lvert \rvert` とする(`| |` などでない)。 +- TeX 数式の等号付き不等号や否定記号は `e` で終わるコマンド(`\ge`, `\le`, `\ne`)で記述する(`\geq`, `\leq`, `\neq` などでない)。 +- 複数のインライン数式が連続して並ぶ場合、1 つの TeX 数式として記述する(数式の外の `,` や `、` などで区切られた複数の TeX 数式にしない)。 + +## ライブラリのドキュメント +- ライブラリのドキュメントは箇条書きを中心とした簡潔な記述にする。 +- 先頭に、`title`, `documentation_of` の順に Jekyll Front Matter を記述する。 + - `documentation_of` は対応するヘッダファイルを指すようにする。 + - `title` は人間にとって分かりやすいタイトルにする(TeX 数式を使用してもよい)。 +- 「前提: 」や「備考: 」などにおけるコロンは、半角コロンと半角スペースとする(「前提:」「前提:」「前提 : 」などでない)。 +- 自動で挿入される、対応するヘッダファイルの include 指令のテキストを必要なく記述しない。 + - 使用例のソースコードなどの、include 指令が実際に必要である例は除く。 +- `## 概要`、`## 使い方`、`## 計算量` の節をこの順に記述する。 +- `## 使い方` の節では、各公開 API の使い方を説明する。 + - 返り値、区間や引数の意味、変更する引数やメンバ変数などを簡潔に書く。 + - 必要な前提や境界の扱いを書く。 + - ソースコードによる例だけで説明を済ませない。 +- `## 計算量` の節で、計算量の種類を略して「時間」または「空間」と表記する場合、`時間 $O(n)$` のように計算量よりも前に書く(`$O(n)$ 時間` などでない)。 +- `## 計算量` の節に記載する、big-O 記法などのランダウの記法による計算量オーダーは、ランダウの記法の数学的な定義に従った厳密な値であり、ランダウの記法を用いることが自然なものにする。 + - 関数 $f$ を用いて計算量オーダーを $O(f)$ と記述する場合、 $f$ は正しい上界でなければならない(悪い例は、入力サイズ $n$ についての漸近計算量オーダーが実際は $\Theta(n\log n)$ であるのにもかかわらず、 $O(n)$ と記述するなどである)。 + - 関数 $f$ を用いて計算量オーダーを $\Theta(f)$ と記述する場合、計算量オーダーは実際に $f$ で上からも下からも抑えられなければならない(悪い例は、入力サイズ $n$ についての漸近計算量オーダーが実際は $O(n)$ であるのにもかかわらず、 $\Theta(n \log n)$ と記述するなどである)。 + - 関数 $f$ を用いて計算量オーダーを $\Omega(f)$ と記述する場合、 $f$ は正しい下界でなければならない。 + - ランダウの記法を用いる場合、非負整数 $N$ に対する $(\log N)^{-1}$ のように値が小さい場合に未定義になる式を用いてもよい。特に、多変数のランダウの記法であっても、一部の変数のみを無限大に飛ばして他の変数を小さい値に固定した場合を考慮して過度に複雑な式にする必要はない。 + - big-O 記法を用いて厳密に記述するのが難しい計算量であれば、適宜 $\tilde{O}$ や $\mathrm{poly}$ などを用いること。 + - このライブラリで特殊化した特定の定数に比例する場合は、ランダウの記法以外を用いてその旨を説明する(悪い例は、 $O(128)$ などである)。 +- `## 計算量` の節で、平均計算量や期待計算量などの最悪計算量と償却計算量以外の計算量を述べる場合は、その旨を説明する。 +- 数式として書くべきである制約などの記述は、バッククォートによる囲みなどではなく TeX 数式として書く。 + - 1 文字の値(数学定数などローマン体で表記されるべき値を除く)はイタリック体にする(`\mathrm{ }` などを使用しない)。 + - 引数などの、通常の数式に現れないような 2 文字以上の文字列で表される値を数式中で使用する場合は、先に別の文字でおく。 + - おいた文字は、イタリック体の 1 文字もしくはイタリック体の 1 文字に上付きまたは下付きの数や文字列が付いたものにする。 + - 上付きまたは下付きの文字列が英字 1 文字(数学定数などローマン体で表記されるべき値を除く)であれば、イタリック体にする(`\mathrm{ }` などを使用しない)。 + - 上付きまたは下付きの文字列が、ローマン体で表記されるべき値または 2 文字以上の文字列であれば、`\mathrm{ }` を使用する。 +- ライブラリのドキュメント中の C++ ソースコードの例は「```C++」から「```」までによって囲む(特に、先頭は「```」や「```c++」「```cpp」などでない)。 + +## リポジトリのドキュメント +- リポジトリ内のファイルやディレクトリのパスは、先頭に `./` を付けずにリポジトリのルートからの相対パスで記述する。 +- リポジトリ内のファイルやディレクトリのパスを、バッククォートで囲まない。 +- リポジトリ内のディレクトリのパスは、末尾に `/` を付けて記述する。 +- リポジトリ内のファイルやディレクトリのパスは、`[path/to/file](path/to/file)` の形でリンクにする。 +- リポジトリ内のファイルやディレクトリのパスが `[ ]` で囲まれている場合、`( )` で囲まれたパスも全く同じパスにする(先頭の `./` の有無や末尾の `/` の有無の違いもない)。 + - `[CC0-1.0 license](LICENSE)` のように、パスでない文字列がリポジトリ内の特定のファイルやディレクトリのパスにリンクされていてもよい。 + +## 依存関係 +- [NotLeonian/competitive-verifier](https://github.com/NotLeonian/competitive-verifier) は [pyproject.toml](pyproject.toml) の `[tool.uv.sources].competitive-verifier` で、`rev` による 40 文字の commit SHA または `tag` によるタグのどちらかによって固定する(`branch` などの更新されうる参照でない)。 +- [.github/workflows/verify.yml](.github/workflows/verify.yml) には、[NotLeonian/competitive-verifier](https://github.com/NotLeonian/competitive-verifier) の commit SHA やタグを直接書かない。 + +## 設定ファイルなど +- [.gitignore](.gitignore) では、各行が `# ` から始まるコメントで下に続く ignore の内容を説明する。 +- [.gitignore](.gitignore) では、各行が `## ` から始まるコメントで下に続く記述の由来を説明する。 + - もし下に続く記述が他のリポジトリのファイルに由来しないこのリポジトリ独自の記述であれば、その旨を説明する。 + - もし下に続く記述が [github/gitignore](https://github.com/github/gitignore) 等の他のリポジトリのファイルに由来する場合は、対象とするプログラミング言語および元となったファイルの permalink を順に記述する。 + - もし permalink 先の記述に変更を加えている場合は、変更内容も詳細に各行が `## ` から始まるコメントで説明する。