diff --git a/include/fmt/core.h b/include/fmt/core.h index 3bd312f2..dcfb5081 100644 --- a/include/fmt/core.h +++ b/include/fmt/core.h @@ -1191,34 +1191,12 @@ template struct named_arg_info { int id; }; -template -inline void init_named_args(named_arg_info*, int, int) {} - template struct is_named_arg : std::false_type {}; template struct is_statically_named_arg : std::false_type {}; template struct is_named_arg> : std::true_type {}; -template ::value)> -void init_named_args(named_arg_info* named_args, int arg_count, - int named_arg_count, const T&, const Tail&... args) { - init_named_args(named_args, arg_count + 1, named_arg_count, args...); -} - -template ::value)> -void init_named_args(named_arg_info* named_args, int arg_count, - int named_arg_count, const T& arg, const Tail&... args) { - named_args[named_arg_count++] = {arg.name, arg_count}; - init_named_args(named_args, arg_count + 1, named_arg_count, args...); -} - -template -FMT_CONSTEXPR FMT_INLINE void init_named_args(std::nullptr_t, int, int, - const Args&...) {} - template constexpr auto count() -> size_t { return B ? 1 : 0; } template constexpr auto count() -> size_t { return (B1 ? 1 : 0) + count(); @@ -1596,46 +1574,47 @@ template using arg_t = conditional_t, basic_format_arg>; +template ::value)> +void init_named_arg(named_arg_info*, int& arg_index, int&, const T&) { + ++arg_index; +} +template ::value)> +void init_named_arg(named_arg_info* 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 struct format_arg_store { - static const bool is_packed = NUM_ARGS <= detail::max_packed_args; - - using char_type = typename Context::char_type; - using value_type = arg_t; - // 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. - value_type args_[1 + (NUM_ARGS != 0 ? NUM_ARGS : +1)]; - detail::named_arg_info named_args[NUM_NAMED_ARGS]; + arg_t args[1 + (NUM_ARGS != 0 ? NUM_ARGS : +1)]; + named_arg_info named_args[NUM_NAMED_ARGS]; template - FMT_CONSTEXPR FMT_INLINE format_arg_store(T&... args) - : args_{{named_args, NUM_NAMED_ARGS}, - detail::make_arg(args)...} { - detail::init_named_args(named_args, 0, 0, args...); - } - - FMT_CONSTEXPR FMT_INLINE auto args() const -> const value_type* { - return args_ + 1; + FMT_CONSTEXPR FMT_INLINE format_arg_store(T&... values) + : args{{named_args, NUM_NAMED_ARGS}, + make_arg(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)...}; } }; // A specialization of format_arg_store without named arguments. +// It is a plain struct to reduce binary size in debug mode. template struct format_arg_store { - using value_type = arg_t; - // +1 to workaround a bug in gcc 7.5 that causes duplicated-branches warning. - value_type args_[NUM_ARGS != 0 ? NUM_ARGS : +1]; - - FMT_CONSTEXPR FMT_INLINE auto args() const -> const value_type* { - return args_; - } + arg_t args[NUM_ARGS != 0 ? NUM_ARGS : +1]; }; + } // namespace detail FMT_BEGIN_EXPORT @@ -1808,14 +1787,14 @@ template class basic_format_args { constexpr basic_format_args( const detail::format_arg_store& store) - : desc_(DESC), values_(store.args()) {} + : desc_(DESC), values_(store.args + (NUM_NAMED_ARGS != 0 ? 1 : 0)) {} template detail::max_packed_args)> constexpr basic_format_args( const detail::format_arg_store& store) - : desc_(DESC), args_(store.args()) {} + : desc_(DESC), args_(store.args + (NUM_NAMED_ARGS != 0 ? 1 : 0)) {} /** \rst