Ada 202x (28日目) - Is_Basic/To_Basic ===================================== .. post:: Dec 28, 2019 :tags: ada, ada_2022 文字コード話はネガティブにならざるを得ないのでさっさと終わらせましょうね。 経緯 ---- ``Ada.Characters.Handling`` にある ``Character`` を扱う関数のうち(``ISO_646`` こと7ビットASCII関係を除けば) ``Is_Basic`` と ``To_Basic`` の2つのみ ``Wide_Character``/``Wide_Wide_Character`` 版が存在していませんでした。 Ada 202xでの改善 ---------------- ``Wide_Character`` 版にあたる ``Ada.Wide_Characters.Is_Basic`` と ``To_Basic`` が追加されました。 ``Ada.Wide_Wide_Characters.Handling`` は ``Ada.Wide_Characters.Handling`` 同様と定義されていますので自動的に ``Wide_Wide_Character`` 版も追加されることになります。 Ada.Wide_Characters.Is_Basic ++++++++++++++++++++++++++++ | http://www.ada-auth.org/standards/2xrm/html/RM-A-3-5.html#p8.1 ``Ada.Wide_Characters.Is_Basic`` は引数の文字が正規分解(canonical decomposition)できるなら ``False`` 、それ以上分解できなければ ``True`` を返します。 Ada.Wide_Characters.To_Basic ++++++++++++++++++++++++++++ | http://www.ada-auth.org/standards/2xrm/html/RM-A-3-5.html#p20.1 ``Ada.Wide_Characters.To_Basic`` は引数の文字が正規分解できるなら分解後の基底文字(base character)を返します。 分解できなければ引数をそのまま返します。 ライブラリの実装が使用しているUnicodeのバージョンは ``Ada.Wide_Characters.Character_Set_Version`` で調べることができます。 関連AI ------ - `AI12-0260-1`_ **Functions Is_Basic and To_Basic in Wide_Characters.Handling** 所感 ---- めでたしめでたし、で済ませたいのです。 はい、例によって書いておきたいことが。 ただの個人の日記ですので例によって読むだけ損です。 Ada.Characters.Is_Basic ----------------------- ``Ada.Characters`` っていつから存在していると思います? Unicodeの最初のバージョンISO/IEC 10646-1:1993が1993年です。 ``Ada.Characters`` が追加されたAda 95は勿論1995年。 時期としては近いので微妙なところです。 勿論どちらの規格も制定の何年も前から練られていたわけです。 結論から書いてしまいますとAda 95ではISO 10646のBMPに対応する16ビット文字型の ``Wide_Character``/``Wide_String`` 、ライブラリとしては ``Ada.Strings`` 以下の ``Wide_*`` 版や ``Ada.Wide_Text_IO`` 等が追加されましたが、これらは言わばコンテナで中身については何もありませんでした。 ``Wide_Character`` の中身を具体的に扱う ``Ada.Wide_Characters`` の登場はAda 2005からです。 そのような時期的な理由で ``Ada.Characters.Is_Basic`` はUnicodeを意識した定義にはなっていません。 | http://www.ada-auth.org/standards/2xrm/html/RM-A-3-2.html#p27 True if Item is a basic letter. A basic letter is a character that is in one of the ranges 'A'..'Z' and 'a'..'z', or that is one of the following: 'Æ', 'æ', 'Ð', 'ð', 'Þ', 'þ', or 'ß'. というわけで動作を比較しますとこうなるわけです。 ============== =========================== ================================ 引数 ``Ada.Characters.Is_Basic`` ``Ada.Wide_Characters.Is_Basic`` ============== =========================== ================================ 上記の基底文字 True True その他基底文字 False True 合成済み文字 False False 結合文字 (Latin-1の範囲にはなし) True それ以外 False True ============== =========================== ================================ ``Ada.Characters.Is_Basic`` は丁度 ``Ada.Wide_Characters.Is_Basic`` と ``Is_Letter`` との論理積を取ったような動作です。 Latin-1の範囲ではアルファベットにしかダイアクリティカルマークは付きませんからこの動作でも良かったですがUnicodeではどんな文字でも合成することができます。 そのため ``Ada.Characters.Is_Basic`` と互換をとっても使い物になりません。 しかし別物に同じ名前が付いていますと ``Character`` と ``Wide_Character`` 両方に対応する ``generic`` なコードを書くのに支障が出ます。 .. code-block:: ada generic type Character_Type is (<>); with function Is_Basic (Item : Character_Type) return Boolean is <>; package Generic_Something is みたいなやつです。 当時、`別物には別の名前を付けてくれと訴えましたが `_、`AIの提案者のJ-P. Rosen先生本人に `_ If you are adapting a program to use the full BMP instead of Latin1, expect many more difficult issues and/or incompatibilities than this one... と言われてしまいました……。 Latin-1用のコードをUnicode用に書き換えるならこんな小さな非互換より大変なことは一杯ある、ということですね……。 幸い ``To_Basic`` の方には差はありません。 ``generic`` なコードを書くときは ``To_Basic`` のみを用いて分解できるかの判定は ``To_Basic (Item) /= Item`` とすればいいでしょう。 .. _`AI12-0260-1`: http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai12s/ai12-0260-1.txt