mirror of
https://github.com/fmtlib/fmt.git
synced 2025-11-27 21:00:01 +01:00
Improve locale support
This commit is contained in:
@@ -422,16 +422,6 @@ inline u8string_view operator"" _u(const char *s, std::size_t n) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// A wrapper around std::locale used to reduce compile times since <locale>
|
||||
// is very heavy.
|
||||
class locale;
|
||||
|
||||
class locale_provider {
|
||||
public:
|
||||
virtual ~locale_provider() {}
|
||||
virtual fmt::locale locale();
|
||||
};
|
||||
|
||||
// The number of characters to store in the basic_memory_buffer object itself
|
||||
// to avoid dynamic memory allocation.
|
||||
enum { inline_buffer_size = 500 };
|
||||
@@ -1034,16 +1024,16 @@ class add_thousands_sep {
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
FMT_API Char thousands_sep_impl(locale_provider *lp);
|
||||
FMT_API Char thousands_sep_impl(locale_ref loc);
|
||||
|
||||
template <typename Char>
|
||||
inline Char thousands_sep(locale_provider *lp) {
|
||||
return Char(thousands_sep_impl<char>(lp));
|
||||
inline Char thousands_sep(locale_ref loc) {
|
||||
return Char(thousands_sep_impl<char>(loc));
|
||||
}
|
||||
|
||||
template <>
|
||||
inline wchar_t thousands_sep(locale_provider *lp) {
|
||||
return thousands_sep_impl<wchar_t>(lp);
|
||||
inline wchar_t thousands_sep(locale_ref loc) {
|
||||
return thousands_sep_impl<wchar_t>(loc);
|
||||
}
|
||||
|
||||
// Formats a decimal unsigned integer value writing into buffer.
|
||||
@@ -1449,7 +1439,8 @@ class arg_formatter_base {
|
||||
}
|
||||
|
||||
public:
|
||||
arg_formatter_base(Range r, format_specs *s): writer_(r), specs_(s) {}
|
||||
arg_formatter_base(Range r, format_specs *s, locale_ref loc)
|
||||
: writer_(r, loc), specs_(s) {}
|
||||
|
||||
iterator operator()(monostate) {
|
||||
FMT_ASSERT(false, "invalid argument type");
|
||||
@@ -2320,7 +2311,7 @@ class arg_formatter:
|
||||
\endrst
|
||||
*/
|
||||
explicit arg_formatter(context_type &ctx, format_specs *spec = FMT_NULL)
|
||||
: base(Range(ctx.out()), spec), ctx_(ctx) {}
|
||||
: base(Range(ctx.out()), spec, ctx.locale()), ctx_(ctx) {}
|
||||
|
||||
// Deprecated.
|
||||
arg_formatter(context_type &ctx, format_specs &spec)
|
||||
@@ -2408,7 +2399,7 @@ class basic_writer {
|
||||
|
||||
private:
|
||||
iterator out_; // Output iterator.
|
||||
std::unique_ptr<locale_provider> locale_;
|
||||
internal::locale_ref locale_;
|
||||
|
||||
iterator out() const { return out_; }
|
||||
|
||||
@@ -2608,7 +2599,7 @@ class basic_writer {
|
||||
|
||||
void on_num() {
|
||||
unsigned num_digits = internal::count_digits(abs_value);
|
||||
char_type sep = internal::thousands_sep<char_type>(writer.locale_.get());
|
||||
char_type sep = internal::thousands_sep<char_type>(writer.locale_);
|
||||
unsigned size = num_digits + SEP_SIZE * ((num_digits - 1) / 3);
|
||||
writer.write_int(size, get_prefix(), spec,
|
||||
num_writer{abs_value, size, sep});
|
||||
@@ -2698,7 +2689,9 @@ class basic_writer {
|
||||
|
||||
public:
|
||||
/** Constructs a ``basic_writer`` object. */
|
||||
explicit basic_writer(Range out): out_(out.begin()) {}
|
||||
explicit basic_writer(
|
||||
Range out, internal::locale_ref loc = internal::locale_ref())
|
||||
: out_(out.begin()), locale_(loc) {}
|
||||
|
||||
void write(int value) { write_decimal(value); }
|
||||
void write(long value) { write_decimal(value); }
|
||||
@@ -3226,8 +3219,9 @@ struct format_handler : internal::error_handler {
|
||||
typedef typename ArgFormatter::range range;
|
||||
|
||||
format_handler(range r, basic_string_view<Char> str,
|
||||
basic_format_args<Context> format_args)
|
||||
: context(r.begin(), str, format_args) {}
|
||||
basic_format_args<Context> format_args,
|
||||
internal::locale_ref loc)
|
||||
: context(r.begin(), str, format_args, loc) {}
|
||||
|
||||
void on_text(const Char *begin, const Char *end) {
|
||||
auto size = internal::to_unsigned(end - begin);
|
||||
@@ -3277,10 +3271,12 @@ struct format_handler : internal::error_handler {
|
||||
|
||||
/** Formats arguments and writes the output to the range. */
|
||||
template <typename ArgFormatter, typename Char, typename Context>
|
||||
typename Context::iterator vformat_to(typename ArgFormatter::range out,
|
||||
basic_string_view<Char> format_str,
|
||||
basic_format_args<Context> args) {
|
||||
format_handler<ArgFormatter, Char, Context> h(out, format_str, args);
|
||||
typename Context::iterator vformat_to(
|
||||
typename ArgFormatter::range out,
|
||||
basic_string_view<Char> format_str,
|
||||
basic_format_args<Context> args,
|
||||
internal::locale_ref loc = internal::locale_ref()) {
|
||||
format_handler<ArgFormatter, Char, Context> h(out, format_str, args, loc);
|
||||
internal::parse_format_string<false>(format_str, h);
|
||||
return h.context.out();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user