diff --git a/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeDateTimeFormat.cpp b/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeDateTimeFormat.cpp index a38f379388f..7a8733ec3e0 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeDateTimeFormat.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeDateTimeFormat.cpp @@ -55,6 +55,9 @@ constexpr auto s_calendar_symbols_list_index_type = "u8"sv; using CalendarIndexType = u8; constexpr auto s_calendar_index_type = "u8"sv; +using TimeZoneIndexType = u16; +constexpr auto s_time_zone_index_type = "u16"sv; + struct CalendarPattern : public Unicode::CalendarPattern { bool contains_only_date_fields() const { @@ -367,11 +370,43 @@ struct AK::Traits : public GenericTraits { }; struct TimeZone { + unsigned hash() const + { + auto hash = int_hash(time_zone); + hash = pair_int_hash(hash, long_name); + hash = pair_int_hash(hash, short_name); + return hash; + } + + bool operator==(TimeZone const& other) const + { + return (time_zone == other.time_zone) + && (long_name == other.long_name) + && (short_name == other.short_name); + } + StringIndexType time_zone { 0 }; StringIndexType long_name { 0 }; StringIndexType short_name { 0 }; }; +template<> +struct AK::Formatter : Formatter { + ErrorOr format(FormatBuilder& builder, TimeZone const& time_zone) + { + return Formatter::format(builder, + "{{ {}, {}, {} }}", + time_zone.time_zone, + time_zone.long_name, + time_zone.short_name); + } +}; + +template<> +struct AK::Traits : public GenericTraits { + static unsigned hash(TimeZone const& t) { return t.hash(); } +}; + struct DayPeriod { Unicode::DayPeriod day_period {}; u8 begin { 0 }; @@ -380,7 +415,7 @@ struct DayPeriod { struct Locale { HashMap calendars; - HashMap time_zones; + HashMap time_zones; Vector day_periods; }; @@ -395,6 +430,7 @@ struct UnicodeLocaleData { UniqueStorage unique_calendar_symbols; UniqueStorage unique_calendar_symbols_lists; UniqueStorage unique_calendars; + UniqueStorage unique_time_zones; HashMap locales; @@ -1282,7 +1318,8 @@ static ErrorOr parse_time_zone_names(String locale_time_zone_names_path, U if (!locale_data.time_zones.contains_slow(time_zone_name)) locale_data.time_zones.append(time_zone_name); - locale.time_zones.set(time_zone_name, move(time_zone)); + auto time_zone_index = locale_data.unique_time_zones.ensure(move(time_zone)); + locale.time_zones.set(time_zone_name, time_zone_index); }; meta_zone_object.as_object().for_each_member([&](auto const& meta_zone, JsonValue const& value) { @@ -1465,6 +1502,7 @@ static void generate_unicode_locale_implementation(Core::File& file, UnicodeLoca generator.set("calendar_symbols_index_type"sv, s_calendar_symbols_index_type); generator.set("calendar_symbols_list_index_type"sv, s_calendar_symbols_list_index_type); generator.set("calendar_index_type"sv, s_calendar_index_type); + generator.set("time_zone_index_type"sv, s_time_zone_index_type); generator.append(R"~~~( #include @@ -1633,6 +1671,7 @@ struct DayPeriodData { locale_data.unique_calendar_symbols.generate(generator, "CalendarSymbols"sv, "s_calendar_symbols"sv, 10); locale_data.unique_calendar_symbols_lists.generate(generator, s_calendar_symbols_index_type, "s_calendar_symbol_lists"sv); locale_data.unique_calendars.generate(generator, "CalendarData"sv, "s_calendars"sv, 10); + locale_data.unique_time_zones.generate(generator, "TimeZoneData"sv, "s_time_zones"sv, 30); auto append_calendars = [&](String name, auto const& calendars) { generator.set("name", name); @@ -1658,35 +1697,18 @@ static constexpr Array<@calendar_index_type@, @size@> @name@ { {)~~~"); generator.set("size", String::number(locale_data.time_zones.size())); generator.append(R"~~~( -static constexpr Array @name@ { {)~~~"); - - constexpr size_t max_values_per_row = 20; - size_t values_in_current_row = 0; +static constexpr Array<@time_zone_index_type@, @size@> @name@ { {)~~~"); + bool first = true; for (auto const& time_zone_key : locale_data.time_zones) { - auto time_zone = time_zones.find(time_zone_key); + auto time_zone = time_zones.get(time_zone_key).value_or(0); - if (values_in_current_row++ > 0) - generator.append(" "); - - if (time_zone == time_zones.end()) { - generator.append("{},"); - } else { - generator.set("time_zone", String::number(time_zone->value.time_zone)); - generator.set("long_name", String::number(time_zone->value.long_name)); - generator.set("short_name", String::number(time_zone->value.short_name)); - generator.append("{ @time_zone@, @long_name@, @short_name@ },"); - } - - if (values_in_current_row == max_values_per_row) { - values_in_current_row = 0; - generator.append("\n "); - } + generator.append(first ? " " : ", "); + generator.append(String::number(time_zone)); + first = false; } - generator.append(R"~~~( -} }; -)~~~"); + generator.append(" } };"); }; auto append_day_periods = [&](String name, auto const& day_periods) { @@ -1724,7 +1746,7 @@ static constexpr Array @name@ { { )~~~"); }; generate_mapping(generator, locale_data.locales, s_calendar_index_type, "s_locale_calendars"sv, "s_calendars_{}", [&](auto const& name, auto const& value) { append_calendars(name, value.calendars); }); - generate_mapping(generator, locale_data.locales, "TimeZoneData"sv, "s_time_zones"sv, "s_time_zones_{}", [&](auto const& name, auto const& value) { append_time_zones(name, value.time_zones); }); + generate_mapping(generator, locale_data.locales, s_time_zone_index_type, "s_locale_time_zones"sv, "s_time_zones_{}", [&](auto const& name, auto const& value) { append_time_zones(name, value.time_zones); }); generate_mapping(generator, locale_data.locales, "DayPeriodData"sv, "s_day_periods"sv, "s_day_periods_{}", [&](auto const& name, auto const& value) { append_day_periods(name, value.day_periods); }); generate_mapping(generator, locale_data.hour_cycle_regions, "u8"sv, "s_hour_cycles"sv, "s_hour_cycles_{}", [&](auto const& name, auto const& value) { append_hour_cycles(name, value); }); @@ -1973,10 +1995,12 @@ static TimeZoneData const* find_time_zone_data(StringView locale, StringView tim return nullptr; auto locale_index = to_underlying(*locale_value) - 1; // Subtract 1 because 0 == Locale::None. - auto time_zone_index = to_underlying(*time_zone_value); + size_t time_zone_index = to_underlying(*time_zone_value); - auto const& time_zones = s_time_zones.at(locale_index); - return &time_zones[time_zone_index]; + auto const& time_zone_indices = s_locale_time_zones.at(locale_index); + time_zone_index = time_zone_indices.at(time_zone_index); + + return &s_time_zones[time_zone_index]; } Optional get_time_zone_name(StringView locale, StringView time_zone, CalendarPatternStyle style)