HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
iso_3166_impl.hpp
1// Copyright Take Vos 2022.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "iso_3166_intf.hpp"
8#include "../utility/utility.hpp"
9#include "../algorithm/module.hpp"
10#include "../macros.hpp"
11#include <array>
12
13hi_export_module(hikogui.i18n.iso_3166 : impl);
14
15namespace hi::inline v1 {
16namespace detail {
17
19 fixed_string<2> code2;
20 fixed_string<3> code3;
21 uint16_t number;
22};
23
28[[nodiscard]] consteval auto iso_3166_infos_init() noexcept
29{
30 // We are using a c-style array to std::array conversion because
31 // compilers, tools and analysers do not handle large std::array constructors.
32
33 // clang-format off
34 constexpr iso_3166_info data[] = {
35 {"AF", "AFG", 4},
36 {"AL", "ALB", 8},
37 {"AQ", "ATA", 10},
38 {"DZ", "DZA", 12},
39 {"AS", "ASM", 16},
40 {"AD", "AND", 20},
41 {"AO", "AGO", 24},
42 {"AG", "ATG", 28},
43 {"AZ", "AZE", 31},
44 {"AR", "ARG", 32},
45 {"AU", "AUS", 36},
46 {"AT", "AUT", 40},
47 {"BS", "BHS", 44},
48 {"BH", "BHR", 48},
49 {"BD", "BGD", 50},
50 {"AM", "ARM", 51},
51 {"BB", "BRB", 52},
52 {"BE", "BEL", 56},
53 {"BM", "BMU", 60},
54 {"BT", "BTN", 64},
55 {"BO", "BOL", 68},
56 {"BA", "BIH", 70},
57 {"BW", "BWA", 72},
58 {"BV", "BVT", 74},
59 {"BR", "BRA", 76},
60 {"BZ", "BLZ", 84},
61 {"IO", "IOT", 86},
62 {"SB", "SLB", 90},
63 {"VG", "VGB", 92},
64 {"BN", "BRN", 96},
65 {"BG", "BGR", 100},
66 {"MM", "MMR", 104},
67 {"BI", "BDI", 108},
68 {"BY", "BLR", 112},
69 {"KH", "KHM", 116},
70 {"CM", "CMR", 120},
71 {"CA", "CAN", 124},
72 {"CV", "CPV", 132},
73 {"KY", "CYM", 136},
74 {"CF", "CAF", 140},
75 {"LK", "LKA", 144},
76 {"TD", "TCD", 148},
77 {"CL", "CHL", 152},
78 {"CN", "CHN", 156},
79 {"TW", "TWN", 158},
80 {"CX", "CXR", 162},
81 {"CC", "CCK", 166},
82 {"CO", "COL", 170},
83 {"KM", "COM", 174},
84 {"YT", "MYT", 175},
85 {"CG", "COG", 178},
86 {"CD", "COD", 180},
87 {"CK", "COK", 184},
88 {"CR", "CRI", 188},
89 {"HR", "HRV", 191},
90 {"CU", "CUB", 192},
91 {"CY", "CYP", 196},
92 {"CZ", "CZE", 203},
93 {"BJ", "BEN", 204},
94 {"DK", "DNK", 208},
95 {"DM", "DMA", 212},
96 {"DO", "DOM", 214},
97 {"EC", "ECU", 218},
98 {"SV", "SLV", 222},
99 {"GQ", "GNQ", 226},
100 {"ET", "ETH", 231},
101 {"ER", "ERI", 232},
102 {"EE", "EST", 233},
103 {"FO", "FRO", 234},
104 {"FK", "FLK", 238},
105 {"GS", "SGS", 239},
106 {"FJ", "FJI", 242},
107 {"FI", "FIN", 246},
108 {"AX", "ALA", 248},
109 {"FR", "FRA", 250},
110 {"GF", "GUF", 254},
111 {"PF", "PYF", 258},
112 {"TF", "ATF", 260},
113 {"DJ", "DJI", 262},
114 {"GA", "GAB", 266},
115 {"GE", "GEO", 268},
116 {"GM", "GMB", 270},
117 {"PS", "PSE", 275},
118 {"DE", "DEU", 276},
119 {"GH", "GHA", 288},
120 {"GI", "GIB", 292},
121 {"KI", "KIR", 296},
122 {"GR", "GRC", 300},
123 {"GL", "GRL", 304},
124 {"GD", "GRD", 308},
125 {"GP", "GLP", 312},
126 {"GU", "GUM", 316},
127 {"GT", "GTM", 320},
128 {"GN", "GIN", 324},
129 {"GY", "GUY", 328},
130 {"HT", "HTI", 332},
131 {"HM", "HMD", 334},
132 {"VA", "VAT", 336},
133 {"HN", "HND", 340},
134 {"HK", "HKG", 344},
135 {"HU", "HUN", 348},
136 {"IS", "ISL", 352},
137 {"IN", "IND", 356},
138 {"ID", "IDN", 360},
139 {"IR", "IRN", 364},
140 {"IQ", "IRQ", 368},
141 {"IE", "IRL", 372},
142 {"IL", "ISR", 376},
143 {"IT", "ITA", 380},
144 {"CI", "CIV", 384},
145 {"JM", "JAM", 388},
146 {"JP", "JPN", 392},
147 {"KZ", "KAZ", 398},
148 {"JO", "JOR", 400},
149 {"KE", "KEN", 404},
150 {"KP", "PRK", 408},
151 {"KR", "KOR", 410},
152 {"KW", "KWT", 414},
153 {"KG", "KGZ", 417},
154 {"LA", "LAO", 418},
155 {"LB", "LBN", 422},
156 {"LS", "LSO", 426},
157 {"LV", "LVA", 428},
158 {"LR", "LBR", 430},
159 {"LY", "LBY", 434},
160 {"LI", "LIE", 438},
161 {"LT", "LTU", 440},
162 {"LU", "LUX", 442},
163 {"MO", "MAC", 446},
164 {"MG", "MDG", 450},
165 {"MW", "MWI", 454},
166 {"MY", "MYS", 458},
167 {"MV", "MDV", 462},
168 {"ML", "MLI", 466},
169 {"MT", "MLT", 470},
170 {"MQ", "MTQ", 474},
171 {"MR", "MRT", 478},
172 {"MU", "MUS", 480},
173 {"MX", "MEX", 484},
174 {"MC", "MCO", 492},
175 {"MN", "MNG", 496},
176 {"MD", "MDA", 498},
177 {"ME", "MNE", 499},
178 {"MS", "MSR", 500},
179 {"MA", "MAR", 504},
180 {"MZ", "MOZ", 508},
181 {"OM", "OMN", 512},
182 {"NA", "NAM", 516},
183 {"NR", "NRU", 520},
184 {"NP", "NPL", 524},
185 {"NL", "NLD", 528},
186 {"CW", "CUW", 531},
187 {"AW", "ABW", 533},
188 {"SX", "SXM", 534},
189 {"BQ", "BES", 535},
190 {"NC", "NCL", 540},
191 {"VU", "VUT", 548},
192 {"NZ", "NZL", 554},
193 {"NI", "NIC", 558},
194 {"NE", "NER", 562},
195 {"NG", "NGA", 566},
196 {"NU", "NIU", 570},
197 {"NF", "NFK", 574},
198 {"NO", "NOR", 578},
199 {"MP", "MNP", 580},
200 {"UM", "UMI", 581},
201 {"FM", "FSM", 583},
202 {"MH", "MHL", 584},
203 {"PW", "PLW", 585},
204 {"PK", "PAK", 586},
205 {"PA", "PAN", 591},
206 {"PG", "PNG", 598},
207 {"PY", "PRY", 600},
208 {"PE", "PER", 604},
209 {"PH", "PHL", 608},
210 {"PN", "PCN", 612},
211 {"PL", "POL", 616},
212 {"PT", "PRT", 620},
213 {"GW", "GNB", 624},
214 {"TL", "TLS", 626},
215 {"PR", "PRI", 630},
216 {"QA", "QAT", 634},
217 {"RE", "REU", 638},
218 {"RO", "ROU", 642},
219 {"RU", "RUS", 643},
220 {"RW", "RWA", 646},
221 {"BL", "BLM", 652},
222 {"SH", "SHN", 654},
223 {"KN", "KNA", 659},
224 {"AI", "AIA", 660},
225 {"LC", "LCA", 662},
226 {"MF", "MAF", 663},
227 {"PM", "SPM", 666},
228 {"VC", "VCT", 670},
229 {"SM", "SMR", 674},
230 {"ST", "STP", 678},
231 {"SA", "SAU", 682},
232 {"SN", "SEN", 686},
233 {"RS", "SRB", 688},
234 {"SC", "SYC", 690},
235 {"SL", "SLE", 694},
236 {"SG", "SGP", 702},
237 {"SK", "SVK", 703},
238 {"VN", "VNM", 704},
239 {"SI", "SVN", 705},
240 {"SO", "SOM", 706},
241 {"ZA", "ZAF", 710},
242 {"ZW", "ZWE", 716},
243 {"ES", "ESP", 724},
244 {"SS", "SSD", 728},
245 {"SD", "SDN", 729},
246 {"EH", "ESH", 732},
247 {"SR", "SUR", 740},
248 {"SJ", "SJM", 744},
249 {"SZ", "SWZ", 748},
250 {"SE", "SWE", 752},
251 {"CH", "CHE", 756},
252 {"SY", "SYR", 760},
253 {"TJ", "TJK", 762},
254 {"TH", "THA", 764},
255 {"TG", "TGO", 768},
256 {"TK", "TKL", 772},
257 {"TO", "TON", 776},
258 {"TT", "TTO", 780},
259 {"AE", "ARE", 784},
260 {"TN", "TUN", 788},
261 {"TR", "TUR", 792},
262 {"TM", "TKM", 795},
263 {"TC", "TCA", 796},
264 {"TV", "TUV", 798},
265 {"UG", "UGA", 800},
266 {"UA", "UKR", 804},
267 {"MK", "MKD", 807},
268 {"EG", "EGY", 818},
269 {"GB", "GBR", 826},
270 {"GG", "GGY", 831},
271 {"JE", "JEY", 832},
272 {"IM", "IMN", 833},
273 {"TZ", "TZA", 834},
274 {"US", "USA", 840},
275 {"VI", "VIR", 850},
276 {"BF", "BFA", 854},
277 {"UY", "URY", 858},
278 {"UZ", "UZB", 860},
279 {"VE", "VEN", 862},
280 {"WF", "WLF", 876},
281 {"WS", "WSM", 882},
282 {"YE", "YEM", 887},
283 {"ZM", "ZMB", 894}};
284 // clang-format on
285 constexpr auto data_size = sizeof(data) / sizeof(data[0]);
286
288
289 for (auto i = 0_uz; i != data_size; ++i) {
290 r[i] = data[i];
291 }
292
293 return r;
294}
295
296constexpr auto iso_3166_infos = iso_3166_infos_init();
297
298[[nodiscard]] consteval auto iso_3166_code2_by_number_init() noexcept
299{
300 auto r = std::array<fixed_string<2>, 1000>{};
301 for (auto i = 0_uz; i != r.size(); ++i) {
302 r[i] = "ZZ";
303 }
304
305 for (hilet& info : iso_3166_infos) {
306 r[info.number] = info.code2;
307 }
308 return r;
309}
310
311[[nodiscard]] consteval auto iso_3166_code3_by_number_init() noexcept
312{
313 auto r = std::array<fixed_string<3>, 1000>{};
314 for (auto i = 0_uz; i != r.size(); ++i) {
315 r[i] = "ZZZ";
316 }
317
318 for (hilet& info : iso_3166_infos) {
319 r[info.number] = info.code3;
320 }
321 return r;
322}
323
324[[nodiscard]] consteval auto iso_3166_number_by_code2_init() noexcept
325{
326 constexpr auto size = std::tuple_size_v<decltype(iso_3166_infos)>;
327 using type = std::pair<fixed_string<2>, uint16_t>;
328
329 auto r = std::array<type, size>{};
330 for (auto i = 0_uz; i != iso_3166_infos.size(); ++i) {
331 hilet& info = iso_3166_infos[i];
332 r[i] = {info.code2, info.number};
333 }
334
335 std::sort(r.begin(), r.end(), [](hilet& a, hilet& b) {
336 return a.first < b.first;
337 });
338 return r;
339}
340
341[[nodiscard]] consteval auto iso_3166_number_by_code3_init() noexcept
342{
343 constexpr auto size = std::tuple_size_v<decltype(iso_3166_infos)>;
344 using type = std::pair<fixed_string<3>, uint16_t>;
345
346 auto r = std::array<type, size>{};
347 for (auto i = 0_uz; i != iso_3166_infos.size(); ++i) {
348 hilet& info = iso_3166_infos[i];
349 r[i] = {info.code3, info.number};
350 }
351
352 std::sort(r.begin(), r.end(), [](hilet& a, hilet& b) {
353 return a.first < b.first;
354 });
355 return r;
356}
357
358constexpr auto iso_3166_code2_by_number = iso_3166_code2_by_number_init();
359constexpr auto iso_3166_code3_by_number = iso_3166_code3_by_number_init();
360constexpr auto iso_3166_number_by_code2 = iso_3166_number_by_code2_init();
361constexpr auto iso_3166_number_by_code3 = iso_3166_number_by_code3_init();
362
363} // namespace detail
364
365constexpr iso_3166::iso_3166(std::string_view str)
366{
367 if (is_digit(str)) {
368 _v = from_string<uint16_t>(str);
369 hi_check(_v < 1000, "ISO-3166 number must be between 000 and 999, got '{}'", _v);
370
371 } else if (str.size() == 2) {
372 auto str_up = to_upper(str);
373
374 hilet it = std::lower_bound(
375 detail::iso_3166_number_by_code2.begin(),
376 detail::iso_3166_number_by_code2.end(),
377 str_up,
378 [](hilet& item, hilet& value) {
379 return item.first < value;
380 });
381
382 hi_check(
383 it != detail::iso_3166_number_by_code2.end() and it->first == str_up,
384 "Could not find ISO-3166 2 letter language code '{}'",
385 str);
386
387 _v = it->second;
388
389 } else if (str.size() == 3) {
390 auto str_up = to_upper(str);
391
392 hilet it = std::lower_bound(
393 detail::iso_3166_number_by_code3.begin(),
394 detail::iso_3166_number_by_code3.end(),
395 str_up,
396 [](hilet& item, hilet& value) {
397 return item.first < value;
398 });
399
400 hi_check(
401 it != detail::iso_3166_number_by_code3.end() and it->first == str_up,
402 "Could not find ISO-3166 3 letter language code '{}'",
403 str);
404
405 _v = it->second;
406
407 } else {
408 throw parse_error(std::format("Could not parse ISO-3166 code '{}'", str));
409 }
410}
411
412[[nodiscard]] constexpr std::string iso_3166::code2() const noexcept
413{
414 hi_assert(_v < 1000);
415 return detail::iso_3166_code2_by_number[_v];
416}
417
418[[nodiscard]] constexpr std::string iso_3166::code3() const noexcept
419{
420 hi_assert(_v < 1000);
421 return detail::iso_3166_code3_by_number[_v];
422}
423
424} // namespace hi::inline v1
DOXYGEN BUG.
Definition algorithm.hpp:16
constexpr Out narrow_cast(In const &rhs) noexcept
Cast numeric values without loss of precision.
Definition cast.hpp:377
Definition iso_3166_impl.hpp:18
T begin(T... args)
T end(T... args)
T lower_bound(T... args)
T sort(T... args)