C++20 以降向けの Unicode ライブラリを作りたい
locale
みたいなクラスが生えてくるのはしょうがないとして、char
が前提みたいなお行儀のよろしくないものにはしない
取り敢えず先駆者としての std::locale
boost::locale
boost::text
をざっくり見ていく
std::locale
について
std::locale
から得られるファセットの殆どは CharT
とテンプレート引数を取っているが1コードポイントに対して1コードユニットでないとまともに動かない設計
それでいて std::cout
などの根幹に関わっているので改修は最早不可能
boost::locale
について
boost::locale::generator
なる物を介して std::locale
をオレオレファセットを追加した状態で作ってくる
Experimental support for C++11 char16_t and char32_t strings and streams.
とか言ってるし char8_t
への対応なんてないのでモダンC++には適さなそう
FYI: https://qiita.com/yumetodo/items/54e1a8230dbf513ea85b
"Boost.locale事件" のセクションが特におすすめです。
これもおすすめ(完全に自分がUnicode周りの実装を過去に書いたときに参照していた記事を貼るオタクと化している)
Unicode正規化について
http://nomenclator.la.coocan.jp/unicode/normalization.htm
モダンなインターフェースを備えた新規ライブラリが作られるなら個人的に優先度高めで欲しい機能
- 符号化方式同士の変換 (UTF-8 / UTF-16 / UTF-32)
- char / wchar_t から UTF-8 / UTF-16 / UTF-32 への変換
- normalization(NFC, NFD, NFKC, NFKD)
- grapheme単位で走査できるiteratorとrange
- Unicodeにおける文字カテゴリを取得する機能
- Unicodeにおけるその文字の名前を取得する機能(デバッグにあると便利)
Unicodeのnormalizationはあまり知られていない概念だと思いますが、これめちゃくちゃ使います。例えばブログ記事や小説原稿など人力で書かれているテキストデータの表記ゆれ統一や、データレベルでの整形に必要な機能です。また、身近な例では、Macで作ったファイルがmacOSのバージョンによっては開けなくなったり、Windowsに持って行ったり圧縮ファイルに固めるとファイル名(パス)がめちゃくちゃになる問題が有名。 https://applech2.com/archives/20230402-nfd-and-nfc-issues-in-macos-13-3-ventura.html
文字コードライブラリとしては、任意の文字コードと相互変換できる機能が基本に感じますが、デスクトップアプリではその手の処理をやらないことが増えています。少なくとも私は過去3年くらい書いていません。(アセット類は事前にUTF-8に変換しておくのが世の中のセオリーなので、アプリを起動してから文字コードを動的に変換するニーズが消滅した)(つまり、Unicodeの世界の処理を充実させた方がよく、それ以外の文字コードを使うのは稀)
ロケール周りは正直使わないです(というか、ロケールに一切依存せず文字コードやUnicode符号化方式をいじれるコードパスを用意してほしい)
江添氏が Boost.Locale について
また、エンコードは、 "windows-936"などのように、文字列で指定しなければならないらしい。何故文字列なのだろうか。enumではダメなのか。
P1885 Naming Text Encodings to Demystify Them が採用されることを視野に入れるとよさそうですかね(?)
P1629 Transcoding the 🌐 - Standard Text Encoding
という提案書を見つけた
リファレンス実装として ztd.text というのが生えているらしい
こっちも見る
素朴に知りたいんですけど、総評としてBoost.Textは使い物になるんですかね?
テストの体制は整っている ように見えますし MSVC の CI で落ちているらしいのが何とかなれば boost::locale
よりかはマシなんではないでしょうか
(レンジアダプタの実装まわりが渋いのは C++17 イテレータでゴネゴネしていた人々からすればまだ妥協できるポイントだと思っています)
Boost.Text をベースに、もうちょっとマシにした実装を目標とする
それはそれとして実際に実装するモチベが低迷しているのでそれなりの形になってきたらスクラップを立て直す
TODO: 実装を生やす