mirror of
https://github.com/fmtlib/fmt.git
synced 2025-07-31 03:07:36 +02:00
num_format_facet -> format_facet
This commit is contained in:
@ -332,7 +332,7 @@ struct monostate {
|
|||||||
#ifdef FMT_DOC
|
#ifdef FMT_DOC
|
||||||
# define FMT_ENABLE_IF(...)
|
# define FMT_ENABLE_IF(...)
|
||||||
#else
|
#else
|
||||||
# define FMT_ENABLE_IF(...) enable_if_t<(__VA_ARGS__), int> = 0
|
# define FMT_ENABLE_IF(...) fmt::enable_if_t<(__VA_ARGS__), int> = 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FMT_BEGIN_DETAIL_NAMESPACE
|
FMT_BEGIN_DETAIL_NAMESPACE
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
#include "format.h"
|
#include "format.h"
|
||||||
|
|
||||||
FMT_BEGIN_NAMESPACE
|
FMT_BEGIN_NAMESPACE
|
||||||
template <typename Locale> typename Locale::id num_format_facet<Locale>::id;
|
template <typename Locale> typename Locale::id format_facet<Locale>::id;
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
@ -118,15 +118,15 @@ template <typename Char> FMT_FUNC Char decimal_point_impl(locale_ref) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FMT_FUNC auto write_int(appender out, loc_value value,
|
FMT_FUNC auto write_int(appender out, basic_format_arg<format_context> 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>();
|
||||||
// We cannot use the num_put<char> facet because it may produce output in
|
// We cannot use the num_put<char> facet because it may produce output in
|
||||||
// a wrong encoding.
|
// a wrong encoding.
|
||||||
if (!std::has_facet<num_format_facet<std::locale>>(locale)) return {};
|
if (!std::has_facet<format_facet<std::locale>>(locale)) return {};
|
||||||
std::use_facet<num_format_facet<std::locale>>(locale).put(out, value, specs,
|
std::use_facet<format_facet<std::locale>>(locale).put(out, value, specs,
|
||||||
locale);
|
locale);
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
|
@ -985,27 +985,20 @@ constexpr auto compile_string_to_view(detail::std_string_view<Char> s)
|
|||||||
}
|
}
|
||||||
} // namespace detail_exported
|
} // namespace detail_exported
|
||||||
|
|
||||||
// A value to localize.
|
// A locale facet that formats values in UTF-8.
|
||||||
struct loc_value {
|
// It is parameterized on the locale to avoid the heavy <locale> include.
|
||||||
union {
|
template <typename Locale> class format_facet : public Locale::facet {
|
||||||
unsigned long long ulong_long_value;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// A locale facet that formats numeric values in UTF-8.
|
|
||||||
// It is parameterized on the locale to avoid heavy <locale> include.
|
|
||||||
template <typename Locale> class num_format_facet : public Locale::facet {
|
|
||||||
public:
|
public:
|
||||||
static FMT_API typename Locale::id id;
|
static FMT_API typename Locale::id id;
|
||||||
|
|
||||||
void put(appender out, loc_value val, const format_specs& specs,
|
void put(appender out, basic_format_arg<format_context> val,
|
||||||
Locale& loc) const {
|
const format_specs& specs, Locale& loc) const {
|
||||||
do_put(out, val, specs, loc);
|
do_put(out, val, specs, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void do_put(appender out, loc_value val, const format_specs& specs,
|
virtual void do_put(appender out, basic_format_arg<format_context> val,
|
||||||
Locale& loc) const = 0;
|
const format_specs& specs, Locale& loc) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
FMT_BEGIN_DETAIL_NAMESPACE
|
FMT_BEGIN_DETAIL_NAMESPACE
|
||||||
@ -2037,23 +2030,21 @@ auto write_int(OutputIt out, UInt value, unsigned prefix,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
FMT_API auto write_int(appender out, loc_value value, const format_specs& specs,
|
FMT_API auto write_int(appender out, basic_format_arg<format_context> value,
|
||||||
locale_ref loc) -> bool;
|
const format_specs& specs, locale_ref loc) -> bool;
|
||||||
template <typename OutputIt, typename Char>
|
template <typename OutputIt, typename Char>
|
||||||
inline auto write_int(OutputIt, loc_value, const basic_format_specs<Char>&,
|
inline auto write_int(OutputIt, basic_format_arg<buffer_context<Char>>,
|
||||||
locale_ref) -> bool {
|
const basic_format_specs<Char>&, locale_ref) -> bool {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename OutputIt, typename UInt, typename Char>
|
template <typename OutputIt, typename UInt, typename Char>
|
||||||
auto write_int(OutputIt& out, UInt value, unsigned prefix,
|
auto write_int(OutputIt& out, UInt value, unsigned prefix,
|
||||||
const basic_format_specs<Char>& specs, locale_ref loc) -> bool {
|
const basic_format_specs<Char>& specs, locale_ref loc) -> bool {
|
||||||
auto result = false;
|
|
||||||
auto buf = memory_buffer();
|
auto buf = memory_buffer();
|
||||||
if (sizeof(value) <= sizeof(unsigned long long))
|
auto written = write_int(appender(buf), make_arg<buffer_context<Char>>(value),
|
||||||
result = write_int(appender(buf), {static_cast<unsigned long long>(value)},
|
|
||||||
specs, loc);
|
specs, loc);
|
||||||
if (!result) {
|
if (!written) {
|
||||||
auto grouping = digit_grouping<Char>(loc);
|
auto grouping = digit_grouping<Char>(loc);
|
||||||
out = write_int(out, value, prefix, specs, grouping);
|
out = write_int(out, value, prefix, specs, grouping);
|
||||||
return true;
|
return true;
|
||||||
|
@ -2312,25 +2312,36 @@ TEST(format_int_test, format_int) {
|
|||||||
EXPECT_EQ(os.str(), fmt::format_int(max_value<int64_t>()).str());
|
EXPECT_EQ(os.str(), fmt::format_int(max_value<int64_t>()).str());
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FMT_STATIC_THOUSANDS_SEPARATOR
|
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
|
||||||
|
|
||||||
# include <locale>
|
# include <locale>
|
||||||
|
|
||||||
class num_format : public fmt::num_format_facet<std::locale> {
|
class format_facet : public fmt::format_facet<std::locale> {
|
||||||
protected:
|
protected:
|
||||||
void do_put(fmt::appender out, fmt::loc_value, const fmt::format_specs&,
|
struct int_formatter {
|
||||||
std::locale&) const override;
|
fmt::appender out;
|
||||||
|
|
||||||
|
template <typename T, FMT_ENABLE_IF(fmt::detail::is_integer<T>::value)>
|
||||||
|
void operator()(T value) {
|
||||||
|
fmt::format_to(out, "[{}]", value);
|
||||||
|
}
|
||||||
|
template <typename T, FMT_ENABLE_IF(!fmt::detail::is_integer<T>::value)>
|
||||||
|
void operator()(T) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
void do_put(fmt::appender out, fmt::basic_format_arg<fmt::format_context> arg,
|
||||||
|
const fmt::format_specs&, std::locale&) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
void num_format::do_put(fmt::appender out, fmt::loc_value value,
|
void format_facet::do_put(fmt::appender out,
|
||||||
const fmt::format_specs&, std::locale&) const {
|
fmt::basic_format_arg<fmt::format_context> arg,
|
||||||
fmt::format_to(out, "[{}]", value.ulong_long_value);
|
const fmt::format_specs&, std::locale&) const {
|
||||||
|
visit_format_arg(int_formatter{out}, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(format_test, num_format) {
|
TEST(format_test, format_facet) {
|
||||||
auto loc = std::locale(std::locale(), new num_format());
|
auto loc = std::locale(std::locale(), new format_facet());
|
||||||
EXPECT_EQ(fmt::format(loc, "{:L}", 42), "[42]");
|
EXPECT_EQ(fmt::format(loc, "{:L}", 42), "[42]");
|
||||||
EXPECT_EQ(fmt::format(loc, "{:L}", -42), "[-42]");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // FMT_STATIC_THOUSANDS_SEPARATOR
|
#endif // FMT_STATIC_THOUSANDS_SEPARATOR
|
||||||
|
Reference in New Issue
Block a user