stdex
Additional custom or not Standard C++ covered algorithms
Loading...
Searching...
No Matches
langid.hpp
1/*
2 SPDX-License-Identifier: MIT
3 Copyright © 2024 Amebis
4*/
5
6#pragma once
7
8#include "compat.hpp"
9#include "string.hpp"
10#include "unicode.hpp"
11#ifdef _WIN32
12#include "windows.h"
13#endif
14#include <stddef.h>
15#include <stdint.h>
16#include <map>
17#include <string>
18
19#if defined(__GNUC__)
20#pragma GCC diagnostic push
21#pragma GCC diagnostic ignored "-Wexit-time-destructors"
22#endif
23
24namespace stdex
25{
26#ifdef _WIN32
27 using langid = LANGID;
28#else
29 using langid = uint16_t;
30#endif
31
32 constexpr langid langid_neutral = 0x0;
33 constexpr langid langid_unknown = 0x7f;
34 constexpr langid langid_system = 0x800;
35
36 constexpr langid sublangid_neutral = 0 << 10;
37 constexpr langid sublangid_default = 1 << 10;
38 constexpr langid sublangid_sys_default = 2 << 10;
39 constexpr langid sublangid_custom_default = 3 << 10;
40 constexpr langid sublangid_custom_unspecified = 4 << 10;
41 constexpr langid sublangid_ui_custom_default = 5 << 10;
42
50 inline constexpr langid primary_langid(_In_ langid lang)
51 {
52 return lang & 0x3ff;
53 }
54
62 inline constexpr langid sub_langid(_In_ langid lang)
63 {
64 return lang & 0xfc00;
65 }
66
74 inline langid langid_from_rfc1766(_In_z_ const char* rfc1766)
75 {
76 struct stricmp_less
77 {
78 bool operator()(_In_z_ const char* str1, _In_z_ const char* str2) const
79 {
80 stdex_assert(str1);
81 stdex_assert(str2);
82 size_t i;
83 for (i = 0; ; ++i) {
84 auto a = stdex::tolower(str1[i]);
85 auto b = stdex::tolower(str2[i]);
86 if (!a && !b) return false;
87 if (!b) return false;
88 if (!a) return true;
89 auto a_punct = stdex::ispunct(a);
90 auto b_punct = stdex::ispunct(b);
91 if (a_punct && b_punct) continue;
92 if (b_punct) return false;
93 if (a_punct) return true;
94 if (a > b) return false;
95 if (a < b) return true;
96 }
97 }
98 };
99 static const std::map<const char*, int, stricmp_less> languages = {
100 {"af-ZA", 0x436}, // Afrikaans (South Africa)
101 {"af", 0x36}, // Afrikaans
102 {"am-ET", 0x45e}, // Amharic (Ethiopia)
103 {"am", 0x5e}, // Amharic
104 {"ar-AE", 0x3801}, // Arabic (United Arab Emirates)
105 {"ar-BH", 0x3c01}, // Arabic (Bahrain)
106 {"ar-DZ", 0x1401}, // Arabic (Algeria)
107 {"ar-EG", 0xc01}, // Arabic (Egypt)
108 {"ar-IQ", 0x801}, // Arabic (Iraq)
109 {"ar-JO", 0x2c01}, // Arabic (Jordan)
110 {"ar-KW", 0x3401}, // Arabic (Kuwait)
111 {"ar-LB", 0x3001}, // Arabic (Lebanon)
112 {"ar-LY", 0x1001}, // Arabic (Libya)
113 {"ar-MA", 0x1801}, // Arabic (Morocco)
114 {"ar-OM", 0x2001}, // Arabic (Oman)
115 {"ar-QA", 0x4001}, // Arabic (Qatar)
116 {"ar-SA", 0x401}, // Arabic (Saudi Arabia)
117 {"ar-SY", 0x2801}, // Arabic (Syria)
118 {"ar-TN", 0x1c01}, // Arabic (Tunisia)
119 {"ar-YE", 0x2401}, // Arabic (Yemen)
120 {"ar", 0x1}, // Arabic
121 {"arn-CL", 0x47a}, // Mapuche (Chile)
122 {"arn", 0x7a}, // Mapuche
123 {"as-IN", 0x44d}, // Assamese (India)
124 {"as", 0x4d}, // Assamese
125 {"az-Cyrl-AZ", 0x742c}, // Azerbaijani (Cyrillic, Azerbaijan)
126 {"az-Cyrl-AZ", 0x82c}, // Azerbaijani (Cyrillic, Azerbaijan)
127 {"az-Latn-AZ", 0x42c}, // Azerbaijani (Latin, Azerbaijan)
128 {"az-Latn-AZ", 0x782c}, // Azerbaijani (Latin, Azerbaijan)
129 {"az", 0x2c}, // Azerbaijani
130 {"ba-RU", 0x46d}, // Bashkir (Russia)
131 {"ba", 0x6d}, // Bashkir
132 {"be-BY", 0x423}, // Belarusian (Belarus)
133 {"be", 0x23}, // Belarusian
134 {"bg-BG", 0x402}, // Bulgarian (Bulgaria)
135 {"bg", 0x2}, // Bulgarian
136 {"bin-NG", 0x466}, // Edo (Nigeria)
137 {"bin", 0x66}, // Edo
138 {"bn-BD", 0x845}, // Bangla (Bangladesh)
139 {"bn-IN", 0x445}, // Bengali (India)
140 {"bn", 0x45}, // Bangla
141 {"bo-CN", 0x451}, // Tibetan (China)
142 {"bo", 0x51}, // Tibetan
143 {"br-FR", 0x47e}, // Breton (France)
144 {"br", 0x7e}, // Breton
145 {"bs-Cyrl-BA", 0x201a}, // Bosnian (Cyrillic, Bosnia and Herzegovina)
146 {"bs-Cyrl-BA", 0x641a}, // Bosnian (Cyrillic, Bosnia and Herzegovina)
147 {"bs-Latn-BA", 0x141a}, // Bosnian (Latin, Bosnia & Herzegovina)
148 {"bs-Latn-BA", 0x681a}, // Bosnian (Latin, Bosnia & Herzegovina)
149 {"bs-Latn-BA", 0x781a}, // Bosnian (Latin, Bosnia & Herzegovina)
150 {"ca-ES-valencia", 0x803}, // Valencian (Spain)
151 {"ca-ES", 0x403}, // Catalan (Catalan)
152 {"ca", 0x3}, // Catalan
153 {"chr-Cher-US", 0x45c}, // Cherokee (Cherokee, United States)
154 {"chr-Cher-US", 0x7c5c}, // Cherokee (Cherokee, United States)
155 {"chr", 0x5c}, // Cherokee
156 {"co-FR", 0x483}, // Corsican (France)
157 {"co", 0x83}, // Corsican
158 {"cs-CZ", 0x405}, // Czech (Czechia)
159 {"cs", 0x5}, // Czech
160 {"cy-GB", 0x452}, // Welsh (United Kingdom)
161 {"cy", 0x52}, // Welsh
162 {"da-DK", 0x406}, // Danish (Denmark)
163 {"da", 0x6}, // Danish
164 {"de-AT", 0xc07}, // German (Austria)
165 {"de-CH", 0x807}, // German (Switzerland)
166 {"de-DE", 0x407}, // German (Germany)
167 {"de-LI", 0x1407}, // German (Liechtenstein)
168 {"de-LU", 0x1007}, // German (Luxembourg)
169 {"de", 0x7}, // German
170 {"dsb-DE", 0x7c2e}, // Lower Sorbian (Germany)
171 {"dsb-DE", 0x82e}, // Lower Sorbian (Germany)
172 {"dv-MV", 0x465}, // Divehi (Maldives)
173 {"dv", 0x65}, // Divehi
174 {"dz-BT", 0xc51}, // Dzongkha (Bhutan)
175 {"el-GR", 0x408}, // Greek (Greece)
176 {"el", 0x8}, // Greek
177 {"en-029", 0x2409}, // English (Caribbean)
178 {"en-AE", 0x4c09}, // English (United Arab Emirates)
179 {"en-AU", 0xc09}, // English (Australia)
180 {"en-BZ", 0x2809}, // English (Belize)
181 {"en-CA", 0x1009}, // English (Canada)
182 {"en-GB", 0x809}, // English (United Kingdom)
183 {"en-HK", 0x3c09}, // English (Hong Kong SAR)
184 {"en-ID", 0x3809}, // English (Indonesia)
185 {"en-IE", 0x1809}, // English (Ireland)
186 {"en-IN", 0x4009}, // English (India)
187 {"en-JM", 0x2009}, // English (Jamaica)
188 {"en-MY", 0x4409}, // English (Malaysia)
189 {"en-NZ", 0x1409}, // English (New Zealand)
190 {"en-PH", 0x3409}, // English (Philippines)
191 {"en-SG", 0x4809}, // English (Singapore)
192 {"en-TT", 0x2c09}, // English (Trinidad & Tobago)
193 {"en-US", 0x409}, // English (United States)
194 {"en-ZA", 0x1c09}, // English (South Africa)
195 {"en-ZW", 0x3009}, // English (Zimbabwe)
196 {"en", 0x9}, // English
197 {"es-419", 0x580a}, // Spanish (Latin America)
198 {"es-AR", 0x2c0a}, // Spanish (Argentina)
199 {"es-BO", 0x400a}, // Spanish (Bolivia)
200 {"es-CL", 0x340a}, // Spanish (Chile)
201 {"es-CO", 0x240a}, // Spanish (Colombia)
202 {"es-CR", 0x140a}, // Spanish (Costa Rica)
203 {"es-CU", 0x5c0a}, // Spanish (Cuba)
204 {"es-DO", 0x1c0a}, // Spanish (Dominican Republic)
205 {"es-EC", 0x300a}, // Spanish (Ecuador)
206 {"es-ES_tradnl", 0x40a}, // Spanish (Spain, Traditional Sort)
207 {"es-ES", 0xc0a}, // Spanish (Spain, International Sort)
208 {"es-GT", 0x100a}, // Spanish (Guatemala)
209 {"es-HN", 0x480a}, // Spanish (Honduras)
210 {"es-MX", 0x80a}, // Spanish (Mexico)
211 {"es-NI", 0x4c0a}, // Spanish (Nicaragua)
212 {"es-PA", 0x180a}, // Spanish (Panama)
213 {"es-PE", 0x280a}, // Spanish (Peru)
214 {"es-PR", 0x500a}, // Spanish (Puerto Rico)
215 {"es-PY", 0x3c0a}, // Spanish (Paraguay)
216 {"es-SV", 0x440a}, // Spanish (El Salvador)
217 {"es-US", 0x540a}, // Spanish (United States)
218 {"es-UY", 0x380a}, // Spanish (Uruguay)
219 {"es-VE", 0x200a}, // Spanish (Venezuela)
220 {"es", 0xa}, // Spanish
221 {"et-EE", 0x425}, // Estonian (Estonia)
222 {"et", 0x25}, // Estonian
223 {"eu-ES", 0x42d}, // Basque (Basque)
224 {"eu", 0x2d}, // Basque
225 {"fa-AF", 0x48c}, // Persian (Afghanistan)
226 {"fa-IR", 0x429}, // Persian (Iran)
227 {"fa", 0x29}, // Persian
228 {"fa", 0x8c}, // Persian
229 {"ff-Latn-NG", 0x467}, // Fulah (Latin, Nigeria)
230 {"ff-Latn-SN", 0x7c67}, // Fulah (Latin, Senegal)
231 {"ff-Latn-SN", 0x867}, // Fulah (Latin, Senegal)
232 {"ff", 0x67}, // Fulah
233 {"fi-FI", 0x40b}, // Finnish (Finland)
234 {"fi", 0xb}, // Finnish
235 {"fil-PH", 0x464}, // Filipino (Philippines)
236 {"fil", 0x64}, // Filipino
237 {"fo-FO", 0x438}, // Faroese (Faroe Islands)
238 {"fo", 0x38}, // Faroese
239 {"fr-029", 0x1c0c}, // French (Caribbean)
240 {"fr-BE", 0x80c}, // French (Belgium)
241 {"fr-CA", 0xc0c}, // French (Canada)
242 {"fr-CD", 0x240c}, // French Congo (DRC)
243 {"fr-CH", 0x100c}, // French (Switzerland)
244 {"fr-CI", 0x300c}, // French (Côte d’Ivoire)
245 {"fr-CM", 0x2c0c}, // French (Cameroon)
246 {"fr-FR", 0x40c}, // French (France)
247 {"fr-HT", 0x3c0c}, // French (Haiti)
248 {"fr-LU", 0x140c}, // French (Luxembourg)
249 {"fr-MA", 0x380c}, // French (Morocco)
250 {"fr-MC", 0x180c}, // French (Monaco)
251 {"fr-ML", 0x340c}, // French (Mali)
252 {"fr-RE", 0x200c}, // French (Réunion)
253 {"fr-SN", 0x280c}, // French (Senegal)
254 {"fr", 0xc}, // French
255 {"fy-NL", 0x462}, // Western Frisian (Netherlands)
256 {"fy", 0x62}, // Western Frisian
257 {"ga-IE", 0x83c}, // Irish (Ireland)
258 {"ga", 0x3c}, // Irish
259 {"gd-GB", 0x491}, // Scottish Gaelic (United Kingdom)
260 {"gd", 0x91}, // Scottish Gaelic
261 {"gl-ES", 0x456}, // Galician (Galician)
262 {"gl", 0x56}, // Galician
263 {"gn-PY", 0x474}, // Guarani (Paraguay)
264 {"gn", 0x74}, // Guarani
265 {"gsw-FR", 0x484}, // Alsatian (France)
266 {"gsw", 0x84}, // Swiss German
267 {"gu-IN", 0x447}, // Gujarati (India)
268 {"gu", 0x47}, // Gujarati
269 {"ha-Latn-NG", 0x468}, // Hausa (Latin, Nigeria)
270 {"ha-Latn-NG", 0x7c68}, // Hausa (Latin, Nigeria)
271 {"ha", 0x68}, // Hausa
272 {"haw-US", 0x475}, // Hawaiian (United States)
273 {"haw", 0x75}, // Hawaiian
274 {"he-IL", 0x40d}, // Hebrew (Israel)
275 {"he", 0xd}, // Hebrew
276 {"hi-IN", 0x439}, // Hindi (India)
277 {"hi", 0x39}, // Hindi
278 {"hr-BA", 0x101a}, // Croatian (Bosnia & Herzegovina)
279 {"hr-HR", 0x41a}, // Croatian (Croatia)
280 {"hr", 0x1a}, // Croatian
281 {"hsb-DE", 0x42e}, // Upper Sorbian (Germany)
282 {"hsb", 0x2e}, // Upper Sorbian
283 {"hu-HU", 0x40e}, // Hungarian (Hungary)
284 {"hu", 0xe}, // Hungarian
285 {"hy-AM", 0x42b}, // Armenian (Armenia)
286 {"hy", 0x2b}, // Armenian
287 {"ibb-NG", 0x469}, // Ibibio (Nigeria)
288 {"ibb", 0x69}, // Ibibio
289 {"id-ID", 0x421}, // Indonesian (Indonesia)
290 {"id", 0x21}, // Indonesian
291 {"ig-NG", 0x470}, // Igbo (Nigeria)
292 {"ig", 0x70}, // Igbo
293 {"ii-CN", 0x478}, // Yi (China)
294 {"ii", 0x78}, // Yi
295 {"is-IS", 0x40f}, // Icelandic (Iceland)
296 {"is", 0xf}, // Icelandic
297 {"it-CH", 0x810}, // Italian (Switzerland)
298 {"it-IT", 0x410}, // Italian (Italy)
299 {"it", 0x10}, // Italian
300 {"iu-Cans-CA", 0x45d}, // Inuktitut (Syllabics, Canada)
301 {"iu-Cans-CA", 0x785d}, // Inuktitut (Syllabics, Canada)
302 {"iu-Latn-CA", 0x7c5d}, // Inuktitut (Latin, Canada)
303 {"iu-Latn-CA", 0x85d}, // Inuktitut (Latin, Canada)
304 {"iu", 0x5d}, // Inuktitut
305 {"ja-JP", 0x411}, // Japanese (Japan)
306 {"ja", 0x11}, // Japanese
307 {"ka-GE", 0x437}, // Georgian (Georgia)
308 {"ka", 0x37}, // Georgian
309 {"kk-KZ", 0x43f}, // Kazakh (Kazakhstan)
310 {"kk", 0x3f}, // Kazakh
311 {"kl-GL", 0x46f}, // Kalaallisut (Greenland)
312 {"kl", 0x6f}, // Kalaallisut
313 {"km-KH", 0x453}, // Khmer (Cambodia)
314 {"km", 0x53}, // Khmer
315 {"kn-IN", 0x44b}, // Kannada (India)
316 {"kn", 0x4b}, // Kannada
317 {"ko-KR", 0x412}, // Korean (Korea)
318 {"ko", 0x12}, // Korean
319 {"kok-IN", 0x457}, // Konkani (India)
320 {"kok", 0x57}, // Konkani
321 {"kr-Latn-NG", 0x471}, // Kanuri (Latin, Nigeria)
322 {"kr", 0x71}, // Kanuri
323 {"ks-Arab-IN", 0x460}, // Kashmiri (Arabic)
324 {"ks-Deva-IN", 0x860}, // Kashmiri (Devanagari)
325 {"ks", 0x60}, // Kashmiri
326 {"ku-Arab-IQ", 0x492}, // Central Kurdish (Iraq)
327 {"ku-Arab-IQ", 0x7c92}, // Central Kurdish (Iraq)
328 {"ku", 0x92}, // Central Kurdish
329 {"ky-KG", 0x440}, // Kyrgyz (Kyrgyzstan)
330 {"ky", 0x40}, // Kyrgyz
331 {"la-VA", 0x476}, // Latin (Vatican City)
332 {"la", 0x76}, // Latin
333 {"lb-LU", 0x46e}, // Luxembourgish (Luxembourg)
334 {"lb", 0x6e}, // Luxembourgish
335 {"lo-LA", 0x454}, // Lao (Laos)
336 {"lo", 0x54}, // Lao
337 {"lt-LT", 0x427}, // Lithuanian (Lithuania)
338 {"lt", 0x27}, // Lithuanian
339 {"lv-LV", 0x426}, // Latvian (Latvia)
340 {"lv", 0x26}, // Latvian
341 {"mi-NZ", 0x481}, // Maori (New Zealand)
342 {"mi", 0x81}, // Maori
343 {"mk-MK", 0x42f}, // Macedonian (North Macedonia)
344 {"mk", 0x2f}, // Macedonian
345 {"ml-IN", 0x44c}, // Malayalam (India)
346 {"ml", 0x4c}, // Malayalam
347 {"mn-MN", 0x450}, // Mongolian (Mongolia)
348 {"mn-MN", 0x7850}, // Mongolian (Mongolia)
349 {"mn-Mong-CN", 0x7c50}, // Mongolian (Traditional Mongolian, China)
350 {"mn-Mong-CN", 0x850}, // Mongolian (Traditional Mongolian, China)
351 {"mn-Mong-MN", 0xc50}, // Mongolian (Traditional Mongolian, Mongolia)
352 {"mn", 0x50}, // Mongolian
353 {"mni-IN", 0x458}, // Manipuri (Bangla, India)
354 {"mni", 0x58}, // Manipuri
355 {"moh-CA", 0x47c}, // Mohawk (Canada)
356 {"moh", 0x7c}, // Mohawk
357 {"mr-IN", 0x44e}, // Marathi (India)
358 {"mr", 0x4e}, // Marathi
359 {"ms-BN", 0x83e}, // Malay (Brunei)
360 {"ms-MY", 0x43e}, // Malay (Malaysia)
361 {"ms", 0x3e}, // Malay
362 {"mt-MT", 0x43a}, // Maltese (Malta)
363 {"mt", 0x3a}, // Maltese
364 {"my-MM", 0x455}, // Burmese (Myanmar)
365 {"my", 0x55}, // Burmese
366 {"nb-NO", 0x414}, // Norwegian Bokmål (Norway)
367 {"nb-NO", 0x7c14}, // Norwegian Bokmål (Norway)
368 {"nb", 0x14}, // Norwegian Bokmål
369 {"ne-IN", 0x861}, // Nepali (India)
370 {"ne-NP", 0x461}, // Nepali (Nepal)
371 {"ne", 0x61}, // Nepali
372 {"nl-BE", 0x813}, // Dutch (Belgium)
373 {"nl-NL", 0x413}, // Dutch (Netherlands)
374 {"nl", 0x13}, // Dutch
375 {"nn-NO", 0x7814}, // Norwegian Nynorsk (Norway)
376 {"nn-NO", 0x814}, // Norwegian Nynorsk (Norway)
377 {"nso-ZA", 0x46c}, // Sesotho sa Leboa (South Africa)
378 {"nso", 0x6c}, // Sesotho sa Leboa
379 {"oc-FR", 0x482}, // Occitan (France)
380 {"oc", 0x82}, // Occitan
381 {"om-ET", 0x472}, // Oromo (Ethiopia)
382 {"om", 0x72}, // Oromo
383 {"or-IN", 0x448}, // Odia (India)
384 {"or", 0x48}, // Odia
385 {"pa-Arab-PK", 0x7c46}, // Punjabi (Pakistan)
386 {"pa-Arab-PK", 0x846}, // Punjabi (Pakistan)
387 {"pa-IN", 0x446}, // Punjabi (India)
388 {"pa", 0x46}, // Punjabi
389 {"pap-029", 0x479}, // Papiamento (Caribbean)
390 {"pap", 0x79}, // Papiamento
391 {"pl-PL", 0x415}, // Polish (Poland)
392 {"pl", 0x15}, // Polish
393 {"ps-AF", 0x463}, // Pashto (Afghanistan)
394 {"ps", 0x63}, // Pashto
395 {"pt-BR", 0x416}, // Portuguese (Brazil)
396 {"pt-PT", 0x816}, // Portuguese (Portugal)
397 {"pt", 0x16}, // Portuguese
398 {"qps-Latn-x-sh", 0x901}, // Pseudo (Pseudo Selfhost)
399 {"qps-ploc", 0x501}, // Pseudo (Pseudo)
400 {"qps-ploca", 0x5fe}, // Pseudo (Pseudo Asia)
401 {"qps-plocm", 0x9ff}, // Pseudo (Pseudo Mirrored)
402 {"quc-Latn-GT", 0x486}, // Kʼicheʼ (Latin, Guatemala)
403 {"quc-Latn-GT", 0x7c86}, // Kʼicheʼ (Latin, Guatemala)
404 {"quc", 0x86}, // Kʼicheʼ
405 {"quz-BO", 0x46b}, // Quechua (Bolivia)
406 {"quz-EC", 0x86b}, // Quechua (Ecuador)
407 {"quz-PE", 0xc6b}, // Quechua (Peru)
408 {"quz", 0x6b}, // Quechua
409 {"rm-CH", 0x417}, // Romansh (Switzerland)
410 {"rm", 0x17}, // Romansh
411 {"ro-MD", 0x818}, // Romanian (Moldova)
412 {"ro-RO", 0x418}, // Romanian (Romania)
413 {"ro", 0x18}, // Romanian
414 {"ru-MD", 0x819}, // Russian (Moldova)
415 {"ru-RU", 0x419}, // Russian (Russia)
416 {"ru", 0x19}, // Russian
417 {"rw-RW", 0x487}, // Kinyarwanda (Rwanda)
418 {"rw", 0x87}, // Kinyarwanda
419 {"sa-IN", 0x44f}, // Sanskrit (India)
420 {"sa", 0x4f}, // Sanskrit
421 {"sah-RU", 0x485}, // Sakha (Russia)
422 {"sah", 0x85}, // Sakha
423 {"sd-Arab-PK", 0x7c59}, // Sindhi (Pakistan)
424 {"sd-Arab-PK", 0x859}, // Sindhi (Pakistan)
425 {"sd-Deva-IN", 0x459}, // Sindhi (Devanagari, India)
426 {"sd", 0x59}, // Sindhi
427 {"se-FI", 0xc3b}, // Sami, Northern (Finland)
428 {"se-NO", 0x43b}, // Sami, Northern (Norway)
429 {"se-SE", 0x83b}, // Sami, Northern (Sweden)
430 {"se", 0x3b}, // Sami, Northern
431 {"si-LK", 0x45b}, // Sinhala (Sri Lanka)
432 {"si", 0x5b}, // Sinhala
433 {"sk-SK", 0x41b}, // Slovak (Slovakia)
434 {"sk", 0x1b}, // Slovak
435 {"sl-SI", 0x424}, // Slovenian (Slovenia)
436 {"sl", 0x24}, // Slovenian
437 {"sma-NO", 0x183b}, // Sami, Southern (Norway)
438 {"sma-SE", 0x1c3b}, // Sami, Southern (Sweden)
439 {"sma-SE", 0x783b}, // Sami, Southern (Sweden)
440 {"smj-NO", 0x103b}, // Sami, Lule (Norway)
441 {"smj-SE", 0x143b}, // Sami, Lule (Sweden)
442 {"smj-SE", 0x7c3b}, // Sami, Lule (Sweden)
443 {"smn-FI", 0x243b}, // Sami, Inari (Finland)
444 {"smn-FI", 0x703b}, // Sami, Inari (Finland)
445 {"sms-FI", 0x203b}, // Sami, Skolt (Finland)
446 {"sms-FI", 0x743b}, // Sami, Skolt (Finland)
447 {"so-SO", 0x477}, // Somali (Somalia)
448 {"so", 0x77}, // Somali
449 {"sq-AL", 0x41c}, // Albanian (Albania)
450 {"sq", 0x1c}, // Albanian
451 {"sr-Cyrl-BA", 0x1c1a}, // Serbian (Cyrillic, Bosnia and Herzegovina)
452 {"sr-Cyrl-CS", 0xc1a}, // Serbian (Cyrillic, Serbia and Montenegro (Former))
453 {"sr-Cyrl-ME", 0x301a}, // Serbian (Cyrillic, Montenegro)
454 {"sr-Cyrl-RS", 0x281a}, // Serbian (Cyrillic, Serbia)
455 {"sr-Cyrl-RS", 0x6c1a}, // Serbian (Cyrillic, Serbia)
456 {"sr-Latn-BA", 0x181a}, // Serbian (Latin, Bosnia & Herzegovina)
457 {"sr-Latn-CS", 0x81a}, // Serbian (Latin, Serbia and Montenegro (Former))
458 {"sr-Latn-ME", 0x2c1a}, // Serbian (Latin, Montenegro)
459 {"sr-Latn-RS", 0x241a}, // Serbian (Latin, Serbia)
460 {"sr-Latn-RS", 0x701a}, // Serbian (Latin, Serbia)
461 {"sr-Latn-RS", 0x7c1a}, // Serbian (Latin, Serbia)
462 {"st-ZA", 0x430}, // Sesotho (South Africa)
463 {"st", 0x30}, // Sesotho
464 {"sv-FI", 0x81d}, // Swedish (Finland)
465 {"sv-SE", 0x41d}, // Swedish (Sweden)
466 {"sv", 0x1d}, // Swedish
467 {"sw-KE", 0x441}, // Kiswahili (Kenya)
468 {"sw", 0x41}, // Kiswahili
469 {"syr-SY", 0x45a}, // Syriac (Syria)
470 {"syr", 0x5a}, // Syriac
471 {"ta-IN", 0x449}, // Tamil (India)
472 {"ta-LK", 0x849}, // Tamil (Sri Lanka)
473 {"ta", 0x49}, // Tamil
474 {"te-IN", 0x44a}, // Telugu (India)
475 {"te", 0x4a}, // Telugu
476 {"tg-Cyrl-TJ", 0x428}, // Tajik (Cyrillic, Tajikistan)
477 {"tg-Cyrl-TJ", 0x7c28}, // Tajik (Cyrillic, Tajikistan)
478 {"tg", 0x28}, // Tajik
479 {"th-TH", 0x41e}, // Thai (Thailand)
480 {"th", 0x1e}, // Thai
481 {"ti-ER", 0x873}, // Tigrinya (Eritrea)
482 {"ti-ET", 0x473}, // Tigrinya (Ethiopia)
483 {"ti", 0x73}, // Tigrinya
484 {"tk-TM", 0x442}, // Turkmen (Turkmenistan)
485 {"tk", 0x42}, // Turkmen
486 {"tn-BW", 0x832}, // Setswana (Botswana)
487 {"tn-ZA", 0x432}, // Setswana (South Africa)
488 {"tn", 0x32}, // Setswana
489 {"tr-TR", 0x41f}, // Turkish (Türkiye)
490 {"tr", 0x1f}, // Turkish
491 {"ts-ZA", 0x431}, // Xitsonga (South Africa)
492 {"ts", 0x31}, // Xitsonga
493 {"tt-RU", 0x444}, // Tatar (Russia)
494 {"tt", 0x44}, // Tatar
495 {"tzm-Arab-MA", 0x45f}, // Central Atlas Tamazight (Arabic, Morocco)
496 {"tzm-Latn-DZ", 0x7c5f}, // Central Atlas Tamazight (Latin, Algeria)
497 {"tzm-Latn-DZ", 0x85f}, // Central Atlas Tamazight (Latin, Algeria)
498 {"tzm-Tfng-MA", 0x105f}, // Central Atlas Tamazight (Tifinagh, Morocco)
499 {"tzm-Tfng-MA", 0x785f}, // Central Atlas Tamazight (Tifinagh, Morocco)
500 {"tzm", 0x5f}, // Central Atlas Tamazight
501 {"ug-CN", 0x480}, // Uyghur (China)
502 {"ug", 0x80}, // Uyghur
503 {"uk-UA", 0x422}, // Ukrainian (Ukraine)
504 {"uk", 0x22}, // Ukrainian
505 {"ur-IN", 0x820}, // Urdu (India)
506 {"ur-PK", 0x420}, // Urdu (Pakistan)
507 {"ur", 0x20}, // Urdu
508 {"uz-Cyrl-UZ", 0x7843}, // Uzbek (Cyrillic, Uzbekistan)
509 {"uz-Cyrl-UZ", 0x843}, // Uzbek (Cyrillic, Uzbekistan)
510 {"uz-Latn-UZ", 0x443}, // Uzbek (Latin, Uzbekistan)
511 {"uz-Latn-UZ", 0x7c43}, // Uzbek (Latin, Uzbekistan)
512 {"uz", 0x43}, // Uzbek
513 {"ve-ZA", 0x433}, // Venda (South Africa)
514 {"ve", 0x33}, // Venda
515 {"vi-VN", 0x42a}, // Vietnamese (Vietnam)
516 {"vi", 0x2a}, // Vietnamese
517 {"wo-SN", 0x488}, // Wolof (Senegal)
518 {"wo", 0x88}, // Wolof
519 {"xh-ZA", 0x434}, // isiXhosa (South Africa)
520 {"xh", 0x34}, // isiXhosa
521 {"yi-001", 0x43d}, // Yiddish (World)
522 {"yi", 0x3d}, // Yiddish
523 {"yo-NG", 0x46a}, // Yoruba (Nigeria)
524 {"yo", 0x6a}, // Yoruba
525 {"zh-CN", 0x7804}, // Chinese (Simplified, China)
526 {"zh-CN", 0x804}, // Chinese (Simplified, China)
527 {"zh-HK", 0x7c04}, // Chinese (Traditional, Hong Kong SAR)
528 {"zh-HK", 0xc04}, // Chinese (Traditional, Hong Kong SAR)
529 {"zh-MO", 0x1404}, // Chinese (Traditional, Macao SAR)
530 {"zh-SG", 0x1004}, // Chinese (Simplified, Singapore)
531 {"zh-TW", 0x404}, // Chinese (Traditional, Taiwan)
532 {"zh", 0x4}, // Chinese
533 {"zu-ZA", 0x435}, // isiZulu (South Africa)
534 {"zu", 0x35}, // isiZulu
535 };
536 if (auto el = languages.find(rfc1766); el != languages.end())
537 return static_cast<langid>(el->second);
538 return langid_unknown;
539 }
540
549 inline _Ret_maybenull_z_ const char* rfc1766_from_langid(_In_ langid lang, _In_opt_z_ const char* fallback = nullptr)
550 {
551 static const std::map<int, const char*> languages = {
552 {0x1, "ar"}, // Arabic
553 {0x401, "ar-SA"}, // Arabic (Saudi Arabia)
554 {0x801, "ar-IQ"}, // Arabic (Iraq)
555 {0xc01, "ar-EG"}, // Arabic (Egypt)
556 {0x1001, "ar-LY"}, // Arabic (Libya)
557 {0x1401, "ar-DZ"}, // Arabic (Algeria)
558 {0x1801, "ar-MA"}, // Arabic (Morocco)
559 {0x1c01, "ar-TN"}, // Arabic (Tunisia)
560 {0x2001, "ar-OM"}, // Arabic (Oman)
561 {0x2401, "ar-YE"}, // Arabic (Yemen)
562 {0x2801, "ar-SY"}, // Arabic (Syria)
563 {0x2c01, "ar-JO"}, // Arabic (Jordan)
564 {0x3001, "ar-LB"}, // Arabic (Lebanon)
565 {0x3401, "ar-KW"}, // Arabic (Kuwait)
566 {0x3801, "ar-AE"}, // Arabic (United Arab Emirates)
567 {0x3c01, "ar-BH"}, // Arabic (Bahrain)
568 {0x4001, "ar-QA"}, // Arabic (Qatar)
569 {0x2, "bg"}, // Bulgarian
570 {0x402, "bg-BG"}, // Bulgarian (Bulgaria)
571 {0x3, "ca"}, // Catalan
572 {0x403, "ca-ES"}, // Catalan (Catalan)
573 {0x803, "ca-ES-valencia"}, // Valencian (Spain)
574 {0x4, "zh"}, // Chinese
575 {0x404, "zh-TW"}, // Chinese (Traditional, Taiwan)
576 {0x804, "zh-CN"}, // Chinese (Simplified, China)
577 {0xc04, "zh-HK"}, // Chinese (Traditional, Hong Kong SAR)
578 {0x1004, "zh-SG"}, // Chinese (Simplified, Singapore)
579 {0x1404, "zh-MO"}, // Chinese (Traditional, Macao SAR)
580 {0x7804, "zh-CN"}, // Chinese (Simplified, China)
581 {0x7c04, "zh-HK"}, // Chinese (Traditional, Hong Kong SAR)
582 {0x5, "cs"}, // Czech
583 {0x405, "cs-CZ"}, // Czech (Czechia)
584 {0x6, "da"}, // Danish
585 {0x406, "da-DK"}, // Danish (Denmark)
586 {0x7, "de"}, // German
587 {0x407, "de-DE"}, // German (Germany)
588 {0x807, "de-CH"}, // German (Switzerland)
589 {0xc07, "de-AT"}, // German (Austria)
590 {0x1007, "de-LU"}, // German (Luxembourg)
591 {0x1407, "de-LI"}, // German (Liechtenstein)
592 {0x8, "el"}, // Greek
593 {0x408, "el-GR"}, // Greek (Greece)
594 {0x9, "en"}, // English
595 {0x409, "en-US"}, // English (United States)
596 {0x809, "en-GB"}, // English (United Kingdom)
597 {0xc09, "en-AU"}, // English (Australia)
598 {0x1009, "en-CA"}, // English (Canada)
599 {0x1409, "en-NZ"}, // English (New Zealand)
600 {0x1809, "en-IE"}, // English (Ireland)
601 {0x1c09, "en-ZA"}, // English (South Africa)
602 {0x2009, "en-JM"}, // English (Jamaica)
603 {0x2409, "en-029"}, // English (Caribbean)
604 {0x2809, "en-BZ"}, // English (Belize)
605 {0x2c09, "en-TT"}, // English (Trinidad & Tobago)
606 {0x3009, "en-ZW"}, // English (Zimbabwe)
607 {0x3409, "en-PH"}, // English (Philippines)
608 {0x3809, "en-ID"}, // English (Indonesia)
609 {0x3c09, "en-HK"}, // English (Hong Kong SAR)
610 {0x4009, "en-IN"}, // English (India)
611 {0x4409, "en-MY"}, // English (Malaysia)
612 {0x4809, "en-SG"}, // English (Singapore)
613 {0x4c09, "en-AE"}, // English (United Arab Emirates)
614 {0xa, "es"}, // Spanish
615 {0x40a, "es-ES_tradnl"}, // Spanish (Spain, Traditional Sort)
616 {0x80a, "es-MX"}, // Spanish (Mexico)
617 {0xc0a, "es-ES"}, // Spanish (Spain, International Sort)
618 {0x100a, "es-GT"}, // Spanish (Guatemala)
619 {0x140a, "es-CR"}, // Spanish (Costa Rica)
620 {0x180a, "es-PA"}, // Spanish (Panama)
621 {0x1c0a, "es-DO"}, // Spanish (Dominican Republic)
622 {0x200a, "es-VE"}, // Spanish (Venezuela)
623 {0x240a, "es-CO"}, // Spanish (Colombia)
624 {0x280a, "es-PE"}, // Spanish (Peru)
625 {0x2c0a, "es-AR"}, // Spanish (Argentina)
626 {0x300a, "es-EC"}, // Spanish (Ecuador)
627 {0x340a, "es-CL"}, // Spanish (Chile)
628 {0x380a, "es-UY"}, // Spanish (Uruguay)
629 {0x3c0a, "es-PY"}, // Spanish (Paraguay)
630 {0x400a, "es-BO"}, // Spanish (Bolivia)
631 {0x440a, "es-SV"}, // Spanish (El Salvador)
632 {0x480a, "es-HN"}, // Spanish (Honduras)
633 {0x4c0a, "es-NI"}, // Spanish (Nicaragua)
634 {0x500a, "es-PR"}, // Spanish (Puerto Rico)
635 {0x540a, "es-US"}, // Spanish (United States)
636 {0x580a, "es-419"}, // Spanish (Latin America)
637 {0x5c0a, "es-CU"}, // Spanish (Cuba)
638 {0xb, "fi"}, // Finnish
639 {0x40b, "fi-FI"}, // Finnish (Finland)
640 {0xc, "fr"}, // French
641 {0x40c, "fr-FR"}, // French (France)
642 {0x80c, "fr-BE"}, // French (Belgium)
643 {0xc0c, "fr-CA"}, // French (Canada)
644 {0x100c, "fr-CH"}, // French (Switzerland)
645 {0x140c, "fr-LU"}, // French (Luxembourg)
646 {0x180c, "fr-MC"}, // French (Monaco)
647 {0x1c0c, "fr-029"}, // French (Caribbean)
648 {0x200c, "fr-RE"}, // French (Réunion)
649 {0x240c, "fr-CD"}, // French Congo (DRC)
650 {0x280c, "fr-SN"}, // French (Senegal)
651 {0x2c0c, "fr-CM"}, // French (Cameroon)
652 {0x300c, "fr-CI"}, // French (Côte d’Ivoire)
653 {0x340c, "fr-ML"}, // French (Mali)
654 {0x380c, "fr-MA"}, // French (Morocco)
655 {0x3c0c, "fr-HT"}, // French (Haiti)
656 {0xd, "he"}, // Hebrew
657 {0x40d, "he-IL"}, // Hebrew (Israel)
658 {0xe, "hu"}, // Hungarian
659 {0x40e, "hu-HU"}, // Hungarian (Hungary)
660 {0xf, "is"}, // Icelandic
661 {0x40f, "is-IS"}, // Icelandic (Iceland)
662 {0x10, "it"}, // Italian
663 {0x410, "it-IT"}, // Italian (Italy)
664 {0x810, "it-CH"}, // Italian (Switzerland)
665 {0x11, "ja"}, // Japanese
666 {0x411, "ja-JP"}, // Japanese (Japan)
667 {0x12, "ko"}, // Korean
668 {0x412, "ko-KR"}, // Korean (Korea)
669 {0x13, "nl"}, // Dutch
670 {0x413, "nl-NL"}, // Dutch (Netherlands)
671 {0x813, "nl-BE"}, // Dutch (Belgium)
672 {0x14, "nb"}, // Norwegian Bokmål
673 {0x414, "nb-NO"}, // Norwegian Bokmål (Norway)
674 {0x814, "nn-NO"}, // Norwegian Nynorsk (Norway)
675 {0x7814, "nn-NO"}, // Norwegian Nynorsk (Norway)
676 {0x7c14, "nb-NO"}, // Norwegian Bokmål (Norway)
677 {0x15, "pl"}, // Polish
678 {0x415, "pl-PL"}, // Polish (Poland)
679 {0x16, "pt"}, // Portuguese
680 {0x416, "pt-BR"}, // Portuguese (Brazil)
681 {0x816, "pt-PT"}, // Portuguese (Portugal)
682 {0x17, "rm"}, // Romansh
683 {0x417, "rm-CH"}, // Romansh (Switzerland)
684 {0x18, "ro"}, // Romanian
685 {0x418, "ro-RO"}, // Romanian (Romania)
686 {0x818, "ro-MD"}, // Romanian (Moldova)
687 {0x19, "ru"}, // Russian
688 {0x419, "ru-RU"}, // Russian (Russia)
689 {0x819, "ru-MD"}, // Russian (Moldova)
690 {0x1a, "hr"}, // Croatian
691 {0x41a, "hr-HR"}, // Croatian (Croatia)
692 {0x81a, "sr-Latn-CS"}, // Serbian (Latin, Serbia and Montenegro (Former))
693 {0xc1a, "sr-Cyrl-CS"}, // Serbian (Cyrillic, Serbia and Montenegro (Former))
694 {0x101a, "hr-BA"}, // Croatian (Bosnia & Herzegovina)
695 {0x141a, "bs-Latn-BA"}, // Bosnian (Latin, Bosnia & Herzegovina)
696 {0x181a, "sr-Latn-BA"}, // Serbian (Latin, Bosnia & Herzegovina)
697 {0x1c1a, "sr-Cyrl-BA"}, // Serbian (Cyrillic, Bosnia and Herzegovina)
698 {0x201a, "bs-Cyrl-BA"}, // Bosnian (Cyrillic, Bosnia and Herzegovina)
699 {0x241a, "sr-Latn-RS"}, // Serbian (Latin, Serbia)
700 {0x281a, "sr-Cyrl-RS"}, // Serbian (Cyrillic, Serbia)
701 {0x2c1a, "sr-Latn-ME"}, // Serbian (Latin, Montenegro)
702 {0x301a, "sr-Cyrl-ME"}, // Serbian (Cyrillic, Montenegro)
703 {0x641a, "bs-Cyrl-BA"}, // Bosnian (Cyrillic, Bosnia and Herzegovina)
704 {0x681a, "bs-Latn-BA"}, // Bosnian (Latin, Bosnia & Herzegovina)
705 {0x6c1a, "sr-Cyrl-RS"}, // Serbian (Cyrillic, Serbia)
706 {0x701a, "sr-Latn-RS"}, // Serbian (Latin, Serbia)
707 {0x781a, "bs-Latn-BA"}, // Bosnian (Latin, Bosnia & Herzegovina)
708 {0x7c1a, "sr-Latn-RS"}, // Serbian (Latin, Serbia)
709 {0x1b, "sk"}, // Slovak
710 {0x41b, "sk-SK"}, // Slovak (Slovakia)
711 {0x1c, "sq"}, // Albanian
712 {0x41c, "sq-AL"}, // Albanian (Albania)
713 {0x1d, "sv"}, // Swedish
714 {0x41d, "sv-SE"}, // Swedish (Sweden)
715 {0x81d, "sv-FI"}, // Swedish (Finland)
716 {0x1e, "th"}, // Thai
717 {0x41e, "th-TH"}, // Thai (Thailand)
718 {0x1f, "tr"}, // Turkish
719 {0x41f, "tr-TR"}, // Turkish (Türkiye)
720 {0x20, "ur"}, // Urdu
721 {0x420, "ur-PK"}, // Urdu (Pakistan)
722 {0x820, "ur-IN"}, // Urdu (India)
723 {0x21, "id"}, // Indonesian
724 {0x421, "id-ID"}, // Indonesian (Indonesia)
725 {0x22, "uk"}, // Ukrainian
726 {0x422, "uk-UA"}, // Ukrainian (Ukraine)
727 {0x23, "be"}, // Belarusian
728 {0x423, "be-BY"}, // Belarusian (Belarus)
729 {0x24, "sl"}, // Slovenian
730 {0x424, "sl-SI"}, // Slovenian (Slovenia)
731 {0x25, "et"}, // Estonian
732 {0x425, "et-EE"}, // Estonian (Estonia)
733 {0x26, "lv"}, // Latvian
734 {0x426, "lv-LV"}, // Latvian (Latvia)
735 {0x27, "lt"}, // Lithuanian
736 {0x427, "lt-LT"}, // Lithuanian (Lithuania)
737 {0x28, "tg"}, // Tajik
738 {0x428, "tg-Cyrl-TJ"}, // Tajik (Cyrillic, Tajikistan)
739 {0x7c28, "tg-Cyrl-TJ"}, // Tajik (Cyrillic, Tajikistan)
740 {0x29, "fa"}, // Persian
741 {0x429, "fa-IR"}, // Persian (Iran)
742 {0x2a, "vi"}, // Vietnamese
743 {0x42a, "vi-VN"}, // Vietnamese (Vietnam)
744 {0x2b, "hy"}, // Armenian
745 {0x42b, "hy-AM"}, // Armenian (Armenia)
746 {0x2c, "az"}, // Azerbaijani
747 {0x42c, "az-Latn-AZ"}, // Azerbaijani (Latin, Azerbaijan)
748 {0x82c, "az-Cyrl-AZ"}, // Azerbaijani (Cyrillic, Azerbaijan)
749 {0x742c, "az-Cyrl-AZ"}, // Azerbaijani (Cyrillic, Azerbaijan)
750 {0x782c, "az-Latn-AZ"}, // Azerbaijani (Latin, Azerbaijan)
751 {0x2d, "eu"}, // Basque
752 {0x42d, "eu-ES"}, // Basque (Basque)
753 {0x2e, "hsb"}, // Upper Sorbian
754 {0x42e, "hsb-DE"}, // Upper Sorbian (Germany)
755 {0x82e, "dsb-DE"}, // Lower Sorbian (Germany)
756 {0x7c2e, "dsb-DE"}, // Lower Sorbian (Germany)
757 {0x2f, "mk"}, // Macedonian
758 {0x42f, "mk-MK"}, // Macedonian (North Macedonia)
759 {0x30, "st"}, // Sesotho
760 {0x430, "st-ZA"}, // Sesotho (South Africa)
761 {0x31, "ts"}, // Xitsonga
762 {0x431, "ts-ZA"}, // Xitsonga (South Africa)
763 {0x32, "tn"}, // Setswana
764 {0x432, "tn-ZA"}, // Setswana (South Africa)
765 {0x832, "tn-BW"}, // Setswana (Botswana)
766 {0x33, "ve"}, // Venda
767 {0x433, "ve-ZA"}, // Venda (South Africa)
768 {0x34, "xh"}, // isiXhosa
769 {0x434, "xh-ZA"}, // isiXhosa (South Africa)
770 {0x35, "zu"}, // isiZulu
771 {0x435, "zu-ZA"}, // isiZulu (South Africa)
772 {0x36, "af"}, // Afrikaans
773 {0x436, "af-ZA"}, // Afrikaans (South Africa)
774 {0x37, "ka"}, // Georgian
775 {0x437, "ka-GE"}, // Georgian (Georgia)
776 {0x38, "fo"}, // Faroese
777 {0x438, "fo-FO"}, // Faroese (Faroe Islands)
778 {0x39, "hi"}, // Hindi
779 {0x439, "hi-IN"}, // Hindi (India)
780 {0x3a, "mt"}, // Maltese
781 {0x43a, "mt-MT"}, // Maltese (Malta)
782 {0x3b, "se"}, // Sami, Northern
783 {0x43b, "se-NO"}, // Sami, Northern (Norway)
784 {0x83b, "se-SE"}, // Sami, Northern (Sweden)
785 {0xc3b, "se-FI"}, // Sami, Northern (Finland)
786 {0x103b, "smj-NO"}, // Sami, Lule (Norway)
787 {0x143b, "smj-SE"}, // Sami, Lule (Sweden)
788 {0x183b, "sma-NO"}, // Sami, Southern (Norway)
789 {0x1c3b, "sma-SE"}, // Sami, Southern (Sweden)
790 {0x203b, "sms-FI"}, // Sami, Skolt (Finland)
791 {0x243b, "smn-FI"}, // Sami, Inari (Finland)
792 {0x703b, "smn-FI"}, // Sami, Inari (Finland)
793 {0x743b, "sms-FI"}, // Sami, Skolt (Finland)
794 {0x783b, "sma-SE"}, // Sami, Southern (Sweden)
795 {0x7c3b, "smj-SE"}, // Sami, Lule (Sweden)
796 {0x3c, "ga"}, // Irish
797 {0x83c, "ga-IE"}, // Irish (Ireland)
798 {0x3d, "yi"}, // Yiddish
799 {0x43d, "yi-001"}, // Yiddish (World)
800 {0x3e, "ms"}, // Malay
801 {0x43e, "ms-MY"}, // Malay (Malaysia)
802 {0x83e, "ms-BN"}, // Malay (Brunei)
803 {0x3f, "kk"}, // Kazakh
804 {0x43f, "kk-KZ"}, // Kazakh (Kazakhstan)
805 {0x40, "ky"}, // Kyrgyz
806 {0x440, "ky-KG"}, // Kyrgyz (Kyrgyzstan)
807 {0x41, "sw"}, // Kiswahili
808 {0x441, "sw-KE"}, // Kiswahili (Kenya)
809 {0x42, "tk"}, // Turkmen
810 {0x442, "tk-TM"}, // Turkmen (Turkmenistan)
811 {0x43, "uz"}, // Uzbek
812 {0x443, "uz-Latn-UZ"}, // Uzbek (Latin, Uzbekistan)
813 {0x843, "uz-Cyrl-UZ"}, // Uzbek (Cyrillic, Uzbekistan)
814 {0x7843, "uz-Cyrl-UZ"}, // Uzbek (Cyrillic, Uzbekistan)
815 {0x7c43, "uz-Latn-UZ"}, // Uzbek (Latin, Uzbekistan)
816 {0x44, "tt"}, // Tatar
817 {0x444, "tt-RU"}, // Tatar (Russia)
818 {0x45, "bn"}, // Bangla
819 {0x445, "bn-IN"}, // Bengali (India)
820 {0x845, "bn-BD"}, // Bangla (Bangladesh)
821 {0x46, "pa"}, // Punjabi
822 {0x446, "pa-IN"}, // Punjabi (India)
823 {0x846, "pa-Arab-PK"}, // Punjabi (Pakistan)
824 {0x7c46, "pa-Arab-PK"}, // Punjabi (Pakistan)
825 {0x47, "gu"}, // Gujarati
826 {0x447, "gu-IN"}, // Gujarati (India)
827 {0x48, "or"}, // Odia
828 {0x448, "or-IN"}, // Odia (India)
829 {0x49, "ta"}, // Tamil
830 {0x449, "ta-IN"}, // Tamil (India)
831 {0x849, "ta-LK"}, // Tamil (Sri Lanka)
832 {0x4a, "te"}, // Telugu
833 {0x44a, "te-IN"}, // Telugu (India)
834 {0x4b, "kn"}, // Kannada
835 {0x44b, "kn-IN"}, // Kannada (India)
836 {0x4c, "ml"}, // Malayalam
837 {0x44c, "ml-IN"}, // Malayalam (India)
838 {0x4d, "as"}, // Assamese
839 {0x44d, "as-IN"}, // Assamese (India)
840 {0x4e, "mr"}, // Marathi
841 {0x44e, "mr-IN"}, // Marathi (India)
842 {0x4f, "sa"}, // Sanskrit
843 {0x44f, "sa-IN"}, // Sanskrit (India)
844 {0x50, "mn"}, // Mongolian
845 {0x450, "mn-MN"}, // Mongolian (Mongolia)
846 {0x850, "mn-Mong-CN"}, // Mongolian (Traditional Mongolian, China)
847 {0xc50, "mn-Mong-MN"}, // Mongolian (Traditional Mongolian, Mongolia)
848 {0x7850, "mn-MN"}, // Mongolian (Mongolia)
849 {0x7c50, "mn-Mong-CN"}, // Mongolian (Traditional Mongolian, China)
850 {0x51, "bo"}, // Tibetan
851 {0x451, "bo-CN"}, // Tibetan (China)
852 {0xc51, "dz-BT"}, // Dzongkha (Bhutan)
853 {0x52, "cy"}, // Welsh
854 {0x452, "cy-GB"}, // Welsh (United Kingdom)
855 {0x53, "km"}, // Khmer
856 {0x453, "km-KH"}, // Khmer (Cambodia)
857 {0x54, "lo"}, // Lao
858 {0x454, "lo-LA"}, // Lao (Laos)
859 {0x55, "my"}, // Burmese
860 {0x455, "my-MM"}, // Burmese (Myanmar)
861 {0x56, "gl"}, // Galician
862 {0x456, "gl-ES"}, // Galician (Galician)
863 {0x57, "kok"}, // Konkani
864 {0x457, "kok-IN"}, // Konkani (India)
865 {0x58, "mni"}, // Manipuri
866 {0x458, "mni-IN"}, // Manipuri (Bangla, India)
867 {0x59, "sd"}, // Sindhi
868 {0x459, "sd-Deva-IN"}, // Sindhi (Devanagari, India)
869 {0x859, "sd-Arab-PK"}, // Sindhi (Pakistan)
870 {0x7c59, "sd-Arab-PK"}, // Sindhi (Pakistan)
871 {0x5a, "syr"}, // Syriac
872 {0x45a, "syr-SY"}, // Syriac (Syria)
873 {0x5b, "si"}, // Sinhala
874 {0x45b, "si-LK"}, // Sinhala (Sri Lanka)
875 {0x5c, "chr"}, // Cherokee
876 {0x45c, "chr-Cher-US"}, // Cherokee (Cherokee, United States)
877 {0x7c5c, "chr-Cher-US"}, // Cherokee (Cherokee, United States)
878 {0x5d, "iu"}, // Inuktitut
879 {0x45d, "iu-Cans-CA"}, // Inuktitut (Syllabics, Canada)
880 {0x85d, "iu-Latn-CA"}, // Inuktitut (Latin, Canada)
881 {0x785d, "iu-Cans-CA"}, // Inuktitut (Syllabics, Canada)
882 {0x7c5d, "iu-Latn-CA"}, // Inuktitut (Latin, Canada)
883 {0x5e, "am"}, // Amharic
884 {0x45e, "am-ET"}, // Amharic (Ethiopia)
885 {0x5f, "tzm"}, // Central Atlas Tamazight
886 {0x45f, "tzm-Arab-MA"}, // Central Atlas Tamazight (Arabic, Morocco)
887 {0x85f, "tzm-Latn-DZ"}, // Central Atlas Tamazight (Latin, Algeria)
888 {0x105f, "tzm-Tfng-MA"}, // Central Atlas Tamazight (Tifinagh, Morocco)
889 {0x785f, "tzm-Tfng-MA"}, // Central Atlas Tamazight (Tifinagh, Morocco)
890 {0x7c5f, "tzm-Latn-DZ"}, // Central Atlas Tamazight (Latin, Algeria)
891 {0x60, "ks"}, // Kashmiri
892 {0x460, "ks-Arab-IN"}, // Kashmiri (Arabic)
893 {0x860, "ks-Deva-IN"}, // Kashmiri (Devanagari)
894 {0x61, "ne"}, // Nepali
895 {0x461, "ne-NP"}, // Nepali (Nepal)
896 {0x861, "ne-IN"}, // Nepali (India)
897 {0x62, "fy"}, // Western Frisian
898 {0x462, "fy-NL"}, // Western Frisian (Netherlands)
899 {0x63, "ps"}, // Pashto
900 {0x463, "ps-AF"}, // Pashto (Afghanistan)
901 {0x64, "fil"}, // Filipino
902 {0x464, "fil-PH"}, // Filipino (Philippines)
903 {0x65, "dv"}, // Divehi
904 {0x465, "dv-MV"}, // Divehi (Maldives)
905 {0x66, "bin"}, // Edo
906 {0x466, "bin-NG"}, // Edo (Nigeria)
907 {0x67, "ff"}, // Fulah
908 {0x467, "ff-Latn-NG"}, // Fulah (Latin, Nigeria)
909 {0x867, "ff-Latn-SN"}, // Fulah (Latin, Senegal)
910 {0x7c67, "ff-Latn-SN"}, // Fulah (Latin, Senegal)
911 {0x68, "ha"}, // Hausa
912 {0x468, "ha-Latn-NG"}, // Hausa (Latin, Nigeria)
913 {0x7c68, "ha-Latn-NG"}, // Hausa (Latin, Nigeria)
914 {0x69, "ibb"}, // Ibibio
915 {0x469, "ibb-NG"}, // Ibibio (Nigeria)
916 {0x6a, "yo"}, // Yoruba
917 {0x46a, "yo-NG"}, // Yoruba (Nigeria)
918 {0x6b, "quz"}, // Quechua
919 {0x46b, "quz-BO"}, // Quechua (Bolivia)
920 {0x86b, "quz-EC"}, // Quechua (Ecuador)
921 {0xc6b, "quz-PE"}, // Quechua (Peru)
922 {0x6c, "nso"}, // Sesotho sa Leboa
923 {0x46c, "nso-ZA"}, // Sesotho sa Leboa (South Africa)
924 {0x6d, "ba"}, // Bashkir
925 {0x46d, "ba-RU"}, // Bashkir (Russia)
926 {0x6e, "lb"}, // Luxembourgish
927 {0x46e, "lb-LU"}, // Luxembourgish (Luxembourg)
928 {0x6f, "kl"}, // Kalaallisut
929 {0x46f, "kl-GL"}, // Kalaallisut (Greenland)
930 {0x70, "ig"}, // Igbo
931 {0x470, "ig-NG"}, // Igbo (Nigeria)
932 {0x71, "kr"}, // Kanuri
933 {0x471, "kr-Latn-NG"}, // Kanuri (Latin, Nigeria)
934 {0x72, "om"}, // Oromo
935 {0x472, "om-ET"}, // Oromo (Ethiopia)
936 {0x73, "ti"}, // Tigrinya
937 {0x473, "ti-ET"}, // Tigrinya (Ethiopia)
938 {0x873, "ti-ER"}, // Tigrinya (Eritrea)
939 {0x74, "gn"}, // Guarani
940 {0x474, "gn-PY"}, // Guarani (Paraguay)
941 {0x75, "haw"}, // Hawaiian
942 {0x475, "haw-US"}, // Hawaiian (United States)
943 {0x76, "la"}, // Latin
944 {0x476, "la-VA"}, // Latin (Vatican City)
945 {0x77, "so"}, // Somali
946 {0x477, "so-SO"}, // Somali (Somalia)
947 {0x78, "ii"}, // Yi
948 {0x478, "ii-CN"}, // Yi (China)
949 {0x79, "pap"}, // Papiamento
950 {0x479, "pap-029"}, // Papiamento (Caribbean)
951 {0x7a, "arn"}, // Mapuche
952 {0x47a, "arn-CL"}, // Mapuche (Chile)
953 {0x7c, "moh"}, // Mohawk
954 {0x47c, "moh-CA"}, // Mohawk (Canada)
955 {0x7e, "br"}, // Breton
956 {0x47e, "br-FR"}, // Breton (France)
957 {0x80, "ug"}, // Uyghur
958 {0x480, "ug-CN"}, // Uyghur (China)
959 {0x81, "mi"}, // Maori
960 {0x481, "mi-NZ"}, // Maori (New Zealand)
961 {0x82, "oc"}, // Occitan
962 {0x482, "oc-FR"}, // Occitan (France)
963 {0x83, "co"}, // Corsican
964 {0x483, "co-FR"}, // Corsican (France)
965 {0x84, "gsw"}, // Swiss German
966 {0x484, "gsw-FR"}, // Alsatian (France)
967 {0x85, "sah"}, // Sakha
968 {0x485, "sah-RU"}, // Sakha (Russia)
969 {0x86, "quc"}, // Kʼicheʼ
970 {0x486, "quc-Latn-GT"}, // Kʼicheʼ (Latin, Guatemala)
971 {0x7c86, "quc-Latn-GT"}, // Kʼicheʼ (Latin, Guatemala)
972 {0x87, "rw"}, // Kinyarwanda
973 {0x487, "rw-RW"}, // Kinyarwanda (Rwanda)
974 {0x88, "wo"}, // Wolof
975 {0x488, "wo-SN"}, // Wolof (Senegal)
976 {0x8c, "fa"}, // Persian
977 {0x48c, "fa-AF"}, // Persian (Afghanistan)
978 {0x91, "gd"}, // Scottish Gaelic
979 {0x491, "gd-GB"}, // Scottish Gaelic (United Kingdom)
980 {0x92, "ku"}, // Central Kurdish
981 {0x492, "ku-Arab-IQ"}, // Central Kurdish (Iraq)
982 {0x7c92, "ku-Arab-IQ"}, // Central Kurdish (Iraq)
983 {0x501, "qps-ploc"}, // Pseudo (Pseudo)
984 {0x901, "qps-Latn-x-sh"}, // Pseudo (Pseudo Selfhost)
985 {0x5fe, "qps-ploca"}, // Pseudo (Pseudo Asia)
986 {0x9ff, "qps-plocm"}, // Pseudo (Pseudo Mirrored)
987 };
988 if (auto el = languages.find(lang); el != languages.end())
989 return el->second;
990 return fallback;
991 }
992}
993
994#if defined(__GNUC__)
995#pragma GCC diagnostic pop
996#endif