mirror of
https://github.com/fmtlib/fmt.git
synced 2025-08-01 19:54:46 +02:00
Improve handling of format specs
This commit is contained in:
@@ -163,6 +163,17 @@
|
|||||||
# define FMT_CATCH(x) if (false)
|
# define FMT_CATCH(x) if (false)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if FMT_HAS_CPP17_ATTRIBUTE(fallthrough)
|
||||||
|
# define FMT_FALLTHROUGH [[fallthrough]]
|
||||||
|
#elif defined(__clang__)
|
||||||
|
# define FMT_FALLTHROUGH [[clang::fallthrough]]
|
||||||
|
#elif FMT_GCC_VERSION >= 700 && \
|
||||||
|
(!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 520)
|
||||||
|
# define FMT_FALLTHROUGH [[gnu::fallthrough]]
|
||||||
|
#else
|
||||||
|
# define FMT_FALLTHROUGH
|
||||||
|
#endif
|
||||||
|
|
||||||
// Disable [[noreturn]] on MSVC/NVCC because of bogus unreachable code warnings.
|
// Disable [[noreturn]] on MSVC/NVCC because of bogus unreachable code warnings.
|
||||||
#if FMT_HAS_CPP_ATTRIBUTE(noreturn) && FMT_EXCEPTIONS && !FMT_MSC_VERSION && \
|
#if FMT_HAS_CPP_ATTRIBUTE(noreturn) && FMT_EXCEPTIONS && !FMT_MSC_VERSION && \
|
||||||
!defined(__NVCC__)
|
!defined(__NVCC__)
|
||||||
@@ -2038,25 +2049,26 @@ template <typename Char> struct fill_t {
|
|||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
enum class presentation_type : unsigned char {
|
enum class presentation_type : unsigned char {
|
||||||
none,
|
// Common specifiers:
|
||||||
dec, // 'd'
|
none = 0,
|
||||||
oct, // 'o'
|
debug = 1, // '?'
|
||||||
hex_lower, // 'x'
|
string = 2, // 's' (string, bool)
|
||||||
hex_upper, // 'X'
|
|
||||||
bin_lower, // 'b'
|
// Integral, bool and character specifiers:
|
||||||
bin_upper, // 'B'
|
dec = 3, // 'd'
|
||||||
hexfloat_lower, // 'a'
|
hex, // 'x' or 'X'
|
||||||
hexfloat_upper, // 'A'
|
oct, // 'o'
|
||||||
exp_lower, // 'e'
|
bin, // 'b' or 'B'
|
||||||
exp_upper, // 'E'
|
chr, // 'c'
|
||||||
fixed_lower, // 'f'
|
|
||||||
fixed_upper, // 'F'
|
// String and pointer specifiers:
|
||||||
general_lower, // 'g'
|
pointer = 3, // 'p'
|
||||||
general_upper, // 'G'
|
|
||||||
chr, // 'c'
|
// Floating-point specifiers:
|
||||||
string, // 's'
|
exp = 1, // 'e' or 'E' (1 since there is no FP debug presentation)
|
||||||
pointer, // 'p'
|
fixed, // 'f' or 'F'
|
||||||
debug // '?'
|
general, // 'g' or 'G'
|
||||||
|
hexfloat // 'a' or 'A'
|
||||||
};
|
};
|
||||||
|
|
||||||
// Format specifiers for built-in and string types.
|
// Format specifiers for built-in and string types.
|
||||||
@@ -2066,7 +2078,8 @@ template <typename Char = char> struct format_specs {
|
|||||||
presentation_type type;
|
presentation_type type;
|
||||||
align_t align : 4;
|
align_t align : 4;
|
||||||
sign_t sign : 3;
|
sign_t sign : 3;
|
||||||
bool alt : 1; // Alternate form ('#').
|
bool upper : 1; // An uppercase version e.g. 'X' for 'x'.
|
||||||
|
bool alt : 1; // Alternate form ('#').
|
||||||
bool localized : 1;
|
bool localized : 1;
|
||||||
detail::fill_t<Char> fill;
|
detail::fill_t<Char> fill;
|
||||||
|
|
||||||
@@ -2076,6 +2089,7 @@ template <typename Char = char> struct format_specs {
|
|||||||
type(presentation_type::none),
|
type(presentation_type::none),
|
||||||
align(align::none),
|
align(align::none),
|
||||||
sign(sign::none),
|
sign(sign::none),
|
||||||
|
upper(false),
|
||||||
alt(false),
|
alt(false),
|
||||||
localized(false) {}
|
localized(false) {}
|
||||||
};
|
};
|
||||||
@@ -2401,32 +2415,38 @@ FMT_CONSTEXPR auto parse_format_specs(const Char* begin, const Char* end,
|
|||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
return parse_presentation_type(pres::dec, integral_set);
|
return parse_presentation_type(pres::dec, integral_set);
|
||||||
|
case 'X':
|
||||||
|
specs.upper = true;
|
||||||
|
FMT_FALLTHROUGH;
|
||||||
|
case 'x':
|
||||||
|
return parse_presentation_type(pres::hex, integral_set);
|
||||||
case 'o':
|
case 'o':
|
||||||
return parse_presentation_type(pres::oct, integral_set);
|
return parse_presentation_type(pres::oct, integral_set);
|
||||||
case 'x':
|
|
||||||
return parse_presentation_type(pres::hex_lower, integral_set);
|
|
||||||
case 'X':
|
|
||||||
return parse_presentation_type(pres::hex_upper, integral_set);
|
|
||||||
case 'b':
|
|
||||||
return parse_presentation_type(pres::bin_lower, integral_set);
|
|
||||||
case 'B':
|
case 'B':
|
||||||
return parse_presentation_type(pres::bin_upper, integral_set);
|
specs.upper = true;
|
||||||
case 'a':
|
FMT_FALLTHROUGH;
|
||||||
return parse_presentation_type(pres::hexfloat_lower, float_set);
|
case 'b':
|
||||||
case 'A':
|
return parse_presentation_type(pres::bin, integral_set);
|
||||||
return parse_presentation_type(pres::hexfloat_upper, float_set);
|
|
||||||
case 'e':
|
|
||||||
return parse_presentation_type(pres::exp_lower, float_set);
|
|
||||||
case 'E':
|
case 'E':
|
||||||
return parse_presentation_type(pres::exp_upper, float_set);
|
specs.upper = true;
|
||||||
case 'f':
|
FMT_FALLTHROUGH;
|
||||||
return parse_presentation_type(pres::fixed_lower, float_set);
|
case 'e':
|
||||||
|
return parse_presentation_type(pres::exp, float_set);
|
||||||
case 'F':
|
case 'F':
|
||||||
return parse_presentation_type(pres::fixed_upper, float_set);
|
specs.upper = true;
|
||||||
case 'g':
|
FMT_FALLTHROUGH;
|
||||||
return parse_presentation_type(pres::general_lower, float_set);
|
case 'f':
|
||||||
|
return parse_presentation_type(pres::fixed, float_set);
|
||||||
case 'G':
|
case 'G':
|
||||||
return parse_presentation_type(pres::general_upper, float_set);
|
specs.upper = true;
|
||||||
|
FMT_FALLTHROUGH;
|
||||||
|
case 'g':
|
||||||
|
return parse_presentation_type(pres::general, float_set);
|
||||||
|
case 'A':
|
||||||
|
specs.upper = true;
|
||||||
|
FMT_FALLTHROUGH;
|
||||||
|
case 'a':
|
||||||
|
return parse_presentation_type(pres::hexfloat, float_set);
|
||||||
case 'c':
|
case 'c':
|
||||||
if (arg_type == type::bool_type)
|
if (arg_type == type::bool_type)
|
||||||
throw_format_error("invalid format specifier");
|
throw_format_error("invalid format specifier");
|
||||||
|
@@ -1735,8 +1735,8 @@ template <typename Char, typename Rep, typename OutputIt,
|
|||||||
auto format_duration_value(OutputIt out, Rep val, int precision) -> OutputIt {
|
auto format_duration_value(OutputIt out, Rep val, int precision) -> OutputIt {
|
||||||
auto specs = format_specs<Char>();
|
auto specs = format_specs<Char>();
|
||||||
specs.precision = precision;
|
specs.precision = precision;
|
||||||
specs.type = precision >= 0 ? presentation_type::fixed_lower
|
specs.type =
|
||||||
: presentation_type::general_lower;
|
precision >= 0 ? presentation_type::fixed : presentation_type::general;
|
||||||
return write<Char>(out, val, specs);
|
return write<Char>(out, val, specs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -71,17 +71,6 @@
|
|||||||
# define FMT_INLINE_VARIABLE
|
# define FMT_INLINE_VARIABLE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if FMT_HAS_CPP17_ATTRIBUTE(fallthrough)
|
|
||||||
# define FMT_FALLTHROUGH [[fallthrough]]
|
|
||||||
#elif defined(__clang__)
|
|
||||||
# define FMT_FALLTHROUGH [[clang::fallthrough]]
|
|
||||||
#elif FMT_GCC_VERSION >= 700 && \
|
|
||||||
(!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 520)
|
|
||||||
# define FMT_FALLTHROUGH [[gnu::fallthrough]]
|
|
||||||
#else
|
|
||||||
# define FMT_FALLTHROUGH
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef FMT_NO_UNIQUE_ADDRESS
|
#ifndef FMT_NO_UNIQUE_ADDRESS
|
||||||
# if FMT_CPLUSPLUS >= 202002L
|
# if FMT_CPLUSPLUS >= 202002L
|
||||||
# if FMT_HAS_CPP_ATTRIBUTE(no_unique_address)
|
# if FMT_HAS_CPP_ATTRIBUTE(no_unique_address)
|
||||||
@@ -2096,30 +2085,17 @@ auto write_int(OutputIt out, UInt value, unsigned prefix,
|
|||||||
FMT_ASSERT(false, "");
|
FMT_ASSERT(false, "");
|
||||||
FMT_FALLTHROUGH;
|
FMT_FALLTHROUGH;
|
||||||
case presentation_type::none:
|
case presentation_type::none:
|
||||||
case presentation_type::dec: {
|
case presentation_type::dec:
|
||||||
num_digits = count_digits(value);
|
num_digits = count_digits(value);
|
||||||
format_decimal<char>(appender(buffer), value, num_digits);
|
format_decimal<char>(appender(buffer), value, num_digits);
|
||||||
break;
|
break;
|
||||||
}
|
case presentation_type::hex:
|
||||||
case presentation_type::hex_lower:
|
|
||||||
case presentation_type::hex_upper: {
|
|
||||||
bool upper = specs.type == presentation_type::hex_upper;
|
|
||||||
if (specs.alt)
|
if (specs.alt)
|
||||||
prefix_append(prefix, unsigned(upper ? 'X' : 'x') << 8 | '0');
|
prefix_append(prefix, unsigned(specs.upper ? 'X' : 'x') << 8 | '0');
|
||||||
num_digits = count_digits<4>(value);
|
num_digits = count_digits<4>(value);
|
||||||
format_uint<4, char>(appender(buffer), value, num_digits, upper);
|
format_uint<4, char>(appender(buffer), value, num_digits, specs.upper);
|
||||||
break;
|
break;
|
||||||
}
|
case presentation_type::oct:
|
||||||
case presentation_type::bin_lower:
|
|
||||||
case presentation_type::bin_upper: {
|
|
||||||
bool upper = specs.type == presentation_type::bin_upper;
|
|
||||||
if (specs.alt)
|
|
||||||
prefix_append(prefix, unsigned(upper ? 'B' : 'b') << 8 | '0');
|
|
||||||
num_digits = count_digits<1>(value);
|
|
||||||
format_uint<1, char>(appender(buffer), value, num_digits);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case presentation_type::oct: {
|
|
||||||
num_digits = count_digits<3>(value);
|
num_digits = count_digits<3>(value);
|
||||||
// Octal prefix '0' is counted as a digit, so only add it if precision
|
// Octal prefix '0' is counted as a digit, so only add it if precision
|
||||||
// is not greater than the number of digits.
|
// is not greater than the number of digits.
|
||||||
@@ -2127,7 +2103,12 @@ auto write_int(OutputIt out, UInt value, unsigned prefix,
|
|||||||
prefix_append(prefix, '0');
|
prefix_append(prefix, '0');
|
||||||
format_uint<3, char>(appender(buffer), value, num_digits);
|
format_uint<3, char>(appender(buffer), value, num_digits);
|
||||||
break;
|
break;
|
||||||
}
|
case presentation_type::bin:
|
||||||
|
if (specs.alt)
|
||||||
|
prefix_append(prefix, unsigned(specs.upper ? 'B' : 'b') << 8 | '0');
|
||||||
|
num_digits = count_digits<1>(value);
|
||||||
|
format_uint<1, char>(appender(buffer), value, num_digits);
|
||||||
|
break;
|
||||||
case presentation_type::chr:
|
case presentation_type::chr:
|
||||||
return write_char(out, static_cast<Char>(value), specs);
|
return write_char(out, static_cast<Char>(value), specs);
|
||||||
}
|
}
|
||||||
@@ -2206,34 +2187,21 @@ FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, write_int_arg<T> arg,
|
|||||||
FMT_FALLTHROUGH;
|
FMT_FALLTHROUGH;
|
||||||
case presentation_type::none:
|
case presentation_type::none:
|
||||||
case presentation_type::dec: {
|
case presentation_type::dec: {
|
||||||
auto num_digits = count_digits(abs_value);
|
int num_digits = count_digits(abs_value);
|
||||||
return write_int(
|
return write_int(
|
||||||
out, num_digits, prefix, specs, [=](reserve_iterator<OutputIt> it) {
|
out, num_digits, prefix, specs, [=](reserve_iterator<OutputIt> it) {
|
||||||
return format_decimal<Char>(it, abs_value, num_digits).end;
|
return format_decimal<Char>(it, abs_value, num_digits).end;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
case presentation_type::hex_lower:
|
case presentation_type::hex: {
|
||||||
case presentation_type::hex_upper: {
|
|
||||||
bool upper = specs.type == presentation_type::hex_upper;
|
|
||||||
if (specs.alt)
|
if (specs.alt)
|
||||||
prefix_append(prefix, unsigned(upper ? 'X' : 'x') << 8 | '0');
|
prefix_append(prefix, unsigned(specs.upper ? 'X' : 'x') << 8 | '0');
|
||||||
int num_digits = count_digits<4>(abs_value);
|
int num_digits = count_digits<4>(abs_value);
|
||||||
return write_int(
|
return write_int(
|
||||||
out, num_digits, prefix, specs, [=](reserve_iterator<OutputIt> it) {
|
out, num_digits, prefix, specs, [=](reserve_iterator<OutputIt> it) {
|
||||||
return format_uint<4, Char>(it, abs_value, num_digits, upper);
|
return format_uint<4, Char>(it, abs_value, num_digits, specs.upper);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
case presentation_type::bin_lower:
|
|
||||||
case presentation_type::bin_upper: {
|
|
||||||
bool upper = specs.type == presentation_type::bin_upper;
|
|
||||||
if (specs.alt)
|
|
||||||
prefix_append(prefix, unsigned(upper ? 'B' : 'b') << 8 | '0');
|
|
||||||
int num_digits = count_digits<1>(abs_value);
|
|
||||||
return write_int(out, num_digits, prefix, specs,
|
|
||||||
[=](reserve_iterator<OutputIt> it) {
|
|
||||||
return format_uint<1, Char>(it, abs_value, num_digits);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
case presentation_type::oct: {
|
case presentation_type::oct: {
|
||||||
int num_digits = count_digits<3>(abs_value);
|
int num_digits = count_digits<3>(abs_value);
|
||||||
// Octal prefix '0' is counted as a digit, so only add it if precision
|
// Octal prefix '0' is counted as a digit, so only add it if precision
|
||||||
@@ -2245,6 +2213,15 @@ FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, write_int_arg<T> arg,
|
|||||||
return format_uint<3, Char>(it, abs_value, num_digits);
|
return format_uint<3, Char>(it, abs_value, num_digits);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
case presentation_type::bin: {
|
||||||
|
if (specs.alt)
|
||||||
|
prefix_append(prefix, unsigned(specs.upper ? 'B' : 'b') << 8 | '0');
|
||||||
|
int num_digits = count_digits<1>(abs_value);
|
||||||
|
return write_int(out, num_digits, prefix, specs,
|
||||||
|
[=](reserve_iterator<OutputIt> it) {
|
||||||
|
return format_uint<1, Char>(it, abs_value, num_digits);
|
||||||
|
});
|
||||||
|
}
|
||||||
case presentation_type::chr:
|
case presentation_type::chr:
|
||||||
return write_char(out, static_cast<Char>(abs_value), specs);
|
return write_char(out, static_cast<Char>(abs_value), specs);
|
||||||
}
|
}
|
||||||
@@ -2456,31 +2433,23 @@ FMT_CONSTEXPR auto parse_float_type_spec(const format_specs<Char>& specs)
|
|||||||
case presentation_type::none:
|
case presentation_type::none:
|
||||||
result.format = float_format::general;
|
result.format = float_format::general;
|
||||||
break;
|
break;
|
||||||
case presentation_type::general_upper:
|
case presentation_type::exp:
|
||||||
result.upper = true;
|
result.format = float_format::exp;
|
||||||
FMT_FALLTHROUGH;
|
result.upper = specs.upper;
|
||||||
case presentation_type::general_lower:
|
result.showpoint |= specs.precision != 0;
|
||||||
|
break;
|
||||||
|
case presentation_type::fixed:
|
||||||
|
result.format = float_format::fixed;
|
||||||
|
result.upper = specs.upper;
|
||||||
|
result.showpoint |= specs.precision != 0;
|
||||||
|
break;
|
||||||
|
case presentation_type::general:
|
||||||
|
result.upper = specs.upper;
|
||||||
result.format = float_format::general;
|
result.format = float_format::general;
|
||||||
break;
|
break;
|
||||||
case presentation_type::exp_upper:
|
case presentation_type::hexfloat:
|
||||||
result.upper = true;
|
|
||||||
FMT_FALLTHROUGH;
|
|
||||||
case presentation_type::exp_lower:
|
|
||||||
result.format = float_format::exp;
|
|
||||||
result.showpoint |= specs.precision != 0;
|
|
||||||
break;
|
|
||||||
case presentation_type::fixed_upper:
|
|
||||||
result.upper = true;
|
|
||||||
FMT_FALLTHROUGH;
|
|
||||||
case presentation_type::fixed_lower:
|
|
||||||
result.format = float_format::fixed;
|
|
||||||
result.showpoint |= specs.precision != 0;
|
|
||||||
break;
|
|
||||||
case presentation_type::hexfloat_upper:
|
|
||||||
result.upper = true;
|
|
||||||
FMT_FALLTHROUGH;
|
|
||||||
case presentation_type::hexfloat_lower:
|
|
||||||
result.format = float_format::hex;
|
result.format = float_format::hex;
|
||||||
|
result.upper = specs.upper;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@@ -373,7 +373,7 @@ auto parse_header(const Char*& it, const Char* end, format_specs<Char>& specs,
|
|||||||
return arg_index;
|
return arg_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline auto parse_printf_presentation_type(char c, type t)
|
inline auto parse_printf_presentation_type(char c, type t, bool& upper)
|
||||||
-> presentation_type {
|
-> presentation_type {
|
||||||
using pt = presentation_type;
|
using pt = presentation_type;
|
||||||
constexpr auto integral_set = sint_set | uint_set | bool_set | char_set;
|
constexpr auto integral_set = sint_set | uint_set | bool_set | char_set;
|
||||||
@@ -382,26 +382,31 @@ inline auto parse_printf_presentation_type(char c, type t)
|
|||||||
return in(t, integral_set) ? pt::dec : pt::none;
|
return in(t, integral_set) ? pt::dec : pt::none;
|
||||||
case 'o':
|
case 'o':
|
||||||
return in(t, integral_set) ? pt::oct : pt::none;
|
return in(t, integral_set) ? pt::oct : pt::none;
|
||||||
case 'x':
|
|
||||||
return in(t, integral_set) ? pt::hex_lower : pt::none;
|
|
||||||
case 'X':
|
case 'X':
|
||||||
return in(t, integral_set) ? pt::hex_upper : pt::none;
|
upper = true;
|
||||||
case 'a':
|
FMT_FALLTHROUGH;
|
||||||
return in(t, float_set) ? pt::hexfloat_lower : pt::none;
|
case 'x':
|
||||||
case 'A':
|
return in(t, integral_set) ? pt::hex : pt::none;
|
||||||
return in(t, float_set) ? pt::hexfloat_upper : pt::none;
|
|
||||||
case 'e':
|
|
||||||
return in(t, float_set) ? pt::exp_lower : pt::none;
|
|
||||||
case 'E':
|
case 'E':
|
||||||
return in(t, float_set) ? pt::exp_upper : pt::none;
|
upper = true;
|
||||||
case 'f':
|
FMT_FALLTHROUGH;
|
||||||
return in(t, float_set) ? pt::fixed_lower : pt::none;
|
case 'e':
|
||||||
|
return in(t, float_set) ? pt::exp : pt::none;
|
||||||
case 'F':
|
case 'F':
|
||||||
return in(t, float_set) ? pt::fixed_upper : pt::none;
|
upper = true;
|
||||||
case 'g':
|
FMT_FALLTHROUGH;
|
||||||
return in(t, float_set) ? pt::general_lower : pt::none;
|
case 'f':
|
||||||
|
return in(t, float_set) ? pt::fixed : pt::none;
|
||||||
case 'G':
|
case 'G':
|
||||||
return in(t, float_set) ? pt::general_upper : pt::none;
|
upper = true;
|
||||||
|
FMT_FALLTHROUGH;
|
||||||
|
case 'g':
|
||||||
|
return in(t, float_set) ? pt::general : pt::none;
|
||||||
|
case 'A':
|
||||||
|
upper = true;
|
||||||
|
FMT_FALLTHROUGH;
|
||||||
|
case 'a':
|
||||||
|
return in(t, float_set) ? pt::hexfloat : pt::none;
|
||||||
case 'c':
|
case 'c':
|
||||||
return in(t, integral_set) ? pt::chr : pt::none;
|
return in(t, integral_set) ? pt::chr : pt::none;
|
||||||
case 's':
|
case 's':
|
||||||
@@ -548,9 +553,11 @@ void vprintf(buffer<Char>& buf, basic_string_view<Char> format,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
specs.type = parse_printf_presentation_type(type, arg.type());
|
bool upper = false;
|
||||||
|
specs.type = parse_printf_presentation_type(type, arg.type(), upper);
|
||||||
if (specs.type == presentation_type::none)
|
if (specs.type == presentation_type::none)
|
||||||
throw_format_error("invalid format specifier");
|
throw_format_error("invalid format specifier");
|
||||||
|
specs.upper = upper;
|
||||||
|
|
||||||
start = it;
|
start = it;
|
||||||
|
|
||||||
|
@@ -516,7 +516,7 @@ TEST(core_test, constexpr_parse_format_specs) {
|
|||||||
static_assert(parse_test_specs(".42").precision == 42, "");
|
static_assert(parse_test_specs(".42").precision == 42, "");
|
||||||
static_assert(parse_test_specs(".{42}").precision_ref.val.index == 42, "");
|
static_assert(parse_test_specs(".{42}").precision_ref.val.index == 42, "");
|
||||||
static_assert(
|
static_assert(
|
||||||
parse_test_specs("f").type == fmt::presentation_type::fixed_lower, "");
|
parse_test_specs("f").type == fmt::presentation_type::fixed, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
struct test_format_string_handler {
|
struct test_format_string_handler {
|
||||||
|
@@ -439,7 +439,7 @@ const char* parse_scan_specs(const char* begin, const char* end,
|
|||||||
switch (to_ascii(*begin)) {
|
switch (to_ascii(*begin)) {
|
||||||
// TODO: parse more scan format specifiers
|
// TODO: parse more scan format specifiers
|
||||||
case 'x':
|
case 'x':
|
||||||
specs.type = presentation_type::hex_lower;
|
specs.type = presentation_type::hex;
|
||||||
++begin;
|
++begin;
|
||||||
break;
|
break;
|
||||||
case '}':
|
case '}':
|
||||||
@@ -508,7 +508,7 @@ auto read_hex(scan_iterator it, T& value) -> scan_iterator {
|
|||||||
template <typename T, FMT_ENABLE_IF(std::is_unsigned<T>::value)>
|
template <typename T, FMT_ENABLE_IF(std::is_unsigned<T>::value)>
|
||||||
auto read(scan_iterator it, T& value, const format_specs<>& specs)
|
auto read(scan_iterator it, T& value, const format_specs<>& specs)
|
||||||
-> scan_iterator {
|
-> scan_iterator {
|
||||||
if (specs.type == presentation_type::hex_lower) return read_hex(it, value);
|
if (specs.type == presentation_type::hex) return read_hex(it, value);
|
||||||
return read(it, value);
|
return read(it, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -584,7 +584,7 @@ template <class charT> struct formatter<std::complex<double>, charT> {
|
|||||||
specs.precision, specs.precision_ref, ctx);
|
specs.precision, specs.precision_ref, ctx);
|
||||||
auto fspecs = std::string();
|
auto fspecs = std::string();
|
||||||
if (specs.precision > 0) fspecs = fmt::format(".{}", specs.precision);
|
if (specs.precision > 0) fspecs = fmt::format(".{}", specs.precision);
|
||||||
if (specs.type == presentation_type::fixed_lower) fspecs += 'f';
|
if (specs.type == presentation_type::fixed) fspecs += 'f';
|
||||||
auto real = fmt::format(ctx.locale().template get<std::locale>(),
|
auto real = fmt::format(ctx.locale().template get<std::locale>(),
|
||||||
fmt::runtime("{:" + fspecs + "}"), c.real());
|
fmt::runtime("{:" + fspecs + "}"), c.real());
|
||||||
auto imag = fmt::format(ctx.locale().template get<std::locale>(),
|
auto imag = fmt::format(ctx.locale().template get<std::locale>(),
|
||||||
|
Reference in New Issue
Block a user