From f681ec9d98acf6f6e07c9e5bf69e92d6ac58254b Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Sun, 12 Dec 2021 14:04:34 -0500 Subject: [PATCH] LibUnicode: Generate unique calendar symbols structures Each of the 374 generated calendars include 4 symbols structures. Of these 1496 structures, only 386 are unique. --- .../GenerateUnicodeDateTimeFormat.cpp | 106 ++++++++++++------ 1 file changed, 69 insertions(+), 37 deletions(-) diff --git a/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeDateTimeFormat.cpp b/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeDateTimeFormat.cpp index 996a82d98c..9ae77a6576 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeDateTimeFormat.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeDateTimeFormat.cpp @@ -40,6 +40,9 @@ constexpr auto s_calendar_format_index_type = "u8"sv; using SymbolListIndexType = u16; constexpr auto s_symbol_list_index_type = "u16"sv; +using CalendarSymbolsIndexType = u16; +constexpr auto s_calendar_symbols_index_type = "u16"sv; + struct CalendarPattern : public Unicode::CalendarPattern { bool contains_only_date_fields() const { @@ -246,11 +249,42 @@ struct AK::Traits : public GenericTraits { using SymbolList = Vector; struct CalendarSymbols { + unsigned hash() const + { + auto hash = pair_int_hash(narrow_symbols, short_symbols); + hash = pair_int_hash(hash, long_symbols); + return hash; + } + + bool operator==(CalendarSymbols const& other) const + { + return (narrow_symbols == other.narrow_symbols) + && (short_symbols == other.short_symbols) + && (long_symbols == other.long_symbols); + } + SymbolListIndexType narrow_symbols { 0 }; SymbolListIndexType short_symbols { 0 }; SymbolListIndexType long_symbols { 0 }; }; +template<> +struct AK::Formatter : Formatter { + ErrorOr format(FormatBuilder& builder, CalendarSymbols const& symbols) + { + return Formatter::format(builder, + "{{ {}, {}, {} }}", + symbols.narrow_symbols, + symbols.short_symbols, + symbols.long_symbols); + } +}; + +template<> +struct AK::Traits : public GenericTraits { + static unsigned hash(CalendarSymbols const& c) { return c.hash(); } +}; + struct Calendar { StringIndexType calendar { 0 }; @@ -263,7 +297,7 @@ struct Calendar { Vector range_formats {}; Vector range12_formats {}; - Vector symbols {}; + Vector symbols {}; }; struct TimeZone { @@ -290,6 +324,7 @@ struct UnicodeLocaleData { UniqueStorage unique_range_patterns; UniqueStorage unique_formats; UniqueStorage unique_symbol_lists; + UniqueStorage unique_calendar_symbols; HashMap locales; @@ -901,10 +936,13 @@ static void parse_calendar_symbols(Calendar& calendar, JsonObject const& calenda if (symbol_index >= calendar.symbols.size()) calendar.symbols.resize(symbol_index + 1); - auto& symbols = calendar.symbols.at(symbol_index); + CalendarSymbols symbols {}; symbols.narrow_symbols = locale_data.unique_symbol_lists.ensure(move(symbol_lists[0])); symbols.short_symbols = locale_data.unique_symbol_lists.ensure(move(symbol_lists[1])); symbols.long_symbols = locale_data.unique_symbol_lists.ensure(move(symbol_lists[2])); + + auto calendar_symbols_index = locale_data.unique_calendar_symbols.ensure(move(symbols)); + calendar.symbols[symbol_index] = calendar_symbols_index; }; auto parse_era_symbols = [&](auto const& symbols_object) { @@ -1340,6 +1378,7 @@ static void generate_unicode_locale_implementation(Core::File& file, UnicodeLoca generator.set("calendar_range_pattern_index_type"sv, s_calendar_range_pattern_index_type); generator.set("calendar_format_index_type"sv, s_calendar_format_index_type); generator.set("symbol_list_index_type"sv, s_symbol_list_index_type); + generator.set("calendar_symbols_index_type"sv, s_calendar_symbols_index_type); generator.append(R"~~~( #include @@ -1467,7 +1506,11 @@ struct CalendarFormat { @calendar_pattern_index_type@ short_format { 0 }; }; -using CalendarSymbols = Span<@string_index_type@ const>; +struct CalendarSymbols { + @symbol_list_index_type@ narrow_symbols { 0 }; + @symbol_list_index_type@ short_symbols { 0 }; + @symbol_list_index_type@ long_symbols { 0 }; +}; struct CalendarData { @string_index_type@ calendar { 0 }; @@ -1481,7 +1524,7 @@ struct CalendarData { Span<@calendar_range_pattern_index_type@ const> range_formats {}; Span<@calendar_range_pattern_index_type@ const> range12_formats {}; - Array symbols {}; + Array<@calendar_symbols_index_type@, 4> symbols {}; }; struct TimeZoneData { @@ -1499,6 +1542,7 @@ struct DayPeriodData { locale_data.unique_formats.generate(generator, "CalendarFormat"sv, "s_calendar_formats"sv, 10); locale_data.unique_symbol_lists.generate(generator, s_string_index_type, "s_symbol_lists"sv); + locale_data.unique_calendar_symbols.generate(generator, "CalendarSymbols"sv, "s_calendar_symbols"sv, 10); auto append_pattern_list = [&](auto name, auto type, auto const& formats) { generator.set("name", move(name)); @@ -1518,28 +1562,11 @@ static constexpr Array<@type@, @size@> @name@ { {)~~~"); generator.append(" } };"); }; - auto append_calendar_symbols = [&](auto name, auto const& symbols) { - static unsigned index = 0; // NOTE: This is very temporary, until the CalendarSymbols struct is made unique. - name = String::formatted("{}_{}", name, index++); - - generator.set("narrow_symbols", String::number(symbols.narrow_symbols)); - generator.set("short_symbols", String::number(symbols.short_symbols)); - generator.set("long_symbols", String::number(symbols.long_symbols)); - generator.set("name", name); - - generator.append(R"~~~( -static constexpr Array<@symbol_list_index_type@, 3> @name@ { { @narrow_symbols@, @short_symbols@, @long_symbols@ } };)~~~"); - - return name; - }; - auto append_calendars = [&](String name, auto const& calendars) { auto format_name = [&](StringView calendar_key, StringView type) { return String::formatted("{}_{}_{}", name, calendar_key, type); }; - Vector symbols_names; - for (auto const& calendar_key : locale_data.calendars) { auto const& calendar = calendars.find(calendar_key)->value; @@ -1547,15 +1574,6 @@ static constexpr Array<@symbol_list_index_type@, 3> @name@ { { @narrow_symbols@, append_pattern_list(format_name(calendar_key, "range_formats"sv), s_calendar_range_pattern_index_type, calendar.range_formats); append_pattern_list(format_name(calendar_key, "range12_formats"sv), s_calendar_range_pattern_index_type, calendar.range12_formats); generator.append("\n"); - - auto symbols_name = format_name(calendar_key, "symbols"sv); - - for (auto const& symbols : calendar.symbols) { - auto name = append_calendar_symbols(symbols_name, symbols); - symbols_names.append(name); - } - - generator.append("\n"); } generator.set("name", name); @@ -1583,9 +1601,9 @@ static constexpr Array @name@ { {)~~~"); generator.append("@default_range_format@, @range_formats@.span(), @range12_formats@.span(), {"); bool first = true; - for (auto const& symbols_name : symbols_names) { + for (auto symbols : calendar.symbols) { generator.append(first ? " " : ", "); - generator.append(String::formatted("{}.span()", symbols_name)); + generator.append(String::number(symbols)); first = false; } @@ -1805,16 +1823,30 @@ Vector get_calendar_range12_formats(StringView lo return result; } -static CalendarSymbols find_calendar_symbols(StringView locale, StringView calendar, CalendarSymbol symbol, CalendarPatternStyle style) +static Span<@string_index_type@ const> find_calendar_symbols(StringView locale, StringView calendar, CalendarSymbol symbol, CalendarPatternStyle style) { if (auto const* data = find_calendar_data(locale, calendar); data != nullptr) { auto symbol_index = to_underlying(symbol); - auto style_index = to_underlying(style); - auto symbols = data->symbols.at(symbol_index); - VERIFY(style_index < symbols.size()); + auto calendar_symbols_index = data->symbols.at(symbol_index); + auto const& symbols = s_calendar_symbols.at(calendar_symbols_index); + + @symbol_list_index_type@ symbol_list_index = 0; + + switch (style) { + case CalendarPatternStyle::Narrow: + symbol_list_index = symbols.narrow_symbols; + break; + case CalendarPatternStyle::Short: + symbol_list_index = symbols.short_symbols; + break; + case CalendarPatternStyle::Long: + symbol_list_index = symbols.long_symbols; + break; + default: + VERIFY_NOT_REACHED(); + } - auto symbol_list_index = symbols.at(style_index); return s_symbol_lists.at(symbol_list_index); }