# Case conversions

**URL:** https://forum.ada-lang.io/t/case-conversions/1843
**Category:** General
**Created:** [February 21, 2025, 11:07pm UTC](https://forum.ada-lang.io/t/case-conversions/1843 "2025-02-21T23:07:59Z")
**Posts on this page:** 14
**Page:** 1

<div class="post-metadata">

### Author: ![simonjwright](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/simonjwright/32/11_2.png) [@simonjwright](https://forum.ada-lang.io/u/simonjwright)
#### Post date: [February 21, 2025, 11:07pm UTC](https://forum.ada-lang.io/t/case-conversions/1843/1 "2025-02-21T23:07:59Z")

</div>

You might have expected GNAT’s`Ada.Wide_Wide_Strings.Maps.Constants.Lower_Case_Map` to support a wide (!) range of characters; however, it only supports a much reduced subset - I think it’s Latin1.

Might be explained by there being (at 2025-02-21) 1858 uppercase and 2258 lowercase Unicode characters, according to [Wikipedia](https://en.wikipedia.org/wiki/Unicode_character_property) (Google’s AI denies that the numbers differ if you ask it why); extending to anything even approaching the full range of possibilities would, of course, be a mammoth & ongoing task.

Or is there some requirement/documentation that I’ve missed?

---

<div class="post-metadata">

### Author: ![mgrojo](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/mgrojo/32/15_2.png) [@mgrojo](https://forum.ada-lang.io/u/mgrojo)
#### Post date: [February 21, 2025, 11:43pm UTC](https://forum.ada-lang.io/t/case-conversions/1843/2 "2025-02-21T23:43:22Z")

</div>

And does `Ada.Wide_Wide_Characters.Handling.To_Lower` cover all the cases?

---

<div class="post-metadata">

### Author: ![jere](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/jere/32/87_2.png) [@jere](https://forum.ada-lang.io/u/jere)
#### Post date: [February 22, 2025, 3:17am UTC](https://forum.ada-lang.io/t/case-conversions/1843/3 "2025-02-22T03:17:17Z")

</div>

> [@mgrojo](#):
>
> And does `Ada.Wide_Wide_Characters.Handling.To_Lower` cover all the cases?

It says in the RM that it does what Wide\_Characters.Handling.To\_Lower does except is uses wide wide characters.

> [@](#):
>
> The package Wide\_Wide\_Characters.Handling has the same contents as Wide\_Characters.Handling except that each occurrence of Wide\_Character is replaced by Wide\_Wide\_Character, and each occurrence of Wide\_String is replaced by Wide\_Wide\_String.

The Wide\_Character version says:

> [@](#):
>
> Returns the Simple Lowercase Mapping as defined by documents referenced in Clause 2 of ISO/IEC 10646:2020 of the Wide\_Character designated by Item. If the Simple Lowercase Mapping does not exist for the Wide\_Character designated by Item, then the value of Item is returned.

Hopefully that helps?

---

<div class="post-metadata">

### Author: ![dmitry-kazakov](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/dmitry-kazakov/32/522_2.png) [@dmitry-kazakov](https://forum.ada-lang.io/u/dmitry-kazakov)
#### Post date: [February 22, 2025, 10:29am UTC](https://forum.ada-lang.io/t/case-conversions/1843/4 "2025-02-22T10:29:22Z")

</div>

In [UnicodeData.txt](https://www.unicode.org/Public/UNIDATA/UnicodeData.txt) the corresponding lines are:

```ada
1858;MONGOLIAN LETTER TODO GAA;Lo;0;L;;;;;N;;;;;

2258;CORRESPONDS TO;Sm;0;ON;;;;;N;;;;;

```

1858 has no lower case counterpart. The categorization field is Lo = other letter. Compare it with

`054A;ARMENIAN CAPITAL LETTER PEH;Lu;0;L;;;;;N;;;;057A;`

Here the categorization is Lu = uppercase letter and the next to last field 057A gives the lower case letter.

I tested 16#054A# Wide/Wide\_Wide To\_Lower and UTF-8 ([Simple Components](https://www.dmitry-kazakov.de/ada/strings_edit.htm#7.6)) all three work fine in Debian (GCC 12).

---

<div class="post-metadata">

### Author: ![godunko](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/godunko/32/22_2.png) [@godunko](https://forum.ada-lang.io/u/godunko)
#### Post date: [February 22, 2025, 12:46pm UTC](https://forum.ada-lang.io/t/case-conversions/1843/5 "2025-02-22T12:46:25Z")

</div>

VSS supports simple and full default Unicode case conversion.

---

<div class="post-metadata">

### Author: ![simonjwright](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/simonjwright/32/11_2.png) [@simonjwright](https://forum.ada-lang.io/u/simonjwright)
#### Post date: [February 22, 2025, 8:28pm UTC](https://forum.ada-lang.io/t/case-conversions/1843/6 "2025-02-22T20:28:38Z")

</div>

Sorry, those numbers (2258/1858) were the count of characters with lower/upper case declared.

For Ḇ, ḇ we have

```ada
1E06;LATIN CAPITAL LETTER B WITH LINE BELOW;Lu;0;L;0042 0331;;;;N;;;;1E07;
1E07;LATIN SMALL LETTER B WITH LINE BELOW;Ll;0;L;0062 0331;;;;N;;;1E06;;1E06

```

which seem to me to have the same kind of mapping as B, b aside from the character decomposition mapping:

```ada
0042;LATIN CAPITAL LETTER B;Lu;0;L;;;;;N;;;;0062;
0062;LATIN SMALL LETTER B;Ll;0;L;;;;;N;;;0042;;0042

```

and I’d say they are simple (single-character) case mappings as defined [here](https://unicode-org.github.io/icu/userguide/transforms/casemappings.html#simple-single-character-case-mapping).

As @jere noted above, the ARM refers to “the Simple Lowercase Mapping as defined by documents referenced in Clause 2 of ISO/IEC 10646:2020” which I have to say isn’t a lot of help. Certainly Google doesn’t tell us **which** documents.

---

<div class="post-metadata">

### Author: ![simonjwright](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/simonjwright/32/11_2.png) [@simonjwright](https://forum.ada-lang.io/u/simonjwright)
#### Post date: [February 22, 2025, 8:41pm UTC](https://forum.ada-lang.io/t/case-conversions/1843/7 "2025-02-22T20:41:55Z")

</div>

Thanks very much: VSS solved the problem for me.

One thing: what’s the difference between Lowercase and Simple\_Lowercase?

Another thing (sorry): is this going to be expensive? it would get called for every identifier in a source text.

```ada
   function To_Lowercase (S : Wide_Wide_String) return Wide_Wide_String is
      use VSS.Strings;
      use VSS.Strings.Conversions;
      use VSS.Transformers.Casing;
      VS : constant Virtual_String := To_Virtual_String (S);
      LVS : constant Virtual_String :=
        Transform (Self => VSS.Transformers.Casing.To_Simple_Lowercase,
                   Item => VS);
   begin
      return Result : Wide_Wide_String (S'Range) do
         Set_Wide_Wide_String (LVS, Into => Result);
      end return;
   end To_Lowercase;

```

---

<div class="post-metadata">

### Author: ![dmitry-kazakov](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/dmitry-kazakov/32/522_2.png) [@dmitry-kazakov](https://forum.ada-lang.io/u/dmitry-kazakov)
#### Post date: [February 22, 2025, 8:58pm UTC](https://forum.ada-lang.io/t/case-conversions/1843/8 "2025-02-22T20:58:30Z")

</div>

Yes, simple mapping is what _sane_ people would understand under case conversion. 😀

Full mapping covers crazy stuff like German ß ↔ SS, which BTW is now officially wrong as the German orthography was changed to avoid the mess and ambiguities like in Schusssicherung.

I am puzzled a bit what did you expect. Ada.Wide\_Wide\_Characters.Handling.To\_Lower looks perfectly OK to me. Full mapping is fool’s errand, IMO. 😀  
[![](https://upload.wikimedia.org/wikipedia/commons/thumb/c/cb/Codex_Bruchsal_1_68r.jpg/330px-Codex_Bruchsal_1_68r.jpg) ](https://upload.wikimedia.org/wikipedia/commons/thumb/c/cb/Codex_Bruchsal_1_68r.jpg/330px-Codex_Bruchsal_1_68r.jpg)  
Lower case U?

---

<div class="post-metadata">

### Author: ![godunko](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/godunko/32/22_2.png) [@godunko](https://forum.ada-lang.io/u/godunko)
#### Post date: [February 23, 2025, 8:00am UTC](https://forum.ada-lang.io/t/case-conversions/1843/9 "2025-02-23T08:00:06Z")

</div>

Yes, it is expensive, it do two encoding conversion and case conversion of variable length encoded text; however, I recommend to investigate performance in context of your particular application. There might be a ways to improve it in your code or in VSS.

Also, for identifiers in general case identifier caseless folding should be used instead on just case conversion. It is even more expensive, but covers many programming languages and representations of source code.

> <https://github.com/AdaCore/VSS/blob/2811167bc0c9a981e7995f38ea21b7a5df72dfaf/source/text/vss-transformers-caseless.ads#L33>

PS. From my experience on ALS and related tools, only few percents of time are spend inside VSS. It might be same or not for your application.

---

<div class="post-metadata">

### Author: ![simonjwright](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/simonjwright/32/11_2.png) [@simonjwright](https://forum.ada-lang.io/u/simonjwright)
#### Post date: [February 23, 2025, 11:42am UTC](https://forum.ada-lang.io/t/case-conversions/1843/10 "2025-02-23T11:42:27Z")

</div>

Both To\_Simple\_Lowercase and To\_Lowercase work for me with text containing ẞ (LATIN CAPITAL LETTER SHARP S).

However, when I tried To\_Identifier\_Caseless I got a Program\_Error in `VSS.Implementation.UTF8_Normalization.Unchecked_Replace` - is this because that hasn’t been updated in v25.0.0?

---

<div class="post-metadata">

### Author: ![dmitry-kazakov](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/dmitry-kazakov/32/522_2.png) [@dmitry-kazakov](https://forum.ada-lang.io/u/dmitry-kazakov)
#### Post date: [February 23, 2025, 12:02pm UTC](https://forum.ada-lang.io/t/case-conversions/1843/11 "2025-02-23T12:02:46Z")

</div>

The reform happened around 2017. In [UnicodeData.txt](https://www.unicode.org/Public/UNIDATA/UnicodeData.txt) small ß has no capital form while the capital ß has small form. 😀

---

<div class="post-metadata">

### Author: ![godunko](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/godunko/32/22_2.png) [@godunko](https://forum.ada-lang.io/u/godunko)
#### Post date: [February 23, 2025, 12:23pm UTC](https://forum.ada-lang.io/t/case-conversions/1843/12 "2025-02-23T12:23:44Z")

</div>

Can you create reproducer?

---

<div class="post-metadata">

### Author: ![simonjwright](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/simonjwright/32/11_2.png) [@simonjwright](https://forum.ada-lang.io/u/simonjwright)
#### Post date: [February 23, 2025, 5:01pm UTC](https://forum.ada-lang.io/t/case-conversions/1843/13 "2025-02-23T17:01:18Z")

</div>

I could do, but the issue in v25.0.0/Unchecked\_Replace arises because it hadn’t been implemented yet, and its body was commented out aside from a `raise Program_Error`.

I tried with VSS commit 2811167, and it turns out that the Identifier\_Caseless conversion expands `"ÀḆĈḒËẞ"` to something with 7 characters, and `"ẞ"` to 2 characters (`"ss"`).

I’ll post an issue if you like? but I suspect this is deliberate.

---

<div class="post-metadata">

### Author: ![godunko](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/godunko/32/22_2.png) [@godunko](https://forum.ada-lang.io/u/godunko)
#### Post date: [February 23, 2025, 5:16pm UTC](https://forum.ada-lang.io/t/case-conversions/1843/14 "2025-02-23T17:16:06Z")

</div>

Thanks, issue is not necessary if it works in development version of VSS. I remember issue like this, and wanted to check that it was fixed and not some new issue.
