basic_format_parse_context -> parse_context

This commit is contained in:
Victor Zverovich 2024-09-01 08:05:06 -07:00
parent 66920feeee
commit 64a6c84592
7 changed files with 55 additions and 71 deletions

View File

@ -782,7 +782,7 @@ using char_t = typename V::value_type;
* You can use the `format_parse_context` type alias for `char` instead.
*/
FMT_EXPORT
template <typename Char> class basic_format_parse_context {
template <typename Char> class parse_context {
private:
basic_string_view<Char> format_str_;
int next_arg_id_;
@ -793,8 +793,8 @@ template <typename Char> class basic_format_parse_context {
using char_type = Char;
using iterator = const Char*;
explicit constexpr basic_format_parse_context(
basic_string_view<Char> format_str, int next_arg_id = 0)
explicit constexpr parse_context(basic_string_view<Char> format_str,
int next_arg_id = 0)
: format_str_(format_str), next_arg_id_(next_arg_id) {}
/// Returns an iterator to the beginning of the format string range being
@ -840,16 +840,17 @@ template <typename Char> class basic_format_parse_context {
};
FMT_EXPORT
using format_parse_context = basic_format_parse_context<char>;
template <typename Char> using basic_format_parse_context = parse_context<Char>;
using format_parse_context = parse_context<char>;
namespace detail {
// A parse context with extra data used only in compile-time checks.
template <typename Char>
class compile_parse_context : public basic_format_parse_context<Char> {
class compile_parse_context : public parse_context<Char> {
private:
int num_args_;
const type* types_;
using base = basic_format_parse_context<Char>;
using base = parse_context<Char>;
public:
explicit FMT_CONSTEXPR compile_parse_context(
@ -1160,7 +1161,7 @@ template <typename T = char> class counting_buffer : public buffer<T> {
} // namespace detail
template <typename Char>
FMT_CONSTEXPR void basic_format_parse_context<Char>::do_check_arg_id(int id) {
FMT_CONSTEXPR void parse_context<Char>::do_check_arg_id(int id) {
// Argument id is only checked at compile-time during parsing because
// formatting has its own validation.
if (detail::is_constant_evaluated() &&
@ -1172,8 +1173,7 @@ FMT_CONSTEXPR void basic_format_parse_context<Char>::do_check_arg_id(int id) {
}
template <typename Char>
FMT_CONSTEXPR void basic_format_parse_context<Char>::check_dynamic_spec(
int arg_id) {
FMT_CONSTEXPR void parse_context<Char>::check_dynamic_spec(int arg_id) {
if (detail::is_constant_evaluated() &&
(!FMT_GCC_VERSION || FMT_GCC_VERSION >= 1200)) {
using context = detail::compile_parse_context<Char>;
@ -2047,7 +2047,7 @@ class context {
using iterator = appender;
using format_arg = basic_format_arg<context>;
using parse_context_type = basic_format_parse_context<char>;
using parse_context_type = parse_context<char>;
template <typename T> using formatter_type = formatter<T, char>;
enum { builtin_types = FMT_BUILTIN_TYPES };
@ -2474,7 +2474,7 @@ FMT_CONSTEXPR auto parse_arg_id(const Char* begin, const Char* end,
}
template <typename Char> struct dynamic_spec_handler {
basic_format_parse_context<Char>& ctx;
parse_context<Char>& ctx;
arg_ref<Char>& ref;
arg_id_kind& kind;
@ -2500,7 +2500,7 @@ template <typename Char> struct parse_dynamic_spec_result {
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)
parse_context<Char>& ctx)
-> parse_dynamic_spec_result<Char> {
FMT_ASSERT(begin != end, "");
auto kind = arg_id_kind::none;
@ -2533,8 +2533,7 @@ FMT_CONSTEXPR auto parse_dynamic_spec(const Char* begin, const Char* end,
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* {
parse_context<Char>& ctx) -> const Char* {
auto result = parse_dynamic_spec(begin, end, specs.width, width_ref, ctx);
specs.set_dynamic_width(result.kind);
return result.end;
@ -2544,8 +2543,7 @@ template <typename Char>
FMT_CONSTEXPR auto parse_precision(const Char* begin, const Char* end,
format_specs& specs,
arg_ref<Char>& precision_ref,
basic_format_parse_context<Char>& ctx)
-> const Char* {
parse_context<Char>& ctx) -> const Char* {
++begin;
if (begin == end) {
report_error("invalid precision");
@ -2563,8 +2561,8 @@ enum class state { start, align, sign, hash, zero, width, precision, locale };
template <typename Char>
FMT_CONSTEXPR auto parse_format_specs(const Char* begin, const Char* end,
dynamic_format_specs<Char>& specs,
basic_format_parse_context<Char>& ctx,
type arg_type) -> const Char* {
parse_context<Char>& ctx, type arg_type)
-> const Char* {
auto c = '\0';
if (end - begin > 1) {
auto next = to_ascii(begin[1]);
@ -2843,7 +2841,7 @@ FMT_CONSTEXPR inline auto check_char_specs(const format_specs& specs) -> bool {
template <typename T, typename Char>
FMT_VISIBILITY("hidden") // Suppress an ld warning on macOS (#3769).
FMT_CONSTEXPR auto parse_format_specs(basic_format_parse_context<Char>& ctx)
FMT_CONSTEXPR auto parse_format_specs(parse_context<Char>& ctx)
-> decltype(ctx.begin()) {
using context = buffered_context<Char>;
using mapped_type =
@ -2870,7 +2868,7 @@ class format_string_checker {
named_arg_info<Char> named_args_[NUM_NAMED_ARGS > 0 ? NUM_NAMED_ARGS : 1];
compile_parse_context<Char> context_;
using parse_func = const Char* (*)(basic_format_parse_context<Char>&);
using parse_func = const Char* (*)(parse_context<Char>&);
parse_func parse_funcs_[NUM_ARGS > 0 ? NUM_ARGS : 1];
public:
@ -2932,8 +2930,7 @@ template <typename T, typename Char, type TYPE> struct native_formatter {
public:
using nonlocking = void;
template <typename ParseContext>
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> const Char* {
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> const Char* {
if (ctx.begin() == ctx.end() || *ctx.begin() == '}') return ctx.begin();
auto end = parse_format_specs(ctx.begin(), ctx.end(), specs_, ctx, TYPE);
if (const_check(TYPE == type::char_type)) check_char_specs(specs_);

View File

@ -2098,8 +2098,7 @@ struct formatter<weekday, Char> : private formatter<std::tm, Char> {
bool use_tm_formatter_ = false;
public:
FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& ctx)
-> decltype(ctx.begin()) {
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> decltype(ctx.begin()) {
auto it = ctx.begin(), end = ctx.end();
if (it != end && *it == 'L') {
++it;
@ -2128,8 +2127,7 @@ struct formatter<day, Char> : private formatter<std::tm, Char> {
bool use_tm_formatter_ = false;
public:
FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& ctx)
-> decltype(ctx.begin()) {
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> decltype(ctx.begin()) {
auto it = ctx.begin(), end = ctx.end();
use_tm_formatter_ = it != end && *it != '}';
return use_tm_formatter_ ? formatter<std::tm, Char>::parse(ctx) : it;
@ -2154,8 +2152,7 @@ struct formatter<month, Char> : private formatter<std::tm, Char> {
bool use_tm_formatter_ = false;
public:
FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& ctx)
-> decltype(ctx.begin()) {
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> decltype(ctx.begin()) {
auto it = ctx.begin(), end = ctx.end();
if (it != end && *it == 'L') {
++it;
@ -2184,8 +2181,7 @@ struct formatter<year, Char> : private formatter<std::tm, Char> {
bool use_tm_formatter_ = false;
public:
FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& ctx)
-> decltype(ctx.begin()) {
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> decltype(ctx.begin()) {
auto it = ctx.begin(), end = ctx.end();
use_tm_formatter_ = it != end && *it != '}';
return use_tm_formatter_ ? formatter<std::tm, Char>::parse(ctx) : it;
@ -2209,8 +2205,7 @@ struct formatter<year_month_day, Char> : private formatter<std::tm, Char> {
bool use_tm_formatter_ = false;
public:
FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& ctx)
-> decltype(ctx.begin()) {
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> decltype(ctx.begin()) {
auto it = ctx.begin(), end = ctx.end();
use_tm_formatter_ = it != end && *it != '}';
return use_tm_formatter_ ? formatter<std::tm, Char>::parse(ctx) : it;
@ -2241,8 +2236,7 @@ struct formatter<std::chrono::duration<Rep, Period>, Char> {
basic_string_view<Char> format_str_;
public:
FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& ctx)
-> decltype(ctx.begin()) {
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> decltype(ctx.begin()) {
auto it = ctx.begin(), end = ctx.end();
if (it == end || *it == '}') return it;
@ -2327,8 +2321,7 @@ template <typename Char> struct formatter<std::tm, Char> {
}
public:
FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& ctx)
-> decltype(ctx.begin()) {
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> decltype(ctx.begin()) {
auto it = ctx.begin(), end = ctx.end();
if (it == end || *it == '}') return it;

View File

@ -71,7 +71,7 @@ constexpr const auto& get([[maybe_unused]] const T& first,
return detail::get<N - 1>(rest...);
}
#if FMT_USE_NONTYPE_TEMPLATE_ARGS
# if FMT_USE_NONTYPE_TEMPLATE_ARGS
template <int N, typename T, typename... Args, typename Char>
constexpr auto get_arg_index_by_name(basic_string_view<Char> name) -> int {
if constexpr (is_statically_named_arg<T>()) {
@ -82,14 +82,14 @@ constexpr auto get_arg_index_by_name(basic_string_view<Char> name) -> int {
(void)name; // Workaround an MSVC bug about "unused" parameter.
return -1;
}
#endif
# endif
template <typename... Args, typename Char>
FMT_CONSTEXPR auto get_arg_index_by_name(basic_string_view<Char> name) -> int {
#if FMT_USE_NONTYPE_TEMPLATE_ARGS
# if FMT_USE_NONTYPE_TEMPLATE_ARGS
if constexpr (sizeof...(Args) > 0)
return get_arg_index_by_name<0, Args...>(name);
#endif
# endif
(void)name;
return -1;
}

View File

@ -1039,7 +1039,7 @@ template <typename OutputIt, typename Char> class generic_context {
public:
using char_type = Char;
using iterator = OutputIt;
using parse_context_type = basic_format_parse_context<Char>;
using parse_context_type = parse_context<Char>;
template <typename T> using formatter_type = formatter<T, Char>;
enum { builtin_types = FMT_BUILTIN_TYPES };
@ -3693,7 +3693,7 @@ template <typename Char> struct default_arg_formatter {
void operator()(typename basic_format_arg<context>::handle h) {
// Use a null locale since the default format must be unlocalized.
auto parse_ctx = basic_format_parse_context<Char>({});
auto parse_ctx = parse_context<Char>({});
auto format_ctx = context(out, {}, {});
h.format(parse_ctx, format_ctx);
}
@ -4099,8 +4099,7 @@ template <typename T, typename Char = char> struct nested_formatter {
public:
constexpr nested_formatter() : width_(0) {}
FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& ctx)
-> decltype(ctx.begin()) {
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> decltype(ctx.begin()) {
auto it = ctx.begin(), end = ctx.end();
if (it == end) return it;
auto specs = format_specs();
@ -4179,46 +4178,45 @@ FMT_END_EXPORT
namespace detail {
template <typename Char> struct format_handler {
basic_format_parse_context<Char> parse_context;
buffered_context<Char> context;
parse_context<Char> parse_ctx;
buffered_context<Char> ctx;
void on_text(const Char* begin, const Char* end) {
copy_noinline<Char>(begin, end, context.out());
copy_noinline<Char>(begin, end, ctx.out());
}
FMT_CONSTEXPR auto on_arg_id() -> int { return parse_context.next_arg_id(); }
FMT_CONSTEXPR auto on_arg_id() -> int { return parse_ctx.next_arg_id(); }
FMT_CONSTEXPR auto on_arg_id(int id) -> int {
parse_context.check_arg_id(id);
parse_ctx.check_arg_id(id);
return id;
}
FMT_CONSTEXPR auto on_arg_id(basic_string_view<Char> id) -> int {
parse_context.check_arg_id(id);
int arg_id = context.arg_id(id);
parse_ctx.check_arg_id(id);
int arg_id = ctx.arg_id(id);
if (arg_id < 0) report_error("argument not found");
return arg_id;
}
FMT_INLINE void on_replacement_field(int id, const Char*) {
context.arg(id).visit(default_arg_formatter<Char>{context.out()});
ctx.arg(id).visit(default_arg_formatter<Char>{ctx.out()});
}
auto on_format_specs(int id, const Char* begin, const Char* end)
-> const Char* {
auto arg = get_arg(context, id);
auto arg = get_arg(ctx, id);
// Not using a visitor for custom types gives better codegen.
if (arg.format_custom(begin, parse_context, context))
return parse_context.begin();
if (arg.format_custom(begin, parse_ctx, ctx)) return parse_ctx.begin();
auto specs = dynamic_format_specs<Char>();
begin = parse_format_specs(begin, end, specs, parse_context, arg.type());
begin = parse_format_specs(begin, end, specs, parse_ctx, arg.type());
if (specs.dynamic()) {
handle_dynamic_spec(specs.dynamic_width(), specs.width, specs.width_ref,
context);
ctx);
handle_dynamic_spec(specs.dynamic_precision(), specs.precision,
specs.precision_ref, context);
specs.precision_ref, ctx);
}
arg.visit(arg_formatter<Char>{context.out(), specs, context.locale()});
arg.visit(arg_formatter<Char>{ctx.out(), specs, ctx.locale()});
return begin;
}
@ -4232,8 +4230,7 @@ void vformat_to(buffer<Char>& buf, basic_string_view<Char> fmt,
if (fmt.size() == 2 && equal2(fmt.data(), "{}"))
return args.get(0).visit(default_arg_formatter<Char>{out});
parse_format_string<false>(
fmt, format_handler<Char>{basic_format_parse_context<Char>(fmt),
{out, args, loc}});
fmt, format_handler<Char>{parse_context<Char>(fmt), {out, args, loc}});
}
FMT_BEGIN_EXPORT

View File

@ -33,7 +33,7 @@ template <typename Char> class basic_printf_context {
public:
using char_type = Char;
using parse_context_type = basic_format_parse_context<Char>;
using parse_context_type = parse_context<Char>;
template <typename T> using formatter_type = printf_formatter<T>;
enum { builtin_types = 1 };
@ -302,7 +302,7 @@ class printf_arg_formatter : public arg_formatter<Char> {
}
void operator()(typename basic_format_arg<context_type>::handle handle) {
auto parse_ctx = basic_format_parse_context<Char>({});
auto parse_ctx = parse_context<Char>({});
handle.format(parse_ctx, context_);
}
};
@ -421,7 +421,7 @@ void vprintf(buffer<Char>& buf, basic_string_view<Char> format,
using iterator = basic_appender<Char>;
auto out = iterator(buf);
auto context = basic_printf_context<Char>(out, args);
auto parse_ctx = basic_format_parse_context<Char>(format);
auto parse_ctx = parse_context<Char>(format);
// Returns the argument with specified index or, if arg_index is -1, the next
// argument.

View File

@ -508,8 +508,7 @@ template <typename Char>
struct formatter<std::type_info, Char // DEPRECATED! Mixing code unit types.
> {
public:
FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& ctx)
-> decltype(ctx.begin()) {
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> decltype(ctx.begin()) {
return ctx.begin();
}
@ -530,8 +529,7 @@ struct formatter<
bool with_typename_ = false;
public:
FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& ctx)
-> decltype(ctx.begin()) {
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> decltype(ctx.begin()) {
auto it = ctx.begin();
auto end = ctx.end();
if (it == end || *it == '}') return it;
@ -659,8 +657,7 @@ template <typename T, typename Char> struct formatter<std::complex<T>, Char> {
}
public:
FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& ctx)
-> decltype(ctx.begin()) {
FMT_CONSTEXPR auto parse(parse_context<Char>& ctx) -> decltype(ctx.begin()) {
if (ctx.begin() == ctx.end() || *ctx.begin() == '}') return ctx.begin();
return parse_format_specs(ctx.begin(), ctx.end(), specs_, ctx,
detail::type_constant<T, Char>::value);

View File

@ -59,7 +59,7 @@ inline auto write_loc(basic_appender<wchar_t> out, loc_value value,
FMT_BEGIN_EXPORT
using wstring_view = basic_string_view<wchar_t>;
using wformat_parse_context = basic_format_parse_context<wchar_t>;
using wformat_parse_context = parse_context<wchar_t>;
using wformat_context = buffered_context<wchar_t>;
using wformat_args = basic_format_args<wformat_context>;
using wmemory_buffer = basic_memory_buffer<wchar_t>;