Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix handling of locale in chrono formatters #1892

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion stl/inc/chrono
Original file line number Diff line number Diff line change
Expand Up @@ -5272,6 +5272,7 @@ struct _Chrono_format_specs {
int _Dynamic_precision_index = -1;
_Fmt_align _Alignment = _Fmt_align::_None;
uint8_t _Fill_length = 1;
bool _Localized = false;
StephanTLavavej marked this conversation as resolved.
Show resolved Hide resolved
vitaut marked this conversation as resolved.
Show resolved Hide resolved
// At most one codepoint (so one char32_t or four utf-8 char8_t)
_CharT _Fill[4 / sizeof(_CharT)] = {_CharT{' '}};
// recursive definition in grammar, so could have any number of these
Expand Down Expand Up @@ -5327,6 +5328,10 @@ public:
_Specs._Dynamic_precision_index = _Verify_dynamic_arg_index_in_range(_Parse_ctx.next_arg_id());
}

constexpr void _On_localized() {
_Specs._Localized = true;
}

constexpr void _On_conversion_spec(char _Modifier, _CharT _Type) {
// NOTE: same performance note from _Basic_format_specs also applies here
if (_Modifier != '\0' && _Modifier != 'E' && _Modifier != 'O') {
Expand Down Expand Up @@ -5408,6 +5413,14 @@ _NODISCARD constexpr const _CharT* _Parse_chrono_format_specs(
}
}

if (*_Begin == 'L') {
_Callbacks._On_localized();
++_Begin;
if (_Begin == _End) {
return _Begin;
}
}

if (*_Begin != '}' && *_Begin != '%') {
_THROW(format_error("Invalid format string - chrono-specs must begin with conversion-spec"));
}
Expand Down Expand Up @@ -5935,7 +5948,7 @@ namespace chrono {
if (_Specs._Chrono_specs_list.empty()) {
_Stream << _Val; // N4885 [time.format]/6
} else {
_Stream.imbue(_FormatCtx.locale());
_Stream.imbue(_Specs._Localized ? _FormatCtx.locale() : std::locale::classic());
vitaut marked this conversation as resolved.
Show resolved Hide resolved
if constexpr (_Is_specialization_v<_Ty, hh_mm_ss>) {
if (_Val.is_negative()) {
_Stream << _CharT{'-'};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ struct testing_callbacks {
int expected_precision = -1;
size_t expected_dynamic_precision = static_cast<size_t>(-1);
bool expected_auto_dynamic_precision = false;
bool expected_localized = false;
vector<_Chrono_spec<CharT>>& expected_chrono_specs;
size_t curr_index = 0;

Expand Down Expand Up @@ -66,6 +67,9 @@ struct testing_callbacks {
void _On_dynamic_precision(_Auto_id_tag) {
assert(expected_auto_dynamic_precision);
}
void _On_localized() {
assert(expected_localized);
}
void _On_conversion_spec(char mod, CharT type) {
assert(mod == expected_chrono_specs[curr_index]._Modifier);
assert(static_cast<char>(type) == expected_chrono_specs[curr_index]._Type);
Expand Down Expand Up @@ -884,6 +888,13 @@ void test_zoned_time_formatter() {
assert(format(STR("{:%g %G %U %V %W}"), zt) == STR("21 2021 16 16 16"));
}

template <typename CharT>
void test_localized() {
auto loc = locale("ru-RU");
vitaut marked this conversation as resolved.
Show resolved Hide resolved
assert(format(loc, STR("{:%S}"), std::chrono::milliseconds(42)) == STR("00.042"));
assert(format(loc, STR("{:L%S}"), std::chrono::milliseconds(42)) == STR("00,042"));
vitaut marked this conversation as resolved.
Show resolved Hide resolved
}

void test() {
test_parse_conversion_spec<char>();
test_parse_conversion_spec<wchar_t>();
Expand Down Expand Up @@ -955,6 +966,9 @@ void test() {

test_zoned_time_formatter<char>();
test_zoned_time_formatter<wchar_t>();

test_localized<char>();
test_localized<wchar_t>();
}

int main() {
Expand Down