Optimize to_string - #1615
Conversation
There was a problem hiding this comment.
Pull request overview
This PR optimizes string conversion utilities in winrt by reducing unnecessary initialization work when converting wide strings to UTF-8, and by simplifying boolean to_hstring conversion to enable better compiler optimization.
Changes:
- Simplifies
to_hstring(bool)to a single ternary-based return expression. - Uses C++23
std::string::resize_and_overwrite(when available) into_string(std::wstring_view)to avoid pre-initializing the entire buffer.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.
Suppressed comments (1)
strings/base_string.h:721
- The new
resize_and_overwriteblock uses tab indentation (inconsistent with the surrounding 4-space indentation) and ignores the size passed byresize_and_overwrite(second lambda parameter), instead relying on the outersizevariable. Using the providedcountparameter both improves readability and ensures the conversion uses the buffer size actually provided by the library.
std::string result;
result.resize_and_overwrite(size, [&](char* buffer, std::size_t) -> std::size_t
{
WINRT_VERIFY_(size, WINRT_IMPL_WideCharToMultiByte(65001 /*CP_UTF8*/, 0, value.data(), static_cast<std::int32_t>(value.size()), buffer, size, nullptr, nullptr));
return size;
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.
Suppressed comments (3)
strings/base_string.h:720
- The new C++23
resize_and_overwriteblock uses tab indentation and inconsistent spacing compared to the surrounding code (which uses spaces). This makes the file formatting inconsistent and harder to review/maintain.
std::string result;
result.resize_and_overwrite(size, [&](char* buffer, std::size_t) -> std::size_t
{
auto bytes_written = WINRT_IMPL_WideCharToMultiByte(65001 /*CP_UTF8*/, 0, value.data(), static_cast<std::int32_t>(value.size()), buffer, size, nullptr, nullptr);
WINRT_VERIFY_(size, bytes_written);
strings/base_string.h:725
- In the non-
resize_and_overwritebranch,WINRT_VERIFY_is a no-op in release builds, so ifWideCharToMultiByteunexpectedly fails the function will return a string full of '?' characters. The C++23 branch would return an empty string (via returning 0 from the overwrite op), so behavior becomes inconsistent across standard library versions. Consider explicitly handling the failure/mismatch here as well and returning{}.
std::string result(size, '?');
WINRT_VERIFY_(size, WINRT_IMPL_WideCharToMultiByte(65001 /*CP_UTF8*/, 0, value.data(), static_cast<std::int32_t>(value.size()), result.data(), size, nullptr, nullptr));
strings/base_string.h:715
- PR description says the
resize_and_overwriteoptimization is forwinrt::to_hstring(std::string_view), but the actual change is into_string(std::wstring_view). Please align the description (or adjust the implementation ifto_hstring(std::string_view)was the intended target) so reviewers/users understand what’s being optimized.
#if defined(__cpp_lib_string_resize_and_overwrite) && __cpp_lib_string_resize_and_overwrite >= 202110L
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.
Suppressed comments (1)
strings/base_string.h:722
WINRT_VERIFY_compiles to a no-op in non-debug builds (strings/base_macros.h:15). In that configuration, returning0whenbytes_written != sizewould silently truncate the result to an empty string. Returning the actualbytes_writtenbetter matchesstd::string::resize_and_overwrite’s contract and avoids dropping partially written output. Also, these added lines use tab indentation while the surrounding code uses spaces.
result.resize_and_overwrite(size, [&](char* buffer, std::size_t) -> std::size_t
{
auto bytes_written = WINRT_IMPL_WideCharToMultiByte(65001 /*CP_UTF8*/, 0, value.data(), static_cast<std::int32_t>(value.size()), buffer, size, nullptr, nullptr);
WINRT_VERIFY_(size, bytes_written);
return bytes_written == size ? size : 0;
C++23 added
resize_and_overwriteto avoid the problem of initializing the entire string to zero duringresize.winrt::to_hstring(std::string_view)can take advantage of this feature.Additionally, using
value ? L"true" : L"false"instead of returning in two separateifbranches allows the compiler to optimize better, avoiding the generation of two constructor calls, see https://godbolt.org/z/xeY5K4vMh.