Commit 3d11eac7 authored by Victor Zverovich's avatar Victor Zverovich

Workaround another MSVC constexpr bug

parent 25aac0be
...@@ -3070,7 +3070,7 @@ struct is_integer { ...@@ -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 { ...@@ -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> { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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< ...@@ -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 { ...@@ -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);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment