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