From c07828669158ba6dd7d7e59fcca73a01409f618a Mon Sep 17 00:00:00 2001 From: Adam Bucior <35536269+AdamBucior@users.noreply.github.com> Date: Mon, 5 Apr 2021 22:47:34 +0200 Subject: [PATCH 1/5] Reserve space in formatted string --- stl/inc/format | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/stl/inc/format b/stl/inc/format index 939581aff94..abbb2f80109 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -1451,6 +1451,10 @@ public: } } + _NODISCARD size_t _Get_count() const noexcept { + return _Num_args; + } + private: size_t _Num_args = 0; const unsigned char* _Storage = nullptr; @@ -2635,26 +2639,49 @@ _OutputIt format_to(_OutputIt _Out, const locale& _Loc, const wstring_view _Fmt, return _STD vformat_to(_STD move(_Out), _Loc, _Fmt, _STD make_format_args<_Context>(_Args...)); } +template +_NODISCARD size_t _Calculate_format_reserve_size(const basic_format_args<_Context> _Args) { + using _CharT = typename _Context::char_type; + size_t _Result = 0; + const auto _Visitor = [&_Result](const _ArgTy _Arg) { + if constexpr (is_same_v<_ArgTy, basic_string_view<_CharT>>) { + _Result += _Arg.size(); + } else if constexpr (is_same_v<_ArgTy, const _CharT*>) { + _Result += char_traits<_CharT>::length(_Arg); + } else { + _Result += 8; + } + }; + for (size_t _Idx = 0; _Idx < _Args._Get_count(); ++_Idx) { + _STD visit_format_arg(_Visitor, _Args.get(_Idx)); + } + return _Result; +} + _NODISCARD inline string vformat(const string_view _Fmt, const format_args _Args) { string _Str; + _Str.reserve(_Fmt.size() + _Calculate_format_reserve_size(_Args)); _STD vformat_to(_STD back_inserter(_Str), _Fmt, _Args); return _Str; } _NODISCARD inline wstring vformat(const wstring_view _Fmt, const wformat_args _Args) { wstring _Str; + _Str.reserve(_Fmt.size() + _Calculate_format_reserve_size(_Args)); _STD vformat_to(_STD back_inserter(_Str), _Fmt, _Args); return _Str; } _NODISCARD inline string vformat(const locale& _Loc, const string_view _Fmt, const format_args _Args) { string _Str; + _Str.reserve(_Fmt.size() + _Calculate_format_reserve_size(_Args)); _STD vformat_to(_STD back_inserter(_Str), _Loc, _Fmt, _Args); return _Str; } _NODISCARD inline wstring vformat(const locale& _Loc, const wstring_view _Fmt, const wformat_args _Args) { wstring _Str; + _Str.reserve(_Fmt.size() + _Calculate_format_reserve_size(_Args)); _STD vformat_to(_STD back_inserter(_Str), _Loc, _Fmt, _Args); return _Str; } From 8ccf924144ab1578f7cab571be09f43c47afb084 Mon Sep 17 00:00:00 2001 From: Adam Bucior <35536269+AdamBucior@users.noreply.github.com> Date: Mon, 5 Apr 2021 22:56:31 +0200 Subject: [PATCH 2/5] Make it a member function --- stl/inc/format | 45 ++++++++++++++++++++------------------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/stl/inc/format b/stl/inc/format index abbb2f80109..f38791dff68 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -1451,8 +1451,22 @@ public: } } - _NODISCARD size_t _Get_count() const noexcept { - return _Num_args; + _NODISCARD size_t _Calculate_reserve_size() const noexcept { + using _CharT = typename _Context::char_type; + size_t _Result = 0; + const auto _Visitor = [&_Result](const _ArgTy _Arg) noexcept { + if constexpr (is_same_v<_ArgTy, basic_string_view<_CharT>>) { + _Result += _Arg.size(); + } else if constexpr (is_same_v<_ArgTy, const _CharT*>) { + _Result += char_traits<_CharT>::length(_Arg); + } else { + _Result += 8; + } + }; + for (size_t _Idx = 0; _Idx < _Num_args; ++_Idx) { + _STD visit_format_arg(_Visitor, get(_Idx)); + } + return _Result; } private: @@ -2639,49 +2653,30 @@ _OutputIt format_to(_OutputIt _Out, const locale& _Loc, const wstring_view _Fmt, return _STD vformat_to(_STD move(_Out), _Loc, _Fmt, _STD make_format_args<_Context>(_Args...)); } -template -_NODISCARD size_t _Calculate_format_reserve_size(const basic_format_args<_Context> _Args) { - using _CharT = typename _Context::char_type; - size_t _Result = 0; - const auto _Visitor = [&_Result](const _ArgTy _Arg) { - if constexpr (is_same_v<_ArgTy, basic_string_view<_CharT>>) { - _Result += _Arg.size(); - } else if constexpr (is_same_v<_ArgTy, const _CharT*>) { - _Result += char_traits<_CharT>::length(_Arg); - } else { - _Result += 8; - } - }; - for (size_t _Idx = 0; _Idx < _Args._Get_count(); ++_Idx) { - _STD visit_format_arg(_Visitor, _Args.get(_Idx)); - } - return _Result; -} - _NODISCARD inline string vformat(const string_view _Fmt, const format_args _Args) { string _Str; - _Str.reserve(_Fmt.size() + _Calculate_format_reserve_size(_Args)); + _Str.reserve(_Fmt.size() + _Args._Calculate_reserve_size()); _STD vformat_to(_STD back_inserter(_Str), _Fmt, _Args); return _Str; } _NODISCARD inline wstring vformat(const wstring_view _Fmt, const wformat_args _Args) { wstring _Str; - _Str.reserve(_Fmt.size() + _Calculate_format_reserve_size(_Args)); + _Str.reserve(_Fmt.size() + _Args._Calculate_reserve_size()); _STD vformat_to(_STD back_inserter(_Str), _Fmt, _Args); return _Str; } _NODISCARD inline string vformat(const locale& _Loc, const string_view _Fmt, const format_args _Args) { string _Str; - _Str.reserve(_Fmt.size() + _Calculate_format_reserve_size(_Args)); + _Str.reserve(_Fmt.size() + _Args._Calculate_reserve_size()); _STD vformat_to(_STD back_inserter(_Str), _Loc, _Fmt, _Args); return _Str; } _NODISCARD inline wstring vformat(const locale& _Loc, const wstring_view _Fmt, const wformat_args _Args) { wstring _Str; - _Str.reserve(_Fmt.size() + _Calculate_format_reserve_size(_Args)); + _Str.reserve(_Fmt.size() + _Args._Calculate_reserve_size()); _STD vformat_to(_STD back_inserter(_Str), _Loc, _Fmt, _Args); return _Str; } From 6d0b529e5579fadaadfb8a8eb8d37fd2a5bb8c9d Mon Sep 17 00:00:00 2001 From: Adam Bucior <35536269+AdamBucior@users.noreply.github.com> Date: Tue, 6 Apr 2021 10:18:37 +0200 Subject: [PATCH 3/5] Rename to _Estimate_required_capacity --- stl/inc/format | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/stl/inc/format b/stl/inc/format index f38791dff68..ddd8138b682 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -1451,7 +1451,7 @@ public: } } - _NODISCARD size_t _Calculate_reserve_size() const noexcept { + _NODISCARD size_t _Estimate_required_capacity() const noexcept { using _CharT = typename _Context::char_type; size_t _Result = 0; const auto _Visitor = [&_Result](const _ArgTy _Arg) noexcept { @@ -2655,28 +2655,28 @@ _OutputIt format_to(_OutputIt _Out, const locale& _Loc, const wstring_view _Fmt, _NODISCARD inline string vformat(const string_view _Fmt, const format_args _Args) { string _Str; - _Str.reserve(_Fmt.size() + _Args._Calculate_reserve_size()); + _Str.reserve(_Fmt.size() + _Args._Estimate_required_capacity()); _STD vformat_to(_STD back_inserter(_Str), _Fmt, _Args); return _Str; } _NODISCARD inline wstring vformat(const wstring_view _Fmt, const wformat_args _Args) { wstring _Str; - _Str.reserve(_Fmt.size() + _Args._Calculate_reserve_size()); + _Str.reserve(_Fmt.size() + _Args._Estimate_required_capacity()); _STD vformat_to(_STD back_inserter(_Str), _Fmt, _Args); return _Str; } _NODISCARD inline string vformat(const locale& _Loc, const string_view _Fmt, const format_args _Args) { string _Str; - _Str.reserve(_Fmt.size() + _Args._Calculate_reserve_size()); + _Str.reserve(_Fmt.size() + _Args._Estimate_required_capacity()); _STD vformat_to(_STD back_inserter(_Str), _Loc, _Fmt, _Args); return _Str; } _NODISCARD inline wstring vformat(const locale& _Loc, const wstring_view _Fmt, const wformat_args _Args) { wstring _Str; - _Str.reserve(_Fmt.size() + _Args._Calculate_reserve_size()); + _Str.reserve(_Fmt.size() + _Args._Estimate_required_capacity()); _STD vformat_to(_STD back_inserter(_Str), _Loc, _Fmt, _Args); return _Str; } From bd1ecdb2f9e8da95d61a4909ee2037648b7fcd2d Mon Sep 17 00:00:00 2001 From: Adam Bucior <35536269+AdamBucior@users.noreply.github.com> Date: Wed, 7 Apr 2021 20:37:05 +0200 Subject: [PATCH 4/5] Eliminate strlen --- stl/inc/format | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/format b/stl/inc/format index ddd8138b682..239570f6e06 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -1458,7 +1458,7 @@ public: if constexpr (is_same_v<_ArgTy, basic_string_view<_CharT>>) { _Result += _Arg.size(); } else if constexpr (is_same_v<_ArgTy, const _CharT*>) { - _Result += char_traits<_CharT>::length(_Arg); + _Result += 32; } else { _Result += 8; } From 7380cbbdaabaa7424b00e9bbc0098b56d444e539 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 20 Apr 2021 01:23:24 -0700 Subject: [PATCH 5/5] Add comments explaining magic numbers. --- stl/inc/format | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stl/inc/format b/stl/inc/format index 239570f6e06..641dc80361a 100644 --- a/stl/inc/format +++ b/stl/inc/format @@ -1458,9 +1458,9 @@ public: if constexpr (is_same_v<_ArgTy, basic_string_view<_CharT>>) { _Result += _Arg.size(); } else if constexpr (is_same_v<_ArgTy, const _CharT*>) { - _Result += 32; + _Result += 32; // estimate for length of null-terminated strings } else { - _Result += 8; + _Result += 8; // estimate for length of all other arguments } }; for (size_t _Idx = 0; _Idx < _Num_args; ++_Idx) {