------------------------------------------------------------------------------
--                                                                          --
--                         GNAT RUNTIME COMPONENTS                          --
--                                                                          --
--                       A D A . C H A R A C T E R S                        --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--                            $Revision: 1.9 $                              --
--                                                                          --
--           Copyright (c) 1992,1993,1994 NYU, All Rights Reserved          --
--                                                                          --
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 2,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
-- for  more details.  You should have  received  a copy of the GNU General --
-- Public License  distributed with GNAT;  see file COPYING.  If not, write --
-- to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. --
--                                                                          --
------------------------------------------------------------------------------

with Ada.Characters.Latin_1; use Ada.Characters.Latin_1;
with Ada.Strings.Maps;
with Ada.Strings.Constants;

package body Ada.Characters is

   ------------------------------------
   -- Character Classification Table --
   ------------------------------------

   type Character_Flags is mod 256;
   for Character_Flags'Size use 8;

   Control    : constant Character_Flags := 1;
   Lower      : constant Character_Flags := 2;
   Upper      : constant Character_Flags := 4;
   Basic      : constant Character_Flags := 8;
   Hex_Digit  : constant Character_Flags := 16;
   Digit      : constant Character_Flags := 32;
   Special    : constant Character_Flags := 64;

   Letter     : constant Character_Flags := Lower or Upper;
   Alphanum   : constant Character_Flags := Letter or Digit;
   Graphic    : constant Character_Flags := Alphanum or Special;

   Char_Map : constant array (Character) of Character_Flags :=
   (
     NUL                         => Control,
     SOH                         => Control,
     STX                         => Control,
     ETX                         => Control,
     EOT                         => Control,
     ENQ                         => Control,
     ACK                         => Control,
     BEL                         => Control,
     BS                          => Control,
     HT                          => Control,
     LF                          => Control,
     VT                          => Control,
     FF                          => Control,
     CR                          => Control,
     SO                          => Control,
     SI                          => Control,

     DLE                         => Control,
     DC1                         => Control,
     DC2                         => Control,
     DC3                         => Control,
     DC4                         => Control,
     NAK                         => Control,
     SYN                         => Control,
     ETB                         => Control,
     CAN                         => Control,
     EM                          => Control,
     SUB                         => Control,
     ESC                         => Control,
     FS                          => Control,
     GS                          => Control,
     RS                          => Control,
     US                          => Control,

     Space                       => Special,
     Exclamation                 => Special,
     Quotation                   => Special,
     Number_Sign                 => Special,
     Dollar_Sign                 => Special,
     Percent_Sign                => Special,
     Ampersand                   => Special,
     Apostrophe                  => Special,
     Left_Parenthesis            => Special,
     Right_Parenthesis           => Special,
     Asterisk                    => Special,
     Plus_Sign                   => Special,
     Comma                       => Special,
     Hyphen                      => Special,
     Full_Stop                   => Special,
     Solidus                     => Special,

     '0' .. '9'                  => Digit + Hex_Digit,

     Colon                       => Special,
     Semicolon                   => Special,
     Less_Than_Sign              => Special,
     Equals_Sign                 => Special,
     Greater_Than_Sign           => Special,
     Question                    => Special,
     Commercial_At               => Special,

     'A' .. 'F'                  => Upper + Basic + Hex_Digit,
     'G' .. 'Z'                  => Upper + Basic,

     Left_Square_Bracket         => Special,
     Reverse_Solidus             => Special,
     Right_Square_Bracket        => Special,
     Circumflex                  => Special,
     Low_Line                    => Special,
     Grave                       => Special,

     'a' .. 'f'                  => Lower + Basic + Hex_Digit,
     'g' .. 'z'                  => Lower + Basic,

     Left_Curly_Bracket          => Special,
     Vertical_Line               => Special,
     Right_Curly_Bracket         => Special,
     Tilde                       => Special,

     DEL                         => Control,

     Reserved_128                => Control,
     Reserved_129                => Control,
     Reserved_130                => Control,
     Reserved_131                => Control,
     IND                         => Control,
     NEL                         => Control,
     SSA                         => Control,
     ESA                         => Control,
     HTS                         => Control,
     HTJ                         => Control,
     VTS                         => Control,
     PLD                         => Control,
     PLU                         => Control,
     RI                          => Control,
     SS2                         => Control,
     SS3                         => Control,

     DCS                         => Control,
     PU1                         => Control,
     PU2                         => Control,
     STS                         => Control,
     CCH                         => Control,
     MW                          => Control,
     SPA                         => Control,
     EPA                         => Control,

     Reserved_152                => Control,
     Reserved_153                => Control,
     Reserved_154                => Control,
     CSI                         => Control,
     ST                          => Control,
     OSC                         => Control,
     PM                          => Control,
     APC                         => Control,

     No_Break_Space              => Special,
     Inverted_Exclamation        => Special,
     Cent_Sign                   => Special,
     Pound_Sign                  => Special,
     Currency_Sign               => Special,
     Yen_Sign                    => Special,
     Broken_Bar                  => Special,
     Section_Sign                => Special,
     Diaeresis                   => Special,
     Copyright_Sign              => Special,
     Feminine_Ordinal_Indicator  => Special,
     Left_Angle_Quotation        => Special,
     Not_Sign                    => Special,
     Soft_Hyphen                 => Special,
     Registered_Trade_Mark_Sign  => Special,
     Macron                      => Special,
     Degree_Sign                 => Special,
     Plus_Minus_Sign             => Special,
     Superscript_Two             => Special,
     Superscript_Three           => Special,
     Acute                       => Special,
     Micro_Sign                  => Special,
     Pilcrow_Sign                => Special,
     Middle_Dot                  => Special,
     Cedilla                     => Special,
     Superscript_One             => Special,
     Masculine_Ordinal_Indicator => Special,
     Right_Angle_Quotation       => Special,
     Fraction_One_Quarter        => Special,
     Fraction_One_Half           => Special,
     Fraction_Three_Quarters     => Special,
     Inverted_Question           => Special,

     UC_A_Grave                  => Upper,
     UC_A_Acute                  => Upper,
     UC_A_Circumflex             => Upper,
     UC_A_Tilde                  => Upper,
     UC_A_Diaeresis              => Upper,
     UC_A_Ring                   => Upper,
     UC_AE_Diphthong             => Upper + Basic,
     UC_C_Cedilla                => Upper,
     UC_E_Grave                  => Upper,
     UC_E_Acute                  => Upper,
     UC_E_Circumflex             => Upper,
     UC_E_Diaeresis              => Upper,
     UC_I_Grave                  => Upper,
     UC_I_Acute                  => Upper,
     UC_I_Circumflex             => Upper,
     UC_I_Diaeresis              => Upper,
     UC_Icelandic_Eth            => Upper + Basic,
     UC_N_Tilde                  => Upper,
     UC_O_Grave                  => Upper,
     UC_O_Acute                  => Upper,
     UC_O_Circumflex             => Upper,
     UC_O_Tilde                  => Upper,
     UC_O_Diaeresis              => Upper,

     Multiplication_Sign         => Special,

     UC_O_Oblique_Stroke         => Upper,
     UC_U_Grave                  => Upper,
     UC_U_Acute                  => Upper,
     UC_U_Circumflex             => Upper,
     UC_U_Diaeresis              => Upper,
     UC_Y_Acute                  => Upper,
     UC_Icelandic_Thorn          => Upper + Basic,

     LC_German_Sharp_S           => Lower + Basic,
     LC_A_Grave                  => Lower,
     LC_A_Acute                  => Lower,
     LC_A_Circumflex             => Lower,
     LC_A_Tilde                  => Lower,
     LC_A_Diaeresis              => Lower,
     LC_A_Ring                   => Lower,
     LC_AE_Diphthong             => Lower + Basic,
     LC_C_Cedilla                => Lower,
     LC_E_Grave                  => Lower,
     LC_E_Acute                  => Lower,
     LC_E_Circumflex             => Lower,
     LC_E_Diaeresis              => Lower,
     LC_I_Grave                  => Lower,
     LC_I_Acute                  => Lower,
     LC_I_Circumflex             => Lower,
     LC_I_Diaeresis              => Lower,
     LC_Icelandic_Eth            => Lower + Basic,
     LC_N_Tilde                  => Lower,
     LC_O_Grave                  => Lower,
     LC_O_Acute                  => Lower,
     LC_O_Circumflex             => Lower,
     LC_O_Tilde                  => Lower,
     LC_O_Diaeresis              => Lower,

     Division_Sign               => Special,

     LC_O_Oblique_Stroke         => Lower,
     LC_U_Grave                  => Lower,
     LC_U_Acute                  => Lower,
     LC_U_Circumflex             => Lower,
     LC_U_Diaeresis              => Lower,
     LC_Y_Acute                  => Lower,
     LC_Icelandic_Thorn          => Lower + Basic,
     LC_Y_Diaeresis              => Lower
   );

   --------------------
   -- Character Maps --
   --------------------

   --  Map special letters to basic equivalents, all other characters
   --  are mapped to themselves, as are all characters that are not
   --  covered by the range of this table.

   Basic_Map : constant Maps.Character_Mapping
     (UC_A_Grave .. Character'Last) :=
   (
     UC_A_Grave                  => 'A',                           -- 192
     UC_A_Acute                  => 'A',                           -- 193
     UC_A_Circumflex             => 'A',                           -- 194
     UC_A_Tilde                  => 'A',                           -- 195
     UC_A_Diaeresis              => 'A',                           -- 196
     UC_A_Ring                   => 'A',                           -- 197
     UC_AE_Diphthong             => UC_AE_Diphthong,               -- 198
     UC_C_Cedilla                => 'C',                           -- 199
     UC_E_Grave                  => 'E',                           -- 200
     UC_E_Acute                  => 'E',                           -- 201
     UC_E_Circumflex             => 'E',                           -- 202
     UC_E_Diaeresis              => 'E',                           -- 203
     UC_I_Grave                  => 'I',                           -- 204
     UC_I_Acute                  => 'I',                           -- 205
     UC_I_Circumflex             => 'I',                           -- 206
     UC_I_Diaeresis              => 'I',                           -- 207
     UC_Icelandic_Eth            => UC_Icelandic_Eth,              -- 208
     UC_N_Tilde                  => 'N',                           -- 209
     UC_O_Grave                  => 'O',                           -- 210
     UC_O_Acute                  => 'O',                           -- 211
     UC_O_Circumflex             => 'O',                           -- 212
     UC_O_Tilde                  => 'O',                           -- 213
     UC_O_Diaeresis              => 'O',                           -- 214
     Multiplication_Sign         => Multiplication_Sign,           -- 215
     UC_O_Oblique_Stroke         => 'O',                           -- 216
     UC_U_Grave                  => 'U',                           -- 217
     UC_U_Acute                  => 'U',                           -- 218
     UC_U_Circumflex             => 'U',                           -- 219
     UC_U_Diaeresis              => 'U',                           -- 220
     UC_Y_Acute                  => 'Y',                           -- 221
     UC_Icelandic_Thorn          => UC_Icelandic_Thorn,            -- 222
     LC_German_Sharp_S           => LC_German_Sharp_S,             -- 223
     LC_A_Grave                  => LC_A,                          -- 224
     LC_A_Acute                  => LC_A,                          -- 225
     LC_A_Circumflex             => LC_A,                          -- 226
     LC_A_Tilde                  => LC_A,                          -- 227
     LC_A_Diaeresis              => LC_A,                          -- 228
     LC_A_Ring                   => LC_A,                          -- 229
     LC_AE_Diphthong             => LC_AE_Diphthong,               -- 230
     LC_C_Cedilla                => LC_C,                          -- 231
     LC_E_Grave                  => LC_E,                          -- 232
     LC_E_Acute                  => LC_E,                          -- 233
     LC_E_Circumflex             => LC_E,                          -- 234
     LC_E_Diaeresis              => LC_E,                          -- 235
     LC_I_Grave                  => LC_I,                          -- 236
     LC_I_Acute                  => LC_I,                          -- 237
     LC_I_Circumflex             => LC_I,                          -- 238
     LC_I_Diaeresis              => LC_I,                          -- 239
     LC_Icelandic_Eth            => LC_Icelandic_Eth,              -- 240
     LC_N_Tilde                  => LC_N,                          -- 241
     LC_O_Grave                  => LC_O,                          -- 242
     LC_O_Acute                  => LC_O,                          -- 243
     LC_O_Circumflex             => LC_O,                          -- 244
     LC_O_Tilde                  => LC_O,                          -- 245
     LC_O_Diaeresis              => LC_O,                          -- 246
     Division_Sign               => Division_Sign,                 -- 247
     LC_O_Oblique_Stroke         => LC_O,                          -- 248
     LC_U_Grave                  => LC_U,                          -- 249
     LC_U_Acute                  => LC_U,                          -- 250
     LC_U_Circumflex             => LC_U,                          -- 251
     LC_U_Diaeresis              => LC_U,                          -- 252
     LC_Y_Acute                  => LC_Y,                          -- 253
     LC_Icelandic_Thorn          => LC_Icelandic_Thorn,            -- 254
     LC_Y_Diaeresis              => LC_Y                           -- 255
  );
   --  Map upper case letters to their lower case equivalents, all other
   --  characters are mapped to themselves.

   Lower_Map :  Ada.Strings.Constants.Full_Character_Map
     renames Ada.Strings.Constants.Lower_Case_Map;
   --  ??? should be defined of the unconstrained type Maps.Character_Mapping

   --  Map lower case letters to their upper case equivalents, all other
   --  characters are mapped to themselves.

   Upper_Map : constant Maps.Character_Mapping
     (Character'First .. Character'Last) :=
   (

     NUL                         => NUL,                           -- 0
     SOH                         => SOH,                           -- 1
     STX                         => STX,                           -- 2
     ETX                         => ETX,                           -- 3
     EOT                         => EOT,                           -- 4
     ENQ                         => ENQ,                           -- 5
     ACK                         => ACK,                           -- 6
     BEL                         => BEL,                           -- 7
     BS                          => BS,                            -- 8
     HT                          => HT,                            -- 9
     LF                          => LF,                            -- 10
     VT                          => VT,                            -- 11
     FF                          => FF,                            -- 12
     CR                          => CR,                            -- 13
     SO                          => SO,                            -- 14
     SI                          => SI,                            -- 15

     DLE                         => DLE,                           -- 16
     DC1                         => DC1,                           -- 17
     DC2                         => DC2,                           -- 18
     DC3                         => DC3,                           -- 19
     DC4                         => DC4,                           -- 20
     NAK                         => NAK,                           -- 21
     SYN                         => SYN,                           -- 22
     ETB                         => ETB,                           -- 23
     CAN                         => CAN,                           -- 24
     EM                          => EM,                            -- 25
     SUB                         => SUB,                           -- 26
     ESC                         => ESC,                           -- 27
     FS                          => FS,                            -- 28
     GS                          => GS,                            -- 29
     RS                          => RS,                            -- 30
     US                          => US,                            -- 31

     Space                       => Space,                         -- 32
     Exclamation                 => Exclamation,                   -- 33
     Quotation                   => Quotation,                     -- 34
     Number_Sign                 => Number_Sign,                   -- 35
     Dollar_Sign                 => Dollar_Sign,                   -- 36
     Percent_Sign                => Percent_Sign,                  -- 37
     Ampersand                   => Ampersand,                     -- 38
     Apostrophe                  => Apostrophe,                    -- 39
     Left_Parenthesis            => Left_Parenthesis,              -- 40
     Right_Parenthesis           => Right_Parenthesis,             -- 41
     Asterisk                    => Asterisk,                      -- 42
     Plus_Sign                   => Plus_Sign,                     -- 43
     Comma                       => Comma,                         -- 44
     Hyphen                      => Hyphen,                        -- 45
     Full_Stop                   => Full_Stop,                     -- 46
     Solidus                     => Solidus,                       -- 47

     '0'                         => '0',                           -- 48
     '1'                         => '1',                           -- 49
     '2'                         => '2',                           -- 50
     '3'                         => '3',                           -- 51
     '4'                         => '4',                           -- 52
     '5'                         => '5',                           -- 53
     '6'                         => '6',                           -- 54
     '7'                         => '7',                           -- 55
     '8'                         => '8',                           -- 56
     '9'                         => '9',                           -- 57

     Colon                       => Colon,                         -- 58
     Semicolon                   => Semicolon,                     -- 59
     Less_Than_Sign              => Less_Than_Sign,                -- 60
     Equals_Sign                 => Equals_Sign,                   -- 61
     Greater_Than_Sign           => Greater_Than_Sign,             -- 62
     Question                    => Question,                      -- 63
     Commercial_At               => Commercial_At,                 -- 64

     'A'                         => 'A',                           -- 65
     'B'                         => 'B',                           -- 66
     'C'                         => 'C',                           -- 67
     'D'                         => 'D',                           -- 68
     'E'                         => 'E',                           -- 69
     'F'                         => 'F',                           -- 70
     'G'                         => 'G',                           -- 71
     'H'                         => 'H',                           -- 72
     'I'                         => 'I',                           -- 73
     'J'                         => 'J',                           -- 74
     'K'                         => 'K',                           -- 75
     'L'                         => 'L',                           -- 76
     'M'                         => 'M',                           -- 77
     'N'                         => 'N',                           -- 78
     'O'                         => 'O',                           -- 79
     'P'                         => 'P',                           -- 80
     'Q'                         => 'Q',                           -- 81
     'R'                         => 'R',                           -- 82
     'S'                         => 'S',                           -- 83
     'T'                         => 'T',                           -- 84
     'U'                         => 'U',                           -- 85
     'V'                         => 'V',                           -- 86
     'W'                         => 'W',                           -- 87
     'X'                         => 'X',                           -- 88
     'Y'                         => 'Y',                           -- 89
     'Z'                         => 'Z',                           -- 90

     Left_Square_Bracket         => Left_Square_Bracket,           -- 91
     Reverse_Solidus             => Reverse_Solidus,               -- 92
     Right_Square_Bracket        => Right_Square_Bracket,          -- 93
     Circumflex                  => Circumflex,                    -- 94
     Low_Line                    => Low_Line,                      -- 95
     Grave                       => Grave,                         -- 96

     LC_A                        => 'A',                           -- 97
     LC_B                        => 'B',                           -- 98
     LC_C                        => 'C',                           -- 99
     LC_D                        => 'D',                           -- 100
     LC_E                        => 'E',                           -- 101
     LC_F                        => 'F',                           -- 102
     LC_G                        => 'G',                           -- 103
     LC_H                        => 'H',                           -- 104
     LC_I                        => 'I',                           -- 105
     LC_J                        => 'J',                           -- 106
     LC_K                        => 'K',                           -- 107
     LC_L                        => 'L',                           -- 108
     LC_M                        => 'M',                           -- 109
     LC_N                        => 'N',                           -- 110
     LC_O                        => 'O',                           -- 111
     LC_P                        => 'P',                           -- 112
     LC_Q                        => 'Q',                           -- 113
     LC_R                        => 'R',                           -- 114
     LC_S                        => 'S',                           -- 115
     LC_T                        => 'T',                           -- 116
     LC_U                        => 'U',                           -- 117
     LC_V                        => 'V',                           -- 118
     LC_W                        => 'W',                           -- 119
     LC_X                        => 'X',                           -- 120
     LC_Y                        => 'Y',                           -- 121
     LC_Z                        => 'Z',                           -- 122

     Left_Curly_Bracket          => Left_Curly_Bracket,            -- 123
     Vertical_Line               => Vertical_Line,                 -- 125
     Right_Curly_Bracket         => Right_Curly_Bracket,           -- 125
     Tilde                       => Tilde,                         -- 126

     DEL                         => DEL,                           -- 127

     Reserved_128                => Reserved_128,                  -- 128
     Reserved_129                => Reserved_129,                  -- 129
     Reserved_130                => Reserved_130,                  -- 130
     Reserved_131                => Reserved_131,                  -- 131
     IND                         => IND,                           -- 132
     NEL                         => NEL,                           -- 133
     SSA                         => SSA,                           -- 134
     ESA                         => ESA,                           -- 135
     HTS                         => HTS,                           -- 136
     HTJ                         => HTJ,                           -- 137
     VTS                         => VTS,                           -- 138
     PLD                         => PLD,                           -- 139
     PLU                         => PLU,                           -- 140
     RI                          => RI,                            -- 141
     SS2                         => SS2,                           -- 142
     SS3                         => SS3,                           -- 143

     DCS                         => DCS,                           -- 144
     PU1                         => PU1,                           -- 145
     PU2                         => PU2,                           -- 146
     STS                         => STS,                           -- 147
     CCH                         => CCH,                           -- 148
     MW                          => MW,                            -- 149
     SPA                         => SPA,                           -- 150
     EPA                         => EPA,                           -- 151

     Reserved_152                => Reserved_152,                  -- 152
     Reserved_153                => Reserved_153,                  -- 153
     Reserved_154                => Reserved_154,                  -- 154
     CSI                         => CSI,                           -- 155
     ST                          => ST,                            -- 156
     OSC                         => OSC,                           -- 157
     PM                          => PM,                            -- 158
     APC                         => APC,                           -- 159

     No_Break_Space              => No_Break_Space,                -- 160
     Inverted_Exclamation        => Inverted_Exclamation,          -- 161
     Cent_Sign                   => Cent_Sign,                     -- 162
     Pound_Sign                  => Pound_Sign,                    -- 163
     Currency_Sign               => Currency_Sign,                 -- 164
     Yen_Sign                    => Yen_Sign,                      -- 165
     Broken_Bar                  => Broken_Bar,                    -- 166
     Section_Sign                => Section_Sign,                  -- 167
     Diaeresis                   => Diaeresis,                     -- 168
     Copyright_Sign              => Copyright_Sign,                -- 169
     Feminine_Ordinal_Indicator  => Feminine_Ordinal_Indicator,    -- 170
     Left_Angle_Quotation        => Left_Angle_Quotation,          -- 171
     Not_Sign                    => Not_Sign,                      -- 172
     Soft_Hyphen                 => Soft_Hyphen,                   -- 173
     Registered_Trade_Mark_Sign  => Registered_Trade_Mark_Sign,    -- 174
     Macron                      => Macron,                        -- 175
     Degree_Sign                 => Degree_Sign,                   -- 176
     Plus_Minus_Sign             => Plus_Minus_Sign,               -- 177
     Superscript_Two             => Superscript_Two,               -- 178
     Superscript_Three           => Superscript_Three,             -- 179
     Acute                       => Acute,                         -- 180
     Micro_Sign                  => Micro_Sign,                    -- 181
     Pilcrow_Sign                => Pilcrow_Sign,                  -- 182
     Middle_Dot                  => Middle_Dot,                    -- 183
     Cedilla                     => Cedilla,                       -- 184
     Superscript_One             => Superscript_One,               -- 185
     Masculine_Ordinal_Indicator => Masculine_Ordinal_Indicator,   -- 186
     Right_Angle_Quotation       => Right_Angle_Quotation,         -- 187
     Fraction_One_Quarter        => Fraction_One_Quarter,          -- 188
     Fraction_One_Half           => Fraction_One_Half,             -- 189
     Fraction_Three_Quarters     => Fraction_Three_Quarters,       -- 190
     Inverted_Question           => Inverted_Question,             -- 191

     UC_A_Grave                  => UC_A_Grave,                    -- 192
     UC_A_Acute                  => UC_A_Acute,                    -- 193
     UC_A_Circumflex             => UC_A_Circumflex,               -- 194
     UC_A_Tilde                  => UC_A_Tilde,                    -- 195
     UC_A_Diaeresis              => UC_A_Diaeresis,                -- 196
     UC_A_Ring                   => UC_A_Ring,                     -- 197
     UC_AE_Diphthong             => UC_AE_Diphthong,               -- 198
     UC_C_Cedilla                => UC_C_Cedilla,                  -- 199
     UC_E_Grave                  => UC_E_Grave,                    -- 200
     UC_E_Acute                  => UC_E_Acute,                    -- 201
     UC_E_Circumflex             => UC_E_Circumflex,               -- 202
     UC_E_Diaeresis              => UC_E_Diaeresis,                -- 203
     UC_I_Grave                  => UC_I_Grave,                    -- 204
     UC_I_Acute                  => UC_I_Acute,                    -- 205
     UC_I_Circumflex             => UC_I_Circumflex,               -- 206
     UC_I_Diaeresis              => UC_I_Diaeresis,                -- 207
     UC_Icelandic_Eth            => UC_Icelandic_Eth,              -- 208
     UC_N_Tilde                  => UC_N_Tilde,                    -- 209
     UC_O_Grave                  => UC_O_Grave,                    -- 210
     UC_O_Acute                  => UC_O_Acute,                    -- 211
     UC_O_Circumflex             => UC_O_Circumflex,               -- 212
     UC_O_Tilde                  => UC_O_Tilde,                    -- 213
     UC_O_Diaeresis              => UC_O_Diaeresis,                -- 214

     Multiplication_Sign         => Multiplication_Sign,           -- 215

     UC_O_Oblique_Stroke         => UC_O_Oblique_Stroke,           -- 216
     UC_U_Grave                  => UC_U_Grave,                    -- 217
     UC_U_Acute                  => UC_U_Acute,                    -- 218
     UC_U_Circumflex             => UC_U_Circumflex,               -- 219
     UC_U_Diaeresis              => UC_U_Diaeresis,                -- 220
     UC_Y_Acute                  => UC_Y_Acute,                    -- 221
     UC_Icelandic_Thorn          => UC_Icelandic_Thorn,            -- 222

     LC_German_Sharp_S           => LC_German_Sharp_S,             -- 223
     LC_A_Grave                  => UC_A_Grave,                    -- 224
     LC_A_Acute                  => UC_A_Acute,                    -- 225
     LC_A_Circumflex             => UC_A_Circumflex,               -- 226
     LC_A_Tilde                  => UC_A_Tilde,                    -- 227
     LC_A_Diaeresis              => UC_A_Diaeresis,                -- 228
     LC_A_Ring                   => UC_A_Ring,                     -- 229
     LC_AE_Diphthong             => UC_AE_Diphthong,               -- 230
     LC_C_Cedilla                => UC_C_Cedilla,                  -- 231
     LC_E_Grave                  => UC_E_Grave,                    -- 232
     LC_E_Acute                  => UC_E_Acute,                    -- 233
     LC_E_Circumflex             => UC_E_Circumflex,               -- 234
     LC_E_Diaeresis              => UC_E_Diaeresis,                -- 235
     LC_I_Grave                  => UC_I_Grave,                    -- 236
     LC_I_Acute                  => UC_I_Acute,                    -- 237
     LC_I_Circumflex             => UC_I_Circumflex,               -- 238
     LC_I_Diaeresis              => UC_I_Diaeresis,                -- 239
     LC_Icelandic_Eth            => UC_Icelandic_Eth,              -- 240
     LC_N_Tilde                  => UC_N_Tilde,                    -- 241
     LC_O_Grave                  => UC_O_Grave,                    -- 242
     LC_O_Acute                  => UC_O_Acute,                    -- 243
     LC_O_Circumflex             => UC_O_Circumflex,               -- 244
     LC_O_Tilde                  => UC_O_Tilde,                    -- 245
     LC_O_Diaeresis              => UC_O_Diaeresis,                -- 246

     Division_Sign               => Division_Sign,                 -- 247

     LC_O_Oblique_Stroke         => UC_O_Oblique_Stroke,           -- 248
     LC_U_Grave                  => UC_U_Grave,                    -- 249
     LC_U_Acute                  => UC_U_Acute,                    -- 250
     LC_U_Circumflex             => UC_U_Circumflex,               -- 251
     LC_U_Diaeresis              => UC_U_Diaeresis,                -- 252
     LC_Y_Acute                  => UC_Y_Acute,                    -- 253
     LC_Icelandic_Thorn          => UC_Icelandic_Thorn,            -- 254
     LC_Y_Diaeresis              => LC_Y_Diaeresis);               -- 255

   ---------------------
   -- Is_Alphanumeric --
   ---------------------

   function Is_Alphanumeric (Item : in Character) return Boolean is
   begin
      return (Char_Map (Item) and Alphanum) /= 0;
   end Is_Alphanumeric;

   --------------
   -- Is_Basic --
   --------------

   function Is_Basic (Item : in Character) return Boolean is
   begin
      return (Char_Map (Item) and Basic) /= 0;
   end Is_Basic;

   ------------------
   -- Is_Character --
   ------------------

   function Is_Character (Item : in Wide_Character) return Boolean is
   begin
      return Wide_Character'Pos (Item) < 256;
   end Is_Character;

   ----------------
   -- Is_Control --
   ----------------

   function Is_Control (Item : in Character) return Boolean is
   begin
      return (Char_Map (Item) and Control) /= 0;
   end Is_Control;

   --------------
   -- Is_Digit --
   --------------

   function Is_Digit (Item : in Character) return Boolean is
   begin
      return Item in '0' .. '9';
   end Is_Digit;

   --------------------------
   -- Is_Hexadecimal_Digit --
   --------------------------

   function Is_Hexadecimal_Digit (Item : in Character) return Boolean is
   begin
      return (Char_Map (Item) and Hex_Digit) /= 0;
   end Is_Hexadecimal_Digit;

   ----------------
   -- Is_ISO_646 --
   ----------------

   function Is_ISO_646 (Item : in Character) return Boolean is
   begin
      return Item in ISO_646;
   end Is_ISO_646;

   --  Note: much more efficient coding of the following function is possible
   --  by testing several 16#80# bits in a complete word in a single operation

   function Is_ISO_646 (Item : in String) return Boolean is
   begin
      for I in Item'range loop
         if Item (I) not in ISO_646 then
            return False;
         end if;
      end loop;

      return True;
   end Is_ISO_646;

   ----------------
   -- Is_Graphic --
   ----------------

   function Is_Graphic (Item : in Character) return Boolean is
   begin
      return (Char_Map (Item) and Graphic) /= 0;
   end Is_Graphic;

   ---------------
   -- Is_Letter --
   ---------------

   function Is_Letter (Item : in Character) return Boolean is
   begin
      return (Char_Map (Item) and Letter) /= 0;
   end Is_Letter;

   --------------
   -- Is_Lower --
   --------------

   function Is_Lower (Item : in Character) return Boolean is
   begin
      return (Char_Map (Item) and Lower) /= 0;
   end Is_Lower;

   ------------------------
   -- Is_Special_Graphic --
   ------------------------

   function Is_Special_Graphic (Item : in Character) return Boolean is
   begin
      return (Char_Map (Item) and Special) /= 0;
   end Is_Special_Graphic;

   ---------------
   -- Is_String --
   ---------------

   function Is_String (Item : in Wide_String) return Boolean is
   begin
      for I in Item'range loop
         if Wide_Character'Pos (Item (I)) >= 256 then
            return False;
         end if;
      end loop;

      return True;
   end Is_String;

   --------------
   -- Is_Upper --
   --------------

   function Is_Upper (Item : in Character) return Boolean is
   begin
      return (Char_Map (Item) and Upper) /= 0;
   end Is_Upper;

   --------------
   -- To_Basic --
   --------------

   function To_Basic (Item : in Character) return Character is
   begin
      if Item < Basic_Map'First then
         return Item;
      else
         return Basic_Map (Item);
      end if;
   end To_Basic;

   function To_Basic (Item : in String) return String is
      Result : String (1 .. Item'Length);

   begin
      for I in Item'range loop
         Result (I - (Item'First - 1)) := Basic_Map (Item (I));
      end loop;

      return Result;
   end To_Basic;

   ------------------
   -- To_Character --
   ------------------

   function To_Character (
     Item       : in Wide_Character;
     Substitute : in Character := ' ')
     return Character
   is

   begin
      if Is_Character (Item) then
         return Character'Val (Wide_Character'Pos (Item));
      else
         return Substitute;
      end if;
   end To_Character;

   ----------------
   -- To_ISO_646 --
   ----------------

   function To_ISO_646 (
     Item       : in Character;
     Substitute : in ISO_646 := ' ')
     return ISO_646
   is

   begin
      if Item in ISO_646 then
         return Item;
      else
         return Substitute;
      end if;
   end To_ISO_646;

   function To_ISO_646 (
     Item       : in String;
     Substitute : in ISO_646 := ' ')
     return String
   is
      Result : String (1 .. Item'Length);

   begin
      for I in Item'range loop
         if Item (I) in ISO_646 then
            Result (I - (Item'First - 1)) := Item (I);
         else
            Result (I - (Item'First - 1)) := Substitute;
         end if;
      end loop;

      return Result;
   end To_ISO_646;

   --------------
   -- To_Lower --
   --------------

   function To_Lower (Item : in Character) return Character is
   begin
      return Lower_Map (Item);
   end To_Lower;

   function To_Lower (Item : in String) return String is
      Result : String (1 .. Item'Length);

   begin
      for I in Item'range loop
         Result (I - (Item'First - 1)) := Lower_Map (Item (I));
      end loop;

      return Result;
   end To_Lower;

   ---------------
   -- To_String --
   ---------------

   function To_String
     (Item : in Wide_String; Substitute : in Character := ' ')
     return String
   is
      Result : String (1 .. Item'Length);

   begin
      for I in Item'range loop
         Result (I) := To_Character (Item (I), Substitute);
      end loop;
      return Result;
   end To_String;

   --------------
   -- To_Upper --
   --------------

   function To_Upper (Item : in Character) return Character is
   begin
      return Upper_Map (Item);
   end To_Upper;

   function To_Upper (Item : in String) return String is
      Result : String (1 .. Item'Length);

   begin
      for I in Item'range loop
         Result (I - (Item'First - 1)) := Upper_Map (Item (I));
      end loop;

      return Result;
   end To_Upper;

   -----------------------
   -- To_Wide_Character --
   -----------------------

   function To_Wide_Character (Item : in Character) return Wide_Character is
   begin
      return Wide_Character'Val (Character'Pos (Item));
   end To_Wide_Character;

   --------------------
   -- To_Wide_String --
   --------------------

   function To_Wide_String (Item : in String) return Wide_String is
      Result : Wide_String (1 .. Item'Length);

   begin
      for I in Item'range loop
         Result (I - (Item'First - 1)) := To_Wide_Character (Item (I));
      end loop;
      return Result;
   end To_Wide_String;
end Ada.Characters;
