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 @@ -124,6 +124,9 @@ back_insert_iterator<_Container> __it) : __container_(__it.__get_container()) {} + _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 @@ -560,15 +560,25 @@ 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{_VSTD::addressof(__buffer)}, __fmt, + __args); + __buffer.out(); return __res; } #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 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{_VSTD::addressof(__buffer)}, __fmt, + __args); + __buffer.out(); return __res; } #endif @@ -714,18 +724,26 @@ 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{_VSTD::addressof(__buffer)}, + _VSTD::move(__loc), __fmt, __args); + __buffer.out(); return __res; } #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS 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{_VSTD::addressof(__buffer)}, + _VSTD::move(__loc), __fmt, __args); + __buffer.out(); return __res; } #endif