diff --git a/include/fmt/base.h b/include/fmt/base.h index cc06b9c4..d1cb5ef6 100644 --- a/include/fmt/base.h +++ b/include/fmt/base.h @@ -837,7 +837,7 @@ struct format_specs : basic_specs { */ template class parse_context { private: - basic_string_view format_str_; + basic_string_view fmt_; int next_arg_id_; enum { use_constexpr_cast = !FMT_GCC_VERSION || FMT_GCC_VERSION >= 1200 }; @@ -848,22 +848,20 @@ template class parse_context { using char_type = Char; using iterator = const Char*; - explicit constexpr parse_context(basic_string_view format_str, + explicit constexpr parse_context(basic_string_view fmt, int next_arg_id = 0) - : format_str_(format_str), next_arg_id_(next_arg_id) {} + : fmt_(fmt), next_arg_id_(next_arg_id) {} /// Returns an iterator to the beginning of the format string range being /// parsed. - constexpr auto begin() const noexcept -> iterator { - return format_str_.begin(); - } + constexpr auto begin() const noexcept -> iterator { return fmt_.begin(); } /// Returns an iterator past the end of the format string range being parsed. - constexpr auto end() const noexcept -> iterator { return format_str_.end(); } + constexpr auto end() const noexcept -> iterator { return fmt_.end(); } /// Advances the begin iterator to `it`. FMT_CONSTEXPR void advance_to(iterator it) { - format_str_.remove_prefix(detail::to_unsigned(it - begin())); + fmt_.remove_prefix(detail::to_unsigned(it - begin())); } /// Reports an error if using the manual argument indexing; otherwise returns @@ -1273,10 +1271,10 @@ class compile_parse_context : public parse_context { using base = parse_context; public: - explicit FMT_CONSTEXPR compile_parse_context( - basic_string_view format_str, int num_args, const type* types, - int next_arg_id = 0) - : base(format_str, next_arg_id), num_args_(num_args), types_(types) {} + explicit FMT_CONSTEXPR compile_parse_context(basic_string_view fmt, + int num_args, const type* types, + int next_arg_id = 0) + : base(fmt, next_arg_id), num_args_(num_args), types_(types) {} constexpr auto num_args() const -> int { return num_args_; } constexpr auto arg_type(int id) const -> type { return types_[id]; } diff --git a/include/fmt/chrono.h b/include/fmt/chrono.h index 940f357e..de06dfaf 100644 --- a/include/fmt/chrono.h +++ b/include/fmt/chrono.h @@ -2133,7 +2133,7 @@ struct formatter, Char> { detail::arg_ref width_ref_; detail::arg_ref precision_ref_; bool localized_ = false; - basic_string_view format_str_; + basic_string_view fmt_; public: FMT_CONSTEXPR auto parse(parse_context& ctx) -> const Char* { @@ -2159,7 +2159,7 @@ struct formatter, Char> { ++it; } end = detail::parse_chrono_format(it, end, checker); - format_str_ = {it, detail::to_unsigned(end - it)}; + fmt_ = {it, detail::to_unsigned(end - it)}; return end; } @@ -2169,7 +2169,7 @@ struct formatter, Char> { auto specs = specs_; auto precision = specs.precision; specs.precision = -1; - auto begin = format_str_.begin(), end = format_str_.end(); + auto begin = fmt_.begin(), end = fmt_.end(); // As a possible future optimization, we could avoid extra copying if width // is not specified. auto buf = basic_memory_buffer(); @@ -2200,7 +2200,7 @@ template struct formatter { detail::arg_ref width_ref_; protected: - basic_string_view format_str_; + basic_string_view fmt_; template auto do_format(const std::tm& tm, FormatContext& ctx, @@ -2215,7 +2215,7 @@ template struct formatter { detail::get_locale loc(static_cast(loc_ref), loc_ref); auto w = detail::tm_writer(loc, out, tm, subsecs); - detail::parse_chrono_format(format_str_.begin(), format_str_.end(), w); + detail::parse_chrono_format(fmt_.begin(), fmt_.end(), w); return detail::write( ctx.out(), basic_string_view(buf.data(), buf.size()), specs); } @@ -2235,8 +2235,8 @@ template struct formatter { } end = detail::parse_chrono_format(it, end, detail::tm_format_checker()); - // Replace the default format_str only if the new spec is not empty. - if (end != it) format_str_ = {it, detail::to_unsigned(end - it)}; + // Replace the default format string only if the new spec is not empty. + if (end != it) fmt_ = {it, detail::to_unsigned(end - it)}; return end; } @@ -2250,7 +2250,7 @@ template struct formatter { template struct formatter, Char> : formatter { FMT_CONSTEXPR formatter() { - this->format_str_ = detail::string_literal(); + this->fmt_ = detail::string_literal(); } template @@ -2292,7 +2292,7 @@ struct formatter, Char> template struct formatter, Char> : formatter { FMT_CONSTEXPR formatter() { - this->format_str_ = detail::string_literal(); + this->fmt_ = detail::string_literal(); } template diff --git a/include/fmt/format.h b/include/fmt/format.h index 3ae5ca9d..e442594d 100644 --- a/include/fmt/format.h +++ b/include/fmt/format.h @@ -964,6 +964,14 @@ class basic_memory_buffer : public detail::buffer { using memory_buffer = basic_memory_buffer; +template +FMT_NODISCARD auto to_string(const basic_memory_buffer& buf) + -> std::basic_string { + auto size = buf.size(); + detail::assume(size < std::basic_string().max_size()); + return std::basic_string(buf.data(), size); +} + // A writer to a buffered stream. It doesn't own the underlying stream. class writer { private: @@ -3880,11 +3888,39 @@ FMT_API void report_error(format_func func, int error_code, template struct has_format_as : bool_constant, void>::value> {}; + +FMT_BEGIN_EXPORT + +#ifndef FMT_HEADER_ONLY +extern template FMT_API auto thousands_sep_impl(locale_ref) + -> thousands_sep_result; +extern template FMT_API auto thousands_sep_impl(locale_ref) + -> thousands_sep_result; +extern template FMT_API auto decimal_point_impl(locale_ref) -> char; +extern template FMT_API auto decimal_point_impl(locale_ref) -> wchar_t; +#endif // FMT_HEADER_ONLY + +FMT_END_EXPORT + +template +template +FMT_CONSTEXPR auto native_formatter::format( + const T& val, FormatContext& ctx) const -> decltype(ctx.out()) { + if (!specs_.dynamic()) + return write(ctx.out(), val, specs_, ctx.locale()); + auto specs = format_specs(specs_); + handle_dynamic_spec(specs.dynamic_width(), specs.width, specs_.width_ref, + ctx); + handle_dynamic_spec(specs.dynamic_precision(), specs.precision, + specs_.precision_ref, ctx); + return write(ctx.out(), val, specs, ctx.locale()); +} + } // namespace detail FMT_BEGIN_EXPORT -FMT_API auto vsystem_error(int error_code, string_view format_str, - format_args args) -> std::system_error; +FMT_API auto vsystem_error(int error_code, string_view fmt, format_args args) + -> std::system_error; /** * Constructs `std::system_error` with a message formatted with @@ -4196,80 +4232,6 @@ template struct nested_formatter { } }; -/** - * Converts `value` to `std::string` using the default format for type `T`. - * - * **Example**: - * - * std::string answer = fmt::to_string(42); - */ -template ::value && - !detail::has_format_as::value)> -inline auto to_string(const T& value) -> std::string { - auto buffer = memory_buffer(); - detail::write(appender(buffer), value); - return {buffer.data(), buffer.size()}; -} - -template ::value)> -FMT_NODISCARD inline auto to_string(T value) -> std::string { - // The buffer should be large enough to store the number including the sign - // or "false" for bool. - constexpr int max_size = detail::digits10() + 2; - char buffer[max_size > 5 ? static_cast(max_size) : 5]; - char* begin = buffer; - return std::string(begin, detail::write(begin, value)); -} - -template -FMT_NODISCARD auto to_string(const basic_memory_buffer& buf) - -> std::basic_string { - auto size = buf.size(); - detail::assume(size < std::basic_string().max_size()); - return std::basic_string(buf.data(), size); -} - -template ::value && - detail::has_format_as::value)> -inline auto to_string(const T& value) -> std::string { - return to_string(format_as(value)); -} - -FMT_END_EXPORT - -namespace detail { - -FMT_BEGIN_EXPORT - -#ifndef FMT_HEADER_ONLY -extern template FMT_API auto thousands_sep_impl(locale_ref) - -> thousands_sep_result; -extern template FMT_API auto thousands_sep_impl(locale_ref) - -> thousands_sep_result; -extern template FMT_API auto decimal_point_impl(locale_ref) -> char; -extern template FMT_API auto decimal_point_impl(locale_ref) -> wchar_t; -#endif // FMT_HEADER_ONLY - -FMT_END_EXPORT - -template -template -FMT_CONSTEXPR auto native_formatter::format( - const T& val, FormatContext& ctx) const -> decltype(ctx.out()) { - if (!specs_.dynamic()) - return write(ctx.out(), val, specs_, ctx.locale()); - auto specs = format_specs(specs_); - handle_dynamic_spec(specs.dynamic_width(), specs.width, specs_.width_ref, - ctx); - handle_dynamic_spec(specs.dynamic_precision(), specs.precision, - specs_.precision_ref, ctx); - return write(ctx.out(), val, specs, ctx.locale()); -} - -} // namespace detail - -FMT_BEGIN_EXPORT - template struct formatter : detail::native_formatter detail::udl_arg { } // namespace literals #endif // FMT_USE_USER_LITERALS -FMT_API auto vformat(string_view fmt, format_args args) -> std::string; - -/** - * Formats `args` according to specifications in `fmt` and returns the result - * as a string. - * - * **Example**: - * - * #include - * std::string message = fmt::format("The answer is {}.", 42); - */ -template -FMT_NODISCARD FMT_INLINE auto format(format_string fmt, T&&... args) - -> std::string { - return vformat(fmt.str, vargs{{args...}}); -} - template ::value)> -inline auto vformat(const Locale& loc, string_view fmt, format_args args) +auto vformat(const Locale& loc, string_view fmt, format_args args) -> std::string { return detail::vformat(loc, fmt, args); } template ::value)> -inline auto format(const Locale& loc, format_string fmt, T&&... args) +FMT_INLINE auto format(const Locale& loc, format_string fmt, T&&... args) -> std::string { return fmt::vformat(loc, fmt.str, vargs{{args...}}); } @@ -4343,7 +4288,7 @@ template ::value)> FMT_INLINE auto format_to(OutputIt out, const Locale& loc, format_string fmt, T&&... args) -> OutputIt { - return vformat_to(out, loc, fmt.str, vargs{{args...}}); + return fmt::vformat_to(out, loc, fmt.str, vargs{{args...}}); } template std::string; + +/** + * Formats `args` according to specifications in `fmt` and returns the result + * as a string. + * + * **Example**: + * + * #include + * std::string message = fmt::format("The answer is {}.", 42); + */ +template +FMT_NODISCARD FMT_INLINE auto format(format_string fmt, T&&... args) + -> std::string { + return vformat(fmt.str, vargs{{args...}}); +} + +/** + * Converts `value` to `std::string` using the default format for type `T`. + * + * **Example**: + * + * std::string answer = fmt::to_string(42); + */ +template ::value)> +FMT_NODISCARD auto to_string(T value) -> std::string { + // The buffer should be large enough to store the number including the sign + // or "false" for bool. + constexpr int max_size = detail::digits10() + 2; + char buffer[max_size > 5 ? static_cast(max_size) : 5]; + char* begin = buffer; + return std::string(buffer, detail::write(begin, value)); +} + +template ::value && + !detail::has_format_as::value)> +FMT_NODISCARD auto to_string(const T& value) -> std::string { + auto buffer = memory_buffer(); + detail::write(appender(buffer), value); + return {buffer.data(), buffer.size()}; +} + +template ::value && + detail::has_format_as::value)> +FMT_NODISCARD auto to_string(const T& value) -> std::string { + return to_string(format_as(value)); +} + FMT_END_EXPORT FMT_END_NAMESPACE diff --git a/include/fmt/os.h b/include/fmt/os.h index 393a5f65..75b47c69 100644 --- a/include/fmt/os.h +++ b/include/fmt/os.h @@ -118,7 +118,7 @@ FMT_API void format_windows_error(buffer& out, int error_code, const char* message) noexcept; } -FMT_API std::system_error vwindows_error(int error_code, string_view format_str, +FMT_API std::system_error vwindows_error(int error_code, string_view fmt, format_args args); /** @@ -164,8 +164,8 @@ inline auto system_category() noexcept -> const std::error_category& { // std::system is not available on some platforms such as iOS (#2248). #ifdef __OSX__ template > -void say(const S& format_str, Args&&... args) { - std::system(format("say \"{}\"", format(format_str, args...)).c_str()); +void say(const S& fmt, Args&&... args) { + std::system(format("say \"{}\"", format(fmt, args...)).c_str()); } #endif diff --git a/include/fmt/xchar.h b/include/fmt/xchar.h index 51c11255..07599eb1 100644 --- a/include/fmt/xchar.h +++ b/include/fmt/xchar.h @@ -162,11 +162,11 @@ auto join(const std::tuple& tuple, basic_string_view sep) } template ::value)> -auto vformat(basic_string_view format_str, +auto vformat(basic_string_view fmt, typename detail::vformat_args::type args) -> std::basic_string { auto buf = basic_memory_buffer(); - detail::vformat_to(buf, format_str, args); + detail::vformat_to(buf, fmt, args); return to_string(buf); } @@ -188,8 +188,8 @@ template , FMT_ENABLE_IF(!std::is_same::value && !std::is_same::value)> -auto format(const S& format_str, T&&... args) -> std::basic_string { - return vformat(detail::to_string_view(format_str), +auto format(const S& fmt, T&&... args) -> std::basic_string { + return vformat(detail::to_string_view(fmt), fmt::make_format_args>(args...)); } @@ -210,9 +210,9 @@ template , FMT_ENABLE_IF(detail::is_locale::value&& detail::is_exotic_char::value)> -inline auto format(const Locale& loc, const S& format_str, T&&... args) +inline auto format(const Locale& loc, const S& fmt, T&&... args) -> std::basic_string { - return vformat(loc, detail::to_string_view(format_str), + return vformat(loc, detail::to_string_view(fmt), fmt::make_format_args>(args...)); } @@ -220,10 +220,10 @@ template , FMT_ENABLE_IF(detail::is_output_iterator::value&& detail::is_exotic_char::value)> -auto vformat_to(OutputIt out, const S& format_str, +auto vformat_to(OutputIt out, const S& fmt, typename detail::vformat_args::type args) -> OutputIt { auto&& buf = detail::get_buffer(out); - detail::vformat_to(buf, detail::to_string_view(format_str), args); + detail::vformat_to(buf, detail::to_string_view(fmt), args); return detail::get_iterator(buf, out); } @@ -242,12 +242,11 @@ template ::value&& detail::is_locale::value&& detail::is_exotic_char::value)> -inline auto vformat_to(OutputIt out, const Locale& loc, const S& format_str, +inline auto vformat_to(OutputIt out, const Locale& loc, const S& fmt, typename detail::vformat_args::type args) -> OutputIt { auto&& buf = detail::get_buffer(out); - vformat_to(buf, detail::to_string_view(format_str), args, - detail::locale_ref(loc)); + vformat_to(buf, detail::to_string_view(fmt), args, detail::locale_ref(loc)); return detail::get_iterator(buf, out); } @@ -256,23 +255,22 @@ template ::value && detail::is_locale::value && detail::is_exotic_char::value> -inline auto format_to(OutputIt out, const Locale& loc, const S& format_str, +inline auto format_to(OutputIt out, const Locale& loc, const S& fmt, T&&... args) -> typename std::enable_if::type { - return vformat_to(out, loc, detail::to_string_view(format_str), + return vformat_to(out, loc, detail::to_string_view(fmt), fmt::make_format_args>(args...)); } template ::value&& detail::is_exotic_char::value)> -inline auto vformat_to_n(OutputIt out, size_t n, - basic_string_view format_str, +inline auto vformat_to_n(OutputIt out, size_t n, basic_string_view fmt, typename detail::vformat_args::type args) -> format_to_n_result { using traits = detail::fixed_buffer_traits; auto buf = detail::iterator_buffer(out, n); - detail::vformat_to(buf, format_str, args); + detail::vformat_to(buf, fmt, args); return {buf.out(), buf.count()}; }