[libcxx-commits] [PATCH] D110498: [libc++][format][4/6] Improve formatted_size.

Mark de Wever via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Sat Oct 16 08:00:29 PDT 2021


Mordante updated this revision to Diff 380185.
Mordante added a comment.

Rebased to test with `wchar_t` changes.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D110498/new/

https://reviews.llvm.org/D110498

Files:
  libcxx/include/__format/buffer.h
  libcxx/include/format


Index: libcxx/include/format
===================================================================
--- libcxx/include/format
+++ libcxx/include/format
@@ -624,16 +624,24 @@
 template <class... _Args>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
 formatted_size(string_view __fmt, const _Args&... __args) {
-  // TODO FMT Improve PoC: using std::string is inefficient.
-  return _VSTD::vformat(__fmt, _VSTD::make_format_args(__args...)).size();
+  using _Buffer = __format::__formatted_size_buffer<char>;
+  _Buffer __buffer;
+  _VSTD::__vformat_to(
+      __format::__output_iterator<char>{_VSTD::addressof(__buffer)}, __fmt,
+      basic_format_args{_VSTD::make_format_args(__args...)});
+  return __buffer.formatted_size();
 }
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
 template <class... _Args>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
 formatted_size(wstring_view __fmt, const _Args&... __args) {
-  // TODO FMT Improve PoC: using std::string is inefficient.
-  return _VSTD::vformat(__fmt, _VSTD::make_wformat_args(__args...)).size();
+  using _Buffer = __format::__formatted_size_buffer<wchar_t>;
+  _Buffer __buffer;
+  _VSTD::__vformat_to(
+      __format::__output_iterator<wchar_t>{_VSTD::addressof(__buffer)}, __fmt,
+      basic_format_args{_VSTD::make_wformat_args(__args...)});
+  return __buffer.formatted_size();
 }
 #endif
 
@@ -771,20 +779,26 @@
 template <class... _Args>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
 formatted_size(locale __loc, string_view __fmt, const _Args&... __args) {
-  // TODO FMT Improve PoC: using std::string is inefficient.
-  return _VSTD::vformat(_VSTD::move(__loc), __fmt,
-                        _VSTD::make_format_args(__args...))
-      .size();
+  using _Buffer = __format::__formatted_size_buffer<char>;
+  _Buffer __buffer;
+  _VSTD::__vformat_to(
+      __format::__output_iterator<char>{_VSTD::addressof(__buffer)},
+      _VSTD::move(__loc), __fmt,
+      basic_format_args{_VSTD::make_format_args(__args...)});
+  return __buffer.formatted_size();
 }
 
 #ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
 template <class... _Args>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_FORMAT size_t
 formatted_size(locale __loc, wstring_view __fmt, const _Args&... __args) {
-  // TODO FMT Improve PoC: using std::string is inefficient.
-  return _VSTD::vformat(_VSTD::move(__loc), __fmt,
-                        _VSTD::make_wformat_args(__args...))
-      .size();
+  using _Buffer = __format::__formatted_size_buffer<wchar_t>;
+  _Buffer __buffer;
+  _VSTD::__vformat_to(
+      __format::__output_iterator<wchar_t>{_VSTD::addressof(__buffer)},
+      _VSTD::move(__loc), __fmt,
+      basic_format_args{_VSTD::make_wformat_args(__args...)});
+  return __buffer.formatted_size();
 }
 #endif
 
Index: libcxx/include/__format/buffer.h
===================================================================
--- libcxx/include/__format/buffer.h
+++ libcxx/include/__format/buffer.h
@@ -166,6 +166,23 @@
                              __container_buffer<_Iterator>>;
 };
 
+/// A buffer that counts the number of insertions.
+///
+/// Since \ref formatted_size only needs to know the size the output itself is
+/// discarded.
+template <__formatter::__char_type _CharT>
+class _LIBCPP_TEMPLATE_VIS __formatted_size_buffer {
+public:
+  _LIBCPP_HIDE_FROM_ABI void put(_CharT) { ++__size_; }
+
+  _LIBCPP_HIDE_FROM_ABI size_t formatted_size() const noexcept {
+    return __size_;
+  }
+
+private:
+  size_t __size_{0};
+};
+
 } // namespace __format
 
 #endif // !defined(_LIBCPP_HAS_NO_CONCEPTS)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D110498.380185.patch
Type: text/x-patch
Size: 3573 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20211016/eef43ec9/attachment-0001.bin>


More information about the libcxx-commits mailing list