123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- /*
- * Copyright (c) 2022, Tim Flynn <trflynn89@serenityos.org>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
- #pragma once
- #include <AK/Assertions.h>
- #include <AK/StringView.h>
- #include <AK/Types.h>
- #include <LibUnicode/Forward.h>
- namespace Unicode {
- enum class PluralForm {
- Cardinal,
- Ordinal,
- };
- enum class PluralCategory : u8 {
- Other,
- Zero,
- One,
- Two,
- Few,
- Many,
- // https://unicode.org/reports/tr35/tr35-numbers.html#Explicit_0_1_rules
- ExactlyZero,
- ExactlyOne,
- };
- // https://unicode.org/reports/tr35/tr35-numbers.html#Plural_Operand_Meanings
- struct PluralOperands {
- static constexpr StringView symbol_to_variable_name(char symbol)
- {
- if (symbol == 'n')
- return "number"sv;
- if (symbol == 'i')
- return "integer_digits"sv;
- if (symbol == 'f')
- return "fraction_digits"sv;
- if (symbol == 'v')
- return "number_of_fraction_digits"sv;
- if (symbol == 't')
- return "fraction_digits_without_trailing"sv;
- if (symbol == 'w')
- return "number_of_fraction_digits_without_trailing"sv;
- VERIFY_NOT_REACHED();
- }
- static constexpr bool symbol_requires_floating_point_modulus(char symbol)
- {
- // From TR-35: "The modulus (% or mod) is a remainder operation as defined in Java; for
- // example, where n = 4.3 the result of n mod 3 is 1.3."
- //
- // So, this returns whether the symbol represents a decimal value, and thus requires fmod.
- return symbol == 'n';
- }
- double number { 0 };
- u64 integer_digits { 0 };
- u64 fraction_digits { 0 };
- u64 number_of_fraction_digits { 0 };
- u64 fraction_digits_without_trailing { 0 };
- u64 number_of_fraction_digits_without_trailing { 0 };
- };
- PluralForm plural_form_from_string(StringView plural_form);
- StringView plural_form_to_string(PluralForm plural_form);
- // NOTE: This must be defined inline to be callable from the code generators.
- constexpr PluralCategory plural_category_from_string(StringView category)
- {
- if (category == "other"sv)
- return PluralCategory::Other;
- if (category == "zero"sv)
- return PluralCategory::Zero;
- if (category == "one"sv)
- return PluralCategory::One;
- if (category == "two"sv)
- return PluralCategory::Two;
- if (category == "few"sv)
- return PluralCategory::Few;
- if (category == "many"sv)
- return PluralCategory::Many;
- if (category == "0"sv)
- return PluralCategory::ExactlyZero;
- if (category == "1"sv)
- return PluralCategory::ExactlyOne;
- VERIFY_NOT_REACHED();
- }
- // NOTE: This must be defined inline to be callable from the code generators.
- constexpr StringView plural_category_to_string(PluralCategory category)
- {
- switch (category) {
- case PluralCategory::Other:
- return "other"sv;
- case PluralCategory::Zero:
- return "zero"sv;
- case PluralCategory::One:
- return "one"sv;
- case PluralCategory::Two:
- return "two"sv;
- case PluralCategory::Few:
- return "few"sv;
- case PluralCategory::Many:
- return "many"sv;
- case PluralCategory::ExactlyZero:
- return "0"sv;
- case PluralCategory::ExactlyOne:
- return "1"sv;
- }
- VERIFY_NOT_REACHED();
- }
- PluralCategory determine_plural_category(StringView locale, PluralForm form, PluralOperands operands);
- Span<PluralCategory const> available_plural_categories(StringView locale, PluralForm form);
- PluralCategory determine_plural_range(StringView locale, PluralCategory start, PluralCategory end);
- }
|