グローバル修飾リストのルール整備
- https://github.com/cpprefjp/site/issues/1452
こちらからの派生。インラインコードへの修飾とは別に、グローバル修飾リストに関してはこちらで議論を進めましょう。
グローバル修飾リスト (GLOBAL_QUALIFY_LIST.txt) の概要
このファイルにコードブロックへの修飾を列挙することで、すべてのページのコードブロックにそれらの修飾が適用される。
導入意図
- 編集者の負担を減らす
- 何度も同じ修飾を書かないといけない記述量の問題を解消
- 管理する文書を最小限にする
- 人的ミスを減らす
現状の問題
- グローバル修飾リストになにを登録すべきかがあいまい
- オーバーロードされているページを登録できない
- std::moveのようなalgorithm / utilityに登録されているもの
- 引数の数だけならstd::move/1のような形式で区別できそうだが、型はむずかしい
-
グローバル修飾リストにどれくらい登録できるのかがあいまい(解決済み)-
Pythonのreライブラリの制限に引っかからない限り登録できる、という状況 -
コードブロック内で使われている要素だけ使用するようツール改善が必要
-
- グローバル修飾リストのルールがとくに書かれていないために登録しにくい
- コメント構文を追加するPull Requestを提出中
- https://github.com/cpprefjp/site_generator/pull/91
- コメント構文を追加するPull Requestを提出中
- 名前空間の省略、略称をどうすべきかが決まっていない
- 名前空間の省略は、宣言や効果・戻り値の記述で必要になる
- サンプルコードはなるべく名前空間つきで書きたい
- どうしても長くなってしまう場合にサンプルコードで名前空間の略称をルール決めしたい
懸念されることとしては、無制限に登録できるようになったときに、無秩序になってしまうことですね。 いままでは頻出するものを登録してきましたが、これまで通りに頻出で絞るのか、あいまいにならないもの (オーバーロード・特殊化されていないもの) は制限なく登録OKにするのか、判断がむずかしいところです
- コードブロック内で使われている要素だけ使用するようツール改善が必要
これは、以下のコードでやっていることではありませんか?
https://github.com/cpprefjp/markdown_to_html/blob/e2af656da07c963510edcd1971460c283d3a3575/qualified_fenced_code.py#L187
pre_target_re_text_list = [q.get_target_re_text() for q in self._qs if q.find_match(code)]
あ、すでに解決してましたか。ではこれは解決済みですね。
変数名ルールもこの機会にある程度決めておきたいです。
forward_listの変数名がlsになっていたりするので、ls.begin()とかをグローバル修飾リストに登録しにくい、というのがあります。
-
forward_list->fls -
unordered_map->um -
unordered_set->us -
unordered_multimap->umm -
unordered_multiset->ums -
map->m -
set->s -
multimap->mm -
multiset->ms(millisecondsに対するメンバ関数呼び出しと衝突しそうだけどdurationとメンバ関数はあまりかぶってなさそう)
コンテナはalgorithmやranges、iterator関係でよくでてきます。
valarrayはvectorと衝突しないようにvaにしてあります。
いまは単純な置換をしているグローバル修飾リストですが、たとえば変数定義や名前空間定義なども考えられそうな気はします。変数名を決め打ちすることに危険を感じられる場合には有効な手段になりそうな気はします。
# 指定された定義がコードブロック内に見つかったら、インデントされたコード修飾を適用する
* std::vector<T> v[define]
* v.begin()[link /reference/vector/vector/begin.md]
* namespace fs = std::filesystem;[define]
* fs::path[link /reference/filesystem/path.md]
vectorのテンプレート引数をどうするとかの問題はありますが、正規表現でテンプレート引数部分を単に無視したりはできそうな気はします。
なんでもかんでも無制限に登録したくなったら、そのときそれはグローバル修飾リストの役割ではなく、コード解析 + 検索エンジン用の辞書データを使ったツールで自動リンクすべき問題になる気がします。 なので現状のツールの範囲では頻出を登録という方針のままにして、無制限に登録したくなったらツール開発しましょう、というルールでよい気がします。
"see below[italic]" はたくさんのページで定義されているみたいなので GLOBAL_QUALIFTY_LIST.txt に登録しても良いのではと思いました。
$ git grep 'see[ -]below\[italic]' | wc -l
133
それは頻出なので登録してよいかと思います
# 7. オーバーロードされている名前は、優先度の高いプライマリ宣言をグローバル修飾リストに登録する
# 7.1 ライブラリごとにオーバーロード・特殊化されているものはグローバル修飾リストに登録せず、個別ページで指定する
# (std::begin/std::end、std::common_typeなど)
執筆者的には 7.1 の判断が難しく、具体的な登録禁止が列挙されていてもよい気がします。現状だと下記3つだけ?
-
std::begin -
std::end -
std::common_type
すぐ思いつく範囲だと std:hash も例の一つでしょうか。
ほかにもあります!
-
std::floor(chronoでオーバーロードされている。プライマリはcmath) -
std::ceil(chronoでオーバーロードされている。プライマリはcmath) -
std::round(chronoでオーバーロードされている。プライマリはcmath) -
std::formatter(いろんなところで特殊化されている。プライマリはformat) -
std::enable_nonlocking_formatter_optimization(chronoで特殊化されている。プライマリはformat)
ぜんぶ列挙できるか怪しいので、思い出したらまた書きます。
-
is_error_code_enum(futureで特殊化されている。プライマリはsystem_error) -
make_error_code(futureでオーバーロードされている。プライマリはsystem_error) -
make_error_condition(futureでオーバーロードされている。プライマリはsystem_error) -
std::print(ostreamでオーバーロードされている。プライマリはprint) -
std::println(ostreamでオーバーロードされている。プライマリはprint) -
std::vprint_unicode(ostreamでオーバーロードされている。プライマリはprint) -
std::vprint_nonunicode(ostreamでオーバーロードされている。プライマリはprint) -
std::tuple_size(std::arrayとstd::complexが特殊化している。プライマリはtuple) -
std::tuple_element(std::arrayとstd::complexが特殊化している。プライマリはtuple) -
std::get(std::arrayとstd::complexがオーバーロードしている。プライマリはtupleだけど、variantにもある) -
std::swap(swap_free。以下はプライマリがどれとは書けない) -
operator== -
operator!= -
operator<=> -
operator<= -
operator< -
operator>= -
operator>
-
std::abs(cmathとcstdlibにある。valarrayとcomplexにもある) -
std::acos(valarrayとcomplexでオーバーロードされている。プライマリはcmath) -
std::acosh(complexでオーバーロードされている。プライマリはcmath) -
std::asin(valarrayとcomplexでオーバーロードされている。プライマリはcmath) -
std::asinh(complexでオーバーロードされている。プライマリはcmath) -
std::atan(valarrayとcomplexでオーバーロードされている。プライマリはcmath) -
std::atanh(complexでオーバーロードされている。プライマリはcmath) -
std::atan2(valarrayでオーバーロードされている。プライマリはcmath) -
std::cos(valarrayとcomplexでオーバーロードされている。プライマリはcmath) -
std::cosh(valarrayとcomplexでオーバーロードされている。プライマリはcmath) -
std::exp(valarrayとcomplexでオーバーロードされている。プライマリはcmath) -
std::log(valarrayとcomplexでオーバーロードされている。プライマリはcmath) -
std::log10(valarrayとcomplexでオーバーロードされている。プライマリはcmath) -
std::pow(valarrayとcomplexでオーバーロードされている。プライマリはcmath) -
std::sin(valarrayとcomplexでオーバーロードされている。プライマリはcmath) -
std::sinh(complexでオーバーロードされている。プライマリはcmath) -
std::sqrt(valarrayとcomplexでオーバーロードされている。プライマリはcmath) -
std::tan(valarrayとcomplexでオーバーロードされている。プライマリはcmath) -
std::tanh(valarrayとcomplexでオーバーロードされている。プライマリはcmath)
-
operator<<(あちこちでオーバーロードされている。プライマリはostream) -
operator>>(あちこちでオーバーロードされている。プライマリはistream) -
std::move(algorithmでオーバーロードされている。プライマリはutility)
一通り調べました。抜けはあるかもしれません
たくさんあるので、OVERLOAD_SPECIALIZATION_LIST.txtとかを用意して列挙管理するのがいい気がします。
(拡張子以外が全部大文字のファイルは変換対象外)
たくさんあるので、OVERLOAD_SPECIALIZATION_LIST.txtとかを用意して列挙管理するのがいい気がします。
列挙ありがとうございます。想像以上に大量でした... 機械的な対処方針に同意です。
それでは、スクリプトフレンドリーな作りにして、プライマリなオーバーロードと特殊化を列挙するようにしていきます
以下もありました。
-
std::atomic(memoryで特殊化されている。プライマリはatomic) -
std::atomic_compare_exchange_strong(memoryでオーバーロードされている。プライマリはatomic) -
std::atomic_compare_exchange_strong_explicit(memoryでオーバーロードされている。プライマリはatomic) -
std::atomic_compare_exchange_weak(memoryでオーバーロードされている。プライマリはatomic) -
std::atomic_compare_exchange_weak_explicit(memoryでオーバーロードされている。プライマリはatomic) -
std::atomic_exchange(memoryでオーバーロードされている。プライマリはatomic) -
std::atomic_exchange_explicit(memoryでオーバーロードされている。プライマリはatomic) -
std::atomic_is_lock_free(memoryでオーバーロードされている。プライマリはatomic) -
std::atomic_load(memoryでオーバーロードされている。プライマリはatomic) -
std::atomic_load_explicit(memoryでオーバーロードされている。プライマリはatomic) -
std::atomic_store(memoryでオーバーロードされている。プライマリはatomic) -
std::atomic_store_explicit(memoryでオーバーロードされている。プライマリはatomic) -
std::basic_common_reference(tupleとutilityで特殊化されている。プライマリはtype_traits) -
std::erase(dequeとforward_listとlistとstringとvectorでオーバーロードされている) -
std::erase_if(dequeとflat_mapとflat_setとforward_listとlistとmapとsetとstringとunordered_mapとunordered_setとvectorでオーバーロードされている) -
std::iter_swap(algorithmとiteratorにある) -
std::remove(algorithmとcstdioでオーバーロードされている) -
std::sorted_equivalent_t(flat_mapとflat_setにある) -
std::sorted_unique_t(flat_mapとflat_setにある) -
std::this_thread(executionとthreadにある) -
std::tolower(cctypeとlocaleでオーバーロードされている) -
std::toupper(cctypeとlocaleでオーバーロードされている) -
std::unexpected(exceptionとexpectedにある) -
std::uses_allocator(flat_mapとflat_setとfutureで特殊化されている。プライマリはmemory)
ありがとうございます〜。 全部のオーバーロード・特殊化を列挙するのはたいへんだと思うので、ひとまずコメントで「どこでオーバーロード・特殊化されてるのか」をメモ書きする方向でまとめていこうかと思います
各ページで、グローバルの一部修飾をキャンセルする機能が必要な気がしています。
グローバル修飾リストに「* std::move[link /reference/utility/move.md]」を登録したとして、/reference/algorithm/move.mdでは自身へのリンクも貼りたくない、という状況で「* std::move[cancel]」のように指定したいです。
これはmove以外でも、オーバーロード・特殊化されたページで同様の対応が必要になってくると思います。
構文的な指摘も含めて、ご意見あればお願いします。
自身へのリンク阻害以外のユースケースが無いならそこは自動的に推論できないものかと思うわけですが・・・
たしかにそうですね。自身へのリンクはどのページでも必要ないので、その方向でツール改善します。
意図せずリンクが貼られてしまうケースがあるので、キャンセルしたいことはあります。
ただ、現状でも * target[link ] のように空のリンクで上書きすることでグローバル修飾を剥がせます。
キャンセル機能が必要になるケースは、強いて挙げるなら「 vector <string> の <string> に貼られるリンクをキャンセルして string にリンクを貼りたいとき」があるかと思います。
意図せずリンクが貼られている例
- 例1: 自作の
std::type_identity相当のクラスにstd::identityのリンクが貼られてしまっている
https://github.com/cpprefjp/site/blob/4b0e7ea7c835aefe4e7bc318783691ed1d366242/lang/cpp17/type_deduction_for_class_templates.md?plain=1#L216
- 例2: 自作クラスのメンバ関数
viewにstd::ranges::viewのリンクが貼られてしまっている
https://github.com/cpprefjp/site/blob/4b0e7ea7c835aefe4e7bc318783691ed1d366242/lang/cpp20/efficient_sized_delete_for_variable_sized_classes.md?plain=1#L208
なるほど…。一旦、グローバル修飾リストの各修飾がどこに影響するのかを調べるツールをまず作って、それを眺めて対策を考えますかね…。
言語ページだけが問題なら識別子のキャンセル機能で回避でいいかもしれませんが、管理しきれないほどあちこちで問題が起きてそうなら、名前空間をつけないグローバル修飾の影響を、宣言や効果に絞るようにするとかも考えたほうがいいかもしれません。