mirror of
https://github.com/fmtlib/fmt.git
synced 2024-12-25 15:21:54 +00:00
Cleanup arg id parsing
This commit is contained in:
parent
2b0ff62a7f
commit
9ea9b6bcb1
@ -348,22 +348,18 @@ constexpr parse_specs_result<T, Char> parse_specs(basic_string_view<Char> str,
|
||||
template <typename Char> struct arg_id_handler {
|
||||
arg_ref<Char> arg_id;
|
||||
|
||||
constexpr int operator()() {
|
||||
constexpr int on_auto() {
|
||||
FMT_ASSERT(false, "handler cannot be used with automatic indexing");
|
||||
return 0;
|
||||
}
|
||||
constexpr int operator()(int id) {
|
||||
constexpr int on_index(int id) {
|
||||
arg_id = arg_ref<Char>(id);
|
||||
return 0;
|
||||
}
|
||||
constexpr int operator()(basic_string_view<Char> id) {
|
||||
constexpr int on_name(basic_string_view<Char> id) {
|
||||
arg_id = arg_ref<Char>(id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
constexpr void on_error(const char* message) {
|
||||
FMT_THROW(format_error(message));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char> struct parse_arg_id_result {
|
||||
|
@ -2425,20 +2425,20 @@ FMT_CONSTEXPR auto do_parse_arg_id(const Char* begin, const Char* end,
|
||||
else
|
||||
++begin;
|
||||
if (begin == end || (*begin != '}' && *begin != ':'))
|
||||
handler.on_error("invalid format string");
|
||||
throw_format_error("invalid format string");
|
||||
else
|
||||
handler(index);
|
||||
handler.on_index(index);
|
||||
return begin;
|
||||
}
|
||||
if (!is_name_start(c)) {
|
||||
handler.on_error("invalid format string");
|
||||
throw_format_error("invalid format string");
|
||||
return begin;
|
||||
}
|
||||
auto it = begin;
|
||||
do {
|
||||
++it;
|
||||
} while (it != end && (is_name_start(c = *it) || ('0' <= c && c <= '9')));
|
||||
handler(basic_string_view<Char>(begin, to_unsigned(it - begin)));
|
||||
} while (it != end && (is_name_start(*it) || ('0' <= *it && *it <= '9')));
|
||||
handler.on_name({begin, to_unsigned(it - begin)});
|
||||
return it;
|
||||
}
|
||||
|
||||
@ -2447,7 +2447,7 @@ FMT_CONSTEXPR FMT_INLINE auto parse_arg_id(const Char* begin, const Char* end,
|
||||
IDHandler&& handler) -> const Char* {
|
||||
Char c = *begin;
|
||||
if (c != '}' && c != ':') return do_parse_arg_id(begin, end, handler);
|
||||
handler();
|
||||
handler.on_auto();
|
||||
return begin;
|
||||
}
|
||||
|
||||
@ -2455,25 +2455,22 @@ template <typename Char> struct dynamic_spec_id_handler {
|
||||
basic_format_parse_context<Char>& ctx;
|
||||
dynamic_spec<Char> spec;
|
||||
|
||||
FMT_CONSTEXPR void operator()() {
|
||||
FMT_CONSTEXPR void on_auto() {
|
||||
spec.kind = dynamic_spec_kind::index;
|
||||
spec.value = ctx.next_arg_id();
|
||||
ctx.check_dynamic_spec(spec.value);
|
||||
}
|
||||
FMT_CONSTEXPR void operator()(int id) {
|
||||
FMT_CONSTEXPR void on_index(int id) {
|
||||
spec.kind = dynamic_spec_kind::index;
|
||||
spec.value = id;
|
||||
ctx.check_arg_id(id);
|
||||
ctx.check_dynamic_spec(id);
|
||||
}
|
||||
FMT_CONSTEXPR void operator()(basic_string_view<Char> id) {
|
||||
FMT_CONSTEXPR void on_name(basic_string_view<Char> id) {
|
||||
spec.kind = dynamic_spec_kind::name;
|
||||
spec.name = id;
|
||||
ctx.check_arg_id(id);
|
||||
}
|
||||
FMT_CONSTEXPR void on_error(const char* message) {
|
||||
if (message) throw_format_error("invalid format string");
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Char> struct parse_dynamic_spec_result {
|
||||
@ -2654,14 +2651,11 @@ FMT_CONSTEXPR auto parse_replacement_field(const Char* begin, const Char* end,
|
||||
Handler& handler;
|
||||
int arg_id;
|
||||
|
||||
FMT_CONSTEXPR void operator()() { arg_id = handler.on_arg_id(); }
|
||||
FMT_CONSTEXPR void operator()(int id) { arg_id = handler.on_arg_id(id); }
|
||||
FMT_CONSTEXPR void operator()(basic_string_view<Char> id) {
|
||||
FMT_CONSTEXPR void on_auto() { arg_id = handler.on_arg_id(); }
|
||||
FMT_CONSTEXPR void on_index(int id) { arg_id = handler.on_arg_id(id); }
|
||||
FMT_CONSTEXPR void on_name(basic_string_view<Char> id) {
|
||||
arg_id = handler.on_arg_id(id);
|
||||
}
|
||||
FMT_CONSTEXPR void on_error(const char* message) {
|
||||
if (message) handler.on_error(message);
|
||||
}
|
||||
};
|
||||
|
||||
++begin;
|
||||
|
@ -485,30 +485,28 @@ TEST(arg_test, visit_invalid_arg) {
|
||||
|
||||
#if FMT_USE_CONSTEXPR
|
||||
|
||||
enum class arg_id_result { none, empty, index, name, error };
|
||||
enum class arg_id_result { none, empty, index, name };
|
||||
struct test_arg_id_handler {
|
||||
arg_id_result res = arg_id_result::none;
|
||||
int index = 0;
|
||||
string_view name;
|
||||
|
||||
constexpr void operator()() { res = arg_id_result::empty; }
|
||||
constexpr void on_auto() { res = arg_id_result::empty; }
|
||||
|
||||
constexpr void operator()(int i) {
|
||||
constexpr void on_index(int i) {
|
||||
res = arg_id_result::index;
|
||||
index = i;
|
||||
}
|
||||
|
||||
constexpr void operator()(string_view n) {
|
||||
constexpr void on_name(string_view n) {
|
||||
res = arg_id_result::name;
|
||||
name = n;
|
||||
}
|
||||
|
||||
constexpr void on_error(const char*) { res = arg_id_result::error; }
|
||||
};
|
||||
|
||||
template <size_t N>
|
||||
constexpr test_arg_id_handler parse_arg_id(const char (&s)[N]) {
|
||||
test_arg_id_handler h;
|
||||
auto h = test_arg_id_handler();
|
||||
fmt::detail::parse_arg_id(s, s + N, h);
|
||||
return h;
|
||||
}
|
||||
@ -520,7 +518,6 @@ TEST(format_test, constexpr_parse_arg_id) {
|
||||
static_assert(parse_arg_id("42:").index == 42, "");
|
||||
static_assert(parse_arg_id("foo:").res == arg_id_result::name, "");
|
||||
static_assert(parse_arg_id("foo:").name.size() == 3, "");
|
||||
static_assert(parse_arg_id("!").res == arg_id_result::error, "");
|
||||
}
|
||||
|
||||
struct test_format_specs_handler {
|
||||
|
Loading…
Reference in New Issue
Block a user