mirror of
https://github.com/shadps4-emu/ext-fmt.git
synced 2025-02-20 02:03:16 +00:00
Reduce format specs size
This commit is contained in:
parent
98314319ad
commit
50a8c3e9bf
@ -2136,6 +2136,9 @@ struct fill_t {
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
enum class arg_id_kind { none, index, name };
|
||||
|
||||
} // namespace detail
|
||||
|
||||
enum class presentation_type : unsigned char {
|
||||
@ -2168,6 +2171,7 @@ struct format_specs {
|
||||
presentation_type type;
|
||||
align_t align : 4;
|
||||
sign_t sign : 3;
|
||||
unsigned char dynamic : 4;
|
||||
bool upper : 1; // An uppercase version e.g. 'X' for 'x'.
|
||||
bool alt : 1; // Alternate form ('#').
|
||||
bool localized : 1;
|
||||
@ -2179,38 +2183,31 @@ struct format_specs {
|
||||
type(presentation_type::none),
|
||||
align(align::none),
|
||||
sign(sign::none),
|
||||
dynamic(0),
|
||||
upper(false),
|
||||
alt(false),
|
||||
localized(false) {}
|
||||
|
||||
enum { dynamic_width_mask = 3, dynamic_precision_mask = 12 };
|
||||
|
||||
constexpr auto dynamic_width() const -> detail::arg_id_kind {
|
||||
return static_cast<detail::arg_id_kind>(dynamic & dynamic_width_mask);
|
||||
}
|
||||
constexpr auto dynamic_precision() const -> detail::arg_id_kind {
|
||||
return static_cast<detail::arg_id_kind>(
|
||||
(dynamic & dynamic_precision_mask) >> 2);
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
enum class arg_id_kind { none, index, name };
|
||||
|
||||
// An argument reference.
|
||||
template <typename Char> struct arg_ref {
|
||||
FMT_CONSTEXPR arg_ref() : kind(arg_id_kind::none), val() {}
|
||||
template <typename Char> union arg_ref {
|
||||
FMT_CONSTEXPR arg_ref(int idx = 0) : index(idx) {}
|
||||
FMT_CONSTEXPR arg_ref(basic_string_view<Char> n) : name(n) {}
|
||||
|
||||
FMT_CONSTEXPR explicit arg_ref(int index)
|
||||
: kind(arg_id_kind::index), val(index) {}
|
||||
FMT_CONSTEXPR explicit arg_ref(basic_string_view<Char> name)
|
||||
: kind(arg_id_kind::name), val(name) {}
|
||||
|
||||
FMT_CONSTEXPR auto operator=(int idx) -> arg_ref& {
|
||||
kind = arg_id_kind::index;
|
||||
val.index = idx;
|
||||
return *this;
|
||||
}
|
||||
|
||||
arg_id_kind kind;
|
||||
union value {
|
||||
FMT_CONSTEXPR value(int idx = 0) : index(idx) {}
|
||||
FMT_CONSTEXPR value(basic_string_view<Char> n) : name(n) {}
|
||||
|
||||
int index;
|
||||
basic_string_view<Char> name;
|
||||
} val;
|
||||
int index;
|
||||
basic_string_view<Char> name;
|
||||
};
|
||||
|
||||
// Format specifiers with width and precision resolved at formatting rather
|
||||
@ -2321,28 +2318,37 @@ FMT_CONSTEXPR auto parse_arg_id(const Char* begin, const Char* end,
|
||||
return it;
|
||||
}
|
||||
|
||||
template <typename Char> struct dynamic_spec_id_handler {
|
||||
template <typename Char> struct dynamic_spec_handler {
|
||||
basic_format_parse_context<Char>& ctx;
|
||||
arg_ref<Char>& ref;
|
||||
arg_id_kind& kind;
|
||||
|
||||
FMT_CONSTEXPR void on_index(int id) {
|
||||
ref = arg_ref<Char>(id);
|
||||
ref = id;
|
||||
kind = arg_id_kind::index;
|
||||
ctx.check_arg_id(id);
|
||||
ctx.check_dynamic_spec(id);
|
||||
}
|
||||
FMT_CONSTEXPR void on_name(basic_string_view<Char> id) {
|
||||
ref = arg_ref<Char>(id);
|
||||
ref = id;
|
||||
kind = arg_id_kind::name;
|
||||
ctx.check_arg_id(id);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char> struct parse_dynamic_spec_result {
|
||||
const Char* end;
|
||||
arg_id_kind kind;
|
||||
};
|
||||
|
||||
// Parses integer | "{" [arg_id] "}".
|
||||
template <typename Char>
|
||||
FMT_CONSTEXPR auto parse_dynamic_spec(const Char* begin, const Char* end,
|
||||
int& value, arg_ref<Char>& ref,
|
||||
basic_format_parse_context<Char>& ctx)
|
||||
-> const Char* {
|
||||
-> parse_dynamic_spec_result<Char> {
|
||||
FMT_ASSERT(begin != end, "");
|
||||
auto kind = arg_id_kind::none;
|
||||
if ('0' <= *begin && *begin <= '9') {
|
||||
int val = parse_nonnegative_int(begin, end, -1);
|
||||
if (val == -1) report_error("number is too big");
|
||||
@ -2354,31 +2360,48 @@ FMT_CONSTEXPR auto parse_dynamic_spec(const Char* begin, const Char* end,
|
||||
Char c = *begin;
|
||||
if (c == '}' || c == ':') {
|
||||
int id = ctx.next_arg_id();
|
||||
ref = arg_ref<Char>(id);
|
||||
ref = id;
|
||||
kind = arg_id_kind::index;
|
||||
ctx.check_dynamic_spec(id);
|
||||
} else {
|
||||
begin =
|
||||
parse_arg_id(begin, end, dynamic_spec_id_handler<Char>{ctx, ref});
|
||||
begin = parse_arg_id(begin, end,
|
||||
dynamic_spec_handler<Char>{ctx, ref, kind});
|
||||
}
|
||||
}
|
||||
if (begin != end && *begin == '}') return ++begin;
|
||||
if (begin != end && *begin == '}') return {++begin, kind};
|
||||
}
|
||||
report_error("invalid format string");
|
||||
}
|
||||
return begin;
|
||||
return {begin, kind};
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
FMT_CONSTEXPR auto parse_width(const Char* begin, const Char* end,
|
||||
format_specs& specs, arg_ref<Char>& width_ref,
|
||||
basic_format_parse_context<Char>& ctx)
|
||||
-> const Char* {
|
||||
auto result = parse_dynamic_spec(begin, end, specs.width, width_ref, ctx);
|
||||
specs.dynamic = static_cast<unsigned char>(result.kind) & 0x3u;
|
||||
return result.end;
|
||||
}
|
||||
|
||||
template <typename Char>
|
||||
FMT_CONSTEXPR auto parse_precision(const Char* begin, const Char* end,
|
||||
int& value, arg_ref<Char>& ref,
|
||||
format_specs& specs,
|
||||
arg_ref<Char>& precision_ref,
|
||||
basic_format_parse_context<Char>& ctx)
|
||||
-> const Char* {
|
||||
++begin;
|
||||
if (begin != end)
|
||||
begin = parse_dynamic_spec(begin, end, value, ref, ctx);
|
||||
else
|
||||
if (begin == end) {
|
||||
report_error("invalid precision");
|
||||
return begin;
|
||||
return begin;
|
||||
}
|
||||
auto result =
|
||||
parse_dynamic_spec(begin, end, specs.precision, precision_ref, ctx);
|
||||
auto kind_val = static_cast<unsigned char>(result.kind);
|
||||
specs.dynamic =
|
||||
static_cast<unsigned char>(specs.dynamic | (kind_val << 2)) & 0xfu;
|
||||
return result.end;
|
||||
}
|
||||
|
||||
enum class state { start, align, sign, hash, zero, width, precision, locale };
|
||||
@ -2466,13 +2489,12 @@ FMT_CONSTEXPR auto parse_format_specs(const Char* begin, const Char* end,
|
||||
case '9':
|
||||
case '{':
|
||||
enter_state(state::width);
|
||||
begin = parse_dynamic_spec(begin, end, specs.width, specs.width_ref, ctx);
|
||||
begin = parse_width(begin, end, specs, specs.width_ref, ctx);
|
||||
break;
|
||||
case '.':
|
||||
enter_state(state::precision,
|
||||
in(arg_type, float_set | string_set | cstring_set));
|
||||
begin = parse_precision(begin, end, specs.precision, specs.precision_ref,
|
||||
ctx);
|
||||
begin = parse_precision(begin, end, specs, specs.precision_ref, ctx);
|
||||
break;
|
||||
case 'L':
|
||||
enter_state(state::locale, is_arithmetic_type(arg_type));
|
||||
|
@ -2253,15 +2253,14 @@ struct formatter<std::chrono::duration<Rep, Period>, Char> {
|
||||
|
||||
Char c = *it;
|
||||
if ((c >= '0' && c <= '9') || c == '{') {
|
||||
it = detail::parse_dynamic_spec(it, end, specs_.width, width_ref_, ctx);
|
||||
it = detail::parse_width(it, end, specs_, width_ref_, ctx);
|
||||
if (it == end) return it;
|
||||
}
|
||||
|
||||
auto checker = detail::chrono_format_checker();
|
||||
if (*it == '.') {
|
||||
checker.has_precision_integral = !std::is_floating_point<Rep>::value;
|
||||
it = detail::parse_precision(it, end, specs_.precision, precision_ref_,
|
||||
ctx);
|
||||
it = detail::parse_precision(it, end, specs_, precision_ref_, ctx);
|
||||
}
|
||||
if (it != end && *it == 'L') {
|
||||
localized_ = true;
|
||||
@ -2283,8 +2282,10 @@ struct formatter<std::chrono::duration<Rep, Period>, Char> {
|
||||
// is not specified.
|
||||
auto buf = basic_memory_buffer<Char>();
|
||||
auto out = basic_appender<Char>(buf);
|
||||
detail::handle_dynamic_spec(specs.width, width_ref_, ctx);
|
||||
detail::handle_dynamic_spec(precision, precision_ref_, ctx);
|
||||
detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_,
|
||||
ctx);
|
||||
detail::handle_dynamic_spec(specs.dynamic_precision(), precision,
|
||||
precision_ref_, ctx);
|
||||
if (begin == end || *begin == '}') {
|
||||
out = detail::format_duration_value<Char>(out, d.count(), precision);
|
||||
detail::format_duration_unit<Char, Period>(out);
|
||||
@ -2390,7 +2391,8 @@ template <typename Char> struct formatter<std::tm, Char> {
|
||||
auto specs = specs_;
|
||||
auto buf = basic_memory_buffer<Char>();
|
||||
auto out = basic_appender<Char>(buf);
|
||||
detail::handle_dynamic_spec(specs.width, width_ref_, ctx);
|
||||
detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_,
|
||||
ctx);
|
||||
|
||||
auto loc_ref = ctx.locale();
|
||||
detail::get_locale loc(static_cast<bool>(loc_ref), loc_ref);
|
||||
@ -2412,7 +2414,7 @@ template <typename Char> struct formatter<std::tm, Char> {
|
||||
|
||||
Char c = *it;
|
||||
if ((c >= '0' && c <= '9') || c == '{') {
|
||||
it = detail::parse_dynamic_spec(it, end, specs_.width, width_ref_, ctx);
|
||||
it = detail::parse_width(it, end, specs_, width_ref_, ctx);
|
||||
if (it == end) return it;
|
||||
}
|
||||
|
||||
|
@ -269,6 +269,7 @@ constexpr parse_specs_result<T, Char> parse_specs(basic_string_view<Char> str,
|
||||
}
|
||||
|
||||
template <typename Char> struct arg_id_handler {
|
||||
arg_id_kind kind;
|
||||
arg_ref<Char> arg_id;
|
||||
|
||||
constexpr int on_auto() {
|
||||
@ -276,25 +277,28 @@ template <typename Char> struct arg_id_handler {
|
||||
return 0;
|
||||
}
|
||||
constexpr int on_index(int id) {
|
||||
kind = arg_id_kind::index;
|
||||
arg_id = arg_ref<Char>(id);
|
||||
return 0;
|
||||
}
|
||||
constexpr int on_name(basic_string_view<Char> id) {
|
||||
kind = arg_id_kind::name;
|
||||
arg_id = arg_ref<Char>(id);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char> struct parse_arg_id_result {
|
||||
arg_id_kind kind;
|
||||
arg_ref<Char> arg_id;
|
||||
const Char* arg_id_end;
|
||||
};
|
||||
|
||||
template <int ID, typename Char>
|
||||
constexpr auto parse_arg_id(const Char* begin, const Char* end) {
|
||||
auto handler = arg_id_handler<Char>{arg_ref<Char>{}};
|
||||
auto handler = arg_id_handler<Char>{arg_id_kind::none, arg_ref<Char>{}};
|
||||
auto arg_id_end = parse_arg_id(begin, end, handler);
|
||||
return parse_arg_id_result<Char>{handler.arg_id, arg_id_end};
|
||||
return parse_arg_id_result<Char>{handler.kind, handler.arg_id, arg_id_end};
|
||||
}
|
||||
|
||||
template <typename T, typename Enable = void> struct field_type {
|
||||
@ -357,18 +361,18 @@ constexpr auto compile_format_string(S fmt) {
|
||||
constexpr char_type c =
|
||||
arg_id_end_pos != str.size() ? str[arg_id_end_pos] : char_type();
|
||||
static_assert(c == '}' || c == ':', "missing '}' in format string");
|
||||
if constexpr (arg_id_result.arg_id.kind == arg_id_kind::index) {
|
||||
if constexpr (arg_id_result.kind == arg_id_kind::index) {
|
||||
static_assert(
|
||||
ID == manual_indexing_id || ID == 0,
|
||||
"cannot switch from automatic to manual argument indexing");
|
||||
constexpr auto arg_index = arg_id_result.arg_id.val.index;
|
||||
constexpr auto arg_index = arg_id_result.arg_id.index;
|
||||
return parse_replacement_field_then_tail<get_type<arg_index, Args>,
|
||||
Args, arg_id_end_pos,
|
||||
arg_index, manual_indexing_id>(
|
||||
fmt);
|
||||
} else if constexpr (arg_id_result.arg_id.kind == arg_id_kind::name) {
|
||||
} else if constexpr (arg_id_result.kind == arg_id_kind::name) {
|
||||
constexpr auto arg_index =
|
||||
get_arg_index_by_name(arg_id_result.arg_id.val.name, Args{});
|
||||
get_arg_index_by_name(arg_id_result.arg_id.name, Args{});
|
||||
if constexpr (arg_index >= 0) {
|
||||
constexpr auto next_id =
|
||||
ID != manual_indexing_id ? ID + 1 : manual_indexing_id;
|
||||
@ -377,8 +381,7 @@ constexpr auto compile_format_string(S fmt) {
|
||||
arg_index, next_id>(fmt);
|
||||
} else if constexpr (c == '}') {
|
||||
return parse_tail<Args, arg_id_end_pos + 1, ID>(
|
||||
runtime_named_field<char_type>{arg_id_result.arg_id.val.name},
|
||||
fmt);
|
||||
runtime_named_field<char_type>{arg_id_result.arg_id.name}, fmt);
|
||||
} else if constexpr (c == ':') {
|
||||
return unknown_format(); // no type info for specs parsing
|
||||
}
|
||||
|
@ -3696,10 +3696,11 @@ FMT_CONSTEXPR auto get_arg(Context& ctx, ID id) -> basic_format_arg<Context> {
|
||||
|
||||
template <typename Context>
|
||||
FMT_CONSTEXPR int get_dynamic_spec(
|
||||
const arg_ref<typename Context::char_type>& ref, Context& ctx) {
|
||||
FMT_ASSERT(ref.kind != arg_id_kind::none, "");
|
||||
auto arg = ref.kind == arg_id_kind::index ? ctx.arg(ref.val.index)
|
||||
: ctx.arg(ref.val.name);
|
||||
arg_id_kind kind, const arg_ref<typename Context::char_type>& ref,
|
||||
Context& ctx) {
|
||||
FMT_ASSERT(kind != arg_id_kind::none, "");
|
||||
auto arg =
|
||||
kind == arg_id_kind::index ? ctx.arg(ref.index) : ctx.arg(ref.name);
|
||||
if (!arg) report_error("argument not found");
|
||||
unsigned long long value = arg.visit(dynamic_spec_getter());
|
||||
if (value > to_unsigned(max_value<int>()))
|
||||
@ -3709,8 +3710,9 @@ FMT_CONSTEXPR int get_dynamic_spec(
|
||||
|
||||
template <typename Context>
|
||||
FMT_CONSTEXPR void handle_dynamic_spec(
|
||||
int& value, const arg_ref<typename Context::char_type>& ref, Context& ctx) {
|
||||
if (ref.kind != arg_id_kind::none) value = get_dynamic_spec(ref, ctx);
|
||||
arg_id_kind kind, int& value,
|
||||
const arg_ref<typename Context::char_type>& ref, Context& ctx) {
|
||||
if (kind != arg_id_kind::none) value = get_dynamic_spec(kind, ref, ctx);
|
||||
}
|
||||
|
||||
#if FMT_USE_USER_DEFINED_LITERALS
|
||||
@ -3965,8 +3967,10 @@ template <> struct formatter<bytes> {
|
||||
template <typename FormatContext>
|
||||
auto format(bytes b, FormatContext& ctx) const -> decltype(ctx.out()) {
|
||||
auto specs = specs_;
|
||||
detail::handle_dynamic_spec(specs.width, specs.width_ref, ctx);
|
||||
detail::handle_dynamic_spec(specs.precision, specs.precision_ref, ctx);
|
||||
detail::handle_dynamic_spec(specs.dynamic_width(), specs.width,
|
||||
specs.width_ref, ctx);
|
||||
detail::handle_dynamic_spec(specs.dynamic_precision(), specs.precision,
|
||||
specs.precision_ref, ctx);
|
||||
return detail::write_bytes<char>(ctx.out(), b.data_, specs);
|
||||
}
|
||||
};
|
||||
@ -4004,8 +4008,10 @@ template <typename T> struct formatter<group_digits_view<T>> : formatter<T> {
|
||||
auto format(group_digits_view<T> t, FormatContext& ctx) const
|
||||
-> decltype(ctx.out()) {
|
||||
auto specs = specs_;
|
||||
detail::handle_dynamic_spec(specs.width, specs.width_ref, ctx);
|
||||
detail::handle_dynamic_spec(specs.precision, specs.precision_ref, ctx);
|
||||
detail::handle_dynamic_spec(specs.dynamic_width(), specs.width,
|
||||
specs.width_ref, ctx);
|
||||
detail::handle_dynamic_spec(specs.dynamic_precision(), specs.precision,
|
||||
specs.precision_ref, ctx);
|
||||
auto arg = detail::make_write_int_arg(t.value, specs.sign);
|
||||
return detail::write_int(
|
||||
ctx.out(), static_cast<detail::uint64_or_128_t<T>>(arg.abs_value),
|
||||
@ -4051,8 +4057,10 @@ template <typename T, typename Char = char> struct nested_formatter {
|
||||
align_ = specs.align;
|
||||
Char c = *it;
|
||||
auto width_ref = detail::arg_ref<Char>();
|
||||
if ((c >= '0' && c <= '9') || c == '{')
|
||||
it = detail::parse_dynamic_spec(it, end, width_, width_ref, ctx);
|
||||
if ((c >= '0' && c <= '9') || c == '{') {
|
||||
it = detail::parse_width(it, end, specs, width_ref, ctx);
|
||||
width_ = specs.width;
|
||||
}
|
||||
ctx.advance_to(it);
|
||||
return formatter_.parse(ctx);
|
||||
}
|
||||
@ -4149,12 +4157,14 @@ template <typename Char> struct format_handler {
|
||||
if (arg.format_custom(begin, parse_context, context))
|
||||
return parse_context.begin();
|
||||
|
||||
auto specs = detail::dynamic_format_specs<Char>();
|
||||
auto specs = dynamic_format_specs<Char>();
|
||||
begin = parse_format_specs(begin, end, specs, parse_context, arg.type());
|
||||
if (specs.width_ref.kind != detail::arg_id_kind::none)
|
||||
specs.width = detail::get_dynamic_spec(specs.width_ref, context);
|
||||
if (specs.precision_ref.kind != detail::arg_id_kind::none)
|
||||
specs.precision = detail::get_dynamic_spec(specs.precision_ref, context);
|
||||
if (specs.dynamic != 0) {
|
||||
handle_dynamic_spec(specs.dynamic_width(), specs.width, specs.width_ref,
|
||||
context);
|
||||
handle_dynamic_spec(specs.dynamic_precision(), specs.precision,
|
||||
specs.precision_ref, context);
|
||||
}
|
||||
|
||||
if (begin == end || *begin != '}')
|
||||
report_error("missing '}' in format string");
|
||||
@ -4196,13 +4206,13 @@ template <typename T, typename Char, type TYPE>
|
||||
template <typename FormatContext>
|
||||
FMT_CONSTEXPR FMT_INLINE auto native_formatter<T, Char, TYPE>::format(
|
||||
const T& val, FormatContext& ctx) const -> decltype(ctx.out()) {
|
||||
if (specs_.width_ref.kind == arg_id_kind::none &&
|
||||
specs_.precision_ref.kind == arg_id_kind::none) {
|
||||
if (specs_.dynamic == 0)
|
||||
return write<Char>(ctx.out(), val, specs_, ctx.locale());
|
||||
}
|
||||
auto specs = format_specs(specs_);
|
||||
handle_dynamic_spec(specs.width, specs_.width_ref, ctx);
|
||||
handle_dynamic_spec(specs.precision, specs_.precision_ref, ctx);
|
||||
handle_dynamic_spec(specs.dynamic_width(), specs.width, specs_.width_ref,
|
||||
ctx);
|
||||
handle_dynamic_spec(specs.dynamic_precision(), specs.precision,
|
||||
specs_.precision_ref, ctx);
|
||||
return write<Char>(ctx.out(), val, specs, ctx.locale());
|
||||
}
|
||||
|
||||
|
@ -131,7 +131,7 @@ template <typename Char> struct formatter<std::filesystem::path, Char> {
|
||||
|
||||
Char c = *it;
|
||||
if ((c >= '0' && c <= '9') || c == '{')
|
||||
it = detail::parse_dynamic_spec(it, end, specs_.width, width_ref_, ctx);
|
||||
it = detail::parse_width(it, end, specs_, width_ref_, ctx);
|
||||
if (it != end && *it == '?') {
|
||||
debug_ = true;
|
||||
++it;
|
||||
@ -147,7 +147,8 @@ template <typename Char> struct formatter<std::filesystem::path, Char> {
|
||||
!path_type_ ? p.native()
|
||||
: p.generic_string<std::filesystem::path::value_type>();
|
||||
|
||||
detail::handle_dynamic_spec(specs.width, width_ref_, ctx);
|
||||
detail::handle_dynamic_spec(specs.dynamic_width(), specs.width, width_ref_,
|
||||
ctx);
|
||||
if (!debug_) {
|
||||
auto s = detail::get_path_string<Char>(p, path_string);
|
||||
return detail::write(ctx.out(), basic_string_view<Char>(s), specs);
|
||||
@ -669,10 +670,11 @@ template <typename T, typename Char> struct formatter<std::complex<T>, Char> {
|
||||
auto format(const std::complex<T>& c, FormatContext& ctx) const
|
||||
-> decltype(ctx.out()) {
|
||||
auto specs = specs_;
|
||||
if (specs.width_ref.kind != detail::arg_id_kind::none ||
|
||||
specs.precision_ref.kind != detail::arg_id_kind::none) {
|
||||
detail::handle_dynamic_spec(specs.width, specs.width_ref, ctx);
|
||||
detail::handle_dynamic_spec(specs.precision, specs.precision_ref, ctx);
|
||||
if (specs.dynamic != 0) {
|
||||
detail::handle_dynamic_spec(specs.dynamic_width(), specs.width,
|
||||
specs.width_ref, ctx);
|
||||
detail::handle_dynamic_spec(specs.dynamic_precision(), specs.precision,
|
||||
specs.precision_ref, ctx);
|
||||
}
|
||||
|
||||
if (specs.width == 0) return do_format(c, specs, ctx, ctx.out());
|
||||
|
@ -525,9 +525,9 @@ TEST(base_test, constexpr_parse_format_specs) {
|
||||
static_assert(parse_test_specs("0").align == fmt::align::numeric, "");
|
||||
static_assert(parse_test_specs("L").localized, "");
|
||||
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.index == 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.index == 42, "");
|
||||
static_assert(parse_test_specs("f").type == fmt::presentation_type::fixed,
|
||||
"");
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user