Make formatted_size part of the core API

This commit is contained in:
Victor Zverovich 2020-07-23 07:34:35 -07:00
parent 46a63b7087
commit 47f8d7a345
3 changed files with 34 additions and 16 deletions

View File

@ -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<buffer_context<type_identity_t<Char>>>)
.. 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&)

View File

@ -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 <typename T> 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<std::back_insert_iterator<Container>,
}
};
template <typename Container>
using container_buffer = iterator_buffer<std::back_insert_iterator<Container>,
typename Container::value_type>;
// A buffer that counts the number of code units written discarding the output.
template <typename T = char> class counting_buffer : public buffer<T> {
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<T>(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 <typename... Args>
inline size_t formatted_size(string_view format_str, Args&&... args) {
const auto& vargs = fmt::make_args_checked<Args...>(format_str, args...);
detail::counting_buffer<> buf;
detail::vformat_to(buf, format_str, vargs);
return buf.count();
}
template <typename S, typename Char = char_t<S>>
FMT_INLINE std::basic_string<Char> vformat(
const S& format_str,

View File

@ -3586,15 +3586,6 @@ std::basic_string<Char> detail::vformat(
return to_string(buffer);
}
/**
Returns the number of characters in the output of
``format(format_str, args...)``.
*/
template <typename... Args>
inline size_t formatted_size(string_view format_str, const Args&... args) {
return format_to(detail::counting_iterator(), format_str, args...).count();
}
template <typename Char, FMT_ENABLE_IF(std::is_same<Char, wchar_t>::value)>
void vprint(std::FILE* f, basic_string_view<Char> format_str,
wformat_args args) {