HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
unicode_plural.hpp
Go to the documentation of this file.
1// Copyright Take Vos 2023.
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
10#pragma once
11
12#include "../utility/utility.hpp"
13#include "../i18n/i18n.hpp"
14#include "../macros.hpp"
15#include <concepts>
16#include <array>
17#include <cstdint>
18#include <cstddef>
19
20
21
22namespace hi { inline namespace v1 {
23
26enum class plurality_value : uint8_t {
29 zero = 0,
30
33 one = 1,
34
37 two = 2,
38
41 few = 3,
42
45 many = 4,
46
49 other = 5
50};
51
54enum class plurality_mask : uint8_t {
57 zero = 1 << std::to_underlying(plurality_value::zero),
58
61 one = 1 << std::to_underlying(plurality_value::one),
62
65 two = 1 << std::to_underlying(plurality_value::two),
66
69 few = 1 << std::to_underlying(plurality_value::few),
70
73 many = 1 << std::to_underlying(plurality_value::many),
74
77 other = 1 << std::to_underlying(plurality_value::other),
78};
79
82[[nodiscard]] constexpr plurality_mask operator|(plurality_mask const& lhs, plurality_mask const& rhs) noexcept
83{
84 return static_cast<plurality_mask>(std::to_underlying(lhs) | std::to_underlying(rhs));
85}
86
89struct plurality {
90 plurality_value value;
91 plurality_mask mask;
92
93 constexpr plurality(plurality_value value, plurality_mask mask) noexcept : value(value), mask(mask)
94 {
95 // Check if the value uses only bits that are set in the mask.
96 hi_axiom(not to_bool((1 << std::to_underlying(value)) & ~std::to_underlying(mask)));
97 }
98
106 [[nodiscard]] constexpr size_t index(size_t n) const noexcept
107 {
108 hi_assert(n != 0);
109
110 hilet value_as_mask = (1 << (std::to_underlying(value) + 1)) - 1;
111 // Get the index based on the number of '1' bits that are set from the
112 // plurality position to lsb.
113 hilet i = std::popcount(narrow_cast<uint8_t>(value_as_mask & std::to_underlying(mask))) - 1;
114 if (i < n) {
115 return i;
116 } else {
117 return n - 1;
118 }
119 }
120};
121
122namespace detail {
123
131 unsigned long long n = 0;
132
135 unsigned long long f = 0;
136
139 unsigned long long t = 0;
140
143 uint8_t i = 0;
144
147 uint8_t v = 0;
148
151 uint8_t w = 0;
152
155 uint8_t c = 0;
156
157 constexpr plural_operand(std::integral auto value) noexcept : n(std::abs(value)), i(narrow_cast<uint8_t>(decimal_width(value))) {}
158};
159
160// Each of the rules can be shared by multiple languages. Each rule will be named
161// after the first language in alphabetical order.
162
163// clang-format off
164[[nodiscard]] constexpr plurality cardinal_plural_bambara(plural_operand) noexcept
165{
167}
168
169[[nodiscard]] constexpr plurality cardinal_plural_cebuano(plural_operand op) noexcept
170{
171 hilet value = [&] {
172 if (
173 (op.v == 0 and op.i >= 1 and op.i <= 3) or
174 (op.v == 0 and op.i % 10 != 4 and op.i % 10 != 6 and op.i % 10 != 9) or
175 (op.v != 0 and op.f % 10 != 4 and op.f % 10 != 6 and op.f % 10 != 9)) {
177 } else {
179 }
180 }();
181
183}
184
185[[nodiscard]] constexpr plurality cardinal_plural_central_atlas_tamazight(plural_operand op) noexcept
186{
187 hilet value = [&] {
188 if (op.n == 0 or op.n == 1 or (op.n >= 11 and op.n <= 99)) {
190 } else {
192 }
193 }();
194
196}
197
198[[nodiscard]] constexpr plurality cardinal_plural_icelandic(plural_operand op) noexcept
199{
200 hilet value = [&] {
201 if ((op.t == 0 and op.i % 10 == 1 and op.i % 100 != 11) or op.t != 0) {
203 } else {
205 }
206 }();
207
209}
210
211[[nodiscard]] constexpr plurality cardinal_plural_akan(plural_operand op) noexcept
212{
213 hilet value = [&] {
214 if (op.n == 0 or op.n == 1) {
216 } else {
218 }
219 }();
220
222}
223
224[[nodiscard]] constexpr plurality cardinal_plural_afrikaans(plural_operand op) noexcept
225{
226 hilet value = [&] {
227 if (op.n == 1) {
229 } else {
231 }
232 }();
233
235}
236
237[[nodiscard]] constexpr plurality cardinal_plural_latvian(plural_operand op) noexcept
238{
239 hilet value = [&] {
240 if (
241 op.n == 0 or
242 (op.n % 100 >= 11 and op.n % 100 <= 19) or
243 (op.v == 2 and op.f % 100 >= 11 and op.f % 100 <= 19)) {
245 } else if (
246 (op.n % 10 == 1 and op.n % 100 != 11) or
247 (op.v == 2 and op.f % 10 == 1 and op.f % 100 != 11) or
248 (op.v != 2 and op.f % 10 == 1)) {
250 } else {
252 }
253 }();
254
256}
257
258[[nodiscard]] constexpr plurality cardinal_plural_colognian(plural_operand op) noexcept
259{
260 hilet value = [&] {
261 if (op.n == 0) {
263 } else if (op.n == 1) {
265 } else {
267 }
268 }();
269
271}
272
273[[nodiscard]] constexpr plurality cardinal_plural_inari_sami(plural_operand op) noexcept
274{
275 hilet value = [&] {
276 if (op.n == 1) {
278 } else if (op.n == 2) {
280 } else {
282 }
283 }();
284
286}
287
288[[nodiscard]] constexpr plurality cardinal_plural_belarusian(plural_operand op) noexcept
289{
290 hilet value = [&] {
291 if (op.n % 10 == 1 and op.n % 100 != 11) {
293 } else if (op.n % 10 >= 2 and op.n % 10 <= 4 and not (op.n % 100 >= 12 and op.n % 100 <= 14)) {
295 } else if (
296 op.n % 10 == 0 or
297 (op.n % 10 >= 5 and op.n % 10 <= 9) or
298 (op.n % 100 >= 11 and op.n % 100 <= 14)) {
300 } else {
302 }
303 }();
304
306}
307
308[[nodiscard]] constexpr plurality cardinal_plural_polish(plural_operand op) noexcept
309{
310 hilet value = [&] {
311 // The specification uses op.i (number of digits) instead of op.n (absolute value)
312 if (op.n == 1 and op.v == 0) {
314 } else if (op.v == 0 and (op.n % 10 >= 2 and op.n % 10 <= 4) and not (op.n % 100 >= 12 and op.n % 100 <= 14)) {
316 } else if (
317 (op.v == 0 and op.n != 1 and op.n % 10 >= 0 and op.n % 10 <= 1) or
318 (op.v == 0 and op.n % 10 >= 5 and op.n % 10 <= 9) or
319 (op.v == 0 and op.n % 100 >= 12 and op.n % 100 <= 14)) {
321 } else {
323 }
324 }();
325
327}
328
329[[nodiscard]] constexpr plurality cardinal_plural_lithuanian(plural_operand op) noexcept
330{
331 hilet value = [&] {
332 if (op.n % 10 == 1 and not (op.n % 100 >= 11 and op.n % 100 <= 19)) {
334 } else if (op.n % 10 >= 2 and op.n % 10 <= 9 and not (op.n % 100 >= 11 and op.n % 100 <= 19)) {
336 } else if (op.f != 0) {
338 } else {
340 }
341 }();
342
344}
345
346[[nodiscard]] constexpr plurality cardinal_plural_bosnian(plural_operand op) noexcept
347{
348 hilet value = [&] {
349 // The specification uses op.i (number of digits) instead of op.n (absolute value)
350 if (
351 (op.v == 0 and op.n % 10 == 1 and op.n % 100 != 11) or
352 (op.f % 10 == 1 and op.f % 100 != 11)) {
354 } else if (
355 (op.v == 0 and op.n % 10 >= 2 and op.n % 10 <= 4 and not (op.n % 100 >= 12 and op.n % 100 <= 14)) or
356 (op.f % 10 >= 2 and op.f % 10 <= 4 and not (op.f % 100 >= 12 and op.n % 100 <= 14))) {
358 } else {
360 }
361 }();
362
364}
365
366[[nodiscard]] constexpr plurality cardinal_plural_tachelhit(plural_operand op) noexcept
367{
368 hilet value = [&] {
369 if (op.i == 0 or op.n == 1) {
371 } else if (op.n >= 2 and op.n <= 10) {
373 } else {
375 }
376 }();
377
379}
380
381[[nodiscard]] constexpr plurality cardinal_plural_moldavian(plural_operand op) noexcept
382{
383 hilet value = [&] {
384 // The specification uses op.i (number of digits) for determining 'one'
385 // which is wrong.
386 if (op.n == 1 and op.v == 0) {
388 } else if (
389 op.v != 0 or
390 op.n == 0 or
391 (op.n % 100 >= 2 and op.n % 100 <= 19)) {
393 } else {
395 }
396 }();
397
399}
400
401[[nodiscard]] constexpr plurality cardinal_plural_czech(plural_operand op) noexcept
402{
403 hilet value = [&] {
404 // The specification uses op.i (number of digits) instead of
405 // op.n (absolute value).
406 if (op.n == 1 and op.v == 0) {
408 } else if (op.n >= 2 and op.n <= 4 and op.v == 0) {
410 } else if (op.v != 0) {
412 } else {
414 }
415 }();
416
418}
419
420[[nodiscard]] constexpr plurality cardinal_plural_manx(plural_operand op) noexcept
421{
422 hilet value = [&] {
423 // The specification uses op.i (number of digits) instead of
424 // op.n (absolute value).
425 if (op.v == 0 and op.n % 10 == 1) {
427 } else if (op.v == 0 and op.n % 10 == 2) {
429 } else if (op.v == 0 and (
430 op.n % 100 == 0 or op.n % 100 == 20 or op.n % 100 == 40 or op.n % 100 == 60 or op.n % 100 == 80)) {
432 } else if (op.v != 0) {
434 } else {
436 }
437 }();
438
440}
441
442[[nodiscard]] constexpr plurality cardinal_plural_scottish_gaelic(plural_operand op) noexcept
443{
444 hilet value = [&] {
445 if (op.n == 1 or op.n == 11) {
447 } else if (op.n == 2 or op.n == 12) {
449 } else if ((op.n >= 3 and op.n <= 10) or (op.n >= 13 and op.n <= 19)) {
451 } else {
453 }
454 }();
455
457}
458
459[[nodiscard]] constexpr plurality cardinal_plural_breton(plural_operand op) noexcept
460{
461 hilet value = [&] {
462 if (op.n % 10 == 1 and op.n % 100 != 11 and op.n % 100 != 71 and op.n % 100 != 91) {
464 } else if (op.n % 10 == 2 and op.n % 100 != 12 and op.n % 100 != 72 and op.n % 100 != 92) {
466 } else if (
467 (op.n % 10 == 3 or op.n % 10 == 4 or op.n % 10 == 9) and
468 (not (op.n % 100 >= 10 and op.n % 100 <= 19) and
469 not (op.n % 100 >= 70 and op.n % 100 <= 79) and
470 not (op.n % 100 >= 90 and op.n % 100 <= 99))) {
472 } else if (op.n != 0 and op.n % 1'000'000 == 0) {
474 } else {
476 }
477 }();
478
480}
481
482[[nodiscard]] constexpr plurality cardinal_plural_lower_sorbian(plural_operand op) noexcept
483{
484 hilet value = [&] {
485 // The specification use op.i (number of digits) instead of
486 // op.n (absolute value).
487 if (
488 (op.v == 0 and op.n % 100 == 1) or
489 op.f % 100 == 1) {
491 } else if (
492 (op.v == 0 and op.n % 100 == 2) or
493 op.f % 100 == 2) {
495 } else if (
496 (op.v == 0 and op.n % 100 >= 3 and op.n % 100 <= 4) or
497 (op.f % 100 >= 3 and op.f % 100 <= 4)) {
499 } else {
501 }
502 }();
503
505}
506
507[[nodiscard]] constexpr plurality cardinal_plural_hebrew(plural_operand op) noexcept
508{
509 hilet value = [&] {
510 // The specification use op.i (number of digits) instead of
511 // op.n (absolute value).
512 if (op.n == 1 and op.v == 0) {
514 } else if (op.n == 2 and op.v == 0) {
516 } else if (op.v == 0 and not (op.n >= 0 and op.n <= 10) and op.n % 10 == 0) {
518 } else {
520 }
521 }();
522
524}
525
526[[nodiscard]] constexpr plurality cardinal_plural_maltese(plural_operand op) noexcept
527{
528 hilet value = [&] {
529 if (op.n == 1) {
531 } else if (op.n == 0 or (op.n % 100 >= 2 and op.n % 100 <= 10)) {
533 } else if (op.n % 100 >= 11 and op.n % 100 <= 19) {
535 } else {
537 }
538 }();
539
541}
542
543[[nodiscard]] constexpr plurality cardinal_plural_irish(plural_operand op) noexcept
544{
545 hilet value = [&] {
546 if (op.n == 1) {
548 } else if (op.n == 2) {
550 } else if (op.n >= 3 and op.n <= 6) {
552 } else if (op.n >= 7 and op.n <= 10) {
554 } else {
556 }
557 }();
558
560}
561
562[[nodiscard]] constexpr plurality cardinal_plural_arabic(plural_operand op) noexcept
563{
564 hilet value = [&] {
565 if (op.n == 0) {
567 } else if (op.n == 1) {
569 } else if (op.n == 2) {
571 } else if (op.n % 100 >= 3 and op.n % 100 <= 10) {
573 } else if (op.n % 100 >= 11 and op.n % 100 <= 99) {
575 } else {
577 }
578 }();
579
580 return {
581 value,
584}
585
586[[nodiscard]] constexpr plurality cardinal_plural_welsh(plural_operand op) noexcept
587{
588 hilet value = [&] {
589 if (op.n == 0) {
591 } else if (op.n == 1) {
593 } else if (op.n == 2) {
595 } else if (op.n == 3) {
597 } else if (op.n == 6) {
599 } else {
601 }
602 }();
603
604 return {
605 value,
608 }
609
610[[nodiscard]] constexpr plurality cardinal_plural_cornish(plural_operand op) noexcept
611{
612 hilet value = [&] {
613 if (op.n == 0) {
615 } else if (op.n == 1) {
617 } else if (
618 op.n % 100 == 2 or
619 op.n % 100 == 22 or
620 op.n % 100 == 42 or
621 op.n % 100 == 62 or
622 op.n % 100 == 82 or
623 (op.n % 1'000 == 0 and (
624 (op.n % 100'000 >= 1'000 and op.n % 100'000 <= 20'000) or
625 op.n % 100'000 == 40'000 or
626 op.n % 100'000 == 60'000 or
627 op.n % 100'000 == 80'000)) or
628 (op.n != 0 and op.n % 1'000'000 == 100'000)) {
630 } else if (
631 op.n % 100 == 3 or
632 op.n % 100 == 23 or
633 op.n % 100 == 43 or
634 op.n % 100 == 63 or
635 op.n % 100 == 83) {
637 } else if (op.n != 1 and (
638 op.n % 100 == 1 or
639 op.n % 100 == 21 or
640 op.n % 100 == 41 or
641 op.n % 100 == 61 or
642 op.n % 100 == 81)) {
644 } else {
646 }
647 }();
648
649 return {
650 value,
653}
654// clang-format on
655
656using cardinal_plural_fptr = plurality (*)(plural_operand);
657
658[[nodiscard]] constexpr auto cardinal_plural_table_init() noexcept
659{
661
662 // Bambara, Burmese, Cantonese, Chinese, Dzongkha, Igbo, Indonesian,
663 // Japanese, Javanese, Kabuverdianu, Khmer, Korean, Koyraboro Senni, Lakota,
664 // Lao, Lojban, Makonde, Malay, N’Ko, Osage, Root, Sakha, Sango, Sichuan Yi,
665 // Sundanese, Thai, Tibetan, Tongan, Vietnamese, Wolof, Yoruba
666 for (auto& rule_ptr : r) {
667 rule_ptr = cardinal_plural_bambara;
668 }
669
670 // Cebuano, Filipino, Tagalog
671 r[iso_639{"ceb"}.intrinsic()] = cardinal_plural_cebuano;
672 r[iso_639{"fil"}.intrinsic()] = cardinal_plural_cebuano;
673 r[iso_639{"tl"}.intrinsic()] = cardinal_plural_cebuano;
674
675 // Central Atlas Tamazight
676 r[iso_639{"tzm"}.intrinsic()] = cardinal_plural_central_atlas_tamazight;
677
678 // Icelandic, Macedonian
679 r[iso_639{"is"}.intrinsic()] = cardinal_plural_icelandic;
680 r[iso_639{"mk"}.intrinsic()] = cardinal_plural_icelandic;
681
682 // Akan, Amharic, Armenian, Assamese, Bangla, Bihari, French, Fulah,
683 r[iso_639{"ak"}.intrinsic()] = cardinal_plural_akan;
684 r[iso_639{"am"}.intrinsic()] = cardinal_plural_akan;
685 r[iso_639{"hy"}.intrinsic()] = cardinal_plural_akan;
686 r[iso_639{"as"}.intrinsic()] = cardinal_plural_akan;
687 r[iso_639{"bn"}.intrinsic()] = cardinal_plural_akan;
688 r[iso_639{"bh"}.intrinsic()] = cardinal_plural_akan;
689 r[iso_639{"fr"}.intrinsic()] = cardinal_plural_akan;
690 r[iso_639{"ff"}.intrinsic()] = cardinal_plural_akan;
691 // Gujarati, Gun, Hindi, Kabyle, Kannada, Lingala, Malagasy, Northern Sotho,
692 r[iso_639{"gu"}.intrinsic()] = cardinal_plural_akan;
693 r[iso_639{"guw"}.intrinsic()] = cardinal_plural_akan;
694 r[iso_639{"hi"}.intrinsic()] = cardinal_plural_akan;
695 r[iso_639{"kab"}.intrinsic()] = cardinal_plural_akan;
696 r[iso_639{"kn"}.intrinsic()] = cardinal_plural_akan;
697 r[iso_639{"ln"}.intrinsic()] = cardinal_plural_akan;
698 r[iso_639{"mg"}.intrinsic()] = cardinal_plural_akan;
699 r[iso_639{"nso"}.intrinsic()] = cardinal_plural_akan;
700 // Persian, Portuguese, Punjabi, Sinhala, Tigrinya, Walloon, Zulu
701 r[iso_639{"fa"}.intrinsic()] = cardinal_plural_akan;
702 r[iso_639{"pt"}.intrinsic()] = cardinal_plural_akan;
703 r[iso_639{"pa"}.intrinsic()] = cardinal_plural_akan;
704 r[iso_639{"si"}.intrinsic()] = cardinal_plural_akan;
705 r[iso_639{"ti"}.intrinsic()] = cardinal_plural_akan;
706 r[iso_639{"wa"}.intrinsic()] = cardinal_plural_akan;
707 r[iso_639{"zu"}.intrinsic()] = cardinal_plural_akan;
708
709 // Afrikaans, Albanian, Aragonese, Asturian, Asu, Azerbaijani, Basque,
710 r[iso_639{"af"}.intrinsic()] = cardinal_plural_afrikaans;
711 r[iso_639{"sq"}.intrinsic()] = cardinal_plural_afrikaans;
712 r[iso_639{"an"}.intrinsic()] = cardinal_plural_afrikaans;
713 r[iso_639{"ast"}.intrinsic()] = cardinal_plural_afrikaans;
714 r[iso_639{"asa"}.intrinsic()] = cardinal_plural_afrikaans;
715 r[iso_639{"az"}.intrinsic()] = cardinal_plural_afrikaans;
716 r[iso_639{"eu"}.intrinsic()] = cardinal_plural_afrikaans;
717 // Bemba, Bena, Bodo, Bulgarian, Catalan, Central Kurdish, Chechen,
718 r[iso_639{"bem"}.intrinsic()] = cardinal_plural_afrikaans;
719 r[iso_639{"bez"}.intrinsic()] = cardinal_plural_afrikaans;
720 r[iso_639{"brx"}.intrinsic()] = cardinal_plural_afrikaans;
721 r[iso_639{"bg"}.intrinsic()] = cardinal_plural_afrikaans;
722 r[iso_639{"ca"}.intrinsic()] = cardinal_plural_afrikaans;
723 r[iso_639{"ckb"}.intrinsic()] = cardinal_plural_afrikaans;
724 r[iso_639{"ce"}.intrinsic()] = cardinal_plural_afrikaans;
725 // Cherokee, Chiga, Danish, Divehi, Dutch, English, Esperanto, Estonian,
726 r[iso_639{"chr"}.intrinsic()] = cardinal_plural_afrikaans;
727 r[iso_639{"cgg"}.intrinsic()] = cardinal_plural_afrikaans;
728 r[iso_639{"da"}.intrinsic()] = cardinal_plural_afrikaans;
729 r[iso_639{"dv"}.intrinsic()] = cardinal_plural_afrikaans;
730 r[iso_639{"nl"}.intrinsic()] = cardinal_plural_afrikaans;
731 r[iso_639{"en"}.intrinsic()] = cardinal_plural_afrikaans;
732 r[iso_639{"eo"}.intrinsic()] = cardinal_plural_afrikaans;
733 r[iso_639{"et"}.intrinsic()] = cardinal_plural_afrikaans;
734 // European Portuguese, Ewe, Faroese, Finnish, Friulian, Galician, Ganda,
735 //r[iso_639{"pt"}] = cardinal_plural_afrikaans;
736 r[iso_639{"ee"}.intrinsic()] = cardinal_plural_afrikaans;
737 r[iso_639{"fo"}.intrinsic()] = cardinal_plural_afrikaans;
738 r[iso_639{"fi"}.intrinsic()] = cardinal_plural_afrikaans;
739 r[iso_639{"fur"}.intrinsic()] = cardinal_plural_afrikaans;
740 r[iso_639{"gl"}.intrinsic()] = cardinal_plural_afrikaans;
741 r[iso_639{"lg"}.intrinsic()] = cardinal_plural_afrikaans;
742 // Georgian, German, Greek, Hausa, Hawaiian, Hungarian, Ido, Interlingua,
743 r[iso_639{"ka"}.intrinsic()] = cardinal_plural_afrikaans;
744 r[iso_639{"de"}.intrinsic()] = cardinal_plural_afrikaans;
745 r[iso_639{"el"}.intrinsic()] = cardinal_plural_afrikaans;
746 r[iso_639{"ha"}.intrinsic()] = cardinal_plural_afrikaans;
747 r[iso_639{"haw"}.intrinsic()] = cardinal_plural_afrikaans;
748 r[iso_639{"hu"}.intrinsic()] = cardinal_plural_afrikaans;
749 r[iso_639{"io"}.intrinsic()] = cardinal_plural_afrikaans;
750 r[iso_639{"ia"}.intrinsic()] = cardinal_plural_afrikaans;
751 // Italian, Jju, Kako, Kalaallisut, Kashmiri, Kazakh, Kurdish, Kyrgyz,
752 r[iso_639{"it"}.intrinsic()] = cardinal_plural_afrikaans;
753 r[iso_639{"kaj"}.intrinsic()] = cardinal_plural_afrikaans;
754 r[iso_639{"kkj"}.intrinsic()] = cardinal_plural_afrikaans;
755 r[iso_639{"kl"}.intrinsic()] = cardinal_plural_afrikaans;
756 r[iso_639{"ks"}.intrinsic()] = cardinal_plural_afrikaans;
757 r[iso_639{"kk"}.intrinsic()] = cardinal_plural_afrikaans;
758 r[iso_639{"ku"}.intrinsic()] = cardinal_plural_afrikaans;
759 r[iso_639{"ky"}.intrinsic()] = cardinal_plural_afrikaans;
760 // Luxembourgish, Machame, Malayalam, Marathi, Masai, Metaʼ, Mongolian,
761 r[iso_639{"lb"}.intrinsic()] = cardinal_plural_afrikaans;
762 r[iso_639{"jmc"}.intrinsic()] = cardinal_plural_afrikaans;
763 r[iso_639{"ml"}.intrinsic()] = cardinal_plural_afrikaans;
764 r[iso_639{"mr"}.intrinsic()] = cardinal_plural_afrikaans;
765 r[iso_639{"mas"}.intrinsic()] = cardinal_plural_afrikaans;
766 r[iso_639{"mgo"}.intrinsic()] = cardinal_plural_afrikaans;
767 r[iso_639{"mn"}.intrinsic()] = cardinal_plural_afrikaans;
768 // Nahuatl, Nepali, Ngiemboon, Ngomba, North Ndebele, Norwegian,
769 r[iso_639{"nah"}.intrinsic()] = cardinal_plural_afrikaans;
770 r[iso_639{"ne"}.intrinsic()] = cardinal_plural_afrikaans;
771 r[iso_639{"nnh"}.intrinsic()] = cardinal_plural_afrikaans;
772 r[iso_639{"jgo"}.intrinsic()] = cardinal_plural_afrikaans;
773 r[iso_639{"ns"}.intrinsic()] = cardinal_plural_afrikaans;
774 r[iso_639{"no"}.intrinsic()] = cardinal_plural_afrikaans;
775 // Norwegian Bokmål, Norwegian Nynorsk, Nyanja, Nyankole, Odia, Oromo,
776 r[iso_639{"nb"}.intrinsic()] = cardinal_plural_afrikaans;
777 r[iso_639{"nn"}.intrinsic()] = cardinal_plural_afrikaans;
778 r[iso_639{"ny"}.intrinsic()] = cardinal_plural_afrikaans;
779 r[iso_639{"nyn"}.intrinsic()] = cardinal_plural_afrikaans;
780 r[iso_639{"or"}.intrinsic()] = cardinal_plural_afrikaans;
781 r[iso_639{"om"}.intrinsic()] = cardinal_plural_afrikaans;
782 // Ossetic, Papiamento, Pashto, Romansh, Rombo, Rwa, Saho, Samburu,
783 r[iso_639{"os"}.intrinsic()] = cardinal_plural_afrikaans;
784 r[iso_639{"pap"}.intrinsic()] = cardinal_plural_afrikaans;
785 r[iso_639{"ps"}.intrinsic()] = cardinal_plural_afrikaans;
786 r[iso_639{"rm"}.intrinsic()] = cardinal_plural_afrikaans;
787 r[iso_639{"rof"}.intrinsic()] = cardinal_plural_afrikaans;
788 r[iso_639{"rwk"}.intrinsic()] = cardinal_plural_afrikaans;
789 r[iso_639{"ssy"}.intrinsic()] = cardinal_plural_afrikaans;
790 r[iso_639{"saq"}.intrinsic()] = cardinal_plural_afrikaans;
791 // Sardinian, Sena, Shambala, Shona, Sicilian, Sindhi, Soga, Somali,
792 r[iso_639{"sc"}.intrinsic()] = cardinal_plural_afrikaans;
793 r[iso_639{"seh"}.intrinsic()] = cardinal_plural_afrikaans;
794 r[iso_639{"ksb"}.intrinsic()] = cardinal_plural_afrikaans;
795 r[iso_639{"sn"}.intrinsic()] = cardinal_plural_afrikaans;
796 r[iso_639{"scn"}.intrinsic()] = cardinal_plural_afrikaans;
797 r[iso_639{"sd"}.intrinsic()] = cardinal_plural_afrikaans;
798 r[iso_639{"xog"}.intrinsic()] = cardinal_plural_afrikaans;
799 r[iso_639{"so"}.intrinsic()] = cardinal_plural_afrikaans;
800 // South Ndebele, Southern Kurdish, Southern Sotho, Spanish, Swahili,
801 r[iso_639{"nr"}.intrinsic()] = cardinal_plural_afrikaans;
802 r[iso_639{"sdh"}.intrinsic()] = cardinal_plural_afrikaans;
803 r[iso_639{"st"}.intrinsic()] = cardinal_plural_afrikaans;
804 r[iso_639{"es"}.intrinsic()] = cardinal_plural_afrikaans;
805 r[iso_639{"sw"}.intrinsic()] = cardinal_plural_afrikaans;
806 // Swati, Swedish, Swiss German, Syriac, Tamil, Telugu, Teso, Tigre,
807 r[iso_639{"ss"}.intrinsic()] = cardinal_plural_afrikaans;
808 r[iso_639{"sv"}.intrinsic()] = cardinal_plural_afrikaans;
809 r[iso_639{"gsw"}.intrinsic()] = cardinal_plural_afrikaans;
810 r[iso_639{"syr"}.intrinsic()] = cardinal_plural_afrikaans;
811 r[iso_639{"ta"}.intrinsic()] = cardinal_plural_afrikaans;
812 r[iso_639{"te"}.intrinsic()] = cardinal_plural_afrikaans;
813 r[iso_639{"teo"}.intrinsic()] = cardinal_plural_afrikaans;
814 r[iso_639{"tig"}.intrinsic()] = cardinal_plural_afrikaans;
815 // Tsonga, Tswana, Turkish, Turkmen, Tyap, Urdu, Uyghur, Uzbek, Venda,
816 r[iso_639{"ts"}.intrinsic()] = cardinal_plural_afrikaans;
817 r[iso_639{"tn"}.intrinsic()] = cardinal_plural_afrikaans;
818 r[iso_639{"tr"}.intrinsic()] = cardinal_plural_afrikaans;
819 r[iso_639{"tk"}.intrinsic()] = cardinal_plural_afrikaans;
820 r[iso_639{"kcg"}.intrinsic()] = cardinal_plural_afrikaans;
821 r[iso_639{"ur"}.intrinsic()] = cardinal_plural_afrikaans;
822 r[iso_639{"ug"}.intrinsic()] = cardinal_plural_afrikaans;
823 r[iso_639{"uz"}.intrinsic()] = cardinal_plural_afrikaans;
824 r[iso_639{"ve"}.intrinsic()] = cardinal_plural_afrikaans;
825 // Volapük, Vunjo, Walser, Western Frisian, Xhosa, Yiddish
826 r[iso_639{"vo"}.intrinsic()] = cardinal_plural_afrikaans;
827 r[iso_639{"vun"}.intrinsic()] = cardinal_plural_afrikaans;
828 r[iso_639{"wae"}.intrinsic()] = cardinal_plural_afrikaans;
829 r[iso_639{"fy"}.intrinsic()] = cardinal_plural_afrikaans;
830 r[iso_639{"xh"}.intrinsic()] = cardinal_plural_afrikaans;
831 r[iso_639{"ji"}.intrinsic()] = cardinal_plural_afrikaans;
832 r[iso_639{"yi"}.intrinsic()] = cardinal_plural_afrikaans; // Yiddish twice.
833
834 // Latvian, Prussian
835 r[iso_639{"lv"}.intrinsic()] = cardinal_plural_latvian;
836 r[iso_639{"prg"}.intrinsic()] = cardinal_plural_latvian;
837
838 // Colognian, Langi
839 r[iso_639{"ksh"}.intrinsic()] = cardinal_plural_colognian;
840 r[iso_639{"lag"}.intrinsic()] = cardinal_plural_colognian;
841
842 // Inari Sami, Inuktitut, Lule Sami, Nama, Northern Sami,
843 r[iso_639{"smn"}.intrinsic()] = cardinal_plural_inari_sami;
844 r[iso_639{"iu"}.intrinsic()] = cardinal_plural_inari_sami;
845 r[iso_639{"smj"}.intrinsic()] = cardinal_plural_inari_sami;
846 r[iso_639{"naq"}.intrinsic()] = cardinal_plural_inari_sami;
847 r[iso_639{"se"}.intrinsic()] = cardinal_plural_inari_sami;
848 // Sami languages [Other], Skolt Sami, Southern Sami
849 r[iso_639{"smi"}.intrinsic()] = cardinal_plural_inari_sami;
850 r[iso_639{"sms"}.intrinsic()] = cardinal_plural_inari_sami;
851 r[iso_639{"sma"}.intrinsic()] = cardinal_plural_inari_sami;
852
853 // Belarusian, Russian, Ukrainian
854 r[iso_639{"be"}.intrinsic()] = cardinal_plural_belarusian;
855 r[iso_639{"ru"}.intrinsic()] = cardinal_plural_belarusian;
856 r[iso_639{"uk"}.intrinsic()] = cardinal_plural_belarusian;
857
858 // Polish
859 r[iso_639{"pl"}.intrinsic()] = cardinal_plural_polish;
860
861 // Lithuanian
862 r[iso_639{"lt"}.intrinsic()] = cardinal_plural_lithuanian;
863
864 // Bosnian, Croatian, Serbian, Serbo-Croatian
865 r[iso_639{"bs"}.intrinsic()] = cardinal_plural_bosnian;
866 r[iso_639{"hr"}.intrinsic()] = cardinal_plural_bosnian;
867 r[iso_639{"sr"}.intrinsic()] = cardinal_plural_bosnian;
868 r[iso_639{"sh"}.intrinsic()] = cardinal_plural_bosnian;
869
870 // Tachelhit
871 r[iso_639{"shi"}.intrinsic()] = cardinal_plural_tachelhit;
872
873 // Moldavian, Romanian
874 r[iso_639{"mo"}.intrinsic()] = cardinal_plural_moldavian;
875 r[iso_639{"ro"}.intrinsic()] = cardinal_plural_moldavian;
876
877 // Czech, Slovak
878 r[iso_639{"cs"}.intrinsic()] = cardinal_plural_czech;
879 r[iso_639{"sk"}.intrinsic()] = cardinal_plural_czech;
880
881 // Manx
882 r[iso_639{"gv"}.intrinsic()] = cardinal_plural_manx;
883
884 // Scottish Gaelic
885 r[iso_639{"gd"}.intrinsic()] = cardinal_plural_scottish_gaelic;
886
887 // Breton
888 r[iso_639{"br"}.intrinsic()] = cardinal_plural_breton;
889
890 // Lower Sorbian, Slovenian, Upper Sorbian
891 r[iso_639{"dsb"}.intrinsic()] = cardinal_plural_lower_sorbian;
892 r[iso_639{"sl"}.intrinsic()] = cardinal_plural_lower_sorbian;
893 r[iso_639{"hsb"}.intrinsic()] = cardinal_plural_lower_sorbian;
894
895 // Hebrew
896 r[iso_639{"he"}.intrinsic()] = cardinal_plural_hebrew;
897
898 // Maltese
899 r[iso_639{"mt"}.intrinsic()] = cardinal_plural_maltese;
900
901 // Irish
902 r[iso_639{"ga"}.intrinsic()] = cardinal_plural_irish;
903
904 // Arabic, Najdi Arabic
905 r[iso_639{"ar"}.intrinsic()] = cardinal_plural_arabic;
906 r[iso_639{"ars"}.intrinsic()] = cardinal_plural_arabic;
907
908 // Welsh
909 r[iso_639{"cy"}.intrinsic()] = cardinal_plural_welsh;
910
911 // Cornish
912 r[iso_639{"kw"}.intrinsic()] = cardinal_plural_cornish;
913
914 return r;
915}
916
917constexpr auto cardinal_plural_table = cardinal_plural_table_init();
918
919} // namespace detail
920
927[[nodiscard]] constexpr plurality cardinal_plural(language_tag language, std::integral auto n) noexcept
928{
929 if (language == language_tag{"pt-PT"}) {
930 // Portuguese in Portugal is different from Portuguese spoken in
931 // other regions.
932 return cardinal_plural_afrikaans(detail::plural_operand(n));
933 }
934
935 hilet language_index = language.region.intrinsic();
936 hi_axiom_bounds(language_index, detail::cardinal_plural_table);
937 return detail::cardinal_plural_table[language_index](detail::plural_operand(n));
938}
939
947[[nodiscard]] constexpr size_t cardinal_plural(language_tag language, std::integral auto n, size_t size) noexcept
948{
949 return cardinal_plural(language, n).index(size);
950}
951
952}} // namespace hi::v1
953
@ other
The gui_event does not have associated data.
DOXYGEN BUG.
Definition algorithm.hpp:16
geometry/margins.hpp
Definition lookahead_iterator.hpp:5
plurality_value
The plurality value of a cardinal or ordinal number.
Definition unicode_plural.hpp:26
@ other
Any other number, every language will have at least this.
@ few
The number is part of few, and this means something in the current language.
@ many
The number is part of many, and this means something in the current language.
@ two
The number was two, and this means something in the current language.
@ zero
The number was zero, and this means something in the current language.
@ one
The number was one, and this means something in the current language.
plurality_mask
A mask of plurality values that this language supports.
Definition unicode_plural.hpp:54
@ other
Any other number, every language will have at least this.
@ few
The number is part of few, and this means something in the current language.
@ many
The number is part of many, and this means something in the current language.
@ two
The number was two, and this means something in the current language.
@ zero
The number was zero, and this means something in the current language.
@ one
The number was one, and this means something in the current language.
constexpr plurality cardinal_plural(language_tag language, std::integral auto n) noexcept
Get plural information of a number in a given language.
Definition unicode_plural.hpp:927
constexpr Out narrow_cast(In const &rhs) noexcept
Cast numeric values without loss of precision.
Definition cast.hpp:377
The IETF BCP 47 language tag.
Definition language_tag_intf.hpp:28
Plurality of a number.
Definition unicode_plural.hpp:89
constexpr size_t index(size_t n) const noexcept
Get an index to select between translations.
Definition unicode_plural.hpp:106
The operand for the unicode-plural rules.
Definition unicode_plural.hpp:128
uint8_t i
Number of digits in the value.
Definition unicode_plural.hpp:143
unsigned long long f
Visible fraction digits with trailing zeros.
Definition unicode_plural.hpp:135
uint8_t c
Compact decimal exponent value.
Definition unicode_plural.hpp:155
unsigned long long t
Visible fraction digits without trailing zeros.
Definition unicode_plural.hpp:139
uint8_t w
Number of visible fraction digits without trailing zeros.
Definition unicode_plural.hpp:151
uint8_t v
Number of visible fraction digits with trailing zeros.
Definition unicode_plural.hpp:147
unsigned long long n
Absolute value.
Definition unicode_plural.hpp:131