From 47f8d7a3450090a609779093eeabffcf6ff2d319 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Thu, 23 Jul 2020 07:34:35 -0700 Subject: [PATCH] Make formatted_size part of the core API --- doc/api.rst | 4 ++-- include/fmt/core.h | 37 ++++++++++++++++++++++++++++++++----- include/fmt/format.h | 9 --------- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/doc/api.rst b/doc/api.rst index 45f764ac..de032298 100644 --- a/doc/api.rst +++ b/doc/api.rst @@ -48,6 +48,8 @@ participate in an overload resolution if the latter is not a string. .. doxygenfunction:: format(const S&, Args&&...) .. doxygenfunction:: vformat(const S&, basic_format_args>>) +.. doxygenfunction:: fmt::formatted_size(string_view, Args&&...) + .. _print: .. doxygenfunction:: print(const S&, Args&&...) @@ -300,8 +302,6 @@ Utilities .. doxygentypedef:: fmt::char_t -.. doxygenfunction:: fmt::formatted_size(string_view, const Args&...) - .. doxygenfunction:: fmt::to_string(const T&) .. doxygenfunction:: fmt::to_wstring(const T&) diff --git a/include/fmt/core.h b/include/fmt/core.h index 7c1c5f55..e0112c95 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -269,8 +269,7 @@ struct monostate {}; namespace detail { -// A helper function to suppress bogus "conditional expression is constant" -// warnings. +// A helper function to suppress "conditional expression is constant" warnings. template constexpr T const_check(T value) { return value; } FMT_NORETURN FMT_API void assert_fail(const char* file, int line, @@ -797,9 +796,25 @@ class iterator_buffer, } }; -template -using container_buffer = iterator_buffer, - typename Container::value_type>; +// A buffer that counts the number of code units written discarding the output. +template class counting_buffer : public buffer { + private: + enum { buffer_size = 256 }; + T data_[buffer_size]; + size_t count_ = 0; + + protected: + void grow(size_t) final { + if (this->size() != buffer_size) return; + count_ += this->size(); + this->clear(); + } + + public: + counting_buffer() : buffer(data_, 0, buffer_size) {} + + size_t count() { return count_ + this->size(); } +}; // An output iterator that appends to the buffer. // It is used to reduce symbol sizes for the common case. @@ -1957,6 +1972,18 @@ inline OutputIt format_to(OutputIt out, const S& format_str, Args&&... args) { return vformat_to(out, to_string_view(format_str), vargs); } +/** + Returns the number of characters in the output of + ``format(format_str, args...)``. + */ +template +inline size_t formatted_size(string_view format_str, Args&&... args) { + const auto& vargs = fmt::make_args_checked(format_str, args...); + detail::counting_buffer<> buf; + detail::vformat_to(buf, format_str, vargs); + return buf.count(); +} + template > FMT_INLINE std::basic_string vformat( const S& format_str, diff --git a/include/fmt/format.h b/include/fmt/format.h index 712c6ebe..60b6f623 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -3586,15 +3586,6 @@ std::basic_string detail::vformat( return to_string(buffer); } -/** - Returns the number of characters in the output of - ``format(format_str, args...)``. - */ -template -inline size_t formatted_size(string_view format_str, const Args&... args) { - return format_to(detail::counting_iterator(), format_str, args...).count(); -} - template ::value)> void vprint(std::FILE* f, basic_string_view format_str, wformat_args args) {