From f288f45e46a7ce2ae430f8e055e086ccb83f9b31 Mon Sep 17 00:00:00 2001 From: Victor Zverovich Date: Thu, 5 Sep 2024 19:00:48 -0700 Subject: [PATCH] Prepare for arg_store unification --- include/fmt/base.h | 61 +++++++++++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 20 deletions(-) diff --git a/include/fmt/base.h b/include/fmt/base.h index bce0307c..72cac7c4 100644 --- a/include/fmt/base.h +++ b/include/fmt/base.h @@ -2362,12 +2362,9 @@ template using arg_t = conditional_t, basic_format_arg>; -// 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 { +struct named_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_ARRAY_SIZE = 1 + (NUM_ARGS != 0 ? NUM_ARGS : +1); @@ -2376,7 +2373,7 @@ struct format_arg_store { named_arg_info named_args[NUM_NAMED_ARGS]; template - FMT_CONSTEXPR FMT_ALWAYS_INLINE format_arg_store(T&... values) + FMT_CONSTEXPR FMT_ALWAYS_INLINE named_arg_store(T&... values) : args{{named_args, NUM_NAMED_ARGS}, arg_mapper::map(values)...} { int arg_index = 0, named_arg_index = 0; @@ -2384,24 +2381,30 @@ struct format_arg_store { init_named_arg(named_args, arg_index, named_arg_index, values)); } - format_arg_store(format_arg_store&& rhs) { + named_arg_store(named_arg_store&& rhs) { args[0] = {named_args, NUM_NAMED_ARGS}; for (size_t i = 1; i < ARGS_ARRAY_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; + named_arg_store(const named_arg_store& rhs) = delete; + named_arg_store& operator=(const named_arg_store& rhs) = delete; + named_arg_store& operator=(named_arg_store&& rhs) = delete; }; -// 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 { +// An array of references to arguments. It can be implicitly converted to +// `basic_format_args` for passing into type-erased formatting functions +// such as `vformat`. It is a plain struct to reduce binary size in debug mode. +template +struct format_arg_store { // +1 to workaround a bug in gcc 7.5 that causes duplicated-branches warning. - arg_t args[NUM_ARGS != 0 ? NUM_ARGS : +1]; + using type = + conditional_t[NUM_ARGS != 0 ? NUM_ARGS : +1], + named_arg_store>; + type args; }; // TYPE can be different from type_constant, e.g. for __float128. @@ -2640,19 +2643,37 @@ template class basic_format_args { /// Constructs a `basic_format_args` object from `format_arg_store`. template + FMT_ENABLE_IF(NUM_ARGS <= detail::max_packed_args && + NUM_NAMED_ARGS == 0)> constexpr FMT_ALWAYS_INLINE basic_format_args( const detail::format_arg_store& store) - : desc_(DESC), values_(store.args + (NUM_NAMED_ARGS != 0 ? 1 : 0)) {} + : desc_(DESC), values_(store.args) {} template detail::max_packed_args)> + FMT_ENABLE_IF(NUM_ARGS <= detail::max_packed_args && + NUM_NAMED_ARGS != 0)> + constexpr FMT_ALWAYS_INLINE basic_format_args( + const detail::format_arg_store& + store) + : desc_(DESC), values_(store.args.args + 1) {} + + template detail::max_packed_args && + NUM_NAMED_ARGS == 0)> constexpr basic_format_args( const detail::format_arg_store& store) : desc_(DESC), args_(store.args + (NUM_NAMED_ARGS != 0 ? 1 : 0)) {} + template detail::max_packed_args && + NUM_NAMED_ARGS != 0)> + constexpr basic_format_args( + const detail::format_arg_store& + store) + : desc_(DESC), args_(store.args.args + 1) {} + /// Constructs a `basic_format_args` object from a dynamic list of arguments. constexpr basic_format_args(const format_arg* args, int count, bool has_named = false) @@ -2863,8 +2884,8 @@ template constexpr FMT_ALWAYS_INLINE auto make_format_args(T&... args) -> detail::format_arg_store { - return {{{detail::arg_mapper::map(args) - FMT_CUSTOM}...}}; + FMT_GCC_PRAGMA(GCC diagnostic ignored "-Wconversion") + return {{detail::arg_mapper::map(args)...}}; } #ifndef FMT_DOC @@ -2876,7 +2897,7 @@ template constexpr auto make_format_args(T&... args) -> detail::format_arg_store { - return {args...}; + return {{args...}}; } #endif