mirror of
https://github.com/fmtlib/fmt.git
synced 2025-08-01 03:34:45 +02:00
Workaround another MSVC constexpr bug
This commit is contained in:
80
fmt/format.h
80
fmt/format.h
@@ -3070,7 +3070,7 @@ struct is_integer {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct width_handler {
|
struct width_checker {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename std::enable_if<is_integer<T>::value, unsigned long long>::type
|
typename std::enable_if<is_integer<T>::value, unsigned long long>::type
|
||||||
operator()(T value) {
|
operator()(T value) {
|
||||||
@@ -3087,7 +3087,7 @@ struct width_handler {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct precision_handler {
|
struct precision_checker {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename std::enable_if<is_integer<T>::value, unsigned long long>::type
|
typename std::enable_if<is_integer<T>::value, unsigned long long>::type
|
||||||
operator()(T value) {
|
operator()(T value) {
|
||||||
@@ -3234,13 +3234,13 @@ class specs_handler: public specs_setter<typename Context::char_type> {
|
|||||||
|
|
||||||
template <typename Id>
|
template <typename Id>
|
||||||
void on_dynamic_width(Id arg_id) {
|
void on_dynamic_width(Id arg_id) {
|
||||||
set_dynamic_spec<internal::width_handler>(
|
set_dynamic_spec<internal::width_checker>(
|
||||||
this->specs_.width_, get_arg(arg_id));
|
this->specs_.width_, get_arg(arg_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Id>
|
template <typename Id>
|
||||||
void on_dynamic_precision(Id arg_id) {
|
void on_dynamic_precision(Id arg_id) {
|
||||||
set_dynamic_spec<internal::precision_handler>(
|
set_dynamic_spec<internal::precision_checker>(
|
||||||
this->specs_.precision_, get_arg(arg_id));
|
this->specs_.precision_, get_arg(arg_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3361,6 +3361,36 @@ constexpr Iterator parse_arg_id(Iterator it, Handler& handler) {
|
|||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Handler, typename Char>
|
||||||
|
struct width_handler {
|
||||||
|
explicit constexpr width_handler(Handler &h) : handler(h) {}
|
||||||
|
|
||||||
|
constexpr void operator()() { handler.on_dynamic_width(auto_id()); }
|
||||||
|
constexpr void operator()(unsigned id) { handler.on_dynamic_width(id); }
|
||||||
|
constexpr void operator()(basic_string_view<Char> id) {
|
||||||
|
handler.on_dynamic_width(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void on_error(const char *message) { handler.on_error(message); }
|
||||||
|
|
||||||
|
Handler &handler;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Handler, typename Char>
|
||||||
|
struct precision_handler {
|
||||||
|
explicit constexpr precision_handler(Handler &h) : handler(h) {}
|
||||||
|
|
||||||
|
constexpr void operator()() { handler.on_dynamic_precision(auto_id()); }
|
||||||
|
constexpr void operator()(unsigned id) { handler.on_dynamic_precision(id); }
|
||||||
|
constexpr void operator()(basic_string_view<Char> id) {
|
||||||
|
handler.on_dynamic_precision(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr void on_error(const char *message) { handler.on_error(message); }
|
||||||
|
|
||||||
|
Handler &handler;
|
||||||
|
};
|
||||||
|
|
||||||
// Parses standard format specifiers and sends notifications about parsed
|
// Parses standard format specifiers and sends notifications about parsed
|
||||||
// components to handler.
|
// components to handler.
|
||||||
// it: an iterator pointing to the beginning of a null-terminated range of
|
// it: an iterator pointing to the beginning of a null-terminated range of
|
||||||
@@ -3436,21 +3466,7 @@ constexpr Iterator parse_format_specs(Iterator it, Handler &handler) {
|
|||||||
if ('0' <= *it && *it <= '9') {
|
if ('0' <= *it && *it <= '9') {
|
||||||
handler.on_width(parse_nonnegative_int(it));
|
handler.on_width(parse_nonnegative_int(it));
|
||||||
} else if (*it == '{') {
|
} else if (*it == '{') {
|
||||||
struct width_handler {
|
width_handler<Handler, char_type> wh(handler);
|
||||||
explicit constexpr width_handler(Handler &h) : handler(h) {}
|
|
||||||
|
|
||||||
constexpr void operator()() { handler.on_dynamic_width(auto_id()); }
|
|
||||||
constexpr void operator()(unsigned id) { handler.on_dynamic_width(id); }
|
|
||||||
constexpr void operator()(basic_string_view<char_type> id) {
|
|
||||||
handler.on_dynamic_width(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr void on_error(const char *message) {
|
|
||||||
handler.on_error(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
Handler &handler;
|
|
||||||
} wh(handler);
|
|
||||||
it = parse_arg_id(it + 1, wh);
|
it = parse_arg_id(it + 1, wh);
|
||||||
if (*it++ != '}') {
|
if (*it++ != '}') {
|
||||||
handler.on_error("invalid format string");
|
handler.on_error("invalid format string");
|
||||||
@@ -3464,23 +3480,7 @@ constexpr Iterator parse_format_specs(Iterator it, Handler &handler) {
|
|||||||
if ('0' <= *it && *it <= '9') {
|
if ('0' <= *it && *it <= '9') {
|
||||||
handler.on_precision(parse_nonnegative_int(it));
|
handler.on_precision(parse_nonnegative_int(it));
|
||||||
} else if (*it == '{') {
|
} else if (*it == '{') {
|
||||||
struct precision_handler {
|
precision_handler<Handler, char_type> ph(handler);
|
||||||
explicit constexpr precision_handler(Handler &h) : handler(h) {}
|
|
||||||
|
|
||||||
constexpr void operator()() { handler.on_dynamic_precision(auto_id()); }
|
|
||||||
constexpr void operator()(unsigned id) {
|
|
||||||
handler.on_dynamic_precision(id);
|
|
||||||
}
|
|
||||||
constexpr void operator()(basic_string_view<char_type> id) {
|
|
||||||
handler.on_dynamic_precision(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr void on_error(const char *message) {
|
|
||||||
handler.on_error(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
Handler &handler;
|
|
||||||
} ph(handler);
|
|
||||||
it = parse_arg_id(it + 1, ph);
|
it = parse_arg_id(it + 1, ph);
|
||||||
if (*it++ != '}') {
|
if (*it++ != '}') {
|
||||||
handler.on_error("invalid format string");
|
handler.on_error("invalid format string");
|
||||||
@@ -3567,9 +3567,9 @@ struct formatter<
|
|||||||
}
|
}
|
||||||
|
|
||||||
void format(basic_buffer<Char> &buf, const T &val, basic_context<Char> &ctx) {
|
void format(basic_buffer<Char> &buf, const T &val, basic_context<Char> &ctx) {
|
||||||
internal::handle_dynamic_spec<internal::width_handler>(
|
internal::handle_dynamic_spec<internal::width_checker>(
|
||||||
specs_.width_, specs_.width_ref, ctx);
|
specs_.width_, specs_.width_ref, ctx);
|
||||||
internal::handle_dynamic_spec<internal::precision_handler>(
|
internal::handle_dynamic_spec<internal::precision_checker>(
|
||||||
specs_.precision_, specs_.precision_ref, ctx);
|
specs_.precision_, specs_.precision_ref, ctx);
|
||||||
visit(arg_formatter<Char>(buf, ctx, specs_),
|
visit(arg_formatter<Char>(buf, ctx, specs_),
|
||||||
internal::make_arg<basic_context<Char>>(val));
|
internal::make_arg<basic_context<Char>>(val));
|
||||||
@@ -3645,9 +3645,9 @@ struct dynamic_formatter {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void handle_specs(basic_context<Char> &ctx) {
|
void handle_specs(basic_context<Char> &ctx) {
|
||||||
internal::handle_dynamic_spec<internal::width_handler>(
|
internal::handle_dynamic_spec<internal::width_checker>(
|
||||||
specs_.width_, specs_.width_ref, ctx);
|
specs_.width_, specs_.width_ref, ctx);
|
||||||
internal::handle_dynamic_spec<internal::precision_handler>(
|
internal::handle_dynamic_spec<internal::precision_checker>(
|
||||||
specs_.precision_, specs_.precision_ref, ctx);
|
specs_.precision_, specs_.precision_ref, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user