mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-05-12 06:02:51 +00:00
LibUnicode: Generate unique number systems
This commit is contained in:
parent
2a7f36b392
commit
4c2c8b8e33
Notes:
sideshowbarker
2024-07-17 22:59:18 +09:00
Author: https://github.com/trflynn89
Commit: 4c2c8b8e33
Pull-request: https://github.com/SerenityOS/serenity/pull/11210
Reviewed-by: https://github.com/linusg ✅
1 changed files with 90 additions and 31 deletions
|
@ -41,6 +41,9 @@ constexpr auto s_number_format_list_index_type = "u16"sv;
|
|||
using NumericSymbolListIndexType = u8;
|
||||
constexpr auto s_numeric_symbol_list_index_type = "u8"sv;
|
||||
|
||||
using NumberSystemIndexType = u8;
|
||||
constexpr auto s_number_system_index_type = "u8"sv;
|
||||
|
||||
enum class NumberFormatType {
|
||||
Standard,
|
||||
Compact,
|
||||
|
@ -141,6 +144,40 @@ struct AK::Traits<NumberFormatList> : public GenericTraits<NumberFormatList> {
|
|||
using NumericSymbolList = Vector<StringIndexType>;
|
||||
|
||||
struct NumberSystem {
|
||||
unsigned hash() const
|
||||
{
|
||||
auto hash = pair_int_hash(system, symbols);
|
||||
hash = pair_int_hash(hash, primary_grouping_size);
|
||||
hash = pair_int_hash(hash, secondary_grouping_size);
|
||||
hash = pair_int_hash(hash, decimal_format);
|
||||
hash = pair_int_hash(hash, decimal_long_formats);
|
||||
hash = pair_int_hash(hash, decimal_short_formats);
|
||||
hash = pair_int_hash(hash, currency_format);
|
||||
hash = pair_int_hash(hash, accounting_format);
|
||||
hash = pair_int_hash(hash, currency_unit_formats);
|
||||
hash = pair_int_hash(hash, currency_short_formats);
|
||||
hash = pair_int_hash(hash, percent_format);
|
||||
hash = pair_int_hash(hash, scientific_format);
|
||||
return hash;
|
||||
}
|
||||
|
||||
bool operator==(NumberSystem const& other) const
|
||||
{
|
||||
return (system == other.system)
|
||||
&& (symbols == other.symbols)
|
||||
&& (primary_grouping_size == other.primary_grouping_size)
|
||||
&& (secondary_grouping_size == other.secondary_grouping_size)
|
||||
&& (decimal_format == other.decimal_format)
|
||||
&& (decimal_long_formats == other.decimal_long_formats)
|
||||
&& (decimal_short_formats == other.decimal_short_formats)
|
||||
&& (currency_format == other.currency_format)
|
||||
&& (accounting_format == other.accounting_format)
|
||||
&& (currency_unit_formats == other.currency_unit_formats)
|
||||
&& (currency_short_formats == other.currency_short_formats)
|
||||
&& (percent_format == other.percent_format)
|
||||
&& (scientific_format == other.scientific_format);
|
||||
}
|
||||
|
||||
StringIndexType system { 0 };
|
||||
NumericSymbolListIndexType symbols { 0 };
|
||||
|
||||
|
@ -160,6 +197,33 @@ struct NumberSystem {
|
|||
NumberFormatIndexType scientific_format { 0 };
|
||||
};
|
||||
|
||||
template<>
|
||||
struct AK::Formatter<NumberSystem> : Formatter<FormatString> {
|
||||
ErrorOr<void> format(FormatBuilder& builder, NumberSystem const& system)
|
||||
{
|
||||
return Formatter<FormatString>::format(builder,
|
||||
"{{ {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {} }}",
|
||||
system.system,
|
||||
system.symbols,
|
||||
system.primary_grouping_size,
|
||||
system.secondary_grouping_size,
|
||||
system.decimal_format,
|
||||
system.decimal_long_formats,
|
||||
system.decimal_short_formats,
|
||||
system.currency_format,
|
||||
system.accounting_format,
|
||||
system.currency_unit_formats,
|
||||
system.currency_short_formats,
|
||||
system.percent_format,
|
||||
system.scientific_format);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct AK::Traits<NumberSystem> : public GenericTraits<NumberSystem> {
|
||||
static unsigned hash(NumberSystem const& s) { return s.hash(); }
|
||||
};
|
||||
|
||||
struct Unit {
|
||||
StringIndexType unit { 0 };
|
||||
NumberFormatListIndexType long_formats { 0 };
|
||||
|
@ -168,7 +232,7 @@ struct Unit {
|
|||
};
|
||||
|
||||
struct Locale {
|
||||
HashMap<String, NumberSystem> number_systems;
|
||||
HashMap<String, NumberSystemIndexType> number_systems;
|
||||
HashMap<String, Unit> units {};
|
||||
};
|
||||
|
||||
|
@ -177,6 +241,7 @@ struct UnicodeLocaleData {
|
|||
UniqueStorage<NumberFormat, NumberFormatIndexType> unique_formats;
|
||||
UniqueStorage<NumberFormatList, NumberFormatListIndexType> unique_format_lists;
|
||||
UniqueStorage<NumericSymbolList, NumericSymbolListIndexType> unique_symbols;
|
||||
UniqueStorage<NumberSystem, NumberSystemIndexType> unique_systems;
|
||||
|
||||
HashMap<String, Locale> locales;
|
||||
size_t max_identifier_count { 0 };
|
||||
|
@ -332,8 +397,10 @@ static ErrorOr<void> parse_number_systems(String locale_numbers_path, UnicodeLoc
|
|||
auto const& locale_object = main_object.as_object().get(numbers_path.parent().basename());
|
||||
auto const& locale_numbers_object = locale_object.as_object().get("numbers"sv);
|
||||
|
||||
HashMap<String, NumberSystem> number_systems;
|
||||
|
||||
auto ensure_number_system = [&](auto const& system) -> NumberSystem& {
|
||||
return locale.number_systems.ensure(system, [&]() {
|
||||
return number_systems.ensure(system, [&]() {
|
||||
auto system_index = locale_data.unique_strings.ensure(system);
|
||||
return NumberSystem { .system = system_index };
|
||||
});
|
||||
|
@ -464,6 +531,11 @@ static ErrorOr<void> parse_number_systems(String locale_numbers_path, UnicodeLoc
|
|||
}
|
||||
});
|
||||
|
||||
for (auto& number_system : number_systems) {
|
||||
auto system_index = locale_data.unique_systems.ensure(move(number_system.value));
|
||||
locale.number_systems.set(number_system.key, system_index);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -720,39 +792,24 @@ struct Unit {
|
|||
locale_data.unique_formats.generate(generator, "NumberFormat"sv, "s_number_formats"sv, 10);
|
||||
locale_data.unique_format_lists.generate(generator, s_number_format_index_type, "s_number_format_lists"sv);
|
||||
locale_data.unique_symbols.generate(generator, s_string_index_type, "s_numeric_symbol_lists"sv);
|
||||
locale_data.unique_systems.generate(generator, "NumberSystem"sv, "s_number_systems"sv, 10);
|
||||
|
||||
auto append_number_systems = [&](String name, auto const& number_systems) {
|
||||
auto append_map = [&](String name, auto type, auto const& map) {
|
||||
generator.set("name", name);
|
||||
generator.set("size", String::number(number_systems.size()));
|
||||
generator.set("type", type);
|
||||
generator.set("size", String::number(map.size()));
|
||||
|
||||
generator.append(R"~~~(
|
||||
static constexpr Array<NumberSystem, @size@> @name@ { {)~~~");
|
||||
static constexpr Array<@type@, @size@> @name@ { {)~~~");
|
||||
|
||||
for (auto const& number_system : number_systems) {
|
||||
generator.set("system"sv, String::number(number_system.value.system));
|
||||
generator.set("symbols"sv, String::number(number_system.value.symbols));
|
||||
generator.set("primary_grouping_size"sv, String::number(number_system.value.primary_grouping_size));
|
||||
generator.set("secondary_grouping_size"sv, String::number(number_system.value.secondary_grouping_size));
|
||||
generator.set("decimal_format", String::number(number_system.value.decimal_format));
|
||||
generator.set("decimal_long_formats"sv, String::number(number_system.value.decimal_long_formats));
|
||||
generator.set("decimal_short_formats"sv, String::number(number_system.value.decimal_short_formats));
|
||||
generator.set("currency_format", String::number(number_system.value.currency_format));
|
||||
generator.set("accounting_format", String::number(number_system.value.accounting_format));
|
||||
generator.set("currency_unit_formats"sv, String::number(number_system.value.currency_unit_formats));
|
||||
generator.set("currency_short_formats"sv, String::number(number_system.value.currency_short_formats));
|
||||
generator.set("percent_format", String::number(number_system.value.percent_format));
|
||||
generator.set("scientific_format", String::number(number_system.value.scientific_format));
|
||||
|
||||
generator.append("\n { ");
|
||||
generator.append("@system@, @symbols@, @primary_grouping_size@, @secondary_grouping_size@, ");
|
||||
generator.append("@decimal_format@, @decimal_long_formats@, @decimal_short_formats@, ");
|
||||
generator.append("@currency_format@, @accounting_format@, @currency_unit_formats@, @currency_short_formats@, ");
|
||||
generator.append("@percent_format@, @scientific_format@ },");
|
||||
bool first = true;
|
||||
for (auto const& item : map) {
|
||||
generator.append(first ? " " : ", ");
|
||||
generator.append(String::number(item.value));
|
||||
first = false;
|
||||
}
|
||||
|
||||
generator.append(R"~~~(
|
||||
} };
|
||||
)~~~");
|
||||
generator.append(" } };");
|
||||
};
|
||||
|
||||
auto append_units = [&](String name, auto const& units) {
|
||||
|
@ -777,7 +834,7 @@ static constexpr Array<Unit, @size@> @name@ { {)~~~");
|
|||
generator.append(" } };");
|
||||
};
|
||||
|
||||
generate_mapping(generator, locale_data.locales, "NumberSystem"sv, "s_number_systems"sv, "s_number_systems_{}", [&](auto const& name, auto const& value) { append_number_systems(name, value.number_systems); });
|
||||
generate_mapping(generator, locale_data.locales, s_number_system_index_type, "s_locale_number_systems"sv, "s_number_systems_{}", [&](auto const& name, auto const& value) { append_map(name, s_number_system_index_type, value.number_systems); });
|
||||
generate_mapping(generator, locale_data.locales, "Unit"sv, "s_units"sv, "s_units_{}", [&](auto const& name, auto const& value) { append_units(name, value.units); });
|
||||
|
||||
generator.append(R"~~~(
|
||||
|
@ -788,9 +845,11 @@ static NumberSystem const* find_number_system(StringView locale, StringView syst
|
|||
return nullptr;
|
||||
|
||||
auto locale_index = to_underlying(*locale_value) - 1; // Subtract 1 because 0 == Locale::None.
|
||||
auto const& number_systems = s_number_systems.at(locale_index);
|
||||
auto const& number_systems = s_locale_number_systems.at(locale_index);
|
||||
|
||||
for (auto system_index : number_systems) {
|
||||
auto const& number_system = s_number_systems.at(system_index);
|
||||
|
||||
for (auto const& number_system : number_systems) {
|
||||
if (system == s_string_list[number_system.system])
|
||||
return &number_system;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue