diff --git a/libcxx/include/__format/buffer.h b/libcxx/include/__format/buffer.h --- a/libcxx/include/__format/buffer.h +++ b/libcxx/include/__format/buffer.h @@ -148,6 +148,9 @@ back_insert_iterator<_Container> __it) : __container_(__container_extractor<_Container>{__it}.get()) {} + _LIBCPP_HIDE_FROM_ABI explicit __container_buffer(_Container* __container) + : __container_(__container) {} + _LIBCPP_HIDE_FROM_ABI void put(_CharT __c) { *__buffer_it_++ = __c; // Profiling showed flushing after adding is more efficient than flushing diff --git a/libcxx/include/format b/libcxx/include/format --- a/libcxx/include/format +++ b/libcxx/include/format @@ -550,14 +550,26 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string vformat(string_view __fmt, format_args __args) { string __res; - _VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args); + using _Buffer = typename __format::__container_buffer; + _Buffer __buffer{&__res}; + _VSTD::__vformat_to( + __format::__output_iterator{&__format::__put<_Buffer, char>, + &__buffer}, + __fmt, __args); + __buffer.out(); return __res; } inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring vformat(wstring_view __fmt, wformat_args __args) { + using _Buffer = typename __format::__container_buffer; wstring __res; - _VSTD::vformat_to(_VSTD::back_inserter(__res), __fmt, __args); + _Buffer __buffer{&__res}; + _VSTD::__vformat_to( + __format::__output_iterator{&__format::__put<_Buffer, wchar_t>, + &__buffer}, + __fmt, __args); + __buffer.out(); return __res; } @@ -696,17 +708,27 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT string vformat(locale __loc, string_view __fmt, format_args __args) { + using _Buffer = typename __format::__container_buffer; string __res; - _VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt, - __args); + _Buffer __buffer{&__res}; + _VSTD::__vformat_to( + __format::__output_iterator{&__format::__put<_Buffer, char>, + &__buffer}, + _VSTD::move(__loc), __fmt, __args); + __buffer.out(); return __res; } inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT wstring vformat(locale __loc, wstring_view __fmt, wformat_args __args) { + using _Buffer = typename __format::__container_buffer; wstring __res; - _VSTD::vformat_to(_VSTD::back_inserter(__res), _VSTD::move(__loc), __fmt, - __args); + _Buffer __buffer{&__res}; + _VSTD::__vformat_to( + __format::__output_iterator{&__format::__put<_Buffer, wchar_t>, + &__buffer}, + _VSTD::move(__loc), __fmt, __args); + __buffer.out(); return __res; }