site icon indicating copy to clipboard operation
site copied to clipboard

グローバル修飾リストのルール整備

Open faithandbrave opened this issue 6 months ago • 24 comments

  • 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
  • 名前空間の省略、略称をどうすべきかが決まっていない
    • 名前空間の省略は、宣言や効果・戻り値の記述で必要になる
    • サンプルコードはなるべく名前空間つきで書きたい
      • どうしても長くなってしまう場合にサンプルコードで名前空間の略称をルール決めしたい

faithandbrave avatar Jul 08 '25 06:07 faithandbrave

懸念されることとしては、無制限に登録できるようになったときに、無秩序になってしまうことですね。 いままでは頻出するものを登録してきましたが、これまで通りに頻出で絞るのか、あいまいにならないもの (オーバーロード・特殊化されていないもの) は制限なく登録OKにするのか、判断がむずかしいところです

faithandbrave avatar Jul 08 '25 07:07 faithandbrave

    • コードブロック内で使われている要素だけ使用するようツール改善が必要

これは、以下のコードでやっていることではありませんか?

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)]

Raclamusi avatar Jul 08 '25 07:07 Raclamusi

あ、すでに解決してましたか。ではこれは解決済みですね。

faithandbrave avatar Jul 08 '25 08:07 faithandbrave

変数名ルールもこの機会にある程度決めておきたいです。

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関係でよくでてきます。

valarrayvectorと衝突しないようにvaにしてあります。

faithandbrave avatar Jul 08 '25 08:07 faithandbrave

いまは単純な置換をしているグローバル修飾リストですが、たとえば変数定義や名前空間定義なども考えられそうな気はします。変数名を決め打ちすることに危険を感じられる場合には有効な手段になりそうな気はします。

# 指定された定義がコードブロック内に見つかったら、インデントされたコード修飾を適用する
* 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のテンプレート引数をどうするとかの問題はありますが、正規表現でテンプレート引数部分を単に無視したりはできそうな気はします。

faithandbrave avatar Jul 08 '25 12:07 faithandbrave

なんでもかんでも無制限に登録したくなったら、そのときそれはグローバル修飾リストの役割ではなく、コード解析 + 検索エンジン用の辞書データを使ったツールで自動リンクすべき問題になる気がします。 なので現状のツールの範囲では頻出を登録という方針のままにして、無制限に登録したくなったらツール開発しましょう、というルールでよい気がします。

faithandbrave avatar Jul 08 '25 16:07 faithandbrave

"see below[italic]" はたくさんのページで定義されているみたいなので GLOBAL_QUALIFTY_LIST.txt に登録しても良いのではと思いました。

$ git grep 'see[ -]below\[italic]' | wc -l
133

akinomyoga avatar Jul 13 '25 05:07 akinomyoga

それは頻出なので登録してよいかと思います

faithandbrave avatar Jul 14 '25 07:07 faithandbrave

# 7. オーバーロードされている名前は、優先度の高いプライマリ宣言をグローバル修飾リストに登録する
#     7.1 ライブラリごとにオーバーロード・特殊化されているものはグローバル修飾リストに登録せず、個別ページで指定する
#         (std::begin/std::end、std::common_typeなど)

執筆者的には 7.1 の判断が難しく、具体的な登録禁止が列挙されていてもよい気がします。現状だと下記3つだけ?

  • std::begin
  • std::end
  • std::common_type

すぐ思いつく範囲だと std:hash も例の一つでしょうか。

yohhoy avatar Jul 17 '25 07:07 yohhoy

ほかにもあります!

  • std::floor (chronoでオーバーロードされている。プライマリはcmath)
  • std::ceil (chronoでオーバーロードされている。プライマリはcmath)
  • std::round (chronoでオーバーロードされている。プライマリはcmath)
  • std::formatter (いろんなところで特殊化されている。プライマリはformat)
  • std::enable_nonlocking_formatter_optimization (chronoで特殊化されている。プライマリはformat)

ぜんぶ列挙できるか怪しいので、思い出したらまた書きます。

faithandbrave avatar Jul 17 '25 07:07 faithandbrave

  • 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>

faithandbrave avatar Jul 17 '25 08:07 faithandbrave

  • 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)

faithandbrave avatar Jul 17 '25 08:07 faithandbrave

  • operator<< (あちこちでオーバーロードされている。プライマリはostream)
  • operator>> (あちこちでオーバーロードされている。プライマリはistream)
  • std::move (algorithmでオーバーロードされている。プライマリはutility)

faithandbrave avatar Jul 17 '25 08:07 faithandbrave

一通り調べました。抜けはあるかもしれません

faithandbrave avatar Jul 17 '25 08:07 faithandbrave

たくさんあるので、OVERLOAD_SPECIALIZATION_LIST.txtとかを用意して列挙管理するのがいい気がします。 (拡張子以外が全部大文字のファイルは変換対象外)

faithandbrave avatar Jul 17 '25 08:07 faithandbrave

たくさんあるので、OVERLOAD_SPECIALIZATION_LIST.txtとかを用意して列挙管理するのがいい気がします。

列挙ありがとうございます。想像以上に大量でした... 機械的な対処方針に同意です。

yohhoy avatar Jul 17 '25 10:07 yohhoy

それでは、スクリプトフレンドリーな作りにして、プライマリなオーバーロードと特殊化を列挙するようにしていきます

faithandbrave avatar Jul 17 '25 10:07 faithandbrave

以下もありました。

  • 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)

Raclamusi avatar Jul 18 '25 03:07 Raclamusi

ありがとうございます〜。 全部のオーバーロード・特殊化を列挙するのはたいへんだと思うので、ひとまずコメントで「どこでオーバーロード・特殊化されてるのか」をメモ書きする方向でまとめていこうかと思います

faithandbrave avatar Jul 18 '25 08:07 faithandbrave

各ページで、グローバルの一部修飾をキャンセルする機能が必要な気がしています。

グローバル修飾リストに「* std::move[link /reference/utility/move.md]」を登録したとして、/reference/algorithm/move.mdでは自身へのリンクも貼りたくない、という状況で「* std::move[cancel]」のように指定したいです。 これはmove以外でも、オーバーロード・特殊化されたページで同様の対応が必要になってくると思います。

構文的な指摘も含めて、ご意見あればお願いします。

faithandbrave avatar Jul 23 '25 05:07 faithandbrave

自身へのリンク阻害以外のユースケースが無いならそこは自動的に推論できないものかと思うわけですが・・・

yumetodo avatar Jul 23 '25 06:07 yumetodo

たしかにそうですね。自身へのリンクはどのページでも必要ないので、その方向でツール改善します。

faithandbrave avatar Jul 23 '25 06:07 faithandbrave

意図せずリンクが貼られてしまうケースがあるので、キャンセルしたいことはあります。

ただ、現状でも * 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

Image
  • 例2: 自作クラスのメンバ関数 viewstd::ranges::view のリンクが貼られてしまっている

https://github.com/cpprefjp/site/blob/4b0e7ea7c835aefe4e7bc318783691ed1d366242/lang/cpp20/efficient_sized_delete_for_variable_sized_classes.md?plain=1#L208

Image

Raclamusi avatar Jul 23 '25 12:07 Raclamusi

なるほど…。一旦、グローバル修飾リストの各修飾がどこに影響するのかを調べるツールをまず作って、それを眺めて対策を考えますかね…。

言語ページだけが問題なら識別子のキャンセル機能で回避でいいかもしれませんが、管理しきれないほどあちこちで問題が起きてそうなら、名前空間をつけないグローバル修飾の影響を、宣言や効果に絞るようにするとかも考えたほうがいいかもしれません。

faithandbrave avatar Jul 23 '25 16:07 faithandbrave