mirror of
https://github.com/fmtlib/fmt.git
synced 2025-08-02 20:24:43 +02:00
Improve locale API
This commit is contained in:
@@ -116,7 +116,7 @@ template <typename Char> FMT_FUNC Char decimal_point_impl(locale_ref) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FMT_FUNC auto write_loc(appender out, basic_format_arg<format_context> value,
|
FMT_FUNC auto write_loc(appender out, loc_value value,
|
||||||
const format_specs& specs, locale_ref loc) -> bool {
|
const format_specs& specs, locale_ref loc) -> bool {
|
||||||
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
|
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
|
||||||
auto locale = loc.get<std::locale>();
|
auto locale = loc.get<std::locale>();
|
||||||
@@ -142,11 +142,9 @@ template <typename Locale> format_facet<Locale>::format_facet(Locale& loc) {
|
|||||||
|
|
||||||
template <>
|
template <>
|
||||||
FMT_API FMT_FUNC auto format_facet<std::locale>::do_put(
|
FMT_API FMT_FUNC auto format_facet<std::locale>::do_put(
|
||||||
appender out, basic_format_arg<format_context> val,
|
appender out, loc_value val, const format_specs& specs) const -> bool {
|
||||||
const format_specs& specs) const -> bool {
|
return val.visit(
|
||||||
return visit_format_arg(
|
detail::loc_writer<>{out, specs, separator_, grouping_, decimal_point_});
|
||||||
detail::loc_writer<>{out, specs, separator_, grouping_, decimal_point_},
|
|
||||||
val);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -1001,6 +1001,22 @@ constexpr auto compile_string_to_view(detail::std_string_view<Char> s)
|
|||||||
}
|
}
|
||||||
} // namespace detail_exported
|
} // namespace detail_exported
|
||||||
|
|
||||||
|
class loc_value {
|
||||||
|
private:
|
||||||
|
basic_format_arg<format_context> value_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
template <typename T, FMT_ENABLE_IF(!detail::is_float128<T>::value)>
|
||||||
|
loc_value(T value) : value_(detail::make_arg<format_context>(value)) {}
|
||||||
|
|
||||||
|
template <typename T, FMT_ENABLE_IF(detail::is_float128<T>::value)>
|
||||||
|
loc_value(T) {}
|
||||||
|
|
||||||
|
template <typename Visitor> auto visit(Visitor&& vis) -> decltype(vis(0)) {
|
||||||
|
return visit_format_arg(vis, value_);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// A locale facet that formats values in UTF-8.
|
// A locale facet that formats values in UTF-8.
|
||||||
// It is parameterized on the locale to avoid the heavy <locale> include.
|
// It is parameterized on the locale to avoid the heavy <locale> include.
|
||||||
template <typename Locale> class format_facet : public Locale::facet {
|
template <typename Locale> class format_facet : public Locale::facet {
|
||||||
@@ -1010,7 +1026,7 @@ template <typename Locale> class format_facet : public Locale::facet {
|
|||||||
std::string decimal_point_;
|
std::string decimal_point_;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual auto do_put(appender out, basic_format_arg<format_context> val,
|
virtual auto do_put(appender out, loc_value val,
|
||||||
const format_specs& specs) const -> bool;
|
const format_specs& specs) const -> bool;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -1024,8 +1040,8 @@ template <typename Locale> class format_facet : public Locale::facet {
|
|||||||
grouping_(g.begin(), g.end()),
|
grouping_(g.begin(), g.end()),
|
||||||
decimal_point_(decimal_point) {}
|
decimal_point_(decimal_point) {}
|
||||||
|
|
||||||
auto put(appender out, basic_format_arg<format_context> val,
|
auto put(appender out, loc_value val, const format_specs& specs) const
|
||||||
const format_specs& specs) const -> bool {
|
-> bool {
|
||||||
return do_put(out, val, specs);
|
return do_put(out, val, specs);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -2053,22 +2069,12 @@ auto write_int(OutputIt out, UInt value, unsigned prefix,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, FMT_ENABLE_IF(!is_float128<T>::value)>
|
|
||||||
auto make_loc_value(T value) -> basic_format_arg<format_context> {
|
|
||||||
return make_arg<format_context>(value);
|
|
||||||
}
|
|
||||||
template <typename T, FMT_ENABLE_IF(is_float128<T>::value)>
|
|
||||||
auto make_loc_value(T) -> basic_format_arg<format_context> {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Writes a localized value.
|
// Writes a localized value.
|
||||||
FMT_API auto write_loc(appender out, basic_format_arg<format_context> value,
|
FMT_API auto write_loc(appender out, loc_value value, const format_specs& specs,
|
||||||
const format_specs& specs, locale_ref loc) -> bool;
|
locale_ref loc) -> bool;
|
||||||
|
|
||||||
template <typename OutputIt, typename Char>
|
template <typename OutputIt, typename Char>
|
||||||
inline auto write_loc(OutputIt, basic_format_arg<format_context>,
|
inline auto write_loc(OutputIt, loc_value, const basic_format_specs<Char>&,
|
||||||
const basic_format_specs<Char>&, locale_ref) -> bool {
|
locale_ref) -> bool {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2190,8 +2196,7 @@ template <typename Char, typename OutputIt, typename T,
|
|||||||
FMT_CONSTEXPR FMT_INLINE auto write(OutputIt out, T value,
|
FMT_CONSTEXPR FMT_INLINE auto write(OutputIt out, T value,
|
||||||
const basic_format_specs<Char>& specs,
|
const basic_format_specs<Char>& specs,
|
||||||
locale_ref loc) -> OutputIt {
|
locale_ref loc) -> OutputIt {
|
||||||
if (specs.localized && write_loc(out, make_loc_value(value), specs, loc))
|
if (specs.localized && write_loc(out, value, specs, loc)) return out;
|
||||||
return out;
|
|
||||||
return write_int_noinline(out, make_write_int_arg(value, specs.sign), specs,
|
return write_int_noinline(out, make_write_int_arg(value, specs.sign), specs,
|
||||||
loc);
|
loc);
|
||||||
}
|
}
|
||||||
@@ -2203,8 +2208,7 @@ template <typename Char, typename OutputIt, typename T,
|
|||||||
FMT_CONSTEXPR FMT_INLINE auto write(OutputIt out, T value,
|
FMT_CONSTEXPR FMT_INLINE auto write(OutputIt out, T value,
|
||||||
const basic_format_specs<Char>& specs,
|
const basic_format_specs<Char>& specs,
|
||||||
locale_ref loc) -> OutputIt {
|
locale_ref loc) -> OutputIt {
|
||||||
if (specs.localized && write_loc(out, make_loc_value(value), specs, loc))
|
if (specs.localized && write_loc(out, value, specs, loc)) return out;
|
||||||
return out;
|
|
||||||
return write_int(out, make_write_int_arg(value, specs.sign), specs, loc);
|
return write_int(out, make_write_int_arg(value, specs.sign), specs, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3311,7 +3315,7 @@ FMT_CONSTEXPR20 auto write(OutputIt out, T value,
|
|||||||
basic_format_specs<Char> specs, locale_ref loc = {})
|
basic_format_specs<Char> specs, locale_ref loc = {})
|
||||||
-> OutputIt {
|
-> OutputIt {
|
||||||
if (const_check(!is_supported_floating_point(value))) return out;
|
if (const_check(!is_supported_floating_point(value))) return out;
|
||||||
return specs.localized && write_loc(out, make_loc_value(value), specs, loc)
|
return specs.localized && write_loc(out, value, specs, loc)
|
||||||
? out
|
? out
|
||||||
: write_float(out, value, specs, loc);
|
: write_float(out, value, specs, loc);
|
||||||
}
|
}
|
||||||
|
@@ -23,7 +23,7 @@ template <typename T>
|
|||||||
using is_exotic_char = bool_constant<!std::is_same<T, char>::value>;
|
using is_exotic_char = bool_constant<!std::is_same<T, char>::value>;
|
||||||
|
|
||||||
template <typename OutputIt>
|
template <typename OutputIt>
|
||||||
auto write_loc(OutputIt out, basic_format_arg<format_context> val,
|
auto write_loc(OutputIt out, loc_value value,
|
||||||
const basic_format_specs<wchar_t>& specs, locale_ref loc)
|
const basic_format_specs<wchar_t>& specs, locale_ref loc)
|
||||||
-> bool {
|
-> bool {
|
||||||
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
|
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
|
||||||
@@ -32,8 +32,7 @@ auto write_loc(OutputIt out, basic_format_arg<format_context> val,
|
|||||||
auto separator = std::wstring();
|
auto separator = std::wstring();
|
||||||
auto grouping = numpunct.grouping();
|
auto grouping = numpunct.grouping();
|
||||||
if (!grouping.empty()) separator = std::wstring(1, numpunct.thousands_sep());
|
if (!grouping.empty()) separator = std::wstring(1, numpunct.thousands_sep());
|
||||||
return visit_format_arg(
|
return value.visit(loc_writer<wchar_t>{out, specs, separator, grouping, {}});
|
||||||
loc_writer<wchar_t>{out, specs, separator, grouping, {}}, val);
|
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@@ -2335,14 +2335,13 @@ class format_facet : public fmt::format_facet<std::locale> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
auto do_put(fmt::appender out, fmt::basic_format_arg<fmt::format_context> arg,
|
auto do_put(fmt::appender out, fmt::loc_value val,
|
||||||
const fmt::format_specs&) const -> bool override;
|
const fmt::format_specs&) const -> bool override;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto format_facet::do_put(fmt::appender out,
|
auto format_facet::do_put(fmt::appender out, fmt::loc_value val,
|
||||||
fmt::basic_format_arg<fmt::format_context> arg,
|
|
||||||
const fmt::format_specs&) const -> bool {
|
const fmt::format_specs&) const -> bool {
|
||||||
return visit_format_arg(int_formatter{out}, arg);
|
return val.visit(int_formatter{out});
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(format_test, format_facet) {
|
TEST(format_test, format_facet) {
|
||||||
|
Reference in New Issue
Block a user