mirror of
https://github.com/fmtlib/fmt.git
synced 2024-10-02 13:02:03 +00:00
Make 'L' a modifier
This commit is contained in:
parent
6972b5f3d2
commit
e4f2cf455e
@ -1252,6 +1252,7 @@ template <typename Char> struct basic_format_specs {
|
|||||||
align_t align : 4;
|
align_t align : 4;
|
||||||
sign_t sign : 3;
|
sign_t sign : 3;
|
||||||
bool alt : 1; // Alternate form ('#').
|
bool alt : 1; // Alternate form ('#').
|
||||||
|
bool localized : 1;
|
||||||
detail::fill_t<Char> fill;
|
detail::fill_t<Char> fill;
|
||||||
|
|
||||||
constexpr basic_format_specs()
|
constexpr basic_format_specs()
|
||||||
@ -1260,7 +1261,8 @@ template <typename Char> struct basic_format_specs {
|
|||||||
type(0),
|
type(0),
|
||||||
align(align::none),
|
align(align::none),
|
||||||
sign(sign::none),
|
sign(sign::none),
|
||||||
alt(false) {}
|
alt(false),
|
||||||
|
localized(false) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
using format_specs = basic_format_specs<char>;
|
using format_specs = basic_format_specs<char>;
|
||||||
@ -1427,6 +1429,7 @@ FMT_CONSTEXPR float_specs parse_float_type_spec(
|
|||||||
const basic_format_specs<Char>& specs, ErrorHandler&& eh = {}) {
|
const basic_format_specs<Char>& specs, ErrorHandler&& eh = {}) {
|
||||||
auto result = float_specs();
|
auto result = float_specs();
|
||||||
result.showpoint = specs.alt;
|
result.showpoint = specs.alt;
|
||||||
|
result.locale = specs.localized;
|
||||||
switch (specs.type) {
|
switch (specs.type) {
|
||||||
case 0:
|
case 0:
|
||||||
result.format = float_format::general;
|
result.format = float_format::general;
|
||||||
@ -1693,6 +1696,7 @@ template <typename OutputIt, typename Char, typename UInt> struct int_writer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FMT_CONSTEXPR void on_dec() {
|
FMT_CONSTEXPR void on_dec() {
|
||||||
|
if (specs.localized) return on_num();
|
||||||
auto num_digits = count_digits(abs_value);
|
auto num_digits = count_digits(abs_value);
|
||||||
out = write_int(
|
out = write_int(
|
||||||
out, num_digits, get_prefix(), specs, [this, num_digits](iterator it) {
|
out, num_digits, get_prefix(), specs, [this, num_digits](iterator it) {
|
||||||
@ -2527,6 +2531,7 @@ template <typename Char> class specs_setter {
|
|||||||
FMT_CONSTEXPR void on_minus() { specs_.sign = sign::minus; }
|
FMT_CONSTEXPR void on_minus() { specs_.sign = sign::minus; }
|
||||||
FMT_CONSTEXPR void on_space() { specs_.sign = sign::space; }
|
FMT_CONSTEXPR void on_space() { specs_.sign = sign::space; }
|
||||||
FMT_CONSTEXPR void on_hash() { specs_.alt = true; }
|
FMT_CONSTEXPR void on_hash() { specs_.alt = true; }
|
||||||
|
FMT_CONSTEXPR void on_localized() { specs_.localized = true; }
|
||||||
|
|
||||||
FMT_CONSTEXPR void on_zero() {
|
FMT_CONSTEXPR void on_zero() {
|
||||||
specs_.align = align::numeric;
|
specs_.align = align::numeric;
|
||||||
@ -2616,6 +2621,11 @@ template <typename Handler> class specs_checker : public Handler {
|
|||||||
Handler::on_hash();
|
Handler::on_hash();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FMT_CONSTEXPR void on_localized() {
|
||||||
|
checker_.require_numeric_argument();
|
||||||
|
Handler::on_localized();
|
||||||
|
}
|
||||||
|
|
||||||
FMT_CONSTEXPR void on_zero() {
|
FMT_CONSTEXPR void on_zero() {
|
||||||
checker_.require_numeric_argument();
|
checker_.require_numeric_argument();
|
||||||
Handler::on_zero();
|
Handler::on_zero();
|
||||||
@ -2996,6 +3006,12 @@ FMT_CONSTEXPR const Char* parse_format_specs(const Char* begin, const Char* end,
|
|||||||
// Parse precision.
|
// Parse precision.
|
||||||
if (*begin == '.') {
|
if (*begin == '.') {
|
||||||
begin = parse_precision(begin, end, handler);
|
begin = parse_precision(begin, end, handler);
|
||||||
|
if (begin == end) return begin;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*begin == 'L') {
|
||||||
|
handler.on_localized();
|
||||||
|
++begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse type.
|
// Parse type.
|
||||||
|
@ -1112,7 +1112,7 @@ TEST(FormatterTest, RuntimePrecision) {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
void check_unknown_types(const T& value, const char* types, const char*) {
|
void check_unknown_types(const T& value, const char* types, const char*) {
|
||||||
char format_str[BUFFER_SIZE];
|
char format_str[BUFFER_SIZE];
|
||||||
const char* special = ".0123456789}";
|
const char* special = ".0123456789L}";
|
||||||
for (int i = CHAR_MIN; i <= CHAR_MAX; ++i) {
|
for (int i = CHAR_MIN; i <= CHAR_MAX; ++i) {
|
||||||
char c = static_cast<char>(i);
|
char c = static_cast<char>(i);
|
||||||
if (std::strchr(types, c) || std::strchr(special, c) || !c) continue;
|
if (std::strchr(types, c) || std::strchr(special, c) || !c) continue;
|
||||||
@ -2140,7 +2140,7 @@ TEST(FormatTest, ConstexprParseArgID) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct test_format_specs_handler {
|
struct test_format_specs_handler {
|
||||||
enum Result { NONE, PLUS, MINUS, SPACE, HASH, ZERO, ERROR };
|
enum Result { NONE, PLUS, MINUS, SPACE, HASH, ZERO, LOC, ERROR };
|
||||||
Result res = NONE;
|
Result res = NONE;
|
||||||
|
|
||||||
fmt::align_t alignment = fmt::align::none;
|
fmt::align_t alignment = fmt::align::none;
|
||||||
@ -2172,6 +2172,7 @@ struct test_format_specs_handler {
|
|||||||
FMT_CONSTEXPR void on_space() { res = SPACE; }
|
FMT_CONSTEXPR void on_space() { res = SPACE; }
|
||||||
FMT_CONSTEXPR void on_hash() { res = HASH; }
|
FMT_CONSTEXPR void on_hash() { res = HASH; }
|
||||||
FMT_CONSTEXPR void on_zero() { res = ZERO; }
|
FMT_CONSTEXPR void on_zero() { res = ZERO; }
|
||||||
|
FMT_CONSTEXPR void on_localized() { res = LOC; }
|
||||||
|
|
||||||
FMT_CONSTEXPR void on_width(int w) { width = w; }
|
FMT_CONSTEXPR void on_width(int w) { width = w; }
|
||||||
FMT_CONSTEXPR void on_dynamic_width(fmt::detail::auto_id) {}
|
FMT_CONSTEXPR void on_dynamic_width(fmt::detail::auto_id) {}
|
||||||
@ -2204,6 +2205,7 @@ TEST(FormatTest, ConstexprParseFormatSpecs) {
|
|||||||
static_assert(parse_test_specs(" ").res == handler::SPACE, "");
|
static_assert(parse_test_specs(" ").res == handler::SPACE, "");
|
||||||
static_assert(parse_test_specs("#").res == handler::HASH, "");
|
static_assert(parse_test_specs("#").res == handler::HASH, "");
|
||||||
static_assert(parse_test_specs("0").res == handler::ZERO, "");
|
static_assert(parse_test_specs("0").res == handler::ZERO, "");
|
||||||
|
static_assert(parse_test_specs("L").res == handler::LOC, "");
|
||||||
static_assert(parse_test_specs("42").width == 42, "");
|
static_assert(parse_test_specs("42").width == 42, "");
|
||||||
static_assert(parse_test_specs("{42}").width_ref.val.index == 42, "");
|
static_assert(parse_test_specs("{42}").width_ref.val.index == 42, "");
|
||||||
static_assert(parse_test_specs(".42").precision == 42, "");
|
static_assert(parse_test_specs(".42").precision == 42, "");
|
||||||
|
@ -45,6 +45,7 @@ template <typename Char> struct small_grouping : std::numpunct<Char> {
|
|||||||
TEST(LocaleTest, DoubleDecimalPoint) {
|
TEST(LocaleTest, DoubleDecimalPoint) {
|
||||||
std::locale loc(std::locale(), new numpunct<char>());
|
std::locale loc(std::locale(), new numpunct<char>());
|
||||||
EXPECT_EQ("1?23", fmt::format(loc, "{:L}", 1.23));
|
EXPECT_EQ("1?23", fmt::format(loc, "{:L}", 1.23));
|
||||||
|
EXPECT_EQ("1?230000", fmt::format(loc, "{:Lf}", 1.23));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(LocaleTest, Format) {
|
TEST(LocaleTest, Format) {
|
||||||
|
Loading…
Reference in New Issue
Block a user