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