From 69f7fe357a92e09c00fd0f535049c2c26f11ac6e Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Fri, 23 Apr 2021 09:12:08 -0700 Subject: [PATCH 1/5] Prepare for adding compile-time checks in --- stl/inc/format | 66 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/stl/inc/format b/stl/inc/format index e5a549e7749..1bfc69afe1e 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -2857,6 +2857,20 @@ _NODISCARD auto make_wformat_args(const _Args&... _Vals) { return _Format_arg_store{_Vals...}; } +template +struct _Fmt_basic_string { + basic_string_view<_CharT> _Str; + + template >, int> = 0> + constexpr _Fmt_basic_string(const _Ty& _Str_) : _Str{_Str_} {} +}; + +template +using _Fmt_string = _Fmt_basic_string...>; + +template +using _Fmt_wstring = _Fmt_basic_string...>; + template _OutputIt> _OutputIt vformat_to(_OutputIt _Out, const string_view _Fmt, const format_args _Args) { if constexpr (is_same_v<_OutputIt, _Fmt_it>) { @@ -2962,23 +2976,23 @@ _NODISCARD inline wstring vformat(const locale& _Loc, const wstring_view _Fmt, c } template -_NODISCARD string format(const string_view _Fmt, const _Types&... _Args) { - return _STD vformat(_Fmt, _STD make_format_args(_Args...)); +_NODISCARD string format(const _Fmt_string<_Types...> _Fmt, const _Types&... _Args) { + return _STD vformat(_Fmt._Str, _STD make_format_args(_Args...)); } template -_NODISCARD wstring format(const wstring_view _Fmt, const _Types&... _Args) { - return _STD vformat(_Fmt, _STD make_wformat_args(_Args...)); +_NODISCARD wstring format(const _Fmt_wstring<_Types...> _Fmt, const _Types&... _Args) { + return _STD vformat(_Fmt._Str, _STD make_wformat_args(_Args...)); } template -_NODISCARD string format(const locale& _Loc, const string_view _Fmt, const _Types&... _Args) { - return _STD vformat(_Loc, _Fmt, _STD make_format_args(_Args...)); +_NODISCARD string format(const locale& _Loc, const _Fmt_string<_Types...> _Fmt, const _Types&... _Args) { + return _STD vformat(_Loc, _Fmt._Str, _STD make_format_args(_Args...)); } template -_NODISCARD wstring format(const locale& _Loc, const wstring_view _Fmt, const _Types&... _Args) { - return _STD vformat(_Loc, _Fmt, _STD make_wformat_args(_Args...)); +_NODISCARD wstring format(const locale& _Loc, const _Fmt_wstring<_Types...> _Fmt, const _Types&... _Args) { + return _STD vformat(_Loc, _Fmt._Str, _STD make_wformat_args(_Args...)); } template @@ -2988,62 +3002,62 @@ struct format_to_n_result { }; template _OutputIt, class... _Types> -format_to_n_result<_OutputIt> format_to_n( - _OutputIt _Out, const iter_difference_t<_OutputIt> _Max, const string_view _Fmt, const _Types&... _Args) { +format_to_n_result<_OutputIt> format_to_n(_OutputIt _Out, const iter_difference_t<_OutputIt> _Max, + const _Fmt_string<_Types...> _Fmt, const _Types&... _Args) { _Fmt_iterator_buffer<_OutputIt, char, _Fmt_fixed_buffer_traits> _Buf(_STD move(_Out), _Max); - _STD vformat_to(_Fmt_it{_Buf}, _Fmt, _STD make_format_args(_Args...)); + _STD vformat_to(_Fmt_it{_Buf}, _Fmt._Str, _STD make_format_args(_Args...)); return {.out = _Buf._Out(), .size = _Buf._Count()}; } template _OutputIt, class... _Types> -format_to_n_result<_OutputIt> format_to_n( - _OutputIt _Out, const iter_difference_t<_OutputIt> _Max, const wstring_view _Fmt, const _Types&... _Args) { +format_to_n_result<_OutputIt> format_to_n(_OutputIt _Out, const iter_difference_t<_OutputIt> _Max, + const _Fmt_wstring<_Types...> _Fmt, const _Types&... _Args) { _Fmt_iterator_buffer<_OutputIt, wchar_t, _Fmt_fixed_buffer_traits> _Buf(_STD move(_Out), _Max); - _STD vformat_to(_Fmt_wit{_Buf}, _Fmt, _STD make_wformat_args(_Args...)); + _STD vformat_to(_Fmt_wit{_Buf}, _Fmt._Str, _STD make_wformat_args(_Args...)); return {.out = _Buf._Out(), .size = _Buf._Count()}; } template _OutputIt, class... _Types> format_to_n_result<_OutputIt> format_to_n(_OutputIt _Out, const iter_difference_t<_OutputIt> _Max, const locale& _Loc, - const string_view _Fmt, const _Types&... _Args) { + const _Fmt_string<_Types...> _Fmt, const _Types&... _Args) { _Fmt_iterator_buffer<_OutputIt, char, _Fmt_fixed_buffer_traits> _Buf(_STD move(_Out), _Max); - _STD vformat_to(_Fmt_it{_Buf}, _Loc, _Fmt, _STD make_format_args(_Args...)); + _STD vformat_to(_Fmt_it{_Buf}, _Loc, _Fmt._Str, _STD make_format_args(_Args...)); return {.out = _Buf._Out(), .size = _Buf._Count()}; } template _OutputIt, class... _Types> format_to_n_result<_OutputIt> format_to_n(_OutputIt _Out, const iter_difference_t<_OutputIt> _Max, const locale& _Loc, - const wstring_view _Fmt, const _Types&... _Args) { + const _Fmt_wstring<_Types...> _Fmt, const _Types&... _Args) { _Fmt_iterator_buffer<_OutputIt, wchar_t, _Fmt_fixed_buffer_traits> _Buf(_STD move(_Out), _Max); - _STD vformat_to(_Fmt_wit{_Buf}, _Loc, _Fmt, _STD make_wformat_args(_Args...)); + _STD vformat_to(_Fmt_wit{_Buf}, _Loc, _Fmt._Str, _STD make_wformat_args(_Args...)); return {.out = _Buf._Out(), .size = _Buf._Count()}; } template -_NODISCARD size_t formatted_size(const string_view _Fmt, const _Types&... _Args) { +_NODISCARD size_t formatted_size(const _Fmt_string<_Types...> _Fmt, const _Types&... _Args) { _Fmt_counting_buffer _Buf; - _STD vformat_to(_Fmt_it{_Buf}, _Fmt, _STD make_format_args(_Args...)); + _STD vformat_to(_Fmt_it{_Buf}, _Fmt._Str, _STD make_format_args(_Args...)); return _Buf._Count(); } template -_NODISCARD size_t formatted_size(const wstring_view _Fmt, const _Types&... _Args) { +_NODISCARD size_t formatted_size(const _Fmt_wstring<_Types...> _Fmt, const _Types&... _Args) { _Fmt_counting_buffer _Buf; - _STD vformat_to(_Fmt_wit{_Buf}, _Fmt, _STD make_wformat_args(_Args...)); + _STD vformat_to(_Fmt_wit{_Buf}, _Fmt._Str, _STD make_wformat_args(_Args...)); return _Buf._Count(); } template -_NODISCARD size_t formatted_size(const locale& _Loc, const string_view _Fmt, const _Types&... _Args) { +_NODISCARD size_t formatted_size(const locale& _Loc, const _Fmt_string<_Types...> _Fmt, const _Types&... _Args) { _Fmt_counting_buffer _Buf; - _STD vformat_to(_Fmt_it{_Buf}, _Loc, _Fmt, _STD make_format_args(_Args...)); + _STD vformat_to(_Fmt_it{_Buf}, _Loc, _Fmt._Str, _STD make_format_args(_Args...)); return _Buf._Count(); } template -_NODISCARD size_t formatted_size(const locale& _Loc, const wstring_view _Fmt, const _Types&... _Args) { +_NODISCARD size_t formatted_size(const locale& _Loc, const _Fmt_wstring<_Types...> _Fmt, const _Types&... _Args) { _Fmt_counting_buffer _Buf; - _STD vformat_to(_Fmt_wit{_Buf}, _Loc, _Fmt, _STD make_wformat_args(_Args...)); + _STD vformat_to(_Fmt_wit{_Buf}, _Loc, _Fmt._Str, _STD make_wformat_args(_Args...)); return _Buf._Count(); } From 20d8e8f27aaa8cc79af8ffcf9d21fc4e1a3bfc0c Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Mon, 26 Apr 2021 18:03:37 -0700 Subject: [PATCH 2/5] Add comment, _Fmt_basic_string -> _Basic_format_string --- stl/inc/format | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/stl/inc/format b/stl/inc/format index 1bfc69afe1e..a69c482d09c 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -2858,18 +2858,19 @@ _NODISCARD auto make_wformat_args(const _Args&... _Vals) { } template -struct _Fmt_basic_string { +struct _Basic_format_string { basic_string_view<_CharT> _Str; + // This constructor should be consteval once there is a compiler support. template >, int> = 0> - constexpr _Fmt_basic_string(const _Ty& _Str_) : _Str{_Str_} {} + constexpr _Basic_format_string(const _Ty& _Str_) : _Str{_Str_} {} }; template -using _Fmt_string = _Fmt_basic_string...>; +using _Fmt_string = _Basic_format_string...>; template -using _Fmt_wstring = _Fmt_basic_string...>; +using _Fmt_wstring = _Basic_format_string...>; template _OutputIt> _OutputIt vformat_to(_OutputIt _Out, const string_view _Fmt, const format_args _Args) { From 1fc3171f48f4a94d692df868cd2127b7e65bc02b Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Tue, 27 Apr 2021 21:22:02 -0700 Subject: [PATCH 3/5] Update comment --- stl/inc/format | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/format b/stl/inc/format index a69c482d09c..5593fac86a4 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -2861,7 +2861,7 @@ template struct _Basic_format_string { basic_string_view<_CharT> _Str; - // This constructor should be consteval once there is a compiler support. + // TRANSITION, consteval compiler support template >, int> = 0> constexpr _Basic_format_string(const _Ty& _Str_) : _Str{_Str_} {} }; From b8c5676a0acf6cb8ea9e2dd0ca450f70b5720e68 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Thu, 29 Apr 2021 06:26:03 -0700 Subject: [PATCH 4/5] Use _Fmt_*string in format_to overloads --- stl/inc/format | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/stl/inc/format b/stl/inc/format index 5593fac86a4..43e40fb6bea 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -2929,23 +2929,23 @@ _OutputIt vformat_to(_OutputIt _Out, const locale& _Loc, const wstring_view _Fmt } template _OutputIt, class... _Types> -_OutputIt format_to(_OutputIt _Out, const string_view _Fmt, const _Types&... _Args) { - return _STD vformat_to(_STD move(_Out), _Fmt, _STD make_format_args(_Args...)); +_OutputIt format_to(_OutputIt _Out, const _Fmt_string<_Types...> _Fmt, const _Types&... _Args) { + return _STD vformat_to(_STD move(_Out), _Fmt._Str, _STD make_format_args(_Args...)); } template _OutputIt, class... _Types> -_OutputIt format_to(_OutputIt _Out, const wstring_view _Fmt, const _Types&... _Args) { - return _STD vformat_to(_STD move(_Out), _Fmt, _STD make_wformat_args(_Args...)); +_OutputIt format_to(_OutputIt _Out, const _Fmt_wstring<_Types...> _Fmt, const _Types&... _Args) { + return _STD vformat_to(_STD move(_Out), _Fmt._Str, _STD make_wformat_args(_Args...)); } template _OutputIt, class... _Types> -_OutputIt format_to(_OutputIt _Out, const locale& _Loc, const string_view _Fmt, const _Types&... _Args) { - return _STD vformat_to(_STD move(_Out), _Loc, _Fmt, _STD make_format_args(_Args...)); +_OutputIt format_to(_OutputIt _Out, const locale& _Loc, const _Fmt_string<_Types...> _Fmt, const _Types&... _Args) { + return _STD vformat_to(_STD move(_Out), _Loc, _Fmt._Str, _STD make_format_args(_Args...)); } template _OutputIt, class... _Types> -_OutputIt format_to(_OutputIt _Out, const locale& _Loc, const wstring_view _Fmt, const _Types&... _Args) { - return _STD vformat_to(_STD move(_Out), _Loc, _Fmt, _STD make_wformat_args(_Args...)); +_OutputIt format_to(_OutputIt _Out, const locale& _Loc, const _Fmt_wstring<_Types...> _Fmt, const _Types&... _Args) { + return _STD vformat_to(_STD move(_Out), _Loc, _Fmt._Str, _STD make_wformat_args(_Args...)); } _NODISCARD inline string vformat(const string_view _Fmt, const format_args _Args) { From 09cb3f036c9abd30c3773bcb91ee9337d8e5a2f7 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Thu, 29 Apr 2021 07:14:43 -0700 Subject: [PATCH 5/5] Replace SFINAE with a concept check --- stl/inc/format | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/stl/inc/format b/stl/inc/format index 43e40fb6bea..0683f56dd28 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -2862,8 +2862,9 @@ struct _Basic_format_string { basic_string_view<_CharT> _Str; // TRANSITION, consteval compiler support - template >, int> = 0> - constexpr _Basic_format_string(const _Ty& _Str_) : _Str{_Str_} {} + template + requires convertible_to> constexpr _Basic_format_string(const _Ty& _Str_) + : _Str{_Str_} {} }; template