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

Code before:
  return make_arg<Context>(val);
}

template <typename Context, size_t NUM_ARGS>
using arg_t = conditional_t<NUM_ARGS <= max_packed_args, value<Context>,
                            basic_format_arg<Context>>;

template <typename Char, typename T, FMT_ENABLE_IF(!is_named_arg<T>::value)>
void init_named_arg(named_arg_info<Char>*, int& arg_index, int&, const T&) {
  ++arg_index;
}
template <typename Char, typename T, FMT_ENABLE_IF(is_named_arg<T>::value)>
void init_named_arg(named_arg_info<Char>* named_args, int& arg_index,
                    int& named_arg_index, const T& arg) {
  named_args[named_arg_index++] = {arg.name, arg_index++};
}

// An array of references to arguments. It can be implicitly converted to
// `fmt::basic_format_args` for passing into type-erased formatting functions
// such as `fmt::vformat`.
template <typename Context, size_t NUM_ARGS, size_t NUM_NAMED_ARGS,
          unsigned long long DESC>
struct format_arg_store {
  // args_[0].named_args points to named_args to avoid bloating format_args.
  // +1 to workaround a bug in gcc 7.5 that causes duplicated-branches warning.
  static constexpr int ARGS_ARR_SIZE = 1 + (NUM_ARGS != 0 ? NUM_ARGS : +1);

  arg_t<Context, NUM_ARGS> args[ARGS_ARR_SIZE];
  named_arg_info<typename Context::char_type> named_args[NUM_NAMED_ARGS];

  template <typename... T>
  FMT_MAP_API format_arg_store(T&... values)
      : args{{named_args, NUM_NAMED_ARGS},
             make_arg<NUM_ARGS <= max_packed_args, Context>(values)...} {
    using dummy = int[];
    int arg_index = 0, named_arg_index = 0;
    (void)dummy{
        0,
        (init_named_arg(named_args, arg_index, named_arg_index, values), 0)...};
  }

  format_arg_store(const format_arg_store& rhs) {
    args[0] = {named_args, NUM_NAMED_ARGS};
    for (int i = 1; i < ARGS_ARR_SIZE; ++i) args[i] = rhs.args[i];
    for (int i = 0; i < static_cast<int>(NUM_NAMED_ARGS); ++i)
      named_args[i] = rhs.named_args[i];
  }

  format_arg_store(format_arg_store&& rhs) = delete;
  format_arg_store& operator=(const format_arg_store& rhs) = delete;
  format_arg_store& operator=(format_arg_store&& rhs) = delete;

Review comment (suggestion):
Maybe ``size_t`` (and ``i`` in copy constructor)?
Like ``size_t NUM_ARGS, size_t NUM_NAMED_ARGS`` template arguments.

Code after:
  return make_arg<Context>(val);
}

template <typename Context, size_t NUM_ARGS>
using arg_t = conditional_t<NUM_ARGS <= max_packed_args, value<Context>,
                            basic_format_arg<Context>>;

template <typename Char, typename T, FMT_ENABLE_IF(!is_named_arg<T>::value)>
void init_named_arg(named_arg_info<Char>*, int& arg_index, int&, const T&) {
  ++arg_index;
}
template <typename Char, typename T, FMT_ENABLE_IF(is_named_arg<T>::value)>
void init_named_arg(named_arg_info<Char>* named_args, int& arg_index,
                    int& named_arg_index, const T& arg) {
  named_args[named_arg_index++] = {arg.name, arg_index++};
}

// An array of references to arguments. It can be implicitly converted to
// `fmt::basic_format_args` for passing into type-erased formatting functions
// such as `fmt::vformat`.
template <typename Context, size_t NUM_ARGS, size_t NUM_NAMED_ARGS,
          unsigned long long DESC>
struct format_arg_store {
  // args_[0].named_args points to named_args to avoid bloating format_args.
  // +1 to workaround a bug in gcc 7.5 that causes duplicated-branches warning.
  static constexpr size_t ARGS_ARR_SIZE = 1 + (NUM_ARGS != 0 ? NUM_ARGS : +1);

  arg_t<Context, NUM_ARGS> args[ARGS_ARR_SIZE];
  named_arg_info<typename Context::char_type> named_args[NUM_NAMED_ARGS];

  template <typename... T>
  FMT_MAP_API format_arg_store(T&... values)
      : args{{named_args, NUM_NAMED_ARGS},
             make_arg<NUM_ARGS <= max_packed_args, Context>(values)...} {
    using dummy = int[];
    int arg_index = 0, named_arg_index = 0;
    (void)dummy{
        0,
        (init_named_arg(named_args, arg_index, named_arg_index, values), 0)...};
  }

  format_arg_store(format_arg_store&& rhs) {
    args[0] = {named_args, NUM_NAMED_ARGS};
    for (size_t i = 1; i < ARGS_ARR_SIZE; ++i) args[i] = rhs.args[i];
    for (size_t i = 0; i < NUM_NAMED_ARGS; ++i)
      named_args[i] = rhs.named_args[i];
  }

  format_arg_store(const format_arg_store& rhs) = delete;
  format_arg_store& operator=(const format_arg_store& rhs) = delete;
  format_arg_store& operator=(format_arg_store&& rhs) = delete;