Repository: fmtlib/fmt
File: include/fmt/core.h (C/C++)

Code before:
  }

  template <typename Char>
  auto get_id(basic_string_view<Char> name) const -> int {
    if (!has_named_args()) return -1;
    const auto& named_args =
        (is_packed() ? values_[-1] : args_[-1].value_).named_args;
    for (size_t i = 0; i < named_args.size; ++i) {
      if (named_args.data[i].name == name) return named_args.data[i].id;
    }
    return -1;
  }

  auto max_size() const -> int {
    unsigned long long max_packed = detail::max_packed_args;
    return static_cast<int>(is_packed() ? max_packed
                                        : desc_ & ~detail::is_unpacked_bit);
  }
};

/** An alias to ``basic_format_args<format_context>``. */
// A separate type would result in shorter symbols but break ABI compatibility
// between clang and gcc on ARM (#1919).
using format_args = basic_format_args<format_context>;

// We cannot use enum classes as bit fields because of a gcc bug before 9.3
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61414.
#if FMT_GCC_VERSION && FMT_GCC_VERSION < 903
# define FMT_ENUM_UNDERLYING_TYPE(type)
#else
# define FMT_ENUM_UNDERLYING_TYPE(type) : type
#endif

namespace align {
enum type FMT_ENUM_UNDERLYING_TYPE(unsigned char) { none, left, right, center, numeric };
}
using align_t = align::type;
namespace sign {
enum type FMT_ENUM_UNDERLYING_TYPE(unsigned char) { none, minus, plus, space };
}
using sign_t = sign::type;

FMT_BEGIN_DETAIL_NAMESPACE

// Workaround an array initialization issue in gcc 4.8.
template <typename Char> struct fill_t {
 private:
  enum { max_size = 4 };
  Char data_[max_size] = {Char(' '), Char(0), Char(0), Char(0)};
  unsigned char size_ = 1;


Review comment (suggestion):
The issue with pre-9.3 gcc version seems to be about underlying types rather than enum classes because we don't use the former in both branches below. So the part about 9.3 should probably not be folded in the original comment which belongs in front of `namespace align` to explain why we use namespace + enum instead of scoped enums.

Code after:
  }

  template <typename Char>
  auto get_id(basic_string_view<Char> name) const -> int {
    if (!has_named_args()) return -1;
    const auto& named_args =
        (is_packed() ? values_[-1] : args_[-1].value_).named_args;
    for (size_t i = 0; i < named_args.size; ++i) {
      if (named_args.data[i].name == name) return named_args.data[i].id;
    }
    return -1;
  }

  auto max_size() const -> int {
    unsigned long long max_packed = detail::max_packed_args;
    return static_cast<int>(is_packed() ? max_packed
                                        : desc_ & ~detail::is_unpacked_bit);
  }
};

/** An alias to ``basic_format_args<format_context>``. */
// A separate type would result in shorter symbols but break ABI compatibility
// between clang and gcc on ARM (#1919).
using format_args = basic_format_args<format_context>;

// We cannot use enum classes as bit fields because of a gcc bug,
// so we put them in namespaces instead.
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61414.
// Additionally, if an underlying type is specified, older gcc incorrectly warns
// that the type is too small for all the enum values.
// Both these bugs are fixed as of gcc 9.3.
#if FMT_GCC_VERSION && FMT_GCC_VERSION < 903
# define FMT_ENUM_UNDERLYING_TYPE(type)
#else
# define FMT_ENUM_UNDERLYING_TYPE(type) : type
#endif
namespace align {
enum type FMT_ENUM_UNDERLYING_TYPE(unsigned char) { none, left, right, center, numeric };
}
using align_t = align::type;
namespace sign {
enum type FMT_ENUM_UNDERLYING_TYPE(unsigned char) { none, minus, plus, space };
}
using sign_t = sign::type;

FMT_BEGIN_DETAIL_NAMESPACE

// Workaround an array initialization issue in gcc 4.8.
template <typename Char> struct fill_t {
 private:
  enum { max_size = 4 };