mirror of
https://github.com/fmtlib/fmt.git
synced 2024-11-07 17:41:11 +00:00
Optimize and simplify format string parsing
This commit is contained in:
parent
10c7f89351
commit
5614289dd8
@ -2124,34 +2124,27 @@ FMT_CONSTEXPR void parse_format_string(
|
|||||||
basic_string_view<Char> format_str, Handler &&handler) {
|
basic_string_view<Char> format_str, Handler &&handler) {
|
||||||
struct writer {
|
struct writer {
|
||||||
FMT_CONSTEXPR void operator()(const Char *begin, const Char *end) {
|
FMT_CONSTEXPR void operator()(const Char *begin, const Char *end) {
|
||||||
|
if (begin == end) return;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
const Char *p = FMT_NULL;
|
const Char *p = FMT_NULL;
|
||||||
if (!find<IS_CONSTEXPR>(begin, end, '}', p)) {
|
if (!find<IS_CONSTEXPR>(begin, end, '}', p))
|
||||||
handler_.on_text(begin, end);
|
return handler_.on_text(begin, end);
|
||||||
return;
|
|
||||||
}
|
|
||||||
++p;
|
++p;
|
||||||
if (p == end || *p != '}') {
|
if (p == end || *p != '}')
|
||||||
handler_.on_error("unmatched '}' in format string");
|
return handler_.on_error("unmatched '}' in format string");
|
||||||
return;
|
|
||||||
}
|
|
||||||
handler_.on_text(begin, p);
|
handler_.on_text(begin, p);
|
||||||
begin = p + 1;
|
begin = p + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Handler &handler_;
|
Handler &handler_;
|
||||||
} write{handler};
|
} write{handler};
|
||||||
auto begin = format_str.data();
|
auto begin = format_str.data(), end = begin + format_str.size();
|
||||||
auto end = begin + format_str.size();
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
// Doing two passes with memchr (one for '{' and another for '}') is up to
|
// Doing two passes with memchr (one for '{' and another for '}') is up to
|
||||||
// 2.5x faster than the naive one-pass implementation on big format strings.
|
// 2.5x faster than the naive one-pass implementation on big format strings.
|
||||||
const Char *p = FMT_NULL;
|
const Char *p = FMT_NULL;
|
||||||
if (!find<IS_CONSTEXPR>(begin, end, '{', p)) {
|
if (!find<IS_CONSTEXPR>(begin, end, '{', p))
|
||||||
if (begin != end)
|
return write(begin, end);
|
||||||
write(begin, end);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
write(begin, p);
|
write(begin, p);
|
||||||
++p;
|
++p;
|
||||||
if (p != end && *p == '{') {
|
if (p != end && *p == '{') {
|
||||||
@ -2159,7 +2152,6 @@ FMT_CONSTEXPR void parse_format_string(
|
|||||||
begin = p + 1;
|
begin = p + 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal::null_terminating_iterator<Char> it(p, end);
|
internal::null_terminating_iterator<Char> it(p, end);
|
||||||
it = parse_arg_id(it, id_adapter<Handler, Char>(handler));
|
it = parse_arg_id(it, id_adapter<Handler, Char>(handler));
|
||||||
if (*it == '}') {
|
if (*it == '}') {
|
||||||
@ -2167,17 +2159,13 @@ FMT_CONSTEXPR void parse_format_string(
|
|||||||
} else if (*it == ':') {
|
} else if (*it == ':') {
|
||||||
++it;
|
++it;
|
||||||
it = handler.on_format_specs(it);
|
it = handler.on_format_specs(it);
|
||||||
if (*it != '}') {
|
if (*it != '}')
|
||||||
handler.on_error("unknown format specifier");
|
return handler.on_error("unknown format specifier");
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
handler.on_error("missing '}' in format string");
|
return handler.on_error("missing '}' in format string");
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
begin = pointer_from(it) + 1;
|
begin = pointer_from(it) + 1;
|
||||||
if (begin == end)
|
if (begin == end) return;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user