From 9626b9eef173bb50c88de091d2d9662659175e55 Mon Sep 17 00:00:00 2001 From: Charles Barto Date: Thu, 1 Oct 2020 14:22:14 -0700 Subject: [PATCH 01/11] add parse_precision. --- stl/inc/format | 1 - tests/std/tests/P0645R10_text_formatting_parsing/test.cpp | 5 ----- 2 files changed, 6 deletions(-) diff --git a/stl/inc/format b/stl/inc/format index a94aa8f8496..a541042617b 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -220,7 +220,6 @@ constexpr const _CharT* _Parse_precision(const _CharT* _Begin, const _CharT* _En if (_Begin != _End) { _Ch = *_Begin; } - if ('0' <= _Ch && _Ch <= '9') { int _Precision = 0; _Begin = _Parse_nonnegative_integer(_Begin, _End, _Precision); diff --git a/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp b/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp index 187dca249b5..ac54c6f8b10 100644 --- a/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp +++ b/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp @@ -202,11 +202,6 @@ constexpr bool test_parse_precision() { int main() { test_parse_align(); - test_parse_align(); - static_assert(test_parse_align()); - static_assert(test_parse_align()); - test_parse_arg_id(); - test_parse_arg_id(); static_assert(test_parse_arg_id()); static_assert(test_parse_arg_id()); test_parse_width(); From 6208a7413652f12ed7848ad26c69414bc69cf736 Mon Sep 17 00:00:00 2001 From: Charles Barto Date: Mon, 12 Oct 2020 13:44:44 -0700 Subject: [PATCH 02/11] adopt style review comments. --- stl/inc/format | 1 + 1 file changed, 1 insertion(+) diff --git a/stl/inc/format b/stl/inc/format index a541042617b..a94aa8f8496 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -220,6 +220,7 @@ constexpr const _CharT* _Parse_precision(const _CharT* _Begin, const _CharT* _En if (_Begin != _End) { _Ch = *_Begin; } + if ('0' <= _Ch && _Ch <= '9') { int _Precision = 0; _Begin = _Parse_nonnegative_integer(_Begin, _End, _Precision); From 23f2cd9df7090a7d999c66e0893c6fb68a9610c5 Mon Sep 17 00:00:00 2001 From: Charles Barto Date: Mon, 12 Oct 2020 15:47:16 -0700 Subject: [PATCH 03/11] add parse format spec --- stl/inc/format | 73 ++++++++++++++++++- .../P0645R10_text_formatting_parsing/test.cpp | 17 +++++ 2 files changed, 87 insertions(+), 3 deletions(-) diff --git a/stl/inc/format b/stl/inc/format index a94aa8f8496..ec533f68646 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -36,11 +36,13 @@ class format_error : public runtime_error { enum class _Align { _None, _Left, _Right, _Center }; +enum class _Sign { _None, _Plus, _Minus, _Space }; + struct _Auto_id_tag {}; // clang-format off template -concept _Parse_spec_callbacks = requires(_Ty _At, basic_string_view<_CharT> _Sv, _Align _Aln) { +concept _Parse_spec_callbacks = requires(_Ty _At, basic_string_view<_CharT> _Sv, _Align _Aln, _Sign _Sgn) { { _At._On_align(_Aln) } -> same_as; { _At._On_fill(_Sv) } -> same_as; { _At._On_width(_STD declval()) } -> same_as; @@ -49,8 +51,10 @@ concept _Parse_spec_callbacks = requires(_Ty _At, basic_string_view<_CharT> _Sv, { _At._On_precision(_STD declval()) } -> same_as; { _At._On_dynamic_precision(_STD declval()) } -> same_as; { _At._On_dynamic_precision(_STD declval<_Auto_id_tag>()) } -> same_as; - - /* { _At._On_type(_STD declval<_CharT>()) } -> same_as; */ + { _At._O_sign(_Sgn) } -> same_as; + { _At._On_hash() } -> same_as; + { _At._On_zero() } -> same_as; + { _At._On_type(_STD declval<_CharT>()) } -> same_as; }; template concept _Parse_arg_id_callbacks = requires(_Ty _At) { @@ -240,6 +244,69 @@ constexpr const _CharT* _Parse_precision(const _CharT* _Begin, const _CharT* _En return _Begin; } +template _Callbacks_type> +constexpr const _CharT* _Parse_format_specs(const _CharT* _Begin, const _CharT* _End, _Callbacks_type&& _Callbacks) { + if (_Begin == _End || *_Begin == '}') { + return _Begin; + } + + _Begin = _Parse_align(_Begin, _End, _Callbacks); + if (_Begin == _End) { + return _Begin; + } + + switch (*_Begin) { + case '+': + _Callbacks._On_sign(_Sign::_Plus); + ++_Begin; + break; + case '-': + _Callbacks._On_sign(_Sign::_Minus); + ++_Begin; + break; + case ' ': + _Callbacks._On_sign(_Sign::_Space); + ++_Begin; + break; + } + + if (_Begin == _End) { + return _Begin; + } + + // Parse hash. + if (*_Begin == '#') { + _Callbacks._On_hash(); + if (++_Begin == _End) { + return _Begin; + } + } + + // Parse zero flag + if (*_Begin == '0') { + _Callbacks._On_zero(); + if (++_Begin == _End) { + return _Begin; + } + } + + _Begin = _Parse_width(_Begin, _End, _Callbacks); + if (_Begin == _End) { + return _Begin; + } + + // Parse precision + if (*_Begin == '*') { + _Begin == _Parse_precision(_Begin, _End, _Callbacks); + } + + // Parse type + if (_Begin != _End && _Begin != '}') { + _Callbacks._On_type(*_Begin++); + } + return _Begin; +} + template struct formatter; diff --git a/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp b/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp index ac54c6f8b10..14e07dc7544 100644 --- a/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp +++ b/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -32,6 +33,7 @@ struct choose_literal { template struct testing_callbacks { _Align expected_alignment = _Align::_None; + _Sign expected_sign = _Sign::_None; basic_string_view expected_fill; int expected_width = -1; int expected_dynamic_width = -1; @@ -39,6 +41,9 @@ struct testing_callbacks { int expected_precision = -1; int expected_dynamic_precision = -1; bool expected_auto_dynamic_precision = false; + bool expected_hash = false; + bool expected_zero = false; + char expected_type = '\0'; constexpr void _On_align(_Align aln) { assert(aln == expected_alignment); } @@ -63,6 +68,18 @@ struct testing_callbacks { constexpr void _On_dynamic_precision(_Auto_id_tag) { assert(expected_auto_dynamic_precision); } + constexpr void _On_sign(_Sign sgn) { + assert(sgn = expected_sign); + } + constexpr void _On_hash() { + assert(expected_hash); + } + constexpr void _On_zero() { + assert(expected_zero); + } + constexpr void _On_type(CharT type) { + assert(type = expected_type); + } }; template testing_callbacks(_Align, basic_string_view) -> testing_callbacks; From ae8cbd96c78975cc95ab687148a9a8fbf05b9fd0 Mon Sep 17 00:00:00 2001 From: Charles Barto Date: Mon, 12 Oct 2020 16:28:18 -0700 Subject: [PATCH 04/11] add tests for parse_format_specs --- stl/inc/format | 2 +- .../P0645R10_text_formatting_parsing/test.cpp | 47 +++++++++++++++---- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/stl/inc/format b/stl/inc/format index ec533f68646..3d3d7d365cd 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -51,7 +51,7 @@ concept _Parse_spec_callbacks = requires(_Ty _At, basic_string_view<_CharT> _Sv, { _At._On_precision(_STD declval()) } -> same_as; { _At._On_dynamic_precision(_STD declval()) } -> same_as; { _At._On_dynamic_precision(_STD declval<_Auto_id_tag>()) } -> same_as; - { _At._O_sign(_Sgn) } -> same_as; + { _At._On_sign(_Sgn) } -> same_as; { _At._On_hash() } -> same_as; { _At._On_zero() } -> same_as; { _At._On_type(_STD declval<_CharT>()) } -> same_as; diff --git a/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp b/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp index 14e07dc7544..a078d1cf83d 100644 --- a/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp +++ b/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp @@ -43,7 +43,7 @@ struct testing_callbacks { bool expected_auto_dynamic_precision = false; bool expected_hash = false; bool expected_zero = false; - char expected_type = '\0'; + CharT expected_type = '\0'; constexpr void _On_align(_Align aln) { assert(aln == expected_alignment); } @@ -69,7 +69,7 @@ struct testing_callbacks { assert(expected_auto_dynamic_precision); } constexpr void _On_sign(_Sign sgn) { - assert(sgn = expected_sign); + assert(sgn == expected_sign); } constexpr void _On_hash() { assert(expected_hash); @@ -78,7 +78,7 @@ struct testing_callbacks { assert(expected_zero); } constexpr void _On_type(CharT type) { - assert(type = expected_type); + assert(type == expected_type); } }; template @@ -115,18 +115,20 @@ constexpr bool test_parse_align() { view_typ s2(TYPED_LITERAL(CharT, "*>")); view_typ s3(TYPED_LITERAL(CharT, "*^")); - test_parse_helper(parse_align_fn, s0, false, view_typ::npos, {_Align::_None, view_typ(TYPED_LITERAL(CharT, ""))}); - test_parse_helper(parse_align_fn, s1, false, view_typ::npos, {_Align::_Left, view_typ(TYPED_LITERAL(CharT, "*"))}); - test_parse_helper(parse_align_fn, s2, false, view_typ::npos, {_Align::_Right, view_typ(TYPED_LITERAL(CharT, "*"))}); - test_parse_helper( - parse_align_fn, s3, false, view_typ::npos, {_Align::_Center, view_typ(TYPED_LITERAL(CharT, "*"))}); + test_parse_helper(parse_align_fn, s0, false, view_typ::npos, {.expected_fill = view_typ(TYPED_LITERAL(CharT, ""))}); + test_parse_helper(parse_align_fn, s1, false, view_typ::npos, + {.expected_alignment = _Align::_Left, .expected_fill = view_typ(TYPED_LITERAL(CharT, "*"))}); + test_parse_helper(parse_align_fn, s2, false, view_typ::npos, + {.expected_alignment = _Align::_Right, .expected_fill = view_typ(TYPED_LITERAL(CharT, "*"))}); + test_parse_helper(parse_align_fn, s3, false, view_typ::npos, + {.expected_alignment = _Align::_Center, .expected_fill = view_typ(TYPED_LITERAL(CharT, "*"))}); if constexpr (same_as) { // This is a CJK character where the least significant byte is the same as ascii '>', // libfmt and initial drafts of narrowed characters when parsing alignments, causing // \x343E (which is from CJK unified ideographs extension A) and similar characters to parse as // an alignment specifier. auto s4 = L"*\x343E"sv; - test_parse_helper(parse_align_fn, s4, false, view_typ::npos, {_Align::_None, L"*"sv}); + test_parse_helper(parse_align_fn, s4, false, view_typ::npos, {.expected_fill = L"*"sv}); } return true; @@ -217,6 +219,29 @@ constexpr bool test_parse_precision() { return true; } +template +constexpr bool test_parse_format_specs() { + auto parse_format_specs_fn = _Parse_format_specs>; + using view_typ = basic_string_view; + + auto s0 = view_typ(TYPED_LITERAL(CharT, "{:6}")); + auto s1 = view_typ(TYPED_LITERAL(CharT, "{:*<6}")); + auto s2 = view_typ(TYPED_LITERAL(CharT, "{:*>6}")); + auto s3 = view_typ(TYPED_LITERAL(CharT, "{:*^6}")); + auto s4 = view_typ(TYPED_LITERAL(CharT, "{:6d}")); + + test_parse_helper(parse_format_specs_fn, s0, view_typ::npos, {.expected_width = 6}); + test_parse_helper(parse_format_specs_fn, s1, view_typ::npos, + {.expected_fill = view_typ(TYPED_LITERAL(CharT, '*')), .expected_align = _Align::_Left, .expected_width = 6}); + test_parse_helper(parse_format_specs_fn, s2, view_typ::npos, + {.expected_fill = view_typ(TYPED_LITERAL(CharT, '*')), .expected_align = _Align::_Right, .expected_width = 6}); + test_parse_helper(parse_format_specs_fn, s3, view_typ::npos, + {.expected_fill = view_typ(TYPED_LITERAL(CharT, '*')), .expected_align = _Align::_Center, .expected_width = 6}); + test_parse_helper(parse_format_specs_fn, s4, view_typ::npos, {.expected_width = 6, .expected_type = 'd'}); + + return true; +} + int main() { test_parse_align(); static_assert(test_parse_arg_id()); @@ -229,5 +254,9 @@ int main() { test_parse_precision(); static_assert(test_parse_precision()); static_assert(test_parse_precision()); + test_parse_precision(); + test_parse_precision(); + static_assert(test_parse_precision()); + static_assert(test_parse_precision()); return 0; } From 131c1f153222201e13a2b776950986be23bcee64 Mon Sep 17 00:00:00 2001 From: Charles Barto Date: Tue, 13 Oct 2020 17:44:08 -0700 Subject: [PATCH 05/11] actually call the test functions. --- tests/std/tests/P0645R10_text_formatting_parsing/test.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp b/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp index a078d1cf83d..7fb267a66f9 100644 --- a/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp +++ b/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp @@ -258,5 +258,9 @@ int main() { test_parse_precision(); static_assert(test_parse_precision()); static_assert(test_parse_precision()); + test_parse_format_specs(); + test_parse_format_specs(); + static_assert(test_parse_format_specs()); + static_assert(test_parse_format_specs()); return 0; } From 0f5351fa2d80461bf16e59887c3f18fb77c90add Mon Sep 17 00:00:00 2001 From: Charles Barto Date: Thu, 15 Oct 2020 16:30:25 -0700 Subject: [PATCH 06/11] fix tests. --- stl/inc/format | 4 +-- .../P0645R10_text_formatting_parsing/test.cpp | 34 +++++++++++-------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/stl/inc/format b/stl/inc/format index 3d3d7d365cd..522664deda2 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -297,11 +297,11 @@ constexpr const _CharT* _Parse_format_specs(const _CharT* _Begin, const _CharT* // Parse precision if (*_Begin == '*') { - _Begin == _Parse_precision(_Begin, _End, _Callbacks); + _Begin = _Parse_precision(_Begin, _End, _Callbacks); } // Parse type - if (_Begin != _End && _Begin != '}') { + if (_Begin != _End && *_Begin != '}') { _Callbacks._On_type(*_Begin++); } return _Begin; diff --git a/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp b/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp index 7fb267a66f9..6e5f23a095a 100644 --- a/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp +++ b/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp @@ -224,21 +224,25 @@ constexpr bool test_parse_format_specs() { auto parse_format_specs_fn = _Parse_format_specs>; using view_typ = basic_string_view; - auto s0 = view_typ(TYPED_LITERAL(CharT, "{:6}")); - auto s1 = view_typ(TYPED_LITERAL(CharT, "{:*<6}")); - auto s2 = view_typ(TYPED_LITERAL(CharT, "{:*>6}")); - auto s3 = view_typ(TYPED_LITERAL(CharT, "{:*^6}")); - auto s4 = view_typ(TYPED_LITERAL(CharT, "{:6d}")); - - test_parse_helper(parse_format_specs_fn, s0, view_typ::npos, {.expected_width = 6}); - test_parse_helper(parse_format_specs_fn, s1, view_typ::npos, - {.expected_fill = view_typ(TYPED_LITERAL(CharT, '*')), .expected_align = _Align::_Left, .expected_width = 6}); - test_parse_helper(parse_format_specs_fn, s2, view_typ::npos, - {.expected_fill = view_typ(TYPED_LITERAL(CharT, '*')), .expected_align = _Align::_Right, .expected_width = 6}); - test_parse_helper(parse_format_specs_fn, s3, view_typ::npos, - {.expected_fill = view_typ(TYPED_LITERAL(CharT, '*')), .expected_align = _Align::_Center, .expected_width = 6}); - test_parse_helper(parse_format_specs_fn, s4, view_typ::npos, {.expected_width = 6, .expected_type = 'd'}); - + view_typ s0(TYPED_LITERAL(CharT, "6}")); + view_typ s1(TYPED_LITERAL(CharT, "*<6}")); + view_typ s2(TYPED_LITERAL(CharT, "*>6}")); + view_typ s3(TYPED_LITERAL(CharT, "*^6}")); + view_typ s4(TYPED_LITERAL(CharT, "6d}")); + test_parse_helper(parse_format_specs_fn, s0, false, view_typ::npos, {.expected_width = 6}); + test_parse_helper(parse_format_specs_fn, s1, false, view_typ::npos, + {.expected_alignment = _Align::_Left, + .expected_fill = view_typ(TYPED_LITERAL(CharT, "*")), + .expected_width = 6}); + test_parse_helper(parse_format_specs_fn, s2, false, view_typ::npos, + {.expected_alignment = _Align::_Right, + .expected_fill = view_typ(TYPED_LITERAL(CharT, "*")), + .expected_width = 6}); + test_parse_helper(parse_format_specs_fn, s3, false, view_typ::npos, + {.expected_alignment = _Align::_Center, + .expected_fill = view_typ(TYPED_LITERAL(CharT, "*")), + .expected_width = 6}); + test_parse_helper(parse_format_specs_fn, s4, false, view_typ::npos, {.expected_width = 6, .expected_type = 'd'}); return true; } From 42bc1d47521c1346a6c5acbe895ca56331c398ca Mon Sep 17 00:00:00 2001 From: Charles Barto Date: Fri, 16 Oct 2020 13:38:36 -0700 Subject: [PATCH 07/11] test the return value of _Parse_format_specs --- .../tests/P0645R10_text_formatting_parsing/test.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp b/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp index 6e5f23a095a..83ba7e90158 100644 --- a/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp +++ b/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp @@ -225,24 +225,24 @@ constexpr bool test_parse_format_specs() { using view_typ = basic_string_view; view_typ s0(TYPED_LITERAL(CharT, "6}")); - view_typ s1(TYPED_LITERAL(CharT, "*<6}")); + view_typ s1(TYPED_LITERAL(CharT, "*<6")); view_typ s2(TYPED_LITERAL(CharT, "*>6}")); view_typ s3(TYPED_LITERAL(CharT, "*^6}")); view_typ s4(TYPED_LITERAL(CharT, "6d}")); - test_parse_helper(parse_format_specs_fn, s0, false, view_typ::npos, {.expected_width = 6}); - test_parse_helper(parse_format_specs_fn, s1, false, view_typ::npos, + test_parse_helper(parse_format_specs_fn, s0, false, s0.size() - 1, {.expected_width = 6}); + test_parse_helper(parse_format_specs_fn, s1, false, s1.size(), {.expected_alignment = _Align::_Left, .expected_fill = view_typ(TYPED_LITERAL(CharT, "*")), .expected_width = 6}); - test_parse_helper(parse_format_specs_fn, s2, false, view_typ::npos, + test_parse_helper(parse_format_specs_fn, s2, false, s2.size() - 1, {.expected_alignment = _Align::_Right, .expected_fill = view_typ(TYPED_LITERAL(CharT, "*")), .expected_width = 6}); - test_parse_helper(parse_format_specs_fn, s3, false, view_typ::npos, + test_parse_helper(parse_format_specs_fn, s3, false, s3.size() - 1, {.expected_alignment = _Align::_Center, .expected_fill = view_typ(TYPED_LITERAL(CharT, "*")), .expected_width = 6}); - test_parse_helper(parse_format_specs_fn, s4, false, view_typ::npos, {.expected_width = 6, .expected_type = 'd'}); + test_parse_helper(parse_format_specs_fn, s4, false, s4.size() - 1, {.expected_width = 6, .expected_type = 'd'}); return true; } From 1fccd6e59762f88c68058e01ccfe7eedc46c7bcc Mon Sep 17 00:00:00 2001 From: Charles Barto Date: Tue, 27 Oct 2020 16:37:22 -0700 Subject: [PATCH 08/11] added more tests for parse_format_specs. --- stl/inc/format | 2 +- .../P0645R10_text_formatting_parsing/test.cpp | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/stl/inc/format b/stl/inc/format index 522664deda2..9b3afa4818d 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -296,7 +296,7 @@ constexpr const _CharT* _Parse_format_specs(const _CharT* _Begin, const _CharT* } // Parse precision - if (*_Begin == '*') { + if (*_Begin == '.') { _Begin = _Parse_precision(_Begin, _End, _Callbacks); } diff --git a/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp b/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp index 83ba7e90158..2453ddd7726 100644 --- a/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp +++ b/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp @@ -229,6 +229,8 @@ constexpr bool test_parse_format_specs() { view_typ s2(TYPED_LITERAL(CharT, "*>6}")); view_typ s3(TYPED_LITERAL(CharT, "*^6}")); view_typ s4(TYPED_LITERAL(CharT, "6d}")); + view_typ s5(TYPED_LITERAL(CharT, "*^+4.4a}")); + view_typ s6(TYPED_LITERAL(CharT, "*^+#04.4a}")); test_parse_helper(parse_format_specs_fn, s0, false, s0.size() - 1, {.expected_width = 6}); test_parse_helper(parse_format_specs_fn, s1, false, s1.size(), {.expected_alignment = _Align::_Left, @@ -243,6 +245,22 @@ constexpr bool test_parse_format_specs() { .expected_fill = view_typ(TYPED_LITERAL(CharT, "*")), .expected_width = 6}); test_parse_helper(parse_format_specs_fn, s4, false, s4.size() - 1, {.expected_width = 6, .expected_type = 'd'}); + test_parse_helper(parse_format_specs_fn, s5, false, s5.size() - 1, + {.expected_alignment = _Align::_Center, + .expected_sign = _Sign::_Plus, + .expected_fill = view_typ(TYPED_LITERAL(CharT, "*")), + .expected_width = 4, + .expected_precision = 4, + .expected_type = 'a'}); + test_parse_helper(parse_format_specs_fn, s6, false, s6.size() - 1, + {.expected_alignment = _Align::_Center, + .expected_sign = _Sign::_Plus, + .expected_fill = view_typ(TYPED_LITERAL(CharT, "*")), + .expected_width = 4, + .expected_precision = 4, + .expected_hash = true, + .expected_zero = true, + .expected_type = 'a'}); return true; } From f92187a14c1381c011abe4da752ae9d76b59b481 Mon Sep 17 00:00:00 2001 From: Charles Barto Date: Mon, 9 Nov 2020 11:35:47 -0800 Subject: [PATCH 09/11] address review comments. --- stl/inc/format | 5 +---- .../P0645R10_text_formatting_parsing/test.cpp | 14 ++++++++++---- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/stl/inc/format b/stl/inc/format index 9b3afa4818d..a6a271e988b 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -274,7 +274,6 @@ constexpr const _CharT* _Parse_format_specs(const _CharT* _Begin, const _CharT* return _Begin; } - // Parse hash. if (*_Begin == '#') { _Callbacks._On_hash(); if (++_Begin == _End) { @@ -282,7 +281,6 @@ constexpr const _CharT* _Parse_format_specs(const _CharT* _Begin, const _CharT* } } - // Parse zero flag if (*_Begin == '0') { _Callbacks._On_zero(); if (++_Begin == _End) { @@ -295,12 +293,11 @@ constexpr const _CharT* _Parse_format_specs(const _CharT* _Begin, const _CharT* return _Begin; } - // Parse precision if (*_Begin == '.') { _Begin = _Parse_precision(_Begin, _End, _Callbacks); } - // Parse type + // If there's anything remaining we assume it's a type. if (_Begin != _End && *_Begin != '}') { _Callbacks._On_type(*_Begin++); } diff --git a/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp b/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp index 2453ddd7726..df734311038 100644 --- a/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp +++ b/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp @@ -266,23 +266,29 @@ constexpr bool test_parse_format_specs() { int main() { test_parse_align(); + test_parse_align(); + static_assert(test_parse_align()); + static_assert(test_parse_align()); + + test_parse_arg_id(); + test_parse_arg_id(); static_assert(test_parse_arg_id()); static_assert(test_parse_arg_id()); + test_parse_width(); test_parse_width(); static_assert(test_parse_width()); static_assert(test_parse_width()); + test_parse_precision(); test_parse_precision(); static_assert(test_parse_precision()); static_assert(test_parse_precision()); - test_parse_precision(); - test_parse_precision(); - static_assert(test_parse_precision()); - static_assert(test_parse_precision()); + test_parse_format_specs(); test_parse_format_specs(); static_assert(test_parse_format_specs()); static_assert(test_parse_format_specs()); + return 0; } From 49c418c22eb3a8b0808d568f522ff4348f3815e2 Mon Sep 17 00:00:00 2001 From: Charles Barto Date: Thu, 12 Nov 2020 11:23:30 -0800 Subject: [PATCH 10/11] make "we're not done yet" a precondition for _Parse_align. --- stl/inc/format | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/stl/inc/format b/stl/inc/format index a6a271e988b..abe4bb2f886 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -122,10 +122,7 @@ constexpr const _CharT* _Parse_arg_id(const _CharT* _Begin, const _CharT* _End, template _Callbacks_type> constexpr const _CharT* _Parse_align(const _CharT* _Begin, const _CharT* _End, _Callbacks_type&& _Callbacks) { - // done with parsing, or reached the end of a replacement field. - if (_Begin == _End || *_Begin == '}') { - return _Begin; - } + // Preconditions: _Begin != _End && *_Begin != '}' // align and fill auto _Parsed_align = _Align::_None; @@ -268,6 +265,8 @@ constexpr const _CharT* _Parse_format_specs(const _CharT* _Begin, const _CharT* _Callbacks._On_sign(_Sign::_Space); ++_Begin; break; + default: + break; } if (_Begin == _End) { From 2c0f0c40feaef4ca5b74de6ded50c605f1775e8a Mon Sep 17 00:00:00 2001 From: Charles Barto Date: Thu, 12 Nov 2020 13:11:10 -0800 Subject: [PATCH 11/11] remove test that voilates new preconditions on _Parse_align. --- stl/inc/format | 3 +-- tests/std/tests/P0645R10_text_formatting_parsing/test.cpp | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/stl/inc/format b/stl/inc/format index abe4bb2f886..16466b6980d 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -122,8 +122,7 @@ constexpr const _CharT* _Parse_arg_id(const _CharT* _Begin, const _CharT* _End, template _Callbacks_type> constexpr const _CharT* _Parse_align(const _CharT* _Begin, const _CharT* _End, _Callbacks_type&& _Callbacks) { - // Preconditions: _Begin != _End && *_Begin != '}' - + _STL_INTERNAL_CHECK(_Begin != _End && *_Begin != '}'); // align and fill auto _Parsed_align = _Align::_None; auto _Align_pt = _Begin + 1; diff --git a/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp b/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp index df734311038..85da914a9ac 100644 --- a/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp +++ b/tests/std/tests/P0645R10_text_formatting_parsing/test.cpp @@ -110,12 +110,10 @@ constexpr bool test_parse_align() { auto parse_align_fn = _Parse_align>; using view_typ = basic_string_view; - view_typ s0(TYPED_LITERAL(CharT, "")); view_typ s1(TYPED_LITERAL(CharT, "*<")); view_typ s2(TYPED_LITERAL(CharT, "*>")); view_typ s3(TYPED_LITERAL(CharT, "*^")); - test_parse_helper(parse_align_fn, s0, false, view_typ::npos, {.expected_fill = view_typ(TYPED_LITERAL(CharT, ""))}); test_parse_helper(parse_align_fn, s1, false, view_typ::npos, {.expected_alignment = _Align::_Left, .expected_fill = view_typ(TYPED_LITERAL(CharT, "*"))}); test_parse_helper(parse_align_fn, s2, false, view_typ::npos,