Refactor format string checks
This commit is contained in:
+63
-5
@@ -2249,14 +2249,13 @@ FMT_CONSTEXPR auto write(OutputIt out,
|
||||
basic_string_view<type_identity_t<Char>> s,
|
||||
const format_specs<Char>& specs, locale_ref)
|
||||
-> OutputIt {
|
||||
check_string_type_spec(specs.type);
|
||||
return write(out, s, specs);
|
||||
}
|
||||
template <typename Char, typename OutputIt>
|
||||
FMT_CONSTEXPR auto write(OutputIt out, const Char* s,
|
||||
const format_specs<Char>& specs, locale_ref)
|
||||
-> OutputIt {
|
||||
return check_cstring_type_spec(specs.type)
|
||||
return specs.type != presentation_type::pointer
|
||||
? write(out, basic_string_view<Char>(s), specs, {})
|
||||
: write_ptr<Char>(out, bit_cast<uintptr_t>(s), &specs);
|
||||
}
|
||||
@@ -2283,6 +2282,68 @@ FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt {
|
||||
return base_iterator(out, it);
|
||||
}
|
||||
|
||||
// A floating-point presentation format.
|
||||
enum class float_format : unsigned char {
|
||||
general, // General: exponent notation or fixed point based on magnitude.
|
||||
exp, // Exponent notation with the default precision of 6, e.g. 1.2e-3.
|
||||
fixed, // Fixed point with the default precision of 6, e.g. 0.0012.
|
||||
hex
|
||||
};
|
||||
|
||||
struct float_specs {
|
||||
int precision;
|
||||
float_format format : 8;
|
||||
sign_t sign : 8;
|
||||
bool upper : 1;
|
||||
bool locale : 1;
|
||||
bool binary32 : 1;
|
||||
bool showpoint : 1;
|
||||
};
|
||||
|
||||
template <typename ErrorHandler = error_handler, typename Char>
|
||||
FMT_CONSTEXPR auto parse_float_type_spec(const format_specs<Char>& specs,
|
||||
ErrorHandler&& eh = {})
|
||||
-> float_specs {
|
||||
auto result = float_specs();
|
||||
result.showpoint = specs.alt;
|
||||
result.locale = specs.localized;
|
||||
switch (specs.type) {
|
||||
case presentation_type::none:
|
||||
result.format = float_format::general;
|
||||
break;
|
||||
case presentation_type::general_upper:
|
||||
result.upper = true;
|
||||
FMT_FALLTHROUGH;
|
||||
case presentation_type::general_lower:
|
||||
result.format = float_format::general;
|
||||
break;
|
||||
case presentation_type::exp_upper:
|
||||
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;
|
||||
break;
|
||||
default:
|
||||
eh.on_error("invalid format specifier");
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename Char, typename OutputIt>
|
||||
FMT_CONSTEXPR20 auto write_nonfinite(OutputIt out, bool isnan,
|
||||
format_specs<Char> specs,
|
||||
@@ -3465,7 +3526,6 @@ template <typename Char, typename OutputIt, typename T,
|
||||
FMT_ENABLE_IF(std::is_same<T, void>::value)>
|
||||
auto write(OutputIt out, const T* value, const format_specs<Char>& specs = {},
|
||||
locale_ref = {}) -> OutputIt {
|
||||
check_pointer_type_spec(specs.type, error_handler());
|
||||
return write_ptr<Char>(out, bit_cast<uintptr_t>(value), &specs);
|
||||
}
|
||||
|
||||
@@ -3891,7 +3951,6 @@ template <> struct formatter<bytes> {
|
||||
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||
auto end = parse_format_specs(ctx.begin(), ctx.end(), specs_, ctx,
|
||||
detail::type::string_type);
|
||||
detail::check_string_type_spec(specs_.type, detail::error_handler());
|
||||
return end;
|
||||
}
|
||||
|
||||
@@ -3932,7 +3991,6 @@ template <typename T> struct formatter<group_digits_view<T>> : formatter<T> {
|
||||
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
||||
auto end = parse_format_specs(ctx.begin(), ctx.end(), specs_, ctx,
|
||||
detail::type::int_type);
|
||||
detail::check_string_type_spec(specs_.type, detail::error_handler());
|
||||
return end;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user