🐛 Cannot call non-constexpr function in constexpr context (#2010)

Problem:
- gcc-8 gives the following error when compiling this function on all
  standards:
    test/std-format-test.cc: In member function 'constexpr auto std::formatter<S>::parse(std::format_parse_context&)':
    test/std-format-test.cc:112:17: error: call to non-'constexpr' function 'int isdigit(int)'
        if (!isdigit(c) || (++iter, get_char()) != '}')
         ~~~~~~~^~~

Solution:
- Write a `constexpr` version of `isdigit` for use in this function.

Co-authored-by: Jonathan Gopel <jgopel@quantlab.com>
This commit is contained in:
Jonathan Gopel 2020-11-12 11:10:52 -07:00 committed by GitHub
parent 986fa00406
commit aa9b09a9e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -103,13 +103,17 @@ template <> struct std::formatter<S> {
// Parses a width argument id in the format { <digit> }. // Parses a width argument id in the format { <digit> }.
constexpr auto parse(format_parse_context& ctx) { constexpr auto parse(format_parse_context& ctx) {
constexpr auto is_ascii_digit = [](const char c) {
return c >= '0' && c <= '9';
};
auto iter = ctx.begin(); auto iter = ctx.begin();
// auto get_char = [&]() { return iter != ctx.end() ? *iter : 0; }; // auto get_char = [&]() { return iter != ctx.end() ? *iter : 0; };
auto get_char = [&]() { return iter != ctx.end() ? *iter : '\0'; }; auto get_char = [&]() { return iter != ctx.end() ? *iter : '\0'; };
if (get_char() != '{') return iter; if (get_char() != '{') return iter;
++iter; ++iter;
char c = get_char(); char c = get_char();
if (!isdigit(c) || (++iter, get_char()) != '}') if (!is_ascii_digit(c) || (++iter, get_char()) != '}')
throw format_error("invalid format"); throw format_error("invalid format");
width_arg_id = fmt::detail::to_unsigned(c - '0'); width_arg_id = fmt::detail::to_unsigned(c - '0');
ctx.check_arg_id(width_arg_id); ctx.check_arg_id(width_arg_id);