Topic: Unicode support by extending std::locale. Can we make
Author: Dimitrij Mijoski <dim.mj.p@gmail.com>
Date: Wed, 28 Mar 2018 05:45:40 -0700 (PDT)
Raw View
------=_Part_22598_1495971763.1522241140468
Content-Type: multipart/alternative;
boundary="----=_Part_22599_2132005776.1522241140472"
------=_Part_22599_2132005776.1522241140472
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
Unicode support by extending std::locale. Can we make it by 2020?=20
The need for standard Unicode support has been requested many times and I=
=20
wont get into it. It is very obvious that we need it.
Goals:
- No new string class
- No new character type
- Reuse std::locale and facet interfaces
- Follow best practices and see how Linux and POSIX handle locales.
- Follow library ICU.
- See boost::locale which extends std::locale.
- Use bottom up approach while designing. First define low level stuff=
=20
(facets), then their use (e.g. in iostreams).
1. Terms and definitions=20
=20
- Natural Language - a spoken language with its own script/alphabet. A=
=20
script is contained of all characters needed for particular language.
- Computer character set - a strictly defined set (in a mathematical=20
sense) of characters. Usually one character set can serve multiple=20
languages.
- Character map - a mapping between character set and integers.
- Encoding - scheme that specifies how a character from a set is encoded=
=20
into bits.=20
- A popular scheme is first to map the characters to integers and=20
then binary-encode each integer into fixed length of bits and bytes.
- Another popular scheme is to encode a character into variable=20
length sequence of (consecutive) bytes.
- Less popular scheme is to use shift states. In such encodings there=
=20
are bytes that alter a shift state, and bytes that form an actual=20
character. The final characters depends on its "own" bytes plus the s=
ome=20
earlier bytes that altered the shift state.
- Other schemes may exist.
- Unicode - a standard that combines ~ 1 million characters into single=
=20
set, then maps each character into unique integer and defines couple of=
=20
encodings. Namely: UTF-32, UTF-16, and UTF-8. Then defines byte=20
serialization of UTF-16 and UTF-32 as UTF-16-BE, UTF-16-LE, UTF-32-BE an=
d=20
UTF-32-LE.
2. Current state
In C and C++, a locale (in most implementations) is a pair of natural=20
language identifier and a narrow encoding identifier.
In C and C++, the standard groups the encodings into three groups:
1. Narrow single-byte encodings.
2. Narrow multi-byte encodings.
3. Wide encodings - fixed length encodings where the character is mapped=
=20
to a single wchar_t unit that can be wider than 1 byte (it is not=20
necessary) and always is the same length.
Examples are:
1. ASCII, IS0-8859-1 (latin1), IS0-8859-2 (latin2), IS0-8859-5=20
(cyrillic).
2. Shift-JIS, UTF-8, UTF-16-BE, UTF-16-LE
3. UCS-2, UTF-32
In C and C++, the third group is defined as derived from the first two. The=
=20
standard says that for each multi-byte (and single-byte) encoding there=20
should exist a wide fixed-length encoding that encodes each character of=20
the same character set into a single distinct wide character. In another=20
words, the standard says that for each supported character set, there=20
should be one narrow single-byte or multi-byte encoding and one wide=20
encoding.
One last requirement from the standard is that all character sets (narrow=
=20
and wide encoded) should be superset of the basic execution character set=
=20
(narrow and wide encoded).
The standard allows that the wide encoding of one character set to be=20
different with the wide encoding of another character set. In practice this=
=20
is not true.
- On Linux, Android and various Unixes the wide encoding is always=20
UTF-32, whatever the narrow encoding is selected with the locale.
- On Windows, the wide encoding is always UCS-2 when calling standard=20
library functions. When calling Windows API wide strings are interpreted=
as=20
UTF-16.
From what we see, the C++ standard allows, but does not mandates the=20
implementation to have a decent Unicode support. Such is Linux with glibc=
=20
as C standard library and libstdc++ with C++ standard libraries. Just=20
create a locale with the UTF-8 as narrow encoding,=20
std::locale("en_US.UTF-8") and you got an acceptable Unicode support. But=
=20
even on Linux there are drawback. Locales have to be first enabled and=20
configured with the command line utility locale-gen.
Other platforms are less fortunate. On Windows you can not create a locale=
=20
with UTF-8 as narrow, and thus you don't get UTF-32 as wide, you can only=
=20
get UCS-2.
3. Future proposal
ctype<char32_t>=20
This facet should behave almost as ctype<wchar_t> on systems where wchar_t=
=20
is UTF-32 encoded. The wide facet on Linux has one little gotcha. When used=
=20
from the classic/"C" locale, it does not work for characters above ASCII.=
=20
We can test that with the following program.
#include <locale>
#include <cassert>
using namespace std;
int main()
{
// Wide facet of "C" locale does not work for anything above ASCII.
// This is little gotcha.
auto& c =3D std::locale::classic();
assert(isupper(L'=C3=9F', c) =3D=3D false);
assert(islower(L'=C3=9F', c) =3D=3D false);
assert(isupper(L'=E1=BA=9E', c) =3D=3D false);
assert(islower(L'=E1=BA=9E', c) =3D=3D false);
assert(toupper(L'=C3=9F', c) =3D=3D L'=C3=9F');
assert(tolower(L'=C3=9F', c) =3D=3D L'=C3=9F');
assert(toupper(L'=E1=BA=9E', c) =3D=3D L'=E1=BA=9E');
assert(tolower(L'=E1=BA=9E', c) =3D=3D L'=E1=BA=9E');
assert(isupper(L'=D0=B1', c) =3D=3D false);
assert(islower(L'=D0=B1', c) =3D=3D false);
assert(isupper(L'=D0=91', c) =3D=3D false);
assert(islower(L'=D0=91', c) =3D=3D false);
assert(toupper(L'=D0=B1', c) =3D=3D L'=D0=B1');
assert(tolower(L'=D0=B1', c) =3D=3D L'=D0=B1');
assert(toupper(L'=D0=91', c) =3D=3D L'=D0=91');
assert(tolower(L'=D0=91', c) =3D=3D L'=D0=91');
// Generic unicode locale, classifies and converts Latin and Cyrill=
ic
// letters correctly.
auto cu8 =3D locale("C.UTF-8");
assert(isupper(L'=C3=9F', cu8) =3D=3D false);
assert(islower(L'=C3=9F', cu8) =3D=3D true);
assert(isupper(L'=E1=BA=9E', cu8) =3D=3D true);
assert(islower(L'=E1=BA=9E', cu8) =3D=3D false);
assert(toupper(L'=C3=9F', cu8) =3D=3D L'=C3=9F'); //why not =E1=BA=
=9E?
assert(tolower(L'=C3=9F', cu8) =3D=3D L'=C3=9F');
assert(toupper(L'=E1=BA=9E', cu8) =3D=3D L'=E1=BA=9E');
assert(tolower(L'=E1=BA=9E', cu8) =3D=3D L'=C3=9F');
assert(isupper(L'=D0=B1', cu8) =3D=3D false);
assert(islower(L'=D0=B1', cu8) =3D=3D true);
assert(isupper(L'=D0=91', cu8) =3D=3D true);
assert(islower(L'=D0=91', cu8) =3D=3D false);
assert(toupper(L'=D0=B1', cu8) =3D=3D L'=D0=91');
assert(tolower(L'=D0=B1', cu8) =3D=3D L'=D0=B1');
assert(toupper(L'=D0=91', cu8) =3D=3D L'=D0=91');
assert(tolower(L'=D0=91', cu8) =3D=3D L'=D0=B1');
// Latin-1 locale. The wide facet classifies and converts case
// correctly even for Unicode characters that are not part of latin=
-1.
auto l1 =3D locale("en_US.ISO-8859-1");
assert(isupper(L'=C3=9F', l1) =3D=3D false);
assert(islower(L'=C3=9F', l1) =3D=3D true);
assert(isupper(L'=E1=BA=9E', l1) =3D=3D true);
assert(islower(L'=E1=BA=9E', l1) =3D=3D false);
assert(toupper(L'=C3=9F', l1) =3D=3D L'=C3=9F'); //why not =E1=BA=
=9E?
assert(tolower(L'=C3=9F', l1) =3D=3D L'=C3=9F');
assert(toupper(L'=E1=BA=9E', l1) =3D=3D L'=E1=BA=9E');
assert(tolower(L'=E1=BA=9E', l1) =3D=3D L'=C3=9F');
assert(isupper(L'=D0=B1', l1) =3D=3D false);
assert(islower(L'=D0=B1', l1) =3D=3D true);
assert(isupper(L'=D0=91', l1) =3D=3D true);
assert(islower(L'=D0=91', l1) =3D=3D false);
assert(toupper(L'=D0=B1', l1) =3D=3D L'=D0=91');
assert(tolower(L'=D0=B1', l1) =3D=3D L'=D0=B1');
assert(toupper(L'=D0=91', l1) =3D=3D L'=D0=91');
assert(tolower(L'=D0=91', l1) =3D=3D L'=D0=B1');
// English UTF-8 locale, works as expected
// same as the two above.
auto u8 =3D locale("en_US.UTF-8");
assert(isupper(L'=C3=9F', u8) =3D=3D false);
assert(islower(L'=C3=9F', u8) =3D=3D true);
assert(isupper(L'=E1=BA=9E', u8) =3D=3D true);
assert(islower(L'=E1=BA=9E', u8) =3D=3D false);
assert(toupper(L'=C3=9F', u8) =3D=3D L'=C3=9F'); // why not =E1=BA=
=9E?
assert(tolower(L'=C3=9F', u8) =3D=3D L'=C3=9F');
assert(toupper(L'=E1=BA=9E', u8) =3D=3D L'=E1=BA=9E');
assert(tolower(L'=E1=BA=9E', u8) =3D=3D L'=C3=9F');
assert(isupper(L'=D0=B1', u8) =3D=3D false);
assert(islower(L'=D0=B1', u8) =3D=3D true);
assert(isupper(L'=D0=91', u8) =3D=3D true);
assert(islower(L'=D0=91', u8) =3D=3D false);
assert(toupper(L'=D0=B1', u8) =3D=3D L'=D0=91');
assert(tolower(L'=D0=B1', u8) =3D=3D L'=D0=B1');
assert(toupper(L'=D0=91', u8) =3D=3D L'=D0=91');
assert(tolower(L'=D0=91', u8) =3D=3D L'=D0=B1');
return 0;
}
We should completely avoid this gotcha and make ctype<char32_t> work out of=
=20
the box for the whole Unicode range. The locale name should modify only the=
=20
widen() and narrow() functions.
We can additional allow the natural language part of the locale to slightly=
=20
modify the case conversion. E.g. the Turkish dotted and dotless I=20
<https://en.wikipedia.org/wiki/Dotted_and_dotless_I>.
Defining this facet will automatically enable decent Unicode regexes.
ctype<char16_t>=20
This should behave exactly same as the above, except that it will accept=20
only the first 65536 characters of Unicode, i.e. characters from the basic=
=20
multilingual plane (BMP).
codecvt=20
Codecvt specializations of char16_t and char32_t already exists. They=20
convert strictly from/to UTF-8. I am not that happy with this because it is=
=20
not aligned with the codecvt of wchar_t which can convert from/to custom=20
encoding, when the implementations allows.
Maybe we should allow codecvt_byname to create codecvt that can convert=20
between custom encoding and UTF-32/UTF-16.
Additionally, I am not even happy with the general design of codecvt,=20
mostly because it is created with the same names as locales. Codecvt depend=
=20
only on the encoding part of the locale identifier pair, not on the natural=
=20
language identifier. Maybe we should create a new codecvt2 facet.
codecvt2<InternT, ExternT> facet=20
codecvt2 should be constructed only with encoding name. It will convert=20
from/to that encoding. This is the way iconv works. you first call=20
iconv_open with two encoding names. This is the way ICU ucnv.h=20
<http://icu-project.org/apiref/icu4c/ucnv_8h.html> works. You open=20
UConverter with ucnv_open() by giving the name of the encoding.
- codecvt2<char, char> may convert between various narrow encodings,
- codecvt2<char32_t, char> will convert between custom narrow encoding=
=20
and UTF-32.
- codecvt2<char32_t, char16_t> may convert between UTF-32 and UTF-16.
Besides the standard in() and out(), additional functions should be=20
provided. For example simple function that converts one string into another=
=20
without keeping state. The input string is known that it starts and ends,=
=20
it isn't part of larger text. Such functionality was added in C++11 and=20
deprecated in C++17, wstring_convert.
Additional function that converts only one output character may be provided=
..
Conclusion so far=20
Specifying the above facets are the absolute minimum to get a decent=20
Unicode support. More advanced Unicode features like:
1. Querying character properties like general category
2. Language sensitive string case transformations (not character)
3. Normalization
Will need facets on their own.
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/45303792-68f2-4545-8ce4-4a3e1ec35b1b%40isocpp.or=
g.
------=_Part_22599_2132005776.1522241140472
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">
<h1>Unicode support by extending std::locale. Can we make it by 2020?</h1>
<p>The need for standard Unicode support has been requested many times and =
I wont get into it. It is very obvious that we need it.</p>
<p>Goals:</p>
<ul><li>No new string class</li><li>No new character type</li><li>Reuse std=
::locale and facet interfaces</li><li>Follow best practices and see how Lin=
ux and POSIX handle locales.</li><li>Follow library ICU.</li><li>See boost:=
:locale which extends std::locale.</li><li>Use bottom up approach while des=
igning. First define low level stuff (facets), then their use (e.g. in iost=
reams).</li></ul>
<h2>1. Terms and definitions</h2>
<ul><li>Natural Language - a spoken language with its own script/alphabet. =
A
script is contained of all characters needed for particular language.</li>=
<li>Computer character set - a strictly defined set (in a mathematical=20
sense) of characters. Usually one character set can serve multiple=20
languages.</li><li>Character map - a mapping between character set and inte=
gers.</li><li>Encoding - scheme that specifies how a character from a set i=
s encoded into bits.
<ul><li>A popular scheme is first to map the characters to integers and the=
n
binary-encode each integer into fixed length of bits and bytes.</li><li>An=
other popular scheme is to encode a character into variable length sequence=
of (consecutive) bytes.</li><li>Less popular scheme is to use shift states=
.. In such encodings there=20
are bytes that alter a shift state, and bytes that form an actual=20
character. The final characters depends on its "own" bytes plus t=
he some
earlier bytes that altered the shift state.</li><li>Other schemes may exis=
t.</li></ul></li><li>Unicode - a standard that combines ~ 1 million charact=
ers into=20
single set, then maps each character into unique integer and defines=20
couple of encodings. Namely: UTF-32, UTF-16, and UTF-8. Then defines=20
byte serialization of UTF-16 and UTF-32 as UTF-16-BE, UTF-16-LE,=20
UTF-32-BE and UTF-32-LE.</li></ul>
<h2>2. Current state</h2><p><br></p>
<p>In C and C++, a locale (in most implementations) is a pair of natural la=
nguage identifier and a narrow encoding identifier.</p>
<p>In C and C++, the standard groups the encodings into three groups:</p>
<ol><li>Narrow single-byte encodings.</li><li>Narrow multi-byte encodings.<=
/li><li>Wide encodings - fixed length encodings where the character is=20
mapped to a single wchar_t unit that can be wider than 1 byte (it is not
necessary) and always is the same length.</li></ol>
<p>Examples are:</p>
<ol><li>ASCII, IS0-8859-1 (latin1), IS0-8859-2 (latin2), IS0-8859-5 (cyrill=
ic).</li><li>Shift-JIS, UTF-8, UTF-16-BE, UTF-16-LE</li><li>UCS-2, UTF-32</=
li></ol>
<p>In C and C++, the third group is defined as derived from the first=20
two. The standard says that for each multi-byte (and single-byte)=20
encoding there should exist a wide fixed-length encoding that encodes=20
each character of the same character set into a single distinct wide=20
character. In another words, the standard says that for each supported=20
character set, there should be one narrow single-byte or multi-byte=20
encoding and one wide encoding.</p>
<p>One last requirement from the standard is that all character sets=20
(narrow and wide encoded) should be superset of the basic execution=20
character set (narrow and wide encoded).</p>
<p>The standard allows that the wide encoding of one character set to be
different with the wide encoding of another character set. In practice=20
this is not true.</p>
<ul><li>On Linux, Android and various Unixes the wide encoding is always=20
UTF-32, whatever the narrow encoding is selected with the locale.</li><li>O=
n Windows, the wide encoding is always UCS-2 when calling standard=20
library functions. When calling Windows API wide strings are interpreted
as UTF-16.</li></ul>
<p>From what we see, the C++ standard allows, but does not mandates the=20
implementation to have a decent Unicode support. Such is Linux with=20
glibc as C standard library and libstdc++ with C++ standard libraries.=20
Just create a locale with the UTF-8 as narrow encoding,=20
std::locale("en_US.UTF-8") and you got an acceptable Unicode supp=
ort.=20
But even on Linux there are drawback. Locales have to be first enabled=20
and configured with the command line utility locale-gen.</p>
<p>Other platforms are less fortunate. On Windows you can not create a=20
locale with UTF-8 as narrow, and thus you don't get UTF-32 as wide, you=
=20
can only get UCS-2.</p><p><br></p>
<h2>3. Future proposal</h2><p><br></p>
<h3>ctype<char32_t></h3>
<p>This facet should behave almost as <code>ctype<wchar_t></code> on =
systems where <code>wchar_t</code>
is UTF-32 encoded. The wide facet on Linux has one little gotcha. When=20
used from the classic/"C" locale, it does not work for characters=
above=20
ASCII. We can test that with the following program.</p>
<div class=3D"sourceCode"><pre class=3D"sourceCode c++"><code class=3D"sour=
ceCode cpp"><span class=3D"pp"><br><div style=3D"background-color: rgb(250,=
250, 250); border-color: rgb(187, 187, 187); border-style: solid; border-w=
idth: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><code class=3D=
"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #800;" cl=
ass=3D"styled-by-prettify">#include</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #080;" class=3D"styl=
ed-by-prettify"><locale></span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br></span><span style=3D"color: #800;" class=3D"styled=
-by-prettify">#include</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #080;" class=3D"styled-by-prettif=
y"><cassert></span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br><br></span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">using</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">namespac=
e</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> std</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> main</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">()</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:=
#800;" class=3D"styled-by-prettify">// Wide facet of "C" locale =
does not work for anything above ASCII.</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span s=
tyle=3D"color: #800;" class=3D"styled-by-prettify">// This is little gotcha=
..</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">auto</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">&</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> c </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> std</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">locale</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">classic</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">();</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">assert</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">isupper</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">L</span><span style=3D"color: #080;" class=3D"sty=
led-by-prettify">'=C3=9F'</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> c</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">false</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">assert</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">islower</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">L</span><span style=3D"color: #080;" =
class=3D"styled-by-prettify">'=C3=9F'</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> c</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
=3D=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">false</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">ass=
ert</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">isupper</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">L</span><span style=3D"color=
: #080;" class=3D"styled-by-prettify">'=E1=BA=9E'</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> c</span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">=3D=3D</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">f=
alse</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">assert</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">islow=
er</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">L</span><span sty=
le=3D"color: #080;" class=3D"styled-by-prettify">'=E1=BA=9E'</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> c</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D=3D</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">false</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">assert</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">toupper</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">L=
</span><span style=3D"color: #080;" class=3D"styled-by-prettify">'=C3=
=9F'</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> c</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">=3D=3D</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> L</span><span style=3D"color: #080;" cla=
ss=3D"styled-by-prettify">'=C3=9F'</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">assert</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">tolower</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">L</span><span style=3D"color: #080;" class=3D"style=
d-by-prettify">'=C3=9F'</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> c</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> L</span><span sty=
le=3D"color: #080;" class=3D"styled-by-prettify">'=C3=9F'</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">assert=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify">toupper</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">L</span><span style=3D"color: #=
080;" class=3D"styled-by-prettify">'=E1=BA=9E'</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> c</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">=3D=3D</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> L</span><span style=3D"color: #080;" class=3D"styled-by-prettify">=
9;=E1=BA=9E'</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">assert</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">tolower</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">L</sp=
an><span style=3D"color: #080;" class=3D"styled-by-prettify">'=E1=BA=9E=
'</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> c</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">=3D=3D</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> L</span><span style=3D"color: #080;" class=
=3D"styled-by-prettify">'=E1=BA=9E'</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">assert</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">isupper</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">L</span><span style=3D"color: #080;" class=3D"sty=
led-by-prettify">'=D0=B1'</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> c</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">false</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">assert</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">islower</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">L</span><span style=3D"color: #080;" =
class=3D"styled-by-prettify">'=D0=B1'</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> c</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
=3D=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">false</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">ass=
ert</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">isupper</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">L</span><span style=3D"color=
: #080;" class=3D"styled-by-prettify">'=D0=91'</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> c</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">=3D=3D</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">fals=
e</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0=
=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">assert</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">islower<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">L</span><span style=
=3D"color: #080;" class=3D"styled-by-prettify">'=D0=91'</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> c</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">=3D=3D</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">false</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">assert</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">toupper</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">L</span=
><span style=3D"color: #080;" class=3D"styled-by-prettify">'=D0=B1'=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> c</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">=3D=3D</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> L</span><span style=3D"color: #080;" class=3D"st=
yled-by-prettify">'=D0=B1'</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">assert</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">tolower</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">L</span><span style=3D"color: #080;" class=3D"styled-by-pret=
tify">'=D0=B1'</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> c</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> L</span><span style=3D"col=
or: #080;" class=3D"styled-by-prettify">'=D0=B1'</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">assert</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">toupper</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">L</span><span style=3D"color: #080;" =
class=3D"styled-by-prettify">'=D0=91'</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> c</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
=3D=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> L</=
span><span style=3D"color: #080;" class=3D"styled-by-prettify">'=D0=91&=
#39;</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">assert</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">tolow=
er</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">L</span><span sty=
le=3D"color: #080;" class=3D"styled-by-prettify">'=D0=91'</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> c</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">=3D=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> L</span><span style=3D"color: #080;" class=3D"styled-by-p=
rettify">'=D0=91'</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #80=
0;" class=3D"styled-by-prettify">// Generic unicode locale, classifies and =
converts Latin and Cyrillic</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"colo=
r: #800;" class=3D"styled-by-prettify">// letters correctly.</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">aut=
o</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> cu8 </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> locale</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"c=
olor: #080;" class=3D"styled-by-prettify">"C.UTF-8"</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">assert</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify">isupper</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">L</span><span style=3D"color: #080;=
" class=3D"styled-by-prettify">'=C3=9F'</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> cu8</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">=3D=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">false</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">assert</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">islower</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">L</span><span style=
=3D"color: #080;" class=3D"styled-by-prettify">'=C3=9F'</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> cu8</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">=3D=3D</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">true</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">assert</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
">isupper</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify">L</span><s=
pan style=3D"color: #080;" class=3D"styled-by-prettify">'=E1=BA=9E'=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> cu8</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">=3D=3D</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">true</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">assert</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">islower</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">L</span><span style=3D"color: #080;" class=3D"styled-by-prettify">'=
=E1=BA=9E'</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> cu8<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">false</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">assert</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">toupper</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">L</span><span style=3D"color: #080;" class=3D"style=
d-by-prettify">'=C3=9F'</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> cu8</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> L</span><span s=
tyle=3D"color: #080;" class=3D"styled-by-prettify">'=C3=9F'</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #800;" class=3D"styled-by-prettify">//why not =E1=BA=9E?</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">ass=
ert</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">tolower</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">L</span><span style=3D"color=
: #080;" class=3D"styled-by-prettify">'=C3=9F'</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> cu8</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">=3D=3D</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> L</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&=
#39;=C3=9F'</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">assert</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">toupper</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">L</spa=
n><span style=3D"color: #080;" class=3D"styled-by-prettify">'=E1=BA=9E&=
#39;</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> cu8</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">=3D=3D</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> L</span><span style=3D"color: #080;" cla=
ss=3D"styled-by-prettify">'=E1=BA=9E'</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">assert</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">tolower</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">L</span><span style=3D"color: #080;" class=3D"sty=
led-by-prettify">'=E1=BA=9E'</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> cu8</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> L</span><s=
pan style=3D"color: #080;" class=3D"styled-by-prettify">'=C3=9F'</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>=C2=A0 =C2=A0=
=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">assert</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">isupper<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">L</span><span style=
=3D"color: #080;" class=3D"styled-by-prettify">'=D0=B1'</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> cu8</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">=3D=3D</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">false</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">assert</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">islower</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">L</span=
><span style=3D"color: #080;" class=3D"styled-by-prettify">'=D0=B1'=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> cu8</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">=3D=3D</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">true</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">assert</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">isupper</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">L</span><span style=3D"color: #080;" class=3D"styled-by-prettify">'=
=D0=91'</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> cu8</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">=3D=3D</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;"=
class=3D"styled-by-prettify">true</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">assert</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">islower</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">L</span><span style=3D"color: #080;" class=3D"styled-by-pret=
tify">'=D0=91'</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> cu8</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">false</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">assert</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">toupper</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify">L</span><span style=3D"color: #080;" class=3D"=
styled-by-prettify">'=D0=B1'</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> cu8</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> L</span><s=
pan style=3D"color: #080;" class=3D"styled-by-prettify">'=D0=91'</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>assert</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify">tolower</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">L</span><span style=3D"c=
olor: #080;" class=3D"styled-by-prettify">'=D0=B1'</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> cu8</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">=3D=3D</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> L</span><span style=3D"color: #080;" class=3D"styled-by-prettif=
y">'=D0=B1'</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">assert</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">toupper</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">L=
</span><span style=3D"color: #080;" class=3D"styled-by-prettify">'=D0=
=91'</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> cu8</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">=3D=3D</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> L</span><span style=3D"color: #080;" c=
lass=3D"styled-by-prettify">'=D0=91'</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">assert</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify">tolower</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">L</span><span style=3D"color: #080;" class=3D"style=
d-by-prettify">'=D0=91'</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> cu8</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> L</span><span s=
tyle=3D"color: #080;" class=3D"styled-by-prettify">'=D0=B1'</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br><br>=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 </span><span style=3D"color: #800;" class=3D"styled-by-prettify"=
>// Latin-1 locale. The wide facet classifies and converts case</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 </span><span style=3D"color: #800;" class=3D"styled-by-prettify"=
>// correctly even for Unicode characters that are not part of latin-1.</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> l1 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> locale</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span =
style=3D"color: #080;" class=3D"styled-by-prettify">"en_US.ISO-8859-1&=
quot;</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">assert</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">is=
upper</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">L</span><span =
style=3D"color: #080;" class=3D"styled-by-prettify">'=C3=9F'</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> l1</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D=3D</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">false</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">assert</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">islower</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">L</sp=
an><span style=3D"color: #080;" class=3D"styled-by-prettify">'=C3=9F=
9;</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> l1</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">=3D=3D</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">true</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">assert</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">isupper</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">L</span><span style=3D"color: #080;" class=3D"styled-by-prettify">'=
=E1=BA=9E'</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> l1</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">true</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">assert</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify">islower</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify">L</span><span style=3D"color: #080;" class=3D"styled-by-pr=
ettify">'=E1=BA=9E'</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> l1</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">false</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">assert</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">toupper</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify">L</span><span style=3D"color: #080;" cla=
ss=3D"styled-by-prettify">'=C3=9F'</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> l1</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
=3D=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> L</=
span><span style=3D"color: #080;" class=3D"styled-by-prettify">'=C3=9F&=
#39;</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #800;" class=3D"styled-by-prettify">//why not =E1=BA=9E?</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">assert</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">to=
lower</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">L</span><span =
style=3D"color: #080;" class=3D"styled-by-prettify">'=C3=9F'</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> l1</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D=3D</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> L</span><span style=3D"color: #080;" class=3D"styled-b=
y-prettify">'=C3=9F'</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">assert</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">toupper</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">L</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&#=
39;=E1=BA=9E'</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> l=
1</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> L</span><span style=3D"color: =
#080;" class=3D"styled-by-prettify">'=E1=BA=9E'</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">assert</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">tolower</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">L</span><span style=3D"color: #080;" =
class=3D"styled-by-prettify">'=E1=BA=9E'</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> l1</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">=3D=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> L</span><span style=3D"color: #080;" class=3D"styled-by-prettify">'=
=C3=9F'</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br=
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">assert</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">isupper</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">L</spa=
n><span style=3D"color: #080;" class=3D"styled-by-prettify">'=D0=B1'=
;</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> l1</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">=3D=3D</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">false</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">assert</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">islower</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">L</span><span style=3D"color: #080;" class=3D"styled-by-prettify">'=
=D0=B1'</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> l1</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">=3D=3D</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" =
class=3D"styled-by-prettify">true</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">assert</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">isupper</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">L</span><span style=3D"color: #080;" class=3D"styled-by-pret=
tify">'=D0=91'</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> l1</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">true</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">assert</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify">islower</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">L</span><span style=3D"color: #080;" class=3D"style=
d-by-prettify">'=D0=91'</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> l1</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">false</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"><br><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">assert</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify">toupper</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">L</span><span style=3D"color: #080;" =
class=3D"styled-by-prettify">'=D0=B1'</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> l1</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>=3D=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> L<=
/span><span style=3D"color: #080;" class=3D"styled-by-prettify">'=D0=91=
'</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">assert</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">to=
lower</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">L</span><span =
style=3D"color: #080;" class=3D"styled-by-prettify">'=D0=B1'</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> l1</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D=3D</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> L</span><span style=3D"color: #080;" class=3D"styled-b=
y-prettify">'=D0=B1'</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">assert</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">toupper</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">L</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&#=
39;=D0=91'</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> l1</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> L</span><span style=3D"color: #=
080;" class=3D"styled-by-prettify">'=D0=91'</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">assert</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">tolower</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify">L</span><span style=3D"color: #080;" class=3D=
"styled-by-prettify">'=D0=91'</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> l1</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> L</span><s=
pan style=3D"color: #080;" class=3D"styled-by-prettify">'=D0=B1'</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>=C2=A0 =C2=A0=
=C2=A0 =C2=A0 </span><span style=3D"color: #800;" class=3D"styled-by-prett=
ify">// English UTF-8 locale, works as expected</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span=
><span style=3D"color: #800;" class=3D"styled-by-prettify">// same as the t=
wo above.</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D=
"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> u8 </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> locale</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(=
</span><span style=3D"color: #080;" class=3D"styled-by-prettify">"en_U=
S.UTF-8"</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">assert</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">isupper</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">L</span=
><span style=3D"color: #080;" class=3D"styled-by-prettify">'=C3=9F'=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> u8</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> =C2=A0</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">=3D=3D</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">false</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">assert</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify">islower</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">L</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&=
#39;=C3=9F'</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> u8<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">true</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">assert</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify">isupper</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify">L</span><span style=3D"color: #080;" class=3D"styled-by-pr=
ettify">'=E1=BA=9E'</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> u8</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">true</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">assert</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">islower</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify">L</span><span style=3D"color: #080;" class=3D=
"styled-by-prettify">'=E1=BA=9E'</span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> u8</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=
=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">false</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br><br>=C2=A0 =C2=A0 =C2=A0=
=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">as=
sert</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify">toupper</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">L</span><span style=3D"colo=
r: #080;" class=3D"styled-by-prettify">'=C3=9F'</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> u8</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">=3D=3D</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> L</span><span style=3D"color: #080;" class=3D"styled-by-prettif=
y">'=C3=9F'</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">// why n=
ot =E1=BA=9E?</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">assert</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify">tolower</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
L</span><span style=3D"color: #080;" class=3D"styled-by-prettify">'=C3=
=9F'</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> u8</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">=3D=3D</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> L</span><span style=3D"color: #080;" cl=
ass=3D"styled-by-prettify">'=C3=9F'</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">assert</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">toupper</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">L</span><span style=3D"color: #080;" class=3D"style=
d-by-prettify">'=E1=BA=9E'</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> u8</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> L</span><span=
style=3D"color: #080;" class=3D"styled-by-prettify">'=E1=BA=9E'</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>assert</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify">tolower</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">L</span><span style=3D"c=
olor: #080;" class=3D"styled-by-prettify">'=E1=BA=9E'</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> u8</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">=3D=3D</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> L</span><span style=3D"color: #080;" class=3D"styled-by-prett=
ify">'=C3=9F'</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" =
class=3D"styled-by-prettify">assert</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">isupper</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">L</span><span style=3D"color: #080;" class=3D"styled-by-prettify">'=
=D0=B1'</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> u8</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">=3D=3D</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" =
class=3D"styled-by-prettify">false</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">assert</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">islower</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">L</span><span style=3D"color: #080;" class=3D"styled-by-pret=
tify">'=D0=B1'</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> u8</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">true</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">assert</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify">isupper</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">L</span><span style=3D"color: #080;" class=3D"style=
d-by-prettify">'=D0=91'</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> u8</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">true</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">assert</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">islower</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify">L</span><span style=3D"color: #080;" class=
=3D"styled-by-prettify">'=D0=91'</span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> u8</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=
=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">false</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br><br>=C2=A0 =C2=A0 =C2=A0=
=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">as=
sert</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify">toupper</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">L</span><span style=3D"colo=
r: #080;" class=3D"styled-by-prettify">'=D0=B1'</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> u8</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">=3D=3D</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> L</span><span style=3D"color: #080;" class=3D"styled-by-prettif=
y">'=D0=91'</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">assert</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">tolower</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">L=
</span><span style=3D"color: #080;" class=3D"styled-by-prettify">'=D0=
=B1'</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> u8</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">=3D=3D</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> L</span><span style=3D"color: #080;" cl=
ass=3D"styled-by-prettify">'=D0=B1'</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">assert</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">toupper</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">L</span><span style=3D"color: #080;" class=3D"style=
d-by-prettify">'=D0=91'</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> u8</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> L</span><span st=
yle=3D"color: #080;" class=3D"styled-by-prettify">'=D0=91'</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">ass=
ert</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">tolower</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">L</span><span style=3D"color=
: #080;" class=3D"styled-by-prettify">'=D0=91'</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> u8</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">=3D=3D</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> L</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&#=
39;=D0=B1'</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">return</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-prett=
ify">0</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">}</span></div></cod=
e></div><br><br><br></span></code></pre></div>
<p>We should completely avoid this gotcha and make <code>ctype<char32_t&=
gt;</code> work out of the box for the whole Unicode range. The locale name=
should modify only the <code>widen()</code> and <code>narrow()</code> func=
tions.</p>
<p>We can additional allow the natural language part of the locale to sligh=
tly modify the case conversion. E.g. the Turkish <a href=3D"https://en.wiki=
pedia.org/wiki/Dotted_and_dotless_I">dotted and dotless I</a>.</p>
<p>Defining this facet will automatically enable decent Unicode regexes.</p=
><p><br></p>
<h3>ctype<char16_t></h3>
<p>This should behave exactly same as the above, except that it will=20
accept only the first 65536 characters of Unicode, i.e. characters from=20
the basic multilingual plane (BMP).</p><p><br></p>
<h3>codecvt</h3>
<p>Codecvt specializations of <code>char16_t</code> and <code>char32_t</cod=
e>
already exists. They convert strictly from/to UTF-8. I am not that=20
happy with this because it is not aligned with the codecvt of <code>wchar_t=
</code> which can convert from/to custom encoding, when the implementations=
allows.</p>
<p>Maybe we should allow <code>codecvt_byname</code> to create <code>codecv=
t</code> that can convert between custom encoding and UTF-32/UTF-16.</p>
<p>Additionally, I am not even happy with the general design of codecvt,
mostly because it is created with the same names as locales. Codecvt=20
depend only on the encoding part of the locale identifier pair, not on=20
the natural language identifier. Maybe we should create a new codecvt2=20
facet.</p><p><br></p>
<h3>codecvt2<InternT, ExternT> facet</h3>
<p>codecvt2 should be constructed only with encoding name. It will convert =
from/to that encoding. This is the way <code>iconv</code> works. you first =
call <code>iconv_open</code> with two encoding names. This is the way ICU <=
a href=3D"http://icu-project.org/apiref/icu4c/ucnv_8h.html">ucnv.h</a> work=
s. You open <code>UConverter</code> with <code>ucnv_open()</code> by giving=
the name of the encoding.</p>
<ul><li><code>codecvt2<char, char></code> may convert between various=
narrow encodings,</li><li><code>codecvt2<char32_t, char></code> will=
convert between custom narrow encoding and UTF-32.</li><li><code>codecvt2&=
lt;char32_t, char16_t></code> may convert between UTF-32 and UTF-16.</li=
></ul>
<p>Besides the standard <code>in()</code> and <code>out()</code>,=20
additional functions should be provided. For example simple function=20
that converts one string into another without keeping state. The input=20
string is known that it starts and ends, it isn't part of larger text.=
=20
Such functionality was added in C++11 and deprecated in C++17, <code>wstrin=
g_convert</code>.</p>
<p>Additional function that converts only one output character may be provi=
ded.</p><p><br></p>
<h3>Conclusion so far</h3>
<p>Specifying the above facets are the absolute minimum to get a decent Uni=
code support. More advanced Unicode features like:</p>
<ol><li>Querying character properties like general category</li><li>Languag=
e sensitive string case transformations (not character)</li><li>Normalizati=
on</li></ol>
<p>Will need facets on their own.</p>
</div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/45303792-68f2-4545-8ce4-4a3e1ec35b1b%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/45303792-68f2-4545-8ce4-4a3e1ec35b1b=
%40isocpp.org</a>.<br />
------=_Part_22599_2132005776.1522241140472--
------=_Part_22598_1495971763.1522241140468--
.